如何才能让一个非活动窗口获得键盘事件? ( 积分: 200 )

  • 主题发起人 主题发起人 峻祁连
  • 开始时间 开始时间

峻祁连

Unregistered / Unconfirmed
GUEST, unregistred user!
我需要向一个窗口传递一个keyPress或keydown事件,以便在这个事件处理函数里作些工作。但由于要实时信息显示,所以用了mousemove的时候show另外一个信息显示窗体,这样信息显示窗体就总是活动窗口,而接收所有客户事件,我想要接收事件的主窗口反而接收不到?<br> &nbsp;怎么才能禁止信息显示窗口接收制定事件呢?或者指定非活动的主窗口接收事件?或者让信息窗口接收事件后再传递给主窗体?
 
我需要向一个窗口传递一个keyPress或keydown事件,以便在这个事件处理函数里作些工作。但由于要实时信息显示,所以用了mousemove的时候show另外一个信息显示窗体,这样信息显示窗体就总是活动窗口,而接收所有客户事件,我想要接收事件的主窗口反而接收不到?<br> &nbsp;怎么才能禁止信息显示窗口接收制定事件呢?或者指定非活动的主窗口接收事件?或者让信息窗口接收事件后再传递给主窗体?
 
先用SPY++工具查看该窗口的类<br>再用FindWindow(刚才查看到的类名,nil):返回窗口句柄<br>再用SendMessage(刚才得到的窗口句柄,参数1,参数2,参数3)来发送键盘消息<br>参数1,参数2,参数3根据你要发送的具体消息而定
 
To 峻祁连, <br>老大,我看了3分钟您的题目都没看懂,您用代码来表述已一下吧
 
自定义类如下,因为代码比较多,为了看清楚,我把不相关的部分删除了。<br>===========================<br>unit TRouteEditorClass;<br><br>interface<br>uses Controls, Classes, MapXLib_TLB, Variants, TeEngine, windows, SysUtils,<br> &nbsp;frmuRouteSimpleInfo, Math,TypeOfPoint,TRoadRuleClass,frmuRouteDetailInfo,<br> &nbsp;dchyMapModule, &nbsp;Dialogs, DataModuleAdo,<br> &nbsp;frmuRouteDataWin, &nbsp;uConstDefine, PSMainUnit,Messages,<br> &nbsp;uRoutePlanning, uPointSortAndSearch, ProjectionAndSort;<br>type TRouteEditor = class(TMap)<br><br> &nbsp;private<br> &nbsp; &nbsp;{ Private declarations }<br> &nbsp; &nbsp;m_IriMouseMoveEvent: TMouseMoveEvent;<br> &nbsp; &nbsp;m_IriKeyDownEvent : TKeyEvent; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//keydown 和keyPress用一个就可以了,能达到目的就行,<br> &nbsp; &nbsp;m_IriMapKeyPress : TKeyPressEvent; &nbsp; &nbsp; &nbsp;// &nbsp;我这里写了两个是想都试一下,哪个能用用哪个,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//按说要有一个弄同的话,另一个应该也没问题<br> &nbsp; &nbsp;<br> &nbsp; &nbsp;m_frmRouteDetailInfo : TfrmRouteDetailInfo; &nbsp; &nbsp; &nbsp; &nbsp; //信息显示窗口<br><br><br> &nbsp; &nbsp;procedure MyKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);<br><br> &nbsp; &nbsp;procedure MyKeyPress(Sender: TObject; var Key: Char);<br><br> &nbsp;public<br> &nbsp; &nbsp;{ public declarations }<br><br> &nbsp; &nbsp;constructor Create(currentMap : TMap;roadLayer,nodeLayer,GuiHuaRouteLayer,customerLayer : CMapXLayer);<br> &nbsp; &nbsp;function CreateAddRouteTool: Integer;<br> &nbsp; &nbsp;function InstallAddRouteTool(): Boolean;<br> &nbsp; &nbsp;function UnInstallAddRouteTool(): Boolean;<br> &nbsp; &nbsp;function GetToolNum(): Integer;<br> &nbsp;end;<br><br>const<br> &nbsp;MAP_ADDROUTE_TOOL = 805;<br> &nbsp;ADD_ROUTE_TOLERANCE = 30; &nbsp;//手工画线路时,必须和道路中线的最大距离,超出此距离则认为画线无效<br><br>implementation<br><br>var<br> &nbsp;myMapModule : TdchyMapModule;<br><br>{ TRouteEditor }<br><br>function TRouteEditor.InstallAddRouteTool: Boolean;<br>begin<br> &nbsp;if m_pMap &lt;&gt; nil then<br> &nbsp;begin<br> &nbsp; &nbsp;//保存原先的事件处理函数状态<br> &nbsp; &nbsp;m_IriKeyDownEvent := m_pMap.OnKeyDown;<br> &nbsp; &nbsp;m_IriMapKeyPress := m_pMap.OnKeyPress;<br><br> &nbsp; &nbsp;m_pMap.OnKeyDown := MyKeyDown;<br> &nbsp; &nbsp;m_pMap.OnKeyPress := MyKeyPress;<br> &nbsp; &nbsp;result := True;<br> &nbsp;end<br> &nbsp;else<br> &nbsp; &nbsp;result := False;<br>end;<br><br>procedure TRouteEditor.MyKeyDown(Sender: TObject; var Key: Word;<br> &nbsp;Shift: TShiftState);<br>begin<br> &nbsp;if (m_pMap.CurrentTool = MAP_ADDROUTE_TOOL) and (Key = VK_ESCAPE) then begin<br> &nbsp; &nbsp;// 我会在这里写业务相关代码,以相应键盘发送VK_ESCAPE事件***********<br> &nbsp; &nbsp;end;<br><br> &nbsp; &nbsp;//退出自定义工具<br> &nbsp; &nbsp;m_pMap.CurrentTool := miArrowTool;<br> &nbsp; &nbsp;myMapModule.DeleteTempAnimationLayer(m_pMap, m_strRuleFlagLayer);<br> &nbsp; &nbsp;UnInstallAddRouteTool;<br> &nbsp;end;<br><br> &nbsp;if @m_IriKeyDownEvent &lt;&gt; nil then<br> &nbsp; &nbsp;m_IriKeyDownEvent(Sender,Key, Shift);<br>end;<br><br><br>procedure TRouteEditor.MapMouseMove(Sender: TObject; Shift: TShiftState; X,<br> &nbsp;Y: Integer);<br>begin<br> &nbsp; &nbsp;//显示信息窗口出来*******************<br> &nbsp; &nbsp;if m_frmRouteDetailInfo = nil then <br> &nbsp; &nbsp; &nbsp;m_frmRouteDetailInfo := Tm_frmRouteDetailInfo.Create(nil);<br> &nbsp; m_frmRouteDetailInfo.Show;<br><br> &nbsp;if @m_IriMouseMoveEvent &lt;&gt; nil then<br> &nbsp; &nbsp;m_IriMouseMoveEvent(Sender, Shift, X, Y);<br>end;<br><br>function TRouteEditor.UnInstallAddRouteTool: Boolean;<br>begin<br> &nbsp;if m_pMap &lt;&gt; nil then<br> &nbsp;begin<br> &nbsp; &nbsp; &nbsp;//回复原先的事件处理函数状态<br><br> &nbsp; &nbsp;m_pMap.OnKeyDown := m_IriKeyDownEvent;<br> &nbsp; &nbsp;m_pMap.OnKeyPress := m_IriMapKeyPress;<br><br> &nbsp; &nbsp;m_IriKeyDownEvent := nil;<br> &nbsp; &nbsp;m_IriMapKeyPress := nil;<br> &nbsp; &nbsp;result := True;<br> &nbsp;end<br> &nbsp;else<br> &nbsp; &nbsp;result := False;<br>end;<br><br>procedure TRouteEditor.MyKeyPress(Sender: TObject; var Key: Char);<br>begin<br> &nbsp;if (m_pMap.CurrentTool = MAP_ADDROUTE_TOOL) and ((Key = 'u') or (Key = 'U')) then begin<br> &nbsp; &nbsp; // 我会在这里写业务相关代码,以相应键盘事件***********<br> &nbsp;end;<br> &nbsp;<br> &nbsp; &nbsp;//退出自定义工具<br> &nbsp; &nbsp;UnInstallAddRouteTool;<br> &nbsp;end;<br><br><br> &nbsp;if @m_IriMapKeyPress &lt;&gt; nil then<br> &nbsp; &nbsp;m_IriMapKeyPress(Sender, Key);<br>end;<br><br>end.<br>========================<br><br><br>调用代码<br>===========<br> &nbsp;//初始化RouteEditor类,画线工具<br> &nbsp;if RouteEditor = nil then<br> &nbsp;begin<br> &nbsp; &nbsp; &nbsp;RouteEditor := TRouteEditor.Create();<br> &nbsp; &nbsp; &nbsp;RouteEditor.CreateAddRouteTool;<br> &nbsp;end;<br><br>======================<br><br>由于自定义类截获了mouseMove事件,所有在发生mouseMove时会把信息显示窗口(TfrmRouteDetailInfo)show出来,这样主窗体就接受不到键盘事件了。<br><br>我按照 饭前饭后 的方法,在信息显示窗口(TfrmRouteDetailInfo)类中 增加keyPress事件处理函数用sendmessage传给主窗口,但跟踪结果显示 信息显示窗口根本就没有发生keyPress事件,就是说下面的代码没有执行<br>procedure TfrmRouteDetailInfo.FormKeyPress(Sender: TObject; var Key: Char);<br>var<br> &nbsp;MainFormTitle : array[0..127] of char;<br> &nbsp;Hold : string;<br> &nbsp;Found : HWND;<br>begin<br> &nbsp;inherited;<br> &nbsp;//只允许有一个实例运行,如果已经有一个在运行则激活它<br> &nbsp;Hold := frmAPMain.Caption; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//取得程序的标题<br> &nbsp;StrPCopy(MainFormTitle, Hold); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // 原窗口标题<br> &nbsp;Found := FindWindow(nil, MainFormTitle); &nbsp; // 查找窗口<br> &nbsp;if Found &lt;&gt; 0 then<br> &nbsp;begin<br> &nbsp; &nbsp;SendMessage(Found, WM_CHAR, Ord('u'), 0);<br> &nbsp; &nbsp;SendMessage(Found, WM_CHAR, Ord('U'), 0);<br> &nbsp;end;<br>end;
 
没看懂,先留个位置
 
if m_frmRouteDetailInfo = nil then <br> &nbsp; &nbsp; &nbsp;m_frmRouteDetailInfo := Tm_frmRouteDetailInfo.Create(nil);<br> &nbsp; m_frmRouteDetailInfo.Show;<br>这里,你还是可以把主窗口设回为active啊,setforegroundwindow....
 
多人接受答案了。
 
后退
顶部