I only left in the relevant parts because I thought that would be easier for others to see if / where I'm going wrong, here's the whole lot (the _lParam and_wParam thing was just a typo, based on how I'm working it).
theDLL.h:
Code:
#ifndef THEDLL_H_
#define THEDLL_H_
#define WINVER 0x0500
#define _WIN32_WINNT 0x0500
#include <windows.h>
#include <stdio.h>
#include <iostream>
using namespace std;
#ifdef __cplusplus
extern "C" {
#endif
__declspec(dllexport) void __stdcall
registerHooks();
__declspec(dllexport) void __stdcall
unregisterHooks();
#ifdef __cplusplus
}
#endif
#endif /* THEDLL_H_ */
theDLL.cpp:
Code:
#include "theDLL.h"
void ErrorExit(const char*);
HINSTANCE _hInst = NULL;
DWORD hookThreadId = 0;
HHOOK llMouseHookHandle;
HHOOK llCBTHookHandle;
HWND window;
size_t buf_size = 32;
char* buf = new char[buf_size];
extern "C"BOOL APIENTRY DllMain(HINSTANCE hInst, DWORD reason, LPVOID reserved) {
cout << "asdf" << endl;
switch (reason) {
case DLL_PROCESS_ATTACH:
_hInst = hInst;
break;
default:
break;
}
return TRUE;
}
LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam) {
if (nCode < 0)
return CallNextHookEx(NULL, nCode, wParam, lParam);
MOUSEMOVEPOINT * mmp = (MOUSEMOVEPOINT *)lParam;
POINT pt;
pt.x = mmp->x;
pt.y = mmp->y;
switch (wParam) {
case WM_LBUTTONDOWN:
break;
case WM_LBUTTONUP:
{
window = WindowFromPoint(pt);
if (window != NULL) {
strcpy(buf, "");
GetClassNameA(window, buf, buf_size);
cout << buf << endl;
}
}
break;
default:
break;
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam) {
cout << "anything at all" << endl;
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
__declspec(dllexport) void __stdcall
registerHooks() {
if (_hInst == NULL)
ErrorExit("register hooks");
llMouseHookHandle = SetWindowsHookEx(WH_MOUSE_LL, MouseProc, _hInst, 0);
if (llMouseHookHandle == NULL)
ErrorExit("llMouseHookHandle");
llCBTHookHandle = SetWindowsHookEx(WH_CBT, CBTProc, _hInst, 0);
if (llCBTHookHandle == NULL)
ErrorExit("llCBTHookHandle");
hookThreadId = GetCurrentThreadId();
}
__declspec(dllexport) void __stdcall
unregisterHooks() {
int ret_val = UnhookWindowsHookEx(llMouseHookHandle);
if (ret_val == 0)
ErrorExit("Unhook llMouseHookHandle");
ret_val = UnhookWindowsHookEx(llCBTHookHandle);
if (ret_val == 0)
ErrorExit("Unhook llCBTHookHandle");
}
void ErrorExit(const char* pszFunction)
{
LPTSTR pszMessage;
DWORD dwLastError = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dwLastError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&pszMessage,
0, NULL );
printf("%s failed with error %d: %s\n", pszFunction, (int)dwLastError, pszMessage);
LocalFree(pszMessage);
ExitProcess(dwLastError);
}
theDLL.def:
Code:
LIBRARY "ZZZDll.dll"
EXPORTS
registerHooks
unregisterHooks
theDLLtester.cpp
Code:
#include <windows.h>
#include <string>
typedef void (*dllCall)();
dllCall registerHooks, unregisterHooks;
HINSTANCE hinstLib = NULL;
HWND hwnd = NULL;
void error_window(bool error_state, const std::string win_title, const std::string message) {
if (error_state) {
MessageBox(GetDesktopWindow(), message.c_str(), win_title.c_str(), MB_OK | MB_ICONERROR);
if (hinstLib != NULL)
FreeLibrary(hinstLib);
if (hwnd != NULL)
DestroyWindow(hwnd);
exit(0);
}
}
void set_dll_stuff() {
std::string dll_attrib = "theDLL.dll";
hinstLib = LoadLibrary(dll_attrib.c_str());
error_window(hinstLib == NULL, "ERROR: unable to load DLL, ", dll_attrib);
dll_attrib = "registerHooks";
registerHooks = (dllCall)GetProcAddress(hinstLib, dll_attrib.c_str());
error_window(registerHooks == NULL, "ERROR: unable to find DLL function", dll_attrib);
registerHooks();
dll_attrib = "unregisterHooks";
unregisterHooks = (dllCall)GetProcAddress(hinstLib, dll_attrib.c_str());
error_window(unregisterHooks == NULL, "ERROR: unable to find DLL function", dll_attrib);
}
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch (message) {
case WM_CREATE:
set_dll_stuff();
break;
case WM_LBUTTONDOWN:
break;
case WM_COMMAND:
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
unregisterHooks();
FreeLibrary(hinstLib);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
}
int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nFunsterStil)
{
WNDCLASSEX wc;
MSG Msg;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WindowProcedure;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hThisInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = "theDLL window";
wc.hIconSm = NULL;
RegisterClassEx(&wc);
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
"theDLL window",
"The title of my window",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,
NULL, NULL, hThisInstance, NULL);
ShowWindow(hwnd, nFunsterStil);
UpdateWindow(hwnd);
while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
this has just compiled and the global low-level mousehook works as expected, I click on firefox and it prints "MozillaUIWindowClass", I click on the taskbar and it prints "ToolbarWindow32". "anything at all", however only gets printed out when I mess with the tester window. this is clearly only local behaviour and not global, can you see any reason why this would be?