全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:2092
推到 Plurk!
推到 Facebook!

keyboard hook呼出onshow事件為什麼不起作用

尚未結案
mathewzhao
中階會員


發表:121
回覆:164
積分:67
註冊:2003-04-04

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-04-15 14:29:39 IP:61.150.xxx.xxx 未訂閱
我的作業系統為 windows2000 server delphi版本為 delphi5 我設計程式啟動後到desktop 右下角任務區小圖標,使用keyboard Hook做DLL,攔截Ctrl F1按鍵,如攔截到,用showwindow顯示窗體,這時希望窗體一顯示,用onshow事件先向串埠髮指令,然後等待串埠輸入,但窗體顯示後無任何動作發生,即onshow沒起作用,不知怎樣可以解決這個問題
william
版主


發表:66
回覆:2535
積分:3048
註冊:2002-07-11

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-04-15 14:45:18 IP:147.8.xxx.xxx 未訂閱
Perhaps OnShow is not what you want, OnActivate is more suitable, IMHO. Remember to set the form's focus. 
mathewzhao
中階會員


發表:121
回覆:164
積分:67
註冊:2003-04-04

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-04-15 15:15:38 IP:61.150.xxx.xxx 未訂閱
非常感謝william的回應 OnActivate事件我已試用過,仍不成功。 但我不明白你說的"set the form's focus" 在何處設置,我想可能是原因
william
版主


發表:66
回覆:2535
積分:3048
註冊:2002-07-11

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-04-15 16:21:07 IP:147.8.xxx.xxx 未訂閱
Form1.SetFocus?
mathewzhao
中階會員


發表:121
回覆:164
積分:67
註冊:2003-04-04

發送簡訊給我
#5 引用回覆 回覆 發表時間:2003-04-15 16:52:46 IP:61.150.xxx.xxx 未訂閱
我明白你的意思了, 但還不成功!
william
版主


發表:66
回覆:2535
積分:3048
註冊:2002-07-11

發送簡訊給我
#6 引用回覆 回覆 發表時間:2003-04-15 17:05:34 IP:147.8.xxx.xxx 未訂閱
Strange? But since you use ShowWindow to popup the form, why not create a custom message and send it to the form telling it to do the serial port operation?
mathewzhao
中階會員


發表:121
回覆:164
積分:67
註冊:2003-04-04

發送簡訊給我
#7 引用回覆 回覆 發表時間:2003-04-15 17:17:33 IP:61.150.xxx.xxx 未訂閱
能否給出示例,謝謝!
william
版主


發表:66
回覆:2535
積分:3048
註冊:2002-07-11

發送簡訊給我
#8 引用回覆 回覆 發表時間:2003-04-15 17:35:43 IP:147.8.xxx.xxx 未訂閱
const
    WM_TEST = WM_USER   1;
{...}
type
    TForm1 = class(TForm)
        procedure Test(var Msg: TMessage); message WM_TEST;
    end;
{...}
    Form1.Perform(WM_TEST,0,0);
mathewzhao
中階會員


發表:121
回覆:164
積分:67
註冊:2003-04-04

發送簡訊給我
#9 引用回覆 回覆 發表時間:2003-04-15 19:42:12 IP:61.150.xxx.xxx 未訂閱
william兄,我已按你的指點試了一下,還是有問題,你看下面的結構對不對, 希望各位先進也給予指點 const WM_Test = WM_USER 1; type procedure FormShow(Sender: TObject); private procedure WMTest(var Msg : TMESSAGE); message WM_TesT; { Private declarations } public { Public declarations } end; implementation {$R *.DFM} function createkeyboardHook: BOOL; external 'test.DLL'; function freekeyboardHook: BOOL; external 'test.DLL'; procedure TForm1.FormShow(Sender: TObject); begin Form1.Perform(WM_HotKey,0,0); end; procedure TForm1.WMTest(var Msg : TMESSAGE); begin //串埠處理部分 end. procedure TForm1.Formcreate(Sender: TObject); begin createkeyboardHook; end;
william
版主


發表:66
回覆:2535
積分:3048
註冊:2002-07-11

發送簡訊給我
#10 引用回覆 回覆 發表時間:2003-04-15 21:51:44 IP:210.3.xxx.xxx 未訂閱
I think you have some misundstanding here..    1) your hook (DLL) get triggered 2) DLL send a message to the form and the form show up itself and perform serial I/O    Instead of calling ShowWindow with the form's handle, I think you can send a message to the form and let the form itself handle it 
mathewzhao
中階會員


發表:121
回覆:164
積分:67
註冊:2003-04-04

發送簡訊給我
#11 引用回覆 回覆 發表時間:2003-04-16 16:26:56 IP:61.185.xxx.xxx 未訂閱
wlliam兄,我用a custom message發送到form去執行串埠操作,已獲成功,十分感謝你的悉心指點。但有兩個問題,如鯁在喉不去不快。 1)a custom message發送到form,程式可以去執行串埠操作,但是主窗體一直不可見,即原來的visible:=true;不再起作用。因此我繞了一圈,用findwindow先找到自己,再用showwindow(handle,sw_show)顯示自己,我想問有沒有更直接的方法。 2)一個更大的問題是form顯示後,原來form上的Edit變成不可見的,但我並沒有將edit1‧visible:=false;object inspector也沒有將 eit1‧visible:=false,因此串埠操作的最後結果看不到,我想問一下可能的原因
william
版主


發表:66
回覆:2535
積分:3048
註冊:2002-07-11

發送簡訊給我
#12 引用回覆 回覆 發表時間:2003-04-16 17:19:07 IP:147.8.xxx.xxx 未訂閱
This problem sounds strange. Instead of using API to show the form, have you tried using the Show method of the form to show itself? If possible, could you upload you project or send it to me for testing?
mathewzhao
中階會員


發表:121
回覆:164
積分:67
註冊:2003-04-04

發送簡訊給我
#13 引用回覆 回覆 發表時間:2003-04-16 17:34:52 IP:61.185.xxx.xxx 未訂閱
好呀! 但我不知道如何將Project 傳給你
william
版主


發表:66
回覆:2535
積分:3048
註冊:2002-07-11

發送簡訊給我
#14 引用回覆 回覆 發表時間:2003-04-16 21:50:06 IP:210.3.xxx.xxx 未訂閱
引言:好呀! 但我不知道如何將Project 傳給你
You can upload here http://delphi.ktop.com.tw/forum.asp?FORUM_ID=97 or mail to me at wil_321@yahoo.com.hk
mathewzhao
中階會員


發表:121
回覆:164
積分:67
註冊:2003-04-04

發送簡訊給我
#15 引用回覆 回覆 發表時間:2003-04-17 14:36:04 IP:61.150.xxx.xxx 未訂閱
今天我遇到一個有趣的問題,我帶著這個程式和一名同學將各自程式給老師演示,她也用了Keyboard Hook攔截敏感鍵,結果發現她的敏感鍵起作用時,我的敏感鍵就不起作用,反之亦然。課下一討論,才發現我倆都用錢達智兄的HOOKdemo‧zip改寫的(但我倆DLL檔案名不同),只是敏感鍵設的不同,但是不知道原因。 uses Windows, Messages,SysUtils,shellapi, Controls, Forms, Dialogs, StdCtrls; var hNextHookProc: HHook; procSaveExit: Pointer; npad:HWND; function KeyboardHookHandler(iCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; export; function EnableHotKeyHook: BOOL; export; function DisableHotKeyHook: BOOL; export; procedure HotKeyHookExit; far; implementation function KeyboardHookHandler(iCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; export; const _KeyPressMask = $80000000; begin Result := 0; If iCode < 0 Then begin Result := CallNextHookEx(hNextHookProc, iCode, wParam, lParam); Exit; end; //begin 我倆程式就下面這部分不同 if ((lParam and _KeyPressMask) = 0) and (GetKeyState(vk_Control) < 0) and (wParam = 119) then begin Result := 1; npad:=findwindow(nil,'progaramtitle'); if npad <> 0 then begin showwindow(npad,sw_show); BringWindowToTop(Npad); end; end; end; //end 我倆程式就上面這部分不同 function EnableHotKeyHook: BOOL; export; begin Result := False; if hNextHookProc <> 0 then Exit; hNextHookProc := SetWindowsHookEx(WH_KEYBOARD, KeyboardHookHandler, HInstance, 0); Result := hNextHookProc <> 0; end; function DisableHotKeyHook: BOOL; export; begin if hNextHookProc <> 0 then begin UnhookWindowshookEx(hNextHookProc); hNextHookProc := 0; end; Result := hNextHookProc = 0; end; procedure HotKeyHookExit; begin if hNextHookProc <> 0 then DisableHotKeyHook; ExitProc := procSaveExit; end; end‧
william
版主


發表:66
回覆:2535
積分:3048
註冊:2002-07-11

發送簡訊給我
#16 引用回覆 回覆 發表時間:2003-04-17 16:00:22 IP:147.8.xxx.xxx 未訂閱
There is no need to use FindWindow and using ShowWindow to show the form, a simple Show should work, e.g.
procedure TForm1.WMHotKey(var Msg : TMESSAGE);
begin
    Msg.Result := 0;
    Edit1.Text := '1234';
    Show;
end;
For your recent problem, try not setting Result := 1 in your hook procedure and see if it helps. BTW, using the virtual key constant, e.g. VK_F12, is more readable instead of the actual value, e.g. 123
mathewzhao
中階會員


發表:121
回覆:164
積分:67
註冊:2003-04-04

發送簡訊給我
#17 引用回覆 回覆 發表時間:2003-04-17 16:09:59 IP:61.150.xxx.xxx 未訂閱
william兄,謝謝教導! 窗體的edit1在窗體form show時,是可見的嗎? 我這一直都是不可見的呀?
william
版主


發表:66
回覆:2535
積分:3048
註冊:2002-07-11

發送簡訊給我
#18 引用回覆 回覆 發表時間:2003-04-17 16:19:01 IP:147.8.xxx.xxx 未訂閱
引言:william兄,謝謝教導! 窗體的edit1在窗體form show時,是可見的嗎? 我這一直都是不可見的呀?
Yes, it is visible. Any problem? BTW, I commented out all com stuff since I don't want to install that com component. >
mathewzhao
中階會員


發表:121
回覆:164
積分:67
註冊:2003-04-04

發送簡訊給我
#19 引用回覆 回覆 發表時間:2003-04-17 16:25:22 IP:61.150.xxx.xxx 未訂閱
將result:=1去掉還是不行,是不是Message 鏈被破壞了
william
版主


發表:66
回覆:2535
積分:3048
註冊:2002-07-11

發送簡訊給我
#20 引用回覆 回覆 發表時間:2003-04-17 17:00:25 IP:147.8.xxx.xxx 未訂閱
I think you need to call the next hook in chain.. Setting Result is not enough.    
if ((lParam and _KeyPressMask) = 0) and (wParam = 123) then
    {...}
else
    Result := CallNextHookEx(hNextHookProc, iCode, wParam, lParam);
mathewzhao
中階會員


發表:121
回覆:164
積分:67
註冊:2003-04-04

發送簡訊給我
#21 引用回覆 回覆 發表時間:2003-04-18 14:29:16 IP:61.185.xxx.xxx 未訂閱
反反覆覆, 始終找不到原因。 猜測是不是windows同一類型的HooK只能有一個。 但《delphi5 developer'guide》第13章第四節曰:windows可以同時安裝幾個HOOK,並且同一類型的HooK可以有多個。 試著將Result :=1改為Result : CallNextHookEx(hNextHookProc, iCode, wParam, lParam);但還是不行。 長路漫漫,吾將上下而求索
william
版主


發表:66
回覆:2535
積分:3048
註冊:2002-07-11

發送簡訊給我
#22 引用回覆 回覆 發表時間:2003-04-19 10:47:31 IP:210.3.xxx.xxx 未訂閱
Oh... I think some mis-understanding here. Setting Result to non-zero means there is no need for further processing and there is no need to call to the next hook. On the other hand, you should call the next hook when you don't need to process the hook (i.e. the case when Result=0), so.
if ((lParam and _KeyPressMask) = 0) and (wParam = 123) then
    {... hot key pressed; send message to the form ...}
else { ... not hot key ... }
    Result := CallNextHookEx(hNextHookProc, iCode, wParam, lParam);
系統時間:2024-05-05 21:04:52
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!