I'll preface this with saying that I am new to win32 programming.
I'm creating a global keyboard hook using a .dll, I have put in install and uninstall functions to handle the actual setting and removing of the keyboard hook.
#pragma comment(linker, "/SECTION:.SHARED,RWS")
#pragma data_seg(".SHARED")
static HHOOK hk=NULL;
//static CMyFile *pLF;
#pragma data_seg()
HINSTANCE hins = NULL;
__declspec( dllexport ) LRESULT Install(){
std::cout << "Installing" << std::endl;
hk = SetWindowsHookEx(WH_KEYBOARD_LL,EventAnalysis::KeystrokeAnalysis::KeyboardCallback,hins,0);
if(hk == NULL){
std::cout << "Hook creation failed! - " << GetLastError() << std::endl;
}
return 0;
}
__declspec(dllexport) BOOL CALLBACK UnInstall()
{
std::cout << "UnInstalling" << std::endl;
return UnhookWindowsHookEx(hk);
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
hins = (HINSTANCE) hModule;
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
So now that I have my .dll, I created a simple executable that loads the library and installs the hooks:
int _tmain(int argc, _TCHAR* argv[])
{
auto funHandle = LoadLibrary(L"C:\\Users\\tprodanov\\Documents\\visual studio 2010\\Projects\\HaveFun\\Release\\HaveFun.dll");
if(funHandle == NULL){
std::cout << "Library load failed! - " << GetLastError() << std::endl;
}
auto Install = (LRESULT(*)()) GetProcAddress(funHandle, "?Install@@YAJXZ");
if(Install == NULL){
std::cout << "Procedure load failed! - " << GetLastError() << std::endl;
}
Install();
MSG Msg;
while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
auto Uninstall = (BOOL(*)()) GetProcAddress(funHandle, "?UnInstall@@YGHXZ");
if(Uninstall == NULL){
std::cout << "Procedure load failed! - " << GetLastError() << std::endl;
}
Uninstall();
return 0;
}
What I find curious is that the behavior of my program is as expected in its current state (and also if instead of a message loop I just pop out a MessageBox() that waits for the user to click OK), but it doesn't work if I use std::cin.get() or an empty while loop. Can someone please explain why this is the behavior?
Also as a followup question - the KeyboardCallback function just prints to the console "Key Pressed".
LRESULT CALLBACK EventAnalysis::KeystrokeAnalysis::KeyboardCallback(int nCode, WPARAM wParam, LPARAM lParam){
std::cout << "Key pressed" << std::endl;
return CallNextHookEx(NULL,nCode,wParam,lParam);
}
I expected that this will be printed only when I press keys when focused on the console window, but even if I type in notepad the "Key Pressed" messages show up in my executable that called the Install function of the .dll. I don't understand this, since as far as I understood the dynamic library is loaded independently in every process, so every process has its own copy of the KeyboardCallback function and it will try to print to the foreground window's console.