dポイントプレゼントキャンペーン実施中!

Dllにてマウスフックをして、左ボタンが押しあがったらWM_LBUTTONUPされたら
メッセージを送信するというものです。
そのときに、マウスの位置はどこにあってもいいのです。
たとえば、自分のウインドウの中で左ボタンを押して、
デスクトップ上などで左ボタンがあがったらメッセージを送信するというようにしたいのですがうまくいきません。
以下がソースです。
よろしくお願いします。
#include <windows.h>

#include "MouseHook.h"

HINSTANCE hInst;
HHOOK hHook;
HWND hWnd;
BOOL bHook;

int WINAPI DllMain(HINSTANCE hInstance, DWORD fdReason, PVOID pvReserved)
{
hInst = hInstance;
return TRUE;
}

EXPORT int SetMainHWND(HWND hMainWindow)
{
hWnd = hMainWindow;
return 0;
}

EXPORT BOOL IsHooking()
{
if (bHook)
return TRUE;
else
return FALSE;
}

EXPORT int MouseHookSet()
{
hHook = SetWindowsHookEx(WH_MOUSE, (HOOKPROC)MouseHookProc,hInst, NULL);
if (hHook == NULL)
{
return -1;
} else {
bHook = TRUE;
return 0;
}
}

EXPORT int MouseHookEnd()
{
if (UnhookWindowsHookEx(hHook) != 0)
{
bHook = FALSE;
return 0;
}
else
{
return -1;
}
}

EXPORT LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
MOUSEHOOKSTRUCT *pmh;
pmh = (MOUSEHOOKSTRUCT *)lParam;

if (wParam == WM_LBUTTONUP)
{
SendMessage(hWnd,MOUSEHOOK_LBUTTONUP,0,0);
}
if (wParam == WM_NCLBUTTONUP)
{
SendMessage(hWnd,MOUSEHOOK_LBUTTONUP,0,0);
}
return CallNextHookEx(hHook,nCode,wParam,lParam);
}

A 回答 (4件)

>以下のようにして、自ウインドウで呼び出していますが、違いますか?



この関数と、その使い方はあってます。


猫の161章の
>#pragma data_seg("MY_DATA")
>
>.....
>
>#pragma data_seg()
>
>で囲まれた部分のグローバル変数がプロセス間で共有されます。

という記述を理解されましたか?逆に言えば、こういうことをしないとプロセス間でメモリに書き込んだ内容を共有できないということです。

グローバルフックのフックプロシージャはシステムプロセスですからね。プロセス空間は別ものです。
猫162章では、SetMainHWND()で退避したウィンドウハンドルを、
フックの開始と終了時に自プロセスでメッセージボックスの
表示にしか使ってないから問題なく動いているだけです。
というかそれだけのためにこんな関数いるのか?(^^;;;


また、161章ではフックハンドルを共有メモリ上に置いていて、162章では置いていないという違いもあります。

これも実はグローバルフックではCallNextHookEx()にフックハンドルを渡す必要が無い、つまりNULLでもかまわないので動いています。統一性無いですねぇ。


#ちなみに、猫のソースは100%信用しない方がいいですよ。とりあえず動かすだけ程度の参考にしておかないとあとから結構痛い目を見ます。


>自ウインドウから他のウインドウへのDrag&Drop(実際はButtonDown & ButtonUp)みたいにするときのみ、
>反応がありません。

本当にこれだけですか?
他プロセスのウィンドウ上やデスクトップでのDOWNで、
自分で定義されたMOUSEHOOK_LBUTTONUPが自ウィンドウにちゃんと送られてきてますか?


あと、#1の方が書かれてますが、SendMessageはまずいです。PostMessageにしないと。
こちらも正しく違いを理解されてますか?

さらに、フックプロシージャ内での
if (nCode < 0)
は必須ですので必ず記述しましょう。システムごと落ちても知りませんよ。

この回答への補足

>本当にこれだけですか?
>他プロセスのウィンドウ上やデスクトップでのDOWNで、
>自分で定義されたMOUSEHOOK_LBUTTONUPが自ウィンドウ>にちゃんと送られてきてますか?
いいえ、違うようです。すみません。
言われたとおりにソースコードを修正してみました。
よろしければ見てもらえますでしょうか?
お願いします。
あまりDLLは作成したことがないので間違ってたらすみません。
------------------------------------------
//MouseHook.h
#define MOUSEHOOK_LBUTTONUP 84587
#define MOUSEHOOK_OUTWINDOWRECT 84588


#define EXPORT extern "C" __declspec(dllexport)

EXPORT int SetMainHWND(HWND);
EXPORT BOOL IsHooking(void);
EXPORT int MouseHookSet(void);
EXPORT int MouseHookEnd(void);
EXPORT LRESULT CALLBACK MouseHookProc(int, WPARAM, LPARAM);
--------------------------------------------
//MouseHook.cpp
#include <windows.h>
#pragma comment(linker, "/SECTION:.shared,RWS")
#pragma data_seg(".shared")
HHOOK hHook=0;
HWND hWnd=0;
BOOL bHook=0;
HINSTANCE hInst=0;
#pragma data_seg()
#include "MouseHook.h"

int WINAPI DllMain(HINSTANCE hInstance, DWORD fdReason, PVOID pvReserved)
{
switch (fdReason)
{
case DLL_PROCESS_ATTACH:
hInst = hInstance;
break;
case DLL_PROCESS_DETACH:
break;
}
return true;
}
EXPORT int SetMainHWND(HWND hMainWindow)
{
hWnd = hMainWindow;
return 0;
}
EXPORT BOOL IsHooking()
{
if (bHook)
return TRUE;
else
return FALSE;
}
EXPORT int MouseHookSet()
{
hHook = SetWindowsHookEx(WH_MOUSE, (HOOKPROC)MouseHookProc,hInst, NULL);
if (hHook == NULL)
{
return -1;
} else {
bHook = TRUE;
return 0;
}
}
EXPORT int MouseHookEnd()
{
if (UnhookWindowsHookEx(hHook) != 0)
{
bHook = FALSE;
return 0;
}
else
{
return -1;
}
}
EXPORT LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
MOUSEHOOKSTRUCT *pmh;
pmh = (MOUSEHOOKSTRUCT *)lParam;
if (nCode < 0)
{
return CallNextHookEx(hHook,nCode,wParam,lParam);
}
if (wParam == WM_LBUTTONUP)
{
PostMessage(hWnd,MOUSEHOOK_LBUTTONUP,0,0);
MessageBeep(-1);
}
if (wParam == WM_NCLBUTTONUP)
{
PostMessage(hWnd,MOUSEHOOK_LBUTTONUP,0,0);
MessageBeep(-1);
}
return CallNextHookEx(hHook,nCode,wParam,lParam);
}

補足日時:2005/02/19 13:41
    • good
    • 0

>#define MOUSEHOOK_LBUTTONUP 84587


>#define MOUSEHOOK_OUTWINDOWRECT 84588

ウィンドウメッセージにあまり変な値を使用しないように。自分のウィンドウ宛に送るんでしたら
WM_USER~0x7FFFの範囲の値か、RegisterWindowMessage
で取得しましょう。


>#pragma data_seg(".shared")
>HHOOK hHook=0;
>HWND hWnd=0;
>BOOL bHook=0;
>HINSTANCE hInst=0;
>#pragma data_seg()

プロセス間で共有させるのは必要最低限にしましょう。
特にインスタンスハンドルを共有してしまうと、
フックをかける→はずす→かける
とした場合、2回目にかけるとき、システムによってロードされたDLLのHINSTANCEがhInstに上書きされているため失敗するでしょう。

#あと、ハンドルやBOOLを0で初期化するのはあんまり良くないかと。
    • good
    • 0
この回答へのお礼

回答ありがとうございました。
私の技術不足のため今は出来ないようです。
また、いつかがんばってみたいと思います。
皆さんもありがとうございました。

お礼日時:2005/02/21 07:35

メッセージの送信先のウィンドウハンドルがこれでは正しく退避できていません。


DLL上のメモリ領域は、通常の方法では他のプロセスと共用することはできないためグローバルフックでシステムに読み込まれたDLLではhWndの値はNULLになっています。


プロセス間のメモリの共有方法はいろいろありますので自分で調べてみてください。

#猫でも~を参照するのはいいと思いますけど、その前の章もちゃんと見てくださいね。
http://www.kumei.ne.jp/c_lang/sdk2/sdk_161.htm

参考URL:http://www.kumei.ne.jp/c_lang/sdk2/sdk_161.htm

この回答への補足

メッセージの送信先のウィンドウハンドルがこれでは正しく退避できていません。
以下のようにして、自ウインドウで呼び出していますが、違いますか?
EXPORT int SetMainHWND(HWND hMainWindow)
{
hWnd = hMainWindow;
return 0;
}
自ウインドウから他のウインドウへのDrag&Drop(実際はButtonDown & ButtonUp)みたいにするときのみ、反応がありません。
プロセス間のメモリの共有方法と関係ありますか?

よろしくお願いします。

補足日時:2005/02/18 17:38
    • good
    • 0

SendMessageではなくPostMessageを利用してはどうでしょうか?

    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!