Jag försöker göra en dll i Visual C++ som skall vidarbefodra WNDPROC-meddelanden Adressen du skickar till DLLen från VB med AddressOf är bara giltig inom VB programmets process. I en global hook som kan köras från vilken process som helst kan du alltså inte använda pekare hur som helst. Men i EasyHook.dll tycks utvecklaren ha gått runt problemet med AdressOf i VB. Windows Hook problem
till ett VB-program.
Den dll som jag försöker efterskapa är Easyhook.dll som går att ladda ner här:
http://usuarios.bitmailer.com/felisart
Lite kod ifrån C dll´en
SetCallWndHook är en funktion i dll´n som tar emot och lagrar en adress
till en subrutin i VB-programmet som sedan skall vara mottagare av WNDPROC informationen.
int __declspec(dllexport) CALLBACK SetCallWndHook(long ptrfunction)
{
if( g_hHook!=NULL ) return 0;
// Lagrar adresspekaren
ptrCallWndHook = ptrfunction;
//Lägger in sig i windowskön
g_hHook = ::SetWindowsHookEx(WH_CALLWNDPROC, CallWndProc, g_hInstance, 0);
if( g_hHook != NULL) {
return 1;
} else {
return 0;
}
}
Går ur windowskön
int __declspec(dllexport) CALLBACK CallWndUnhook()
{
if( g_hHook == NULL ) return 0;
int bRet = ::UnhookWindowsHookEx(g_hHook);
g_hHook = NULL;
return bRet;
}
Den här funktionen är den som tar emot meddelanden
ifrån windows som den sedan skall vidarbefodra
till subrutinen i VB.
LRESULT WINAPI CallWndProc(int nCode, WPARAM wParam, LPARAM lParam)
{
// Avbryt direkt om nCode är mindre än 0
if (nCode < 0) return CallNextHookEx(g_hHook, nCode, wParam, lParam);
// Annars så hämtas meddelandet
PCWPSTRUCT pcwps;
pcwps = (PCWPSTRUCT)lParam;
// Hämtar den externa funktionenspekaren
typedef void (__stdcall *FNPTR)(int code, long lParam, long wParam, long message, long hwnd);
FNPTR FunctionCall;
FunctionCall = (FNPTR)ptrCallWndHook;
// Kallar på den externa funktionen
FunctionCall(nCode, pcwps->lParam, pcwps->wParam, pcwps->message, pcwps->hwnd);
// Släpper iväg meddelandet till nästa
return CallNextHookEx(g_hHook, nCode, wParam, lParam);
}
I VB-programmet så kallar jag på funktionerna i dll´n:
Declare Function SetCallWndHook Lib "testdll_library.dll" (ByVal ptrfunction As Long) As Long
Declare Function CallWndUnhook Lib "testdll_library.dll" () As Long
Hoppar in i meddelandekön
Dim Result As Long
Result = SetCallWndHook(App.hInstance, AddressOf CallWndProc)
Hoppar ur meddelandekön
Dim Result As Long
Result = CallWndUnhook()
När meddelandet skall skicka infomationen till VB så fungerar det inte. Jag har provat med att skippa att tolka meddelandet och bara skicka siffran 1 till VB men det fungerar inte ändå. Så det verkar som att det inte går att skicka något till VB-subrutinen ifrån CallWndProc-funktionen. Det kanske blir någon korsreferens eller liknande. Som ni ser på koden så är inte någon C-programmerare och windowshooking är väl inte direkt det första man bör mecka med då det är väldigt viktigt att man gör allt helt rätt.
Är det någon som kan hjälpa mig med att lösa problemet så är jag oerhört tacksam.Sv: Windows Hook problem
En vanlig lösning är att skicka in ett HWND för något fönster i programmet istället, och sedan skicka tillbaka information till programmet från hook DLLen med PostMessage.
MSSv: Windows Hook problem
När jag använder mig av den så behöver jag bara göra jag så här:
'----------Hook SENT messages BEFORE call the windowproc----
Declare Function SetCallWndHook Lib "easyhook.dll" (ByVal ptrfunction As Long) As Long
Declare Sub CallWndUnhook Lib "easyhook.dll" ()
'///////// PSEUDO HOOK PROCEDURES /////////////
'//// All procedures will be called in your Application thread
'//// you can call any VB, API, DRAWING function without multithreading
'//// problems.///////
'//// YOU DON'T GET MESSAGES FOR YOUR PROCESS
'//// While running inside the VB IDE your application and VB itself
'//// run in the same process.
'//// ProcessID parameter is the Process Identifier of the process that
'//// owns the message
'//// For more information read "HOOKS" in Win32.hlp file ////////
Function CallWndProc(ByVal ProcessId As Long, ByVal code As Long, ByVal wParam As Long, lParam As CWPSTRUCT) As Long
'-You don't get messages with code <0,
'-they are redirected to CallNextHookEx at Dll level---
'-You can't modify the messages
Dim texto As String, buff As String, i As Integer
If lParam.message > -5000 And lParam.message < 5000 Then
texto = WMMenStr(lParam.message)
Else
texto = CStr(lParam.message)
End If
'Kod för att visa meddelandet....osv
CallWndProc = 0 '// return value should be zero
End Function
Här kan man ladda ner ovanstående projekt:
http://usuarios.bitmailer.com/felisart/
Det är exakt så som jag vill göra min egen C++ dll.
Jag har försökt få kontakt med utvecklaren av den här dll´n utan framgång.