![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?5a7ff87)
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);
}
No.3ベストアンサー
- 回答日時:
>以下のようにして、自ウインドウで呼び出していますが、違いますか?
この関数と、その使い方はあってます。
猫の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);
}
No.4
- 回答日時:
>#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で初期化するのはあんまり良くないかと。
回答ありがとうございました。
私の技術不足のため今は出来ないようです。
また、いつかがんばってみたいと思います。
皆さんもありがとうございました。
No.2
- 回答日時:
メッセージの送信先のウィンドウハンドルがこれでは正しく退避できていません。
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)みたいにするときのみ、反応がありません。
プロセス間のメモリの共有方法と関係ありますか?
よろしくお願いします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- FX・外国為替取引 mql4のコンパイルエラー箇所の修正お願いします。 1 2023/03/15 16:14
- C言語・C++・C# プログラミングのペーパーテスト 実行結果を表示せよ #include <stdio.h> int h 1 2022/07/09 15:27
- C言語・C++・C# プログラムの時、フローチャートはどうなりますか?図でお願いします。 int main(void) { 1 2022/10/01 22:45
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- Java java 引数 戻り値のあるメソッド 3 2023/02/12 06:23
- C言語・C++・C# C言語でif文が予想と違う動きをする件について7 4 2023/03/20 00:26
- C言語・C++・C# leetcode 155 minstack 1 2022/05/07 16:43
- C言語・C++・C# バイナリファイルをコピーするのにかかる時間を測りたいのですが実行するとFatel error:gli 2 2022/11/03 01:10
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
他のウィンドウのボタンを自動...
-
vbaから他のアプリを終了
-
msgboxの表示位置
-
メッセージボックスの選択ボタ...
-
VBAでコントロールのハンドルを...
-
SetWindowText関数について
-
Excel VBA で外部アプリケーシ...
-
windowsメールスロットについて...
-
メッセージハンドラ
-
デスクトップ上のアイコンの位...
-
キーボード入力をHSPでさせたい...
-
エクセルで作った新しいウイン...
-
グラフの交点の求め方(Excel)
-
「アイテムは収集されました」...
-
コンボボックス内の文字サイズ変更
-
フォントの大きさ
-
VBA .Value=.Value ?
-
コントロールの書式設定で、“コ...
-
VBAのフォント変更(エクセルか...
-
VBAにGDI+を参照させる方法
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
vbaから他のアプリを終了
-
msgboxの表示位置
-
他のウィンドウのボタンを自動...
-
メッセージボックスの選択ボタ...
-
SetWindowText関数について
-
VBAでコントロールのハンドルを...
-
Excel VBA で外部アプリケーシ...
-
VB.netでFindWindowExやると・...
-
メッセージハンドラ
-
点滅で知らせる方法
-
CloseHandle()
-
システム例外のメッセージを変...
-
WM_NCLBUTTONUPについて
-
デスクトップ上のアイコンの位...
-
メッセージループについて
-
キーボード・フックのアプリを...
-
VBでRegisterWindowMessage関数...
-
WM_CTLCOLORDLG
-
windowsメールスロットについて...
-
マウスフックについて
おすすめ情報