Lactoferrin 大大 你說的應該是像下面這樣吧!LRESULT (CALLBACK __stdcall MessageProc(int code,WPARAM wParam,LPARAM lParam)) { switch (code) { case WM_PSD_ENVSTAMPRECT: lparamvalue=((PMSG)lParam)->lParam; }; return TRUE; }; 不過出現了一個怪問題 我在VB.net中調用 MessageProc 得到getlparamvalue 如下 Declare Function MessageProc Lib "hookps.dll" (ByVal code As Long, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntegerPrivate Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click '注入鉤子 Dim hwnd0 As IntPtr = GetDesktopWindow() Dim hwnd1 As IntPtr = FindWindowEx(hwnd0, 0, "ThunderRT6FormDC", vbNullString) '找到fw 這個窗口 Dim hwnd2 As IntPtr = FindWindowEx(hwnd1, 0, "Slider20WndClass", vbNullString) Dim um As Long Dim wpa As IntPtr Dim hookk As Object = 0 Dim geterror As Long = 0 Dim getlparamvalue As IntPtr Dim code As Long SetHook(hwnd2, hookk, geterror) '插入鉤子 If hookk = 0 Then 'hookk = Err.LastDllError TextBox10.Text = geterror End If PaintHookProc(hwnd2, um, wpa, lpm) '獲得鉤子數據 MessageProc(code, vbNull, getlparamvalue) TextBox10.Text = getlparamvalue End Sub 這邊有顯示掛勾成功了, 但VB運行程式的時候卻出現在 DLL 'hookps.dll' 中找不到名稱為 'MessageProc' 的進入點。我有用depend工具檢查過MessageProc 有導出函數成功了,怎麼還會出現此問題呢? 求解
Lactoferrin大大 我收到了剛測試了一下你的代碼 可以了 好像只有WH_CALLWNDPROC 這個鉤子才能抓得到數值其他的都不行 這個是直接抓取16進制轉成10進制的數值了 直接省去了我一道麻煩 如果要用其他的鉤子抓看看的話是不是只要把WndProc 換成 MsgProc 就可以了嗎?像下面這樣: Protected Overrides Sub MsgProc (ByRef m As System.Windows.Forms.Message) If m.Msg = &H405 Then TextBox10.Text = m.LParam.ToString() TextBox11.Text = m.WParam.ToString() End If MyBase.WndProc(m) End Sub 還有個問題就是下面這一行 0x405 這個數值是怎麼來的阿? 是隨便設的嗎?PostMessageW(g_myhwnd,0x405,(WPARAM)lParam->hwnd,lParam->lParam);
BOOL WINAPI DllMain(
HMODULE hinstDLL,
DWORD fdwReason,
LPVOID lpvReserved
)
{
if(fdwReason==1)base=hinstDLL;
return 1;
}
SetWindowsHookEx里面用base
Declare Function GetlParam Lib "hookps.dll" (ByVal lParam As IntPtr) As IntegerPrivate Sub Button6_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button6.Click GetlParam(lpm) '獲得lParam 數值
TextBox10.Text = lpm End Sub
//----------------------------
long ( __stdcall GetlParam (LPARAM lParam))
{
lParam=lparamvalue;
return TRUE;
};
LRESULT (CALLBACK __stdcall MessageProc(int code,WPARAM wParam,LPARAM lParam))
{
switch (code)
{
case WM_PSD_ENVSTAMPRECT:
lparamvalue=lParam;
};
return TRUE; };
C++的dll則是像上面這樣寫,請問我沒接到lParam 的數值是因為我的鉤子類型用錯了嗎??還是有其他原因, 我監控的對象是這個這個滾動條照msdn的說法應該可以用 WH_MSGFILTER 來接收 麻煩指點一下小弟 哪邊出錯了呢?
然后lparamvalue=((PMSG)lParam)->lParam;
否则使用WM_CALLWNDPROC和WM_GETMESSAGE
{
switch (code)
{
case WM_PSD_ENVSTAMPRECT:
lparamvalue=((PMSG)lParam)->lParam; };
return TRUE; };
不過出現了一個怪問題 我在VB.net中調用 MessageProc 得到getlparamvalue 如下
Declare Function MessageProc Lib "hookps.dll" (ByVal code As Long, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntegerPrivate Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click '注入鉤子 Dim hwnd0 As IntPtr = GetDesktopWindow()
Dim hwnd1 As IntPtr = FindWindowEx(hwnd0, 0, "ThunderRT6FormDC", vbNullString) '找到fw 這個窗口
Dim hwnd2 As IntPtr = FindWindowEx(hwnd1, 0, "Slider20WndClass", vbNullString)
Dim um As Long
Dim wpa As IntPtr
Dim hookk As Object = 0
Dim geterror As Long = 0
Dim getlparamvalue As IntPtr
Dim code As Long SetHook(hwnd2, hookk, geterror) '插入鉤子
If hookk = 0 Then 'hookk = Err.LastDllError
TextBox10.Text = geterror
End If PaintHookProc(hwnd2, um, wpa, lpm) '獲得鉤子數據
MessageProc(code, vbNull, getlparamvalue)
TextBox10.Text = getlparamvalue
End Sub
這邊有顯示掛勾成功了, 但VB運行程式的時候卻出現在 DLL 'hookps.dll' 中找不到名稱為 'MessageProc' 的進入點。我有用depend工具檢查過MessageProc 有導出函數成功了,怎麼還會出現此問題呢? 求解
LRESULT (CALLBACK __stdcall MessageProc(int code,WPARAM wParam,LPARAM lParam))
{
switch (code)
{
case WM_PSD_ENVSTAMPRECT:
lparamvalue=((PMSG)lParam)->lParam;
};
return TRUE;
};long ( __stdcall GetlParam (LPARAM lParam))
{
lParam=lparamvalue;
return TRUE;
};
然後在VB裡直接調用GetlParam 函數 ,有傳出數值出來了,不過怎麼都一直是數字1阿我滑軌都已經跑離1的點了,它還是回傳1回來。 這是怎麼一回事阿...
{
return lparamvalue;
};
LRESULT (CALLBACK __stdcall MessageProc(int code,WPARAM wParam,LPARAM lParam))
{
switch (code)
{
case WM_PSD_ENVSTAMPRECT:
lparamvalue=((PMSG)lParam)->lParam;
};
return TRUE;
};
LPARAM ( __stdcall GetlParam (void))
{
return lparamvalue;
};LPARAM (__stdcall ReleaseHook(HHOOK hThisHook)) // <<<<<<Off the hook
{
if(hThisHook)
{
UnhookWindowsHookEx(hThisHook);
hThisHook = NULL;
}
return TRUE;
}; 然後下面是我在VB的部分
Declare Function GetlParam Lib "hookps.dll" () As Integer
Declare Function ReleaseHook Lib "hookps.dll" () As Long
Private Sub Button6_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button6.Click TextBox10.Text = GetlParam()
End Sub
Private Sub Button5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button5.Click ReleaseHook() End Sub
鉤子注入的部分 已經確定沒有問題了 目前就是回傳值回傳0 的問題 ,還有卸除鉤子時會出現以下這個錯誤信息:對 PInvoke 函式 'WindowsApplication1!WindowsApplication1.Form1::ReleaseHook' 的呼叫已使堆疊失去平衡。這可能是因為 Managed PInvoke 簽章和 Unmanaged 目標簽章不相符。請確認 PInvoke 簽章的呼叫慣例及參數與目標 Unmanaged 簽章是否相符。請問這兩地方要怎麼修改?
下面是我用SPY++ 監控對象時的數據,提供給您做參考一下:<00059> 000C094A S WM_PSD_ENVSTAMPRECT hDC:00000001 lprcEnvStamp:00000004 [wParam:00000001 lParam:00000004]<00060> 000C094A S WM_PAINT hdc:00000000 [wParam:00000000 lParam:00000000]
<00061> 000C094A S WM_PRINTCLIENT hdc:FB013AA6 uFlags:PRF_CLIENT | PRF_CHILDREN [wParam:FB013AA6 lParam:00000014]
<00062> 000C094A S message:0x2138 [使用者定義:WM_USER+7480] wParam:23014941 lParam:000C094A
<00063> 000C094A R message:0x2138 [使用者定義:WM_USER+7480] lResult:00000010
<00064> 000C094A S message:0x204E [使用者定義:WM_USER+7246] wParam:00000000 lParam:0012E75C
<00065> 000C094A R message:0x204E [使用者定義:WM_USER+7246] lResult:00000000
<00066> 000C094A R WM_PRINTCLIENT lResult:00000000
<00067> 000C094A R WM_PAINT lResult:00000000
<00068> 000C094A R WM_PSD_ENVSTAMPRECT fPreventDraw:False [lResult:00000000]
<00069> 000C094A S WM_PSD_PAGESETUPDLG wPaper:0000 wFlags:0 lppsd:00000000 [wParam:00000000 lParam:00000000]
<00070> 000C094A R WM_PSD_PAGESETUPDLG fPreventDraw:True [lResult:00000004]
<00071> 000C094A S WM_PSD_ENVSTAMPRECT hDC:00000001 lprcEnvStamp:00000005 [wParam:00000001 lParam:00000005]
因此你应该吧lparamvalue放在一个共享的section中你vb中ReleaseHook少个参数
HHOOK hThisHook=0;
LPARAM lparamvalue=0;
HHOOK hook=0;
//HINSTANCE hmod=::LoadLibraryA("hookps.dll");
// save the hook handle
//static UINT_PTR CALLBACK PaintHookProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
//int GetWindowTextRemote(HWND hwnd,LPSTR lpString);
//int ReleaseHook();# pragma data_seg ()
# pragma comment (linker, "/section:.shared,RWS")ReleaseHook 少一個參數,不加參數不可以動作嗎? 那該加什麼參數進去呢?
LPARAM (__stdcall ReleaseHook(HHOOK hThisHook))
但vb里面是 Declare Function ReleaseHook Lib "hookps.dll" () As Long
应该是 Declare Function ReleaseHook Lib "hookps.dll" (byval IntPtr hThisHook) As UIntPtr
只要共享lparamvalue,其他的不要共享你在dll里面把lparam打印出来
# pragma data_seg (".shared") LPARAM lparamvalue=0;
# pragma data_seg ()
# pragma comment (linker, "/section:.shared,RWS")
HWND g_hWnd=0;
HHOOK hThisHook=0;
HHOOK hook=0;LPARAM (__stdcall ReleaseHook(HHOOK hThisHook)) // <<<<<<Off the hook
{
if(hThisHook)
{
UnhookWindowsHookEx(hThisHook);
hThisHook = NULL;
if (hThisHook == NULL)
{
MessageBox(NULL, L"恭喜您 卸除成功", L"The success of the title search window", MB_OK);
return FALSE ;
}
if( hThisHook > NULL )
{
MessageBox(NULL, L"鉤子沒有卸除喔", L"Linked the success of the title window", MB_OK);
return FALSE ;
} }
return TRUE;
};VB 部分
Declare Function ReleaseHook Lib "hookps.dll" (ByVal hThisHook As IntPtr) As UIntPtr Private Sub Button5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button5.Click Dim UNhook As IntPtr
ReleaseHook(UNhook) End Sub鉤子如果有卸除的話應該會跳出<鉤子沒有卸除喔>的窗口信息,可是我按下去之後什麼反應也沒有。在dll里面把lparam打印出来 << 只能使用打印的嗎? 因為這個lparam的數值我是想匯出給VB來做控制用的 有沒有什麼方法可以讓VB直接呼叫這個lparam的變數阿?
_ltow((long)hThisHook,buf,16);MessageBoxW(0,buf,0,0);
_ltow((long)lParam,buf,16);MessageBoxW(0,buf,0,0);
就像这样
LRESULT (__stdcall SetHook(HWND hwnd4,HHOOK hThisHook,DWORD DWord))
{
g_hWnd=hwnd4;
//hThisHook= ::SetWindowsHookExA( WH_CALLWNDPROC,(HOOKPROC) PaintHookProc,hDll,GetWindowThreadProcessId(hwnd4,NULL) ); //GetWindowThreadProcessId(hwnd4,NULL)
//hook = ::SetHook(hwnd4);
hThisHook= ::SetWindowsHookExW( WH_MSGFILTER,MessageProc,base,GetWindowThreadProcessId(hwnd4,NULL) ); //GetWindowThreadProcessId(hwnd4,NULL)
//DWORD __stdcall WINAPI GetLastError(void); if( hThisHook == NULL )
{
//DWORD DWord = GetLastError() ;
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
); // Process any inserts in lpMsgBuf.
// ...
// Display the string.
MessageBox( NULL, (LPCTSTR)lpMsgBuf, L"Error", MB_OK | MB_ICONINFORMATION );
// Free the buffer.
LocalFree( lpMsgBuf ); //----------------------------//-------------------------
MessageBox(NULL, L"Hook failure", L"Title window hook fails", MB_OK);
//DWORD __stdcall WINAPI GetLastError(void);
return TRUE ;
}
if( hThisHook > NULL )
{
MessageBox(NULL, L"Congratulations on your successful hook", L"Linked the success of the title window", MB_OK);wchar_t buf[32];
_ltow((long)hThisHook,buf,16);MessageBoxW(0,buf,0,0);
//LPWSTR _ltow(LONG hThisHook,LPWSTR str,INT radix);
//printf( "String of integer %d (radix 10): %s\n", hThisHook, str );return FALSE ;
}
return TRUE;
};
LRESULT (CALLBACK __stdcall MessageProc(int code,WPARAM wParam,LPARAM lParam))
{
switch (code)
{
case WM_PSD_ENVSTAMPRECT:
lparamvalue=((PMSG)lParam)->lParam;
wchar_t buf[32];
_ltow((long)lParam,buf,16);MessageBoxW(0,buf,0,0);};
return TRUE;
};LPARAM ( __stdcall GetlParam (void))
{
LPARAM lParam=0; wchar_t buf[32];
_ltow((long)lParam,buf,16);MessageBoxW(0,buf,0,0);
return lparamvalue;
};
鉤子的返回值都沒有固定 訊息攔跳出 以下這些東西 錯誤
7010423
錯誤
23700b1
錯誤
1210a05
錯誤
2cf0bf9然後lParam返回數值都是0 這樣應該不是正常的吧 哪邊還需要考慮進去呢? 請求協助
这里不是switch(code)
而是switch(((PMSG)lParam)->message)
如果不能截获,换用WH_CALLWNDPROC和WH_GETMESSAGE
{
switch(((PMSG)lParam)->message)
{
case WM_PSD_ENVSTAMPRECT:
lparamvalue=((PMSG)lParam)->lParam;};
return lparamvalue;};LPARAM ( __stdcall GetlParam (void))
{
wchar_t buf[32];
_ltow((long)lparamvalue,buf,16);MessageBoxW(0,buf,0,0);
return lparamvalue;
};我試著把代碼改成這樣 不過似乎也沒用 好像根本沒有接受到信息值...
应该返回CallNextHookEx(0,code,wParam,lParam);
如果是WH_CALLWNDPROC则PMSG要换成PCWPSTRUCT
{
switch(((PCWPSTRUCT)lParam)->message)
{
case WM_PSD_ENVSTAMPRECT:
lparamvalue=((PCWPSTRUCT)lParam)->lParam;};
CallNextHookEx(0,code,wParam,lParam);
return TRUE;
};這樣運行也是返回值0
怕你沒收到我另外在上傳到skydrive上了https://skydrive.live.com/redir.aspx?cid=105b2868cb2df559&resid=105B2868CB2DF559!190
Protected Overrides Sub MsgProc (ByRef m As System.Windows.Forms.Message)
If m.Msg = &H405 Then
TextBox10.Text = m.LParam.ToString()
TextBox11.Text = m.WParam.ToString()
End If
MyBase.WndProc(m)
End Sub 還有個問題就是下面這一行 0x405 這個數值是怎麼來的阿? 是隨便設的嗎?PostMessageW(g_myhwnd,0x405,(WPARAM)lParam->hwnd,lParam->lParam);
那个数值可以是0x405和0x7FFF之间任意一个