Witam
Tak wiem, ze bylo juz o tym setki razy, ze niby nie szukalem w pozostalych watkach. Otoz przeszukalem cale forum dwa razy i nadal nie znalazlem czegos co poprawnie dziala.
Chce zalozyc globalnego hook-a na klawiature (pozniej nie tylko na nia, interesuja mnie glownie zmiany aktywnych okien). Siedze juz nad tym dwa dni i juz naprawde skonczyly mi sie pomysly. Mam taki kod (oczywisice funkcja jest w dll-ce).
Zawartosc pliku tworzacego DLL-ke:
#include <vcl.h>
#include <windows.h>
/*
* Start of shared data section. All these variable will be shared among all
* DLL instances. The way to declare a shared data section differs from compiler
* to compiler. The following is the MSVC++ method.
*/
#pragma data_seg(".SHARDAT")
static HHOOK g_hkb=NULL;
static HWND g_notifyWnd = NULL;
UINT uKeypressID = ::RegisterWindowMessage("WM_GLOBAL_KEYPRESS");
#pragma data_seg()
#pragma comment(linker, "-section:.SHARDAT,rws")
HINSTANCE g_hInst = NULL;
/*
* Our hook procedure. This will get called whenever a key is pressed
*/
LRESULT __declspec(dllexport)__stdcall CALLBACK KeyboardProc(
int nCode,
WPARAM wParam,
LPARAM lParam)
{
if(nCode == HC_ACTION && g_notifyWnd)
{
SendMessage(g_notifyWnd,uKeypressID,wParam,lParam) ;
}
return CallNextHookEx( g_hkb, nCode, wParam, lParam );
}
extern "C" BOOL __declspec(dllexport) installhook(HWND notifyWnd)
{
if(!g_hInst) return FALSE;
g_notifyWnd = notifyWnd;
g_hkb = SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)KeyboardProc,g_hInst,0);
return (BOOL)g_hkb;
}
extern "C" BOOL __declspec(dllexport) unhook()
{
return UnhookWindowsHookEx(g_hkb);
}
/*
* DLL entry point
*/
BOOL APIENTRY DllMain( HINSTANCE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
if(ul_reason_for_call == DLL_PROCESS_ATTACH)
{
g_hInst = hModule;
}
return TRUE;
}
Zaawartosc pliku glownej aplikacji:
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
/* Global variables */
const UINT uKeypressID = RegisterWindowMessage(_T("WM_GLOBAL_KEYPRESS"));
HWND g_hwnd;
HMODULE g_hMod;
HINSTANCE hInst;
char szWindowClass[] = _T("WinClass");
/* Function prototypes */
ATOM RegisterClassFn(HINSTANCE hInstance);
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow);
/*
* Install the keyboard hook
*/
BOOL LoadHook()
{
typedef BOOL (*FUNCTION_TYPE)(HWND);
//BOOL (CALLBACK *installhook)(HWND);
FUNCTION_TYPE installhook;
/* Load the dll into memory */
g_hMod = LoadLibrary("Project3.dll");
if(!g_hMod)
return FALSE;
/* Get the address of the installhook() function */
installhook = (FUNCTION_TYPE)GetProcAddress(g_hMod,"installhook");
if(!installhook) return FALSE;
return installhook(g_hwnd);
}
/*
* Uninstall the keyboard hook
*/
BOOL UnloadHook()
{
BOOL (*unhook)();
BOOL result;
if(!g_hMod) return FALSE;
/* Get the address of the unhook() function */
unhook = (BOOL (*)())GetProcAddress(g_hMod,"unhook");
if(!unhook) return FALSE;
result = unhook();
FreeLibrary(g_hMod);
return result;
}
/*
* This gets called when a key is pressed. To see what the wParam and
* lParam values indicate, look at KeyboardProc() under MSDN.
*/
void keypressed(WPARAM wParam, LPARAM lParam)
{
int mask = 0x80000000;
char msg[128];
/* we see if bit 31 is set. If it is, then the button
* was pressed
*/
if(mask & lParam)
{
/* Key was pressed */
sprintf(msg,_T("The %c Key was pressed"),wParam);
MessageBox(g_hwnd,msg,_T("KEYPRESS"),MB_OK | MB_SYSTEMMODAL);
}
}
/*
* Application entry point
*/
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
/* Register the window */
RegisterClassFn(hInstance);
/* Initialize the application */
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
/* Main message loop */
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
/*
* Create the window, and display it
*/
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance;
/* Create the window */
hWnd = CreateWindow(szWindowClass, _T("Test Hook"), WS_OVERLAPPEDWINDOW,
100, 100, 100, 100, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
/*
* This is our main window procedure
*/
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
/* First check and see if the message matches our global ID */
if(message == uKeypressID)
{
/* Call the keypressed method to handle a key press */
keypressed(wParam,lParam);
return 0;
}
else
{
switch(message)
{
case WM_CLOSE:
/* Uninstall the hook */
if(!UnloadHook())
MessageBox(g_hwnd,_T("Unable to unload hook"),_T("ERROR"),MB_OK);
return DefWindowProc(hWnd, message, wParam, lParam);
case WM_CREATE:
g_hwnd = hWnd;
/* Install the hook */
if(!LoadHook())
MessageBox(g_hwnd,_T("Unable to install hook"),_T("ERROR"),MB_OK);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
return 0;
}
ATOM RegisterClassFn(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = NULL;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = NULL;
return RegisterClassEx(&wcex);
}
Dodam, ze ten kod akurat nie jest mojego autorstwa, ale ponoc innym dziala, wiec dlaczego nie mi [sciana].
Z gory dziekuje za wszelkie uwagi i sugestie.
Pozdrawiam.