ページ 2 / 2
Re: 自分のアプリにメッセージ送信するには?
Posted: 2005年8月22日(月) 14:45
by KICO
NoWest様、ありがとう御座います。
>ポインタ変数を使うことでメモリへのデータの書き込みが
>あたかも配列のように行えるようになります
説明して頂くと「なるほど」と解るのですが、どの様な時に使用するのか
結び付かず困ったものです。
>私はマウスフックでやっているんですが、KICO様はメッセージフックを
>使っているから動かないのは当然です。
>全体を修正しないから間違うんですね。
>とりあえず、私の方では動作を確認しました。
カーソルが自アプリのウィンドウ外でも、受信出来たのでしょうか?
ウィンドウ内は、修正コードで受信出来ましたが、私もBeep()で動作確認しているのですが
終了時に、鳴り続け終了出来無く成りました。
宜しくお願いします。
Re: 自分のアプリにメッセージ送信するには?
Posted: 2005年8月22日(月) 16:11
by NoWest
> カーソルが自アプリのウィンドウ外でも、受信出来たのでしょうか?
>
> ウィンドウ内は、修正コードで受信出来ましたが、私もBeep()で動作確認しているのですが
> 終了時に、鳴り続け終了出来無く成りました。
デスクトップ上でクリックしても何も起きませんか?
それではもう少し修正したものがあるのでもう一度テストしてみてください。
コード: 全て選択
Type MOUSEHOOKSTRUCT
pt As POINTAPI
hwnd As HWND
wHitTestCode As DWord
dwExtraInfo As DWord
End Type
Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (idHook As DWord, lpfn As DWord,hMod As DWord, dwThreadId As DWord) As DWord
Declare Function UnhookWindowsHookEx Lib "user32" (hHook As DWord) As DWord
Declare Function CallNextHookEx Lib "user32" (hHook As DWord, nCode As Long, wParam As DWord, lParam As DWord) As DWord
Declare Function CreateFileMapping Lib "kernel32" Alias "CreateFileMappingA" (hFile As HANDLE, ByRef lpFileMappingAttributes As SECURITY_ATTRIBUTES, flProtect As DWord, dwMaximumSizeHigh As DWord, dwMaximumSizeLow As DWord, lpName As BytePtr) As HANDLE
Declare Function MapViewOfFile Lib "kernel32" (hFileMappingObject As HANDLE, dwDesiredAccess As DWord, dwFileOffsetHigh As DWord, dwFileOffsetLow As DWord, dwNumberOfBytesToMap As DWord) As VoidPtr
Declare Function UnmapViewOfFile Lib "kernel32" (lpBaseAddress As VoidPtr) As Long
Dim hMF As HANDLE
Dim pData As *DWord
Dim hInst As DWord
Const WM_MusKeyMOVE = (WM_USER+1)
Function Export DllMain(hinstDLL As DWord, fdwReason As DWord, lpvReserved As VoidPtr) As Long
'DLLエントリポイント
Select Case fdwReason
Case DLL_PROCESS_ATTACH
'DLLがプロセス空間にロードされた時に実行されます。
_System_StartupProgram()
DllMain=1
hInst=hinstDLL
'メモリマップトファイルを作成
hMF=CreateFileMapping(-1,ByVal NULL,PAGE_READWRITE,0,(4*8)*2,"Mouse Hook Test DLL")
pData=MapViewOfFile(hMF,FILE_MAP_ALL_ACCESS,0,0,0)
Case DLL_PROCESS_DETACH
'DLLがプロセス空間から解除された時に実行されます。
'メモリマップトファイルを破棄
UnmapViewOfFile(pData)
CloseHandle(hMF)
End Select
End Function
Function Export StartHook(hWnd As DWord) As Long
'Hookのインストール
pData[0]=SetWindowsHookEx(WH_MOUSE, AddressOf(GetMouseMsgProc), hInst, 0)
pData[1]=hWnd
If pData[0]=0 Then StartHook=-1
End Function
Function Export EndHook() As Long
'Hookのアンインストール
If pData[0] Then UnhookWindowsHookEx(pData[0]) Else EndHook=-1
End Function
Function GetMouseMsgProc(code As Long, wParam As DWord, lParam As DWord) As DWord
Dim pmh As *MOUSEHOOKSTRUCT
'Dim c As Long
pmh=lParam
If code<0 Then
GetMouseMsgProc=CallNextHookEx(pData[0],code,wParam,lParam)
Exit Function
End If
Select Case wParam
Case WM_LBUTTONDOWN
Dim buf[255] As Byte
wsprintf(buf,"x:%d y:%d hwnd:%d",pmh->pt.x,pmh->pt.y,pmh->hwnd)
SetWindowText(pData[1],buf)
PostMessage(pData[1],WM_MusKeyMOVE,0,0)
Exit Function
End Select
'次のフックを呼び出す
GetMouseMsgProc = CallNextHookEx(pData[0],code,wParam,lParam)
End Function
Re: 自分のアプリにメッセージ送信するには?
Posted: 2005年8月22日(月) 17:34
by KICO
NoWest様、ありがとう御座います。
ウィンドウ外も、修正コードで受信出来ました。(~o~)
(マウスとキーボードを分けてグローバルフックするのですか。
何故、"WH_GETMESSAGE"では駄目なのでしょうか?)
終了時に、Beep(デバッグ用)が鳴り続け終了出来ません。
MOUSEHOOKSTRUCT構造体中の"hwnd As HWND"を"hwnd As DWord"にして問題無いですか?
それと、ファイルマッピングは、ローカルフックが出来る様に使っているのですか?
それとも、どんなDLLでも作成する時には必要なのでしょうか?
宜しくお願いします。
Re: 自分のアプリにメッセージ送信するには?
Posted: 2005年8月22日(月) 21:14
by NoWest
> NoWest様、ありがとう御座います。
>
> ウィンドウ外も、修正コードで受信出来ました。(~o~)
こちらも安心しました。
> (マウスとキーボードを分けてグローバルフックするのですか。
> 何故、"WH_GETMESSAGE"では駄目なのでしょうか?)
最初の書き込みにマウスの情報を取得したいということだったので。。。
一番の理由は、私はメッセージフックを使ったことが無かったということです。
多分、メッセージフックでも問題なくできると思います。
> 終了時に、Beep(デバッグ用)が鳴り続け終了出来ません。
こちらではそのような問題は起きていないので何ともいえませんが
どうせなのでメッセージの受信側のソースも見せていただけると
何が問題なのか分かるかも知れません。
> MOUSEHOOKSTRUCT構造体中の"hwnd As HWND"を"hwnd As DWord"にして問題無いですか?
全く問題ありませんよ。
ミスに気付いたらドンドン自分で修正していただく方が力になると思います。
> それと、ファイルマッピングは、ローカルフックが出来る様に使っているのですか?
> それとも、どんなDLLでも作成する時には必要なのでしょうか?
ファイルマッピングはグローバルフックの為に必要です。
システムフックがセットされると
全てのプロセスにDLLが自動的にロードされるのですが
そのDLLのグローバル変数は全て、同じ値をとる必要があるので
ファイルマッピングを使って同じメモリ領域からデータを読み取るように
する必要があるんです。※特にActiveBasicではCのように#pragmaとか
使えませんので、、、
ファイルマッピング自体は特にDLLに必要という訳ではありません。
>
> 宜しくお願いします。
Re: 自分のアプリにメッセージ送信するには?
Posted: 2005年8月23日(火) 11:35
by KICO
NoWest様、ありがとう御座います。
> 終了時に、Beep(デバッグ用)が鳴り続け終了出来ません。
>> こちらではそのような問題は起きていないので何ともいえませんが
>> どうせなのでメッセージの受信側のソースも見せていただけると
>> 何が問題なのか分かるかも知れません。
NoWest様の方では、問題無く動いているとの事でしたので、テスト用としてボタン1つだけのウィンドウを作って試した結果、問題は起こりませんでした。
コード: 全て選択
'-----------------------------------------------------------------------------
' イベント プロシージャ
'-----------------------------------------------------------------------------
' このファイルには、ウィンドウ [MainWnd] に関するイベントをコーディングします。
' ウィンドウ ハンドル: hMainWnd
' TODO: この位置にグローバルな変数、構造体、定数、関数を定義します。
Declare Function StartHook Lib "GetStatusMK" (hWnd As DWord) As Long
Declare Function EndHook Lib "GetStatusMK" () As Long
Const WM_MusKeyMOVE = (WM_APP+1)'システムフック用(GetStatusMK.dll)メッセージコード
'-----------------------------------------------------------------------------
' ウィンドウメッセージを処理するためのコールバック関数
Function MainWndProc(hWnd As DWord, dwMsg As DWord, wParam As DWord, lParam As DWord) As DWord
' TODO: この位置にウィンドウメッセージを処理するためのコードを記述します。
Select Case dwMsg
Case WM_MusKeyMOVE
Beep(5000,10)
End Select
' イベントプロシージャの呼び出しを行います。
MainWndProc=EventCall_MainWnd(hWnd,dwMsg,wParam,lParam)
End Function
'-----------------------------------------------------------------------------
' ここから下は、イベントプロシージャを記述するための領域になります。
Sub MainWnd_Destroy()
'System Hookのアンインストール
EndHook()
TestHook_DestroyObjects()
PostQuitMessage(0)
End Sub
Sub MainWnd_Create(ByRef CreateStruct As CREATESTRUCT)
'System Hookのインストール
If StartHook(hMainWnd)<0 Then
SendMessage(hMainWnd,WM_CLOSE, 0, 0): ExitProcess(0)
End If
End Sub
Sub MainWnd_CommandButton1_Click()
SendMessage(hMainWnd,WM_CLOSE,0,0): ExitProcess(0)
End Sub
Sub MainWnd_QueryClose(ByRef cancel As Integer)
Beep(8000,100)
End Sub
問題が起こる方では、システムメニューを外してあるので、
ポップアップメニューから終了しています。(但し、メニューの選択項目を終了にし
Enterキー押下の場合は、大丈夫です。)
ポップアップメニューに、問題が有るのでしょうか?
他にも、タブコントロールシートの格タブが表示され無いとか、部分的に不安定です。
宜しくお願いします]。
Re: 自分のアプリにメッセージ送信するには?
Posted: 2005年8月23日(火) 14:31
by NoWest
確かにポップアップメニューの時に変になりますね。
それの原因が分かりましたので説明しますね。
そもそもフックというのはその名の通り、
ウィンドウに送信されるべきメッセージを釣り上げるという意味があるのですが
今回のサンプルの場合、釣り上げたメッセージをリリースするのを忘れていたんですね。
ですので
コード: 全て選択
Function GetMouseMsgProc(code As Long, wParam As DWord, lParam As DWord) As DWord
Dim pmh As *MOUSEHOOKSTRUCT
pmh=lParam
If code<0 Then
GetMouseMsgProc=CallNextHookEx(pData[0],code,wParam,lParam)
Exit Function
End If
Select Case wParam
Case WM_LBUTTONDOWN
PostMessage(pData[1],WM_MusKeyMOVE,0,0)
End Select
'次のフックを呼び出す
GetMouseMsgProc = CallNextHookEx(pData[0],code,wParam,lParam)
End Function
前回のものと比較して頂くと分かると思いますが
Exit Functionを使っていません。
要するに、WM_LBUTTONDWONを釣り上げた後、CallNextHookExを使って本来
メッセージが通知されるべきウィンドウにメッセージを通知させるわけです。
Re: 自分のアプリにメッセージ送信するには?
Posted: 2005年8月23日(火) 15:35
by KICO
NoWest様、ありがとう御座います。
> 確かにポップアップメニューの時に変になりますね。
ポップアップメニューの動作確認までして頂いて、ありがとう御座います。
Exit Functionを外しましたが、変化ありませんでした。
宜しくお願いします。
Re: 自分のアプリにメッセージ送信するには?
Posted: 2005年8月23日(火) 17:41
by KICO
PostMessage(pData[1],WM_MusKeyMOVE,0,0)を
SendMessage(pData[1],WM_MusKeyMOVE,0,0)に、したら問題は無くなりましたが
PostMessage()でないと、マズイですか?
宜しくお願いします。
Re: 自分のアプリにメッセージ送信するには?
Posted: 2005年8月24日(水) 19:45
by NoWest
> PostMessage(pData[1],WM_MusKeyMOVE,0,0)を
> SendMessage(pData[1],WM_MusKeyMOVE,0,0)に、したら問題は無くなりましたが
> PostMessage()でないと、マズイですか?
>
> 宜しくお願いします。
特にそういうマズイという訳ではありません。
SendMessageで動作しているならSendMessageで十分です。
Re: 自分のアプリにメッセージ送信するには?
Posted: 2005年8月24日(水) 23:14
by KICO
NoWest様、ありがとう御座います。
だいたい基本的な事は、解りました。(チョッと不安ですが)
連日、懇切丁寧に教えて頂きまして、ありがとう御座いました。
関連サイトを、参考に読んでも解り辛い事が有り、この掲示板が
頼りです。
これからも、宜しくお願いします。