如何转发鼠标操作:快来边拿高分边救人啊!(200分)

  • 主题发起人 主题发起人 genuine
  • 开始时间 开始时间
G

genuine

Unregistered / Unconfirmed
GUEST, unregistred user!
举个例子来说,假设有button1,button2两个按钮,我想让按下button1的时候好像按到了<br>button2上,我使用了一个hook来截取Button1上的消息,然后将鼠标消息用postmessage<br>转发到button2的句柄上,可是它不能工作,而且消息被转发后button1居然按不下去了,<br>请问有什么方法能达到我的目的吗?我要转发所有的鼠标操作,<br>哪位大虾能不吝赐教,救我一次,感激一辈子。
 
try<br>Application.OnMouseDown
 
如果两个button是一个应用程序,一定要用hook吗。如果不是一个应用程序,试试sendmessage
 
我还不太明白你说的“按下button1的时候好像按到了button2上”是什么意思?,是在按<br>Button1的时候就等于按Button2吗?<br>procedure TForm1.Button1Click(Sender: TObject);<br>begin<br>&nbsp; Button2.Click;<br>end;<br>还是指的Button2像被按下去的样子?如果是后者,你用成SpeedButton,把Down设成True就<br>好了嘛。
 
这个问题很好解决的阿. 你重写一下Application.OnMessage不就行啦.呵呵,我以前也做过
 
我觉得你可以用button1的事件实现button2的效果,应该可以呀
 
估计你是用了inherited的,这样Button1还是会接收到Onclick事件。
 
{<br>现在将源代码浓缩后贴在这里,请各位大虾诊断一下,使用 hook或<br>App.OnMessage效果完全一样,都是可以触发click,mousemove等事件,<br>但是有许多表现还是做不到完全一样,首先Button2.Cursor我设置成了<br>crHandPoint,Button1.Cursor=crDefault,但是当鼠标在button1上移动<br>时光标却不能变成crhandPoint,仍然是箭头,另外,当按下鼠标左键在<br>button1中移动的时候,button2不能保持按下状态,而是会弹起来,<br>现在怀疑问题可能出在Focus这种系统唯一的资源上,因为在button1上操作,<br>focus就在button1上,虽然将消息转发到了button2,可能也无法做到好像<br>完全象在button2上操作,因为有些消息会造成focus的切换,所以曾经<br>观察到过焦点切换的闪动现象,希望各位大侠告知如何解决这个问题,<br>可以将源代码拷贝到自己delphi里试一下就知道效果到底是怎么样的了,<br>我希望的是能做到完全一样,包括cursor状态等<br>}<br><br>unit MsgTest;<br><br>interface<br><br>uses<br>&nbsp; Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,<br>&nbsp; StdCtrls, ExtCtrls;<br><br>type<br>&nbsp; TForm1 = class(TForm)<br>&nbsp; &nbsp; Memo1: TMemo;<br>&nbsp; &nbsp; btHook: TButton;<br>&nbsp; &nbsp; btUnHook: TButton;<br>&nbsp; &nbsp; btAppMessage: TButton;<br>&nbsp; &nbsp; Button1: TButton;<br>&nbsp; &nbsp; Button2: TButton;<br>&nbsp; &nbsp; procedure button2Click(Sender: TObject);<br>&nbsp; &nbsp; procedure button2MouseMove(Sender: TObject; Shift: TShiftState; X,<br>&nbsp; &nbsp; &nbsp; Y: Integer);<br>&nbsp; &nbsp; procedure btAppMessageClick(Sender: TObject);<br>&nbsp; &nbsp; procedure btHookClick(Sender: TObject);<br>&nbsp; &nbsp; procedure btUnHookClick(Sender: TObject);<br>&nbsp; private<br>&nbsp; &nbsp; FNewProc,FDefProc : Pointer;<br>&nbsp; &nbsp; Procedure AppMessage(var Msg: TMsg; var Handled: Boolean);<br>&nbsp; &nbsp; procedure Button1NewWndProc(var Msg: TMessage);<br>&nbsp; public<br>&nbsp; &nbsp; { Public declarations }<br>&nbsp; end;<br><br>var<br>&nbsp; Form1: TForm1;<br><br>implementation<br><br>{$R *.DFM}<br><br>procedure TForm1.button2Click(Sender: TObject);<br>begin<br>&nbsp; Memo1.lines.Add('Panel2Click');<br>end;<br><br>procedure TForm1.button2MouseMove(Sender: TObject; Shift: TShiftState; X,<br>&nbsp; Y: Integer);<br>begin<br>&nbsp; Memo1.lines.Add('MouseMove');<br>end;<br><br>Procedure TForm1.AppMessage(var Msg: TMsg; var Handled: Boolean);<br>begin<br>&nbsp; if msg.hwnd = button1.handle then<br>&nbsp; begin<br>&nbsp; &nbsp; //必须判断转发的消息范围,如果全部转发,则反而没有任何响应<br>&nbsp; &nbsp; if (Msg.Message &gt;= WM_KEYFIRST) and (Msg.Message &lt;= WM_KEYLAST) or<br>&nbsp; &nbsp; &nbsp; &nbsp;(Msg.Message &gt;= WM_MOUSEFIRST) and (Msg.Message &lt;= WM_MOUSELAST) then<br>&nbsp; &nbsp; &nbsp; //以下消息用于处理mousemove时cursor的正确显示,但还是不能正常显示,暂时先注释掉<br>&nbsp; &nbsp; &nbsp; &nbsp;{(Msg.Message = wm_setcursor) or<br>&nbsp; &nbsp; &nbsp; &nbsp;(Msg.Message = CM_CURSORCHANGED) or<br>&nbsp; &nbsp; &nbsp; &nbsp;(Msg.Message=wm_nchittest) or<br>&nbsp; &nbsp; &nbsp; &nbsp;(Msg.Message = WM_SysCommand) then}<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; postmessage(button2.handle,Msg.Message,Msg.WParam,Msg.LParam);<br>&nbsp; &nbsp; &nbsp; handled := true;<br>&nbsp; &nbsp; end;<br>&nbsp; &nbsp; {if (MSg.message = wm_SetFocus) then //or (MSg.message = wm_KillFocus) then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; Handled := True;<br>&nbsp; &nbsp; end;}<br>&nbsp; end;<br>end;<br><br>procedure TForm1.btAppMessageClick(Sender: TObject);<br>begin<br>&nbsp; application.OnMessage := appmessage;<br><br>end;<br><br>procedure TForm1.Button1NewWndProc(var Msg: TMessage);<br>var<br>&nbsp; Handled : Boolean;<br>begin<br>&nbsp; Handled := False;<br>&nbsp; if (Msg.msg &gt;= WM_KEYFIRST) and (Msg.Msg &lt;= WM_KEYLAST) or<br>&nbsp; &nbsp; &nbsp;(Msg.msg &gt;= WM_MOUSEFIRST) and (Msg.Msg &lt;= WM_MOUSELAST) then<br>&nbsp; &nbsp; &nbsp; { (Msg.Message = wm_setcursor) or<br>&nbsp; &nbsp; &nbsp; &nbsp;(Msg.Message = CM_CURSORCHANGED) or<br>&nbsp; &nbsp; &nbsp; &nbsp;(Msg.Message=wm_nchittest) or<br>&nbsp; &nbsp; &nbsp; &nbsp;(Msg.Message = WM_SysCommand) then}<br>&nbsp; begin<br>&nbsp; &nbsp; postmessage(button2.handle,Msg.Msg,Msg.WParam,Msg.LParam);<br>&nbsp; &nbsp; //sendMessage与此相同<br>&nbsp; &nbsp; handled := true;<br>&nbsp; end;<br><br>&nbsp; if not Handled then<br>&nbsp; &nbsp; Msg.Result := CallWindowProc(FDefProc, Button1.Handle, Msg.Msg, Msg.WParam, Msg.LParam);<br>end;<br><br>procedure TForm1.btHookClick(Sender: TObject);<br>begin<br>&nbsp; FNewProc := MakeObjectInstance(Button1NewWndProc);<br>&nbsp; FDefProc := Pointer(SetWindowLong(button1.handle, GWL_WNDPROC, LongInt(FNewProc)));<br><br>end;<br><br>procedure TForm1.btUnHookClick(Sender: TObject);<br>begin<br>&nbsp; SetWindowLong(button1.Handle, GWL_WNDPROC, LongInt(FDefProc));<br>&nbsp; FreeObjectInstance(FNewProc);<br>end;<br><br>end.<br><br><br><br>
 
提问者:<br>如果你还要继续讨论请定期提前你的帖子,如果不想继续讨论请结束帖子。<br>请认真阅读大富翁论坛规则说明 &nbsp;http://www.delphibbs.com/delphibbs/rules.asp<br>
 
你巴下面的代码写在button1的click事件里就可以了;<br>Button2Click(Sender);<br><br>例:procedure TForm1.Button1Click(Sender: TObject);<br>  begin<br>  Button2Click(Sender);<br>  end;
 
代码如下:<br>unit Unit1;<br><br>interface<br><br>uses<br>&nbsp; Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,<br>&nbsp; StdCtrls, ExtCtrls;<br><br>type<br>&nbsp; TForm1 = class(TForm)<br>&nbsp; &nbsp; Button1: TButton;<br>&nbsp; &nbsp; Button2: TButton;<br>&nbsp; &nbsp; procedure Button1Click(Sender: TObject);<br>&nbsp; &nbsp; procedure FormShow(Sender: TObject);<br>&nbsp; private<br>&nbsp; &nbsp; OldProc : TWndMethod;<br>&nbsp; &nbsp; procedure NewProc(var Message: TMessage);<br>&nbsp; end;<br><br>var<br>&nbsp; Form1: TForm1;<br>implementation<br><br>{$R *.DFM}<br><br>procedure TForm1.Button1Click(Sender: TObject);<br>begin<br>&nbsp; ShowMessage('Button1Click');<br>end;<br><br>procedure TForm1.FormShow(Sender: TObject);<br>begin<br>&nbsp; OldProc := Button2.WindowProc;<br>&nbsp; Self.Button2.WindowProc := Self.NewProc;<br>end;<br><br>procedure TForm1.NewProc(var Message: TMessage);<br>begin<br>&nbsp; if ((Message.Msg &gt;= WM_KEYFIRST) and (Message.Msg &lt;= WM_KEYLAST)) or<br>&nbsp; &nbsp; &nbsp; &nbsp;((Message.Msg &gt;= WM_MOUSEFIRST) and (Message.Msg &lt;= WM_MOUSELAST)) then<br>&nbsp; &nbsp; PostMessage(Button1.Handle,Message.Msg,Message.WParam,Message.LParam)<br>&nbsp; else<br>&nbsp; &nbsp; OldProc(Message);<br>end;<br><br>end.<br>
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
2K
DelphiTeacher的专栏
D
后退
顶部