1000分的问题!!!!!!(100分)

  • 主题发起人 主题发起人 面条
  • 开始时间 开始时间

面条

Unregistered / Unconfirmed
GUEST, unregistred user!

有谁知道用Delphi怎么才能
1、让DHTML Edit控件支持鼠标拖动?
2、怎样才能支持Copy/Paste?
如果回答了以上两问,我将以1000分作为答谢
 
哇,面条馋死俺啦。

不会。 :(
 
大虾们帮忙来看看............
 
自己编程(其实我也想知道)
 
望面而叹...sigh..别忘了知道了通知一下(200点!!)
 
光面?肉丝面?菜面?还是。。。呵呵~~~
旁听!
 
我也很想知道
 
是奄萝卜丝......是奄萝卜片........还是奄萝卜块???
:)
还是当旁听者舒服.......
 
DHTML Edit控件在哪???
提个想法.
1.找个控件支持鼠标拖动的例子看看.
2.给DHTML Edit控件加一个POPMenu.
 
那里有dhtml edit 空间
 
有源程序吗
有的话自己修改,
重载相关的消息

 
MSDN有关于IE的说明!看看便知!
好面!
 

DHTML Edit控件在哪一页。

有源码就好办。
 
我来赚你五百分!
拖动我这里一切正常,而快捷键的失效却百思不得其解。
这几天,我辛辛苦苦搜索了五湖四海,总算功夫不负有心人。
请仔细看,肯定有部分需要改正,假若改对了源代码,请贴上来。

Lost keys in the IE5 ActiveX controls

Abstract:Hooking the IWebBrowser and DHTML controls to properly handle keystrokes

The problem: If you import the Internet Explorer or Microsoft DHTML ActiveX controls into Delphi or C++Builder, the control does not respond to certain keystrokes (Tab, in the case of IE, and delete, in the case of DHTML).


The reasons for the problem: The problem occurs because of a combination of peculiar behavior on the part of the controls, and peculiar behavior on the part of the Delphi and C++Builder IDEs.


How the control is strange: The control believes that the keys in question should be treated as accelerators and wishes to handle them as such, rather than as Windows key down messages.


What Delphi and C++Builder are doing: TApplication catches all windows messages. As part of the processing of such messages, it allows windows contained within the application to respond to key messages themselves rather than use the default processing To allow VCL-wrapped windows to distinguish between messages passed to them by TApplication in the middle of message processing from messages which have been passed on after TApplication has given up on processing them, the VCL modifies the message and passes the modified message to the window via SendMessage. (The relevant code is in forms.pas: Application.IsKeyMsg).

When an ActiveX control is imported, it is wrapped by a descendant class of TOleControl (olectrls.pas). TOleControl hooks the window procedure
the hook catches the messages thrown by Application, modifies them back to their original state, and calls IOleInPlaceActiveObject.TranslateAccelerator, allowing the code to respond to accelerators.

With most controls, this works. Unfortunately, the dynamic nature of the IE controls causes a problem, in that the window which is recieving the messages is either a child or a grandchild of the window which has been subclassed. Their window procedures don't understand the messages they are recieving from TApplication (and so ignore them)
the accelerators never get translated
and the message that was intended by pressing tab or delete gets lost.

How Delphi 5 solves the problem: The problem was solved in Delphi 5 by modifying the behavior of TApplication.IsKeyMsg to walk the parent chain of a non-VCL window until a VCL window is encountered, and then throw the modified message at it. This allows the TOleControl wrapper to ask the control to translate the accelerator.


How you can solve the problem in C++Builder 4 or Delphi 4: The problem can be solved on an ad-hoc basis by dynamically subclassing the window procedures of the controls in question. (An earlier fix to the problem in Delphi5 involved modifying TOleControl to subclass the windows of all children created by the embedded Ole control
the problem with this approach was that, while the controls notify you verify their event interfaces when their children are destroyed and recreated, they do not pass such a notification through a standard Ole interface, so it was difficult to find a general-case mechanism for the container to know when to hook the child windows).


When to hook the window procedure: In the case of the WebBrowser control, a new child window is created whenever a new web page is accessed (and so the window procedure should be hooked in the OnNavigatComplete2 or the OnNewWindow2 event handlers). In the case of the DHTML control, there is usually only one child window whose creation is delayed until well past the creation of the control itself
manually hooking its window procedure in the form's OnActivate method should work).


How to get the handle for the window: The handle for the window that you want to subclass can be retrieved in one of two ways (one is generic, the other is not). You can get the handle for the window which was subclassed at the creation of the control by accessing the Handle method of the TOleControl descendant, using code that looks more or less like the following pascal code:


{these are members of Form1}

WebBrowser1 : TWebBrowser;
FFrameWndProcInstance: Pointer;
FFrameHwnd : HWND;
FFrameDefWndProc : Pointer;

function Form1.SubClassFrame;
var
Child : HWND;
begin
Child := GetWindow(WebBrowser1.Handle, GW_CHILD);
if Child <> 0 then
begin
Child := GetWindow(Child, GW_CHILD);
if (Child <>0) and (Child <> FFrameHwnd) then
{ don't bother subclassing if you've already got it subclassed }
begin
if FFrameWndProcInstance <> nil then
UnSubClassFrame;
FFrameHwnd := Child;
FFrameWndProcInstance := MakeObjectInstance(FrameWndProc);
FFrameDefWndProc := Pointer(GetWindowLong(FFrameHwnd, GWL_WNDPROC));
SetWindowLong(FFrameHwnd, GWL_WNDPROC, LongInt(FFrameWndProcInstance));
end;
end;
end;

function Form1.UnSubClassFrame;
begin
if (FFrameWndProcInstance <> nil and (FDefFrameWndProc) <> nil and (FFrameHwnd <> 0) then
begin
SetWindowLong(FFrameHwnd, GWL_WNDPROC, LongInt(FDefFrameWndProc));
FFrameWndProcInstance := nil;
FFrameHwnd := nil;
{ require the caller to set FDefFrameWndProc to nil so you can unsubclass and then call the default
proc when responding to WM_DESTROY events }
end;
end;
Alternately, you can ask the control to return to you an IOleInPlaceActiveObject interface, and query it for its window handle:
function Form1.SubClassFrame;
var
ActiveObject : IOleInPlaceActiveObject;
Child : HWND;
begin
if (WebBrowser1.DefaultDispatch.QueryInterface(IOleInPlaceActiveObject, ActiveObject) = S_OK) then
try
Child := ActiveObject.GetWindow;
if (Child <> nil) and (Child <> FFrameHwnd) then
begin
if FFrameWndProcInstance <> nil then
UnSubClassFrame;
FFrameHwnd := Child;
FFrameWndProcInstance := MakeObjectInstance(FrameWndProc);
FFrameDefWndProc := Pointer(GetWindowLong(FFrameHwnd, GWL_WNDPROC));
SetWindowLong(FFrameHwnd, GWL_WNDPROC, LongInt(FFrameWndProcInstance));
end;
finally
ActiveObject.Release;
end;
end;

function Form1.UnSubClassFrame;
var
ActiveObject: IOleInPlaceActiveObject;
begin
if (WebBrowser1.DefaultDispatch.QueryInterface(IOleInPlaceActiveObject, ActiveObject) = S_OK) then
try
if (FFrameWndProcInstance <> nil and (FDefFrameWndProc) <> nil and (FFrameHwnd <> 0) then
begin
SetWindowLong(FFrameHwnd, GWL_WNDPROC, LongInt(FDefFrameWndProc));
FFrameWndProcInstance := nil;
FFrameHwnd := nil;
{ require the caller to set FDefFrameWndProc to nil so you can unsubclass and then call the default
proc when responding to WM_DESTROY events }
end;
finally
ActiveObject.Release;
end;
end;
What the window procedure should do. The window procedure hook you install should, at a minimum, pass the key messages on to the ole control's accelerator treanslator, properly unhook itself in response to a WM_DESTROY message,and pass all other messages along to the default window procedure, as per the following example:
procedure Form1.FrameWndProc(var Message: TMessage);
var
WinMsg: TMsg;
ActiveObject : IOleInPlaceActiveObject;
begin
if (Message.Msg >= CN_BASE + WM_KEYFIRST)
and (Message.Msg <= CN_BASE + WM_KEYLAST) then
begin
WinMsg.HWnd := WebBrowser1.Handle;
WinMsg.Message := Message.Msg - CN_BASE;
WinMsg.WParam := Message.WParam;
WinMsg.LParam := Message.LParam;
WinMsg.Time := GetMessagTime;
WinMsg.Pt.X := $115DE1F1;
WinMsg.Pt.Y= $115DE1F1;
if (WebBrowser1.DefaultDispatch.QueryInterface(IOleInPlaceActiveObject, ActiveObject) = S_OK) then
try
if ActiveObject.TranslateAccelerator(WinMsg) = S_OK then
begin
Message.Result := 1;
WinMsg.Pt.X := $5ACC355;
end;
finally
ActiveObject.Release;
end;
if WinMsg.Pt.X = $5ACC355 then
Exit;
end;
with Message do
begin
case Msg of
WM_DESTROY:
begin
UnSubClassFrame;
CallWindowProc(FDefFrameWndProc, FFrameHwnd, Message.Msg, Message.WParam, Message.LParam);
FDefFrameWndProc := nil;
end;
end;
Result := CallWindowProc(FDefFrameWndProc, FFrameHwnd, Msg, WParam, LParam);
end;
end;




 
这是在调用DHTMLEDIT 的SetContextMenu()时要用到的VB代码:
Dim strings() As String
Dim states() As OLE_TRISTATE
strings(0) = "Cut"
strings(1) = "Copy"
strings(2) = "Paste"
states(0) = Unchecked
states(1) = checked
states(2) = Gray

DHTMLEdit1.SetContextMenu strings, states

各位能帮我将它翻译成DELPHI代码么?
或者请到http://www.gislab.ecnu.edu.cn/delphibbs/DispQ.asp?ID=291737回答领赏。
谢谢!
 
luket:
谢谢,我去始一下。
VB我来翻译。
 
有的时候,修改 EDIT 还不如
限制一下 RichEdit 来实现需要的功能
 
luket:
你的代码我看了,答非所问呀!
我要的是如何使DHTML中的文字、按钮等可以用鼠标拖动,
而你的文档及代码是解决在TWebbrowser和DHTML控件中丢失击键事件的问题的!
如果你有满足我要求的源代码,请MEIL我。
 
1000分?未免太好赚了 :-)

先拿300分表示一下诚意吧,成功后另付700可以了吧?哈哈哈...
(自言自语道:我怎么早没看见,好在没有被人"抢走"... ^_^)
 
后退
顶部