-
Yes, also DLL problems
Keda and I are working on a new project together, he's off for some holidays now, and I'm stuck with a simple problem, at least, it should be simple since I've done this before.
Ok here's the deal. I'm making an app that detects right-clicks everywhere on the screen, and using a systemwide hook for it, and yes that's the way I want to do it ;)
It compiles without errors, but when I debug, I see that when I try to get the address with GetProcAddress that it returns 0.
So I think it must be in the DLL, that it doesn't export the functions well or something.
main.cpp
Code:
#include <windows.h>
#include <iostream>
#include <string>
#include <vector>
#include "main.h"
#include "resource.h"
using namespace std;
//Global variables
HHOOK g_hMouseHook;
HWND g_hWnd;
HINSTANCE g_hInstDLL;
typedef HHOOK (*INITPROC)(HOOKPROC);
typedef VOID (*KILLPROC)(VOID);
INITPROC mInitProc;
KILLPROC mKillProc;
HINSTANCE g_hInst;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){
g_hInst = hInstance;
DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(DLG_Main), NULL, MainDialogProc);
return 0;
}
BOOL CALLBACK MainDialogProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam){
switch(Message)
{
case WM_INITDIALOG:
//Set global variables.
g_hWnd = hwnd;
//Load DLL and hook mouse
g_hInstDLL = LoadLibrary((LPCTSTR) "dll");
if (!g_hInstDLL) DisplayError("Failed opening DLL");
mInitProc = (INITPROC) GetProcAddress(g_hInstDLL, "InitHook");
/*if (!mInitProc){
DisplayError("Failed getting ProcAddress");
return 0;
} */
g_hMouseHook = mInitProc(MouseProc); //Access violation over here.
if (!g_hMouseHook) DisplayError("Failed creating Hook");
return TRUE;
case WM_COMMAND:
switch(LOWORD(wParam))
{
//Knopjes en ****
break;
}
break;
case WM_CLOSE:
//KILL THE ****ING HOOK
mKillProc = (KILLPROC)GetProcAddress(g_hInstDLL, "KillHook");
(mKillProc);
FreeLibrary(g_hInstDLL);
EndDialog(hwnd, WM_CLOSE);
break;
default:
return FALSE;
}
return TRUE;
}
dll.cpp
Code:
#include <windows.h>
HHOOK g_hMouseHook;
__declspec(dllexport) HHOOK __stdcall InitHook(HOOKPROC MouseProc){
g_hMouseHook = SetWindowsHookEx(WH_MOUSE, MouseProc,NULL,0);
return g_hMouseHook;
}
__declspec(dllexport) void __stdcall KillHook(){
UnhookWindowsHookEx(g_hMouseHook);
}
dll.def
Code:
LIBRARY DLL
EXPORTS
InitHook
KillHook
I've tried different things with the DLL, like no __declspec etc. but I just can't get it to work.
Maybe I'm missing something? or is my VS just ****ing me by not using the DEF file? (it's in the same dir as the dll.cpp)
Anyhow, thanks alot for all your time reading this, appreciate it :) Glad to be back by the way, for the people who still know me over here ;)
-
Try extern "C" on your hook functions (just a guess, can't test it).
-
Hey Mike, good to see you again mate, how're you doing lately?
Anyway, thanks for the suggestion, @work now so I'll test it when I get home.
but you mean in the dll? like
Code:
#include <windows.h>
HHOOK g_hMouseHook;
extern "C" __declspec(dllexport) HHOOK __stdcall InitHook(HOOKPROC MouseProc){
g_hMouseHook = SetWindowsHookEx(WH_MOUSE, MouseProc,NULL,0);
return g_hMouseHook;
}
extern "C" __declspec(dllexport) void __stdcall KillHook(){
UnhookWindowsHookEx(g_hMouseHook);
}
wait.. I think I've seen it before.. I should put that in the DEF file right? Can you post an example how?
Thanks alot mike!
-
It goes in the code, it might help persuade it to to the names properly.
Not so bad here, started at Uni, back to working again :groan: :D Not seen you around for a very long time :p
-
Ok so the way I posted it is the right way? or you mean just in the code as on top of all the other stuff like below #include <windows.h> ?
Sorry that I'm confused, haven't been programming for a very long time, feel like I lost most of it ;) But I know I'll get a hang of it very soon, just have to refresh my memory :)
Edit: Never mind the above, looked at an example and it seems to be right
Good that you're doing well, I'm doing well too, working at the moment, not sure what I want to do next year, so I decided to start programming in my sparetime again to see if I'd like to learn more of it and maybe study something with computers.. totally unsure what I want ;) Enjoying myself as hell though, nothing to complain :) By the way, how's Cherry (hehe it was the girl right? or am I messing things up over here?).
Thanks Mike ;)
-
Heh. Alice, not Cherry :) But she's ok, thanks :)
-
hmm maybe that was someone else than (DennisWrenn or something? Is he still @ the forums?)
Thanks for the help, almost done working;)
-
Ok it calls the functions now, but I have a new problem...
The hook doesn't get created... Probably due to a problem with the callback function.. Am I passing the Address of the function correctly? Is the defenition of that function correct, so that the DLL can access it?
So please help if someone knows the answer.. thanks!
-
-
sorry forgot to post that :)
it's in the main.cpp
Code:
static LRESULT CALLBACK MouseProc( int nCode, WPARAM wParam, LPARAM lParam ){
if (nCode < 0) return CallNextHookEx((HHOOK)g_hMouseHook, nCode, wParam, lParam);
if (wParam == WM_RBUTTONDOWN)
SetWindowText(g_hWnd, "Right-DOWN!");
if (wParam == WM_RBUTTONUP)
SetWindowText(g_hWnd, "Gesture");
return CallNextHookEx((HHOOK)g_hMouseHook, nCode, wParam, lParam);
}
-
Also just guessing, but try making it not static.
Z.
-
Yeah tried that already, didn't help :(
Thanks for the suggestion though, always appreciate it to see people help.
Anyone else suggestions?
Thanks in advance,
Jop
-
Maybe try moving the MouseProc to the DLL?
Z.
-
Well was thinking of that too, but I remember me and keda doing this before, with a callback also I think, and that's possible to do without moving it to the dll.. I'll keep that as a last option.
Thanks again :)
-
You have to move it to the DLL.
Haven't seen DennisWrenn around here for quite a long time.
-
Ok thanks corned, I'll try that later on than.. I'll let you know if it works!
J.
-
I tried it, but it doesn't seem to work... Maybe I'm not declaring the callback right or something?
The DLL:
Code:
#include <windows.h>
HHOOK g_hMouseHook;
HWND g_hWnd;
LRESULT __stdcall CALLBACK MouseProc( int nCode, WPARAM wParam, LPARAM lParam ){
if (nCode < 0) return CallNextHookEx((HHOOK)g_hMouseHook, nCode, wParam, lParam);
if (wParam == WM_RBUTTONDOWN)
SetWindowText(g_hWnd, "Right-DOWN!");
if (wParam == WM_RBUTTONUP)
SetWindowText(g_hWnd, "Gesture");
return CallNextHookEx((HHOOK)g_hMouseHook, nCode, wParam, lParam);
}
void __stdcall InitHook(HWND hWndOwner){
g_hWnd = hWndOwner;
g_hMouseHook = SetWindowsHookEx(WH_MOUSE, &MouseProc,NULL,0);
if (!g_hMouseHook) MessageBox(NULL, "Hook is not working!!","MSG FROM DLL", MB_OK);
//return g_hMouseHook;
}
void __stdcall KillHook(){
UnhookWindowsHookEx(g_hMouseHook);
}
what's wrong with that? Thanks guys :)
-
You must pass the HMODULE of the DLL as the third parameter to SetWindowsHookEx. It is sent in DllMain, so you have to save it to a global variable there.
-
Yeah I managed to work that out, thanks for your help though, really appreciated! :)
-
And it still doesn't work?
-
i have a similar problem,HERE
i have no idea whats wrong, ive made local hooks, but not system wide ones, and i dont know whats up with my code.
-
Yeah it does work here Corned :)
I tried to test it by setting the WindowText of the main window, but that didn't seem to be visible if the main window was inactive.. so I thought there was nothing happening :)
-
Ok I'm back with a problem again!!!
I've got the Hook to work, now I'm just testing it by setting the title of my main window. But the problem is that the Callback doesn't seem to be able to access my global variables.
I read something vaguely about that the variables have to be static or something. Can anyone please help me out? I know it's something stupid :)
the dll code:
Code:
#include <windows.h>
HHOOK g_hMouseHook;
HINSTANCE g_hInst;
static HWND g_hWnd = NULL;
BOOL g_bDown;
LRESULT __stdcall CALLBACK MouseProc( int nCode, WPARAM wParam, LPARAM lParam ){
if (nCode < 0) return CallNextHookEx((HHOOK)g_hMouseHook, nCode, wParam, lParam);
if (wParam == WM_RBUTTONDOWN) {
SetWindowText(g_hWnd, "Right-DOWN!");
}
if (wParam == WM_RBUTTONUP)
{
SetWindowText(g_hWnd, "Gesture");
}
return CallNextHookEx((HHOOK)g_hMouseHook, nCode, wParam, lParam);
}
void __stdcall InitHook(HWND hWndOwner){
//g_hMouseHook = hMouse;
g_hWnd = hWndOwner;
g_hMouseHook = SetWindowsHookEx(WH_MOUSE, MouseProc,GetModuleHandle("dll"),0);
if (!g_hMouseHook) MessageBox(NULL, "Hook is not working!!","MSG FROM DLL", MB_OK);
SetWindowText((HWND)g_hWnd, "Gesture (DLL loaded)");
}
void __stdcall KillHook(){
UnhookWindowsHookEx(g_hMouseHook);
}
Now the 'strange' thing is, the title does get changed when I right-click on the app itself, but NOT if I click anywhere on the screen. The callback does get called, but it can't access the global variables. Why's that?
Thanks for your time!
void __stdcall KillHook(){
UnhookWindowsHookEx(g_hMouseHook);
}
[/code]
-
When your hook is called, it's in whatever process's space that should receive the event. Global variables in DLLs are seperate for each process.
You can declare the variables in specific segments that you later tell the linker to share.
Code:
#pragma data_seg("shared_data")
#pragma bss_seg("shared_bss")
// All variables that should be available in all process spaces go here.
#pragma data_seg()
#pragma bss_seg()
#pragma comment(linker,"/SECTION:shared_data,RWS")
#pragma comment(linker,"/SECTION:shared_bss,RWS")
-
CB... Thank you so very very much man!
I was suspecting that it had to do something with process space, had no idea how to fix it :)
I think I have to look more into those PRAGMA special kinda things... where did you look up those "shared_bss" things for example? never heard of them.
Anyway, thanks alot CB you really helped me out!!!
-
That comes from The Petzold, but I extended it for uninitialized variables (the bss thing).
-
Thanks!
But do you know if there's any reference with all those codes? You have to know that they exist, because you run into a specific problem you can't think of a PRAGMA thing to type in :)
-
Type 'pragmas' into the index in the VC++ reference. It should give you a list of all permitted pragmas.
Other interesting info is contained in the overview of permitted __declspec declarations.
/SECTION is a linker option, see the linker options for reference. #pragma comment sends additional information to the linker. e.g.
#pragma comment(lib, "name.lib")
specifies that name.lib should be added to the import libraries.
-
Once again, CB.. thanks alot for helping me out!