none
メッセージがフックできません RRS feed

  • 質問

  • 何時もお世話になっております。

    ここで、色々皆さんに教えて頂、メッセージをフックする関数を作りました。

     

    (SrcDioInt.h)

    class TDioInt
    {
    private:
    public:
        HWND hWnd;

    public:
        TDioInt(void);
       ~TDioInt(void);
        HANDLE GetEventHandle(int ChNo);
        HANDLE SetInt(int ChNo, bool PolUpEdge, TDioIntEvent Value);
        int    EnableInt(int ChNo, bool fEnable);
    protected:
    };

     

    LRESULT CALLBACK WndProcDioInt(int code, WPARAM wParam, LPARAM lParam);

    (SrcDioInt.cpp)

    //---------------------------------------------------------------------------
    // WndProc - Dioボードからの割り込みメッセージを受け取るためのエントリ
    //---------------------------------------------------------------------------
    LRESULT CALLBACK WndProcDioInt(int code, WPARAM wParam, LPARAM lParam)
    {
        WORD ChNo;
        MSG  *msg = (MSG *)lParam;

        if(code < 0)
        {
         return CallNextHookEx(hMyHook, code, wParam, lParam);
     }

        if(WM_DIOINT_CH0 <= msg->message && WM_DIOINT_CH3 >= msg->message)
        {
            ChNo = msg->message - WM_DIOINT_CH0;
           
            if(DioInt->EventRes[ChNo].FOnIntProc)
            {
    //yo999            DioInt->EventRes[ChNo].FOnIntProc(this, ChNo);
            }
            if(DioInt->EventRes[ChNo].hEvent)
            {
    //yo999            DioInt->PulseEvent(EventRes[ChNo].hEvent);
            }

        }
       
        return CallNextHookEx( hMyHook, code, wParam, lParam);
    }

    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------

        hMyHook = SetWindowsHookEx(WH_GETMESSAGE,(HOOKPROC)WndProcDioInt,hice_FormMain,0);
        if(hMyHook == NULL)
        {
            LPVOID lpMsgBuf;
            FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
                          FORMAT_MESSAGE_FROM_SYSTEM |
                          FORMAT_MESSAGE_IGNORE_INSERTS,
                          NULL,
                          GetLastError(),
                          MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
                          (LPTSTR)&lpMsgBuf,
                          0,
                          NULL);
            MessageBox(NULL,(LPCTSTR)lpMsgBuf,(LPCTSTR)"AutoUpdate",MB_OK + MB_ICONWARNING+MB_TOPMOST);
            SetErr(ERR_SYSRESOURCE);
            return;
        }

     

    hice_FormMainはNULLでやったら、

    モジュールハンドルなしで非ローカルフックを設定することができません。

    と怒られたので、Main.cpp(MainForm)のインスタンスハンドルを持ってきました。

     

     

    ブレークを張って見たのですが、ぜんぜんメッセージが入ってきません。

    宜しくお願い致します。

     

     

    2007年11月16日 6:48

回答

  • 私は SetWindowsHookEx() を使ったことが無いので詳しくありませんが、

    MSDN ライブラリによれば、第3引数は HINSTANCE であり、HWND ではありません。

     

    追記-->

    あ、コンパイル通っているから、これは違うか。すみませんが上記は無視してください。

    アプリケーションのインスタンスハンドルということですよね?

    <--

     

    それと、本題とは関係ありませんが、lpMsgBuf のメモリを解放していません。

    MSDN ライブラリにあるとおり、LocalFree を使って解放しましょう。

    2007年11月19日 0:12
  • 返信、有難う御座います。

    第三引数には、FormMain.cppのHINSTANCEを入れています。

    でも、フックできないようなのです。

    メモリーの解放は、ご指摘に従い実装してみます。

    しかし、なぜフックできないのか謎が残ります。

     

    補足

    環境は,WindowsXP Visual Studio 2005 VC++/CLI ( /clr )

     

    2007年11月19日 1:16
  • 「すべてのグローバルフック関数は、DLL 内に存在していなければならない」そうですが、この点は大丈夫でしょうか?

    ローカルフックにするなら、第3引数は NULL にしておいて、

    第4引数を GetWindowThreadProcessId() や GetCurrentThreadId() の戻り値にすれば、

    解決しそうな気がします。

    2007年11月19日 1:41
  • ついでに言うと、マネージド(/clr オプションつき)では(低レベルのキーボード・マウスのフックを除いて)グローバルフックは不可能のはずです。

    少なくともフック用の DLL はネイティブで作らないと。

    2007年11月19日 2:50

すべての返信

  • 私は SetWindowsHookEx() を使ったことが無いので詳しくありませんが、

    MSDN ライブラリによれば、第3引数は HINSTANCE であり、HWND ではありません。

     

    追記-->

    あ、コンパイル通っているから、これは違うか。すみませんが上記は無視してください。

    アプリケーションのインスタンスハンドルということですよね?

    <--

     

    それと、本題とは関係ありませんが、lpMsgBuf のメモリを解放していません。

    MSDN ライブラリにあるとおり、LocalFree を使って解放しましょう。

    2007年11月19日 0:12
  • 返信、有難う御座います。

    第三引数には、FormMain.cppのHINSTANCEを入れています。

    でも、フックできないようなのです。

    メモリーの解放は、ご指摘に従い実装してみます。

    しかし、なぜフックできないのか謎が残ります。

     

    補足

    環境は,WindowsXP Visual Studio 2005 VC++/CLI ( /clr )

     

    2007年11月19日 1:16
  • 「すべてのグローバルフック関数は、DLL 内に存在していなければならない」そうですが、この点は大丈夫でしょうか?

    ローカルフックにするなら、第3引数は NULL にしておいて、

    第4引数を GetWindowThreadProcessId() や GetCurrentThreadId() の戻り値にすれば、

    解決しそうな気がします。

    2007年11月19日 1:41
  • ついでに言うと、マネージド(/clr オプションつき)では(低レベルのキーボード・マウスのフックを除いて)グローバルフックは不可能のはずです。

    少なくともフック用の DLL はネイティブで作らないと。

    2007年11月19日 2:50
  • 返信、有難う御座います。

    DLL内にの部分ですが、確かに気になっていました。APIの本を読んだら書いてありました。

    ですが、C++Bulderでは、exe内に置いて正常に動作していたので、移植できるものと思っていました。

    マネージドではグローバルフック不可能ですか!そ、それは大変な事です。

    ネイティブですべてのコードを書き換えしか、道はないのですね。

    ん~頑張ります。

    ご指導、有難う御座いました。

     

     

    2007年11月19日 3:17