線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:2300
推到 Plurk!
推到 Facebook!

請問 hook 如何忽略掉收到的訊息?

尚未結案
solitarygo
一般會員


發表:4
回覆:12
積分:3
註冊:2004-07-30

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-08-10 17:37:46 IP:140.127.xxx.xxx 未訂閱
我寫了一個 Hook 的程式,不想讓視窗收到訊息, 就是用 Hook 攔截視窗的訊息,讓視窗裡面的元件被點取之後, 視窗不會 focused ,下列是我的程式碼:
//-------------------------------------------------------------------
#include 
#pragma hdrstop    #include "hookok.h"
//-------------------------------------------------------------------#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
HINSTANCE hInst = NULL;
HHOOK hHook = NULL;
LRESULT CALLBACK CallCBTProc ( int nCode, WPARAM wParam, LPARAM lParam );
char WCaption[256];
//-------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//-------------------------------------------------------------------
LRESULT CALLBACK CallWNDPROC ( int nCode ,
                               WPARAM wParam ,
                               LPARAM lParam )
{
    if (nCode<0)
    {
        return CallNextHookEx(hHook,nCode,wParam,lParam);
    }
    if(lParam != NULL)
    {
        CWPSTRUCT *cwpmsg = (CWPSTRUCT *) lParam;
        if (cwpmsg->message == WM_SETFOCUS)
        {
            SendMessage(cwpmsg->hwnd, WM_GETTEXT, 255, (int)WCaption);
            return WM_KILLFOCUS;  <== 這邊似乎沒作用
        }
    }
    /*CWPSTRUCT *cwpmsg = (CWPSTRUCT *) lParam;
    if( cwpmsg->message == WM_SETFOCUS || nCode == WM_SETFOCUS )
    {
        return WM_KILLFOCUS;
    }*/
    return CallNextHookEx( hHook, nCode, wParam, lParam );
}
//-------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    if(!hHook)
    {
        ShowMessage("HookWndProc");
        hHook=SetWindowsHookEx(WH_CALLWNDPROC ,(HOOKPROC)CallWNDPROC,0,GetCurrentThreadId());
        ShowMessage("SetWindowsHookEx");
    }
    Label1->Caption = WCaption;        if(!hHook)
    {
        ShowMessage("failed");
    }
}
//-------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
    Label1->Caption = WCaption;
    if (hHook)
    {
        ShowMessage("UnHookWndProc");
        UnhookWindowsHookEx(hHook);
        hHook = NULL ;
    }
    else
        ShowMessage("no hook");
}
//-------------------------------------------------------------------
我參考了這篇討論: http://delphi.ktop.com.tw/topic.php?topic_id=52938 判斷了 WM_SETFOCUS , 也 return 1 ; 可是完成沒作用,是我上面的程式碼,改成 return WM_KILLFOCUS; 還是沒作用, 可以各位大大指點一下嗎?謝謝~~
anpino
版主


發表:31
回覆:477
積分:231
註冊:2003-01-02

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-08-12 11:54:29 IP:211.23.xxx.xxx 未訂閱
注意紅色字體:  
 void __fastcall TForm1::Button1Click(TObject *Sender)
{
    if(!hHook)
    {
        ShowMessage("HookWndProc");
        hHook=::SetWindowsHookEx(WH_CALLWNDPROC ,(HOOKPROC)CallWNDPROC,HInstance,0);
        ShowMessage("SetWindowsHookEx");
    }
    Label1->Caption = WCaption;        if(!hHook)
    {
        ShowMessage("failed");
    }
}
------------------------------- 數學系是內功很強(邏輯/分析) 資工系是招式很多(程式技巧) 就像令狐沖VS東方不敗:D Anpinos Middle Earth http://anpino.hp.infoseek.co.jp/ -------------------------------
solitarygo
一般會員


發表:4
回覆:12
積分:3
註冊:2004-07-30

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-08-12 18:47:50 IP:218.164.xxx.xxx 未訂閱
anpino您好: 我把程式碼改成您上面這樣,卻造成系統嚴重當機, 因為我使用的是 loacl hook,並沒有做成 dll , 如果是 remote hook,才需要做成 dll , 並且最後一個傳入的參數 dwThreadId 才是 0 ,不是嗎 ? 我把 hook 類型改成 WH_CBT , 卻可以把消息忽略 , 依稀好像有看到文章有提到 , "WH_CALLWNDPROC 類型的 hook , 只能負責做監視訊息用 , 所以還會把訊息繼續傳遞下去 , 因此不能忽略訊息吧 ? " <===不太確定 , 是這樣子嗎 ? 如果是這樣的話 , 那我要如何做到點選視窗 , 而 focus 仍停留在上ㄧ個視窗 ? 使用 SetForegroundWindow() 雖然可以把 focus 再次移到上一個視窗 , 卻會造成 focus 跳掉的問題 ,這不是我想要的 , 因為我想讓我的應用程式的視窗框架不會得到 focus , 就像螢幕小鍵盤一樣 , 點取的時候 , 原視窗的 focus 也不會跳掉 。
anpino
版主


發表:31
回覆:477
積分:231
註冊:2003-01-02

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-08-13 10:47:55 IP:211.23.xxx.xxx 未訂閱
程式碼如下, 效果跟messagebox一樣, 視窗不會跑掉,focus也不會跑掉。    loacl hook就必須用WM_KILLFOCUS, 因為點選"其他"視窗時,本視窗收到的是WM_KILLFOCUS, 而不是WM_SETFOCUS。所以你的code當然沒攔到囉!!  至於 class="code"> //--------------------------------------------------------------------------- #include #include #pragma hdrstop #include "Unit1.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; static HHOOK hHook = NULL; LRESULT CALLBACK ProcHook(int iCode, WPARAM wParam, LPARAM lParam); int ActiveCount = 0; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TForm1::BTMstart_hookClick(TObject *Sender) { hHook = ::SetWindowsHookEx(WH_CALLWNDPROC,(HOOKPROC)ProcHook,NULL,GetCurrentThreadId()); ActiveCount = 0; } //--------------------------------------------------------------------------- LRESULT CALLBACK ProcHook(int iCode, WPARAM wParam, LPARAM lParam) { CWPSTRUCT ProcHookStuct; if (iCode < 0) // do not process message { return CallNextHookEx(hHook,iCode,wParam,lParam); } else if (iCode == HC_ACTION) { ProcHookStuct = *(PCWPSTRUCT)lParam; if(ProcHookStuct.message == WM_KILLFOCUS) { ActiveCount ; Form1->Label1->Caption = "Count:" IntToStr(ActiveCount); ::SetForegroundWindow((HWND)Form1->Handle); ::SetFocus((HWND)Form1->Handle); return 1; } } return CallNextHookEx(hHook,iCode,wParam,lParam); } //--------------------------------------------------------------------------- void __fastcall TForm1::BTMstophookClick(TObject *Sender) { if(NULL != hHook) { UnhookWindowsHookEx(hHook); hHook = NULL; } } //--------------------------------------------------------------------------- ------------------------------- 數學系是內功很強(邏輯/分析) 資工系是招式很多(程式技巧) 就像令狐沖VS東方不敗:D Anpinos Middle Earth http://anpino.hp.infoseek.co.jp/ -------------------------------
solitarygo
一般會員


發表:4
回覆:12
積分:3
註冊:2004-07-30

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-08-13 16:21:18 IP:140.127.xxx.xxx 未訂閱
anpino您好: 其實我不是想要效果跟messagebox一樣, 我想做一個小鍵盤, 如下: Click-N-Typehttp://www.lakefolks.org/cnt/ 當它在點選它自己視窗本身按鈕的時候,視窗 Focus 不會跳到它自己本身, 而仍停留在可輸入區域的視窗上面,這樣便可以輸入字, 我想用 Hook 做出這樣的功能,可是我並不曉得何種 hook 類型比較恰當? 我的想法是這樣,當使用點取小鍵盤的按鈕時,讓 hook 去截取交換視窗的訊息,然後把交換視窗的訊息忽略掉,這樣視窗就不會交換了,因為視窗不交換,因此 focus 也能停留在上一個視窗,不曉得這樣的想法對嗎? 我知道一定要把這兩個視窗的交換訊息都略掉才行,不然當其中一個忽略,其中一個繼續送出交換訊息的話,系統可能會出錯, 請問有這方面相關的文章或是程式碼供參考嗎? MSDN 的 widows and messages 我都已經看過了,類似這樣的 message 是屬於 Nonqueued Messages 如何刪除忽略呢?
anpino
版主


發表:31
回覆:477
積分:231
註冊:2003-01-02

發送簡訊給我
#6 引用回覆 回覆 發表時間:2004-08-17 09:16:29 IP:211.23.xxx.xxx 未訂閱
如果你只是要讓form永遠在最上方, 可以用 ::SetWindowPos(Application->Handle,HWND_TOPMOST,...(自填),SWP_NOMOVE); SetWindowPos用法與說明詳見MSDN。 另,小鍵盤的範例本站已有: 【BCB】【發表】ON-Screen Keyboard http://delphi.ktop.com.tw/topic.php?topic_id=53805 請多多利用本站搜尋功能。 ------------------------------- 數學系是內功很強(邏輯/分析) 資工系是招式很多(程式技巧) 就像令狐沖
solitarygo
一般會員


發表:4
回覆:12
積分:3
註冊:2004-07-30

發送簡訊給我
#7 引用回覆 回覆 發表時間:2004-08-17 10:46:13 IP:140.127.xxx.xxx 未訂閱
很感謝anpino的幫忙, 我就是想做這樣的小鍵盤,不過不知道有沒有 source code 可以參考, 因為光是讓 form 永遠在最上方, 點取到 form 的時候,滑鼠的光標還是會跳掉。 我在去弄弄看好了 ~ 謝謝^^
系統時間:2024-04-29 14:05:49
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!