I have a code to display a part of screen when mouse moves. But the WH_MOUSE doesn't work. I need to change GetModuleHandle(0), 0 to hInst, GetCurrentThreadId().
But then the application will work only when the mouse is over the application itself.
I want it global and I tried WH_MOUSE_LL, it is slower then WH_MOUSE.
Is that possible to use WH_MOUSE globally without DLL?
void SetHook()
{
gMouseHook = SetWindowsHookEx(WH_MOUSE, MouseProc, GetModuleHandle(0), 0);
}
//================================================================================
// Mouse Hook
static LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode < 0) {
return CallNextHookEx(gMouseHook, nCode, wParam, lParam);
}
if (wParam == WM_MOUSEMOVE) {
MOUSEHOOKSTRUCT *mouseInfo = (MOUSEHOOKSTRUCT*)lParam;
int x = mouseInfo->pt.x;
int y = mouseInfo->pt.y;
PrintScreen(x, y);
}
return CallNextHookEx(gMouseHook, nCode, wParam, lParam);
}
Is that possible to use WH_MOUSE globally without DLL?
No, the hook procedure needs to be in a DLL so that it can be injected into other processes.
I tried WH_MOUSE_LL, it is slower then WH_MOUSE.
That probably means your hook procedure is slow.
Related
I want to trap keyboard messages in a console application, so I tried this:
HWND GetConsoleHwnd(void)
{
#define SIZEBUF 1024
char szBuffer[SIZEBUF];
GetConsoleTitle(szBuffer, SIZEBUF);
#undef SIZEBUF
return FindWindow(NULL, szBuffer);
}
LRESULT CALLBACK ConsoleProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_KEYDOWN:
switch (wParam)
{
//VK Cases
}
break;
}
return CallWindowProc(OldConsoleProc, hwnd, msg, wParam, lParam);
}
this in main:
HWND hwndConsole = GetConsoleHwnd();
OldConsoleProc = (WNDPROC) SetWindowLong(hwndConsole, GWL_WNDPROC,
ConsoleProc);
and this Global Var: WNDPROC OldConsoleProc;
but it doesnt work, what I am doing wrong?
You can't subclass a window of another process this way. You can do it with hooks but I wouldn't recommend trying this on console window. ReadConsoleInput is low-level enough, and it's as far as you can get without ugly nonportable hacks (I'm not even sure there are some events reaching WndProc when the console window is full screen).
I need to prohibit window moving with some title.
// Hooks.cpp : Defines the exported functions for the DLL application.
//
#include "stdafx.h"
extern "C" __declspec(dllexport) TCHAR s[50];
extern "C" __declspec(dllexport) HHOOK hHook;
extern "C" __declspec(dllexport) LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam);
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
return 1;
}
TCHAR s[50];
HHOOK hHook;
LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
{
// HDC hdc;
if (nCode < 0)
return CallNextHookEx(hHook, nCode, wParam, lParam);
// hdc = GetDC(hWnd);
CBT_CREATEWND* cbt=(CBT_CREATEWND*)lParam;
if (nCode==HCBT_MOVESIZE)
if (!lstrcmp(s,cbt->lpcs->lpszName)) return 1;
return CallNextHookEx(hHook, nCode, wParam, lParam);
return 0;
}
but I've got an error when I move window. When I change its position It changes but then I've got error - access violation at adress 67471040 in module Hooks.dll(my dll).Read of adress 00000116
You are casting lParam into a pointer to CBT_CREATEWND, but that is only so if nCode==HCBT_CREATEWND, and that is obviously not the case. When nCode==HCBT_MOVESIZE then lParam points to a RECT struct.
You should process first the HCBT_CREATEWND, filter it and save the related HWND to make the condition when HCBT_MOVESIZE happens.
That won't work if the window changes the title, however.
BTW, can't you just call GetWindowText() to get the window title?
I am trying to set a global GetMessage hook on all threads. This is my DLL:
#include <windows.h>
__declspec(dllexport) LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam)
{
MessageBeep(0);
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
As you can see, it's not much. I just want it to call MessageBeep whenever it's called.
#include <windows.h>
typedef LRESULT (CALLBACK *LPGetMsgProc)(int nCode, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR pCmdLine, int nCmdShow)
{
if(!(HMODULE hDll = LoadLibrary("library.dll")))
return 1;
if(!(LPGetMsgProc pfnProc = (LPGetMsgProc)GetProcAddress(hDll, "GetMsgProc#12")))
return 2;
HHOOK hMsgHook = SetWindowsHookEx(WH_GETMESSAGE, pfnProc, hInstance, 0);
MSG msg;
while(GetMessage(&msg, NULL, 0, 0) > 0) {}
UnhookWindowsHookEx(hMsgHook);
return 0;
}
My WinMain loads the library, gets the procedure and sets the hook. However, MessageBeep is never being called. Is there something I'm doing wrong here?
Also, one other thing has been bothering me. In this call:
if(!(LPGetMsgProc pfnProc = (LPGetMsgProc)GetProcAddress(hDll, "GetMsgProc#12")))
I was forced to use "GetMsgProc#12" because I couldn't get it right any other way. Can somebody please tell me how I'm supposed to use a .def file or something else so I can just have it as "GetMsgProc"? Though MSDN stated that since I have __declspec(dllexport) in my declaration I wouldn't need it...
My IDE is Code::Blocks with MinGW. Thanks in advance.
The third parameter...
HHOOK hMsgHook = SetWindowsHookEx(WH_GETMESSAGE, pfnProc, hInstance, 0);
...is the handle passed into your WinMain function. But it needs to refer to the DLL where the callback function resides - in your case, that'd be hDLL.
I want to know the value of virtual key pressed when a child window(like 'edit' or 'button') has focus.
How to do that?
Well one way is to use
WNDPROC g_OldProc;
LRESULT CALLBACK MyEditWindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
if ( uMsg == WM_KEYDOWN )
{
// Handle key down.
}
return g_OldProc( hwnd, uMsg, wParam, lParam );
}
then at some opportune moment
g_OldProc = (WNDPROC)GetWindowLongPtr( hEdit, GWLP_WNDPROC );
SetWindowLongPtr( hEdit, GWLP_WNDPROC, (LONG_PTR)MyEditWindowProc );
This will replace the window procedure of the hEdit control with your own window procedure that, in turn, calls the original window procedure.
You could catch them at the level of the message loop (before calling DispatchMessage). Nasty but will work.
You could use the GetKeyState Win32 API from within a WM_SETFOCUS handler.
I'm trying a little concept test to change one of the features of the logitech MS3200 keyboard (the zoom feature). I've got the keys that are sent from the zoom control. So, I have a main app, and a dll that contains a hook procedure.
Here's the main app:
#include <stdio.h>
#include <windows.h>
HANDLE hHook;
int main()
{
HINSTANCE hMod = GetModuleHandle(NULL);
hHook = SetWindowsHookEx(WH_KEYBOARD, HookProc,0,0);
if(hHook == NULL)
printf("Unable to set hook! Error: %d", GetLastError());
else
printf("Hook set successfully!");
while(TRUE)
{
Sleep(1000);
}
return 0;
}
And here is the hook procedure dll:
#include <windows.h>
int __declspec (dllexport) HookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if(nCode < 0)
{
return CallNextHookEx(hHook, nCode, wParam, lParam);
}
if(wParam == VK_ADD || wParam == VK_SUBTRACT)
{
short status = GetKeyState(VK_CONTROL);
if(status == 1)
{
if(wParam == VK_ADD)
wParam = VK_UP;
else
wParam = VK_DOWN;
}
}
return CallNextHookEx(hHook, nCode, wParam, lParam);
}
int WINAPI dllmain(HINSTANCE hMod, DWORD data, LPVOID lpVOid)
{
return 0;
}
I need to be able to access what's returned by SetWindowsHookEx (hHook) from the dll, in order to call CallNextHookEx().
It's probably possible, but it's not worth your time to investigate.
Instead, move the hook setting code to the DLL.
Oh, and I think you need to pass the DLL module handle to the hook setting function, not a NULL
One possible way to handle this would be to have another exported function in your DLL to pass the hHook to, and save that in a variable local within the DLL for use in the HookProc.
HANDLE dllHook;
void __declspec (dllexport) HookHandle(HANDLE hHook)
{
dllHook = hHook;
}
int __declspec (dllexport) HookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if(nCode < 0 && dllHook!= NULL)
{
return CallNextHookEx(dllHook, nCode, wParam, lParam);
}
//....
}
int WINAPI dllmain(HINSTANCE hMod, DWORD data, LPVOID lpVOid)
{
dllHook = NULL; //initialize
return 0;
}
Code in a DLL can't directly access variables in the calling app, because there's no guarantee that the app that loads the DLL will have those variables defined, and even if it did, the DLL has no way to know where it would be stored.
You could have a global variable in the DLL and an extra entry point to set it, which you call after calling SetWindowsHookEx. The DLL would need to wait until this entry point is called before calling CallNextHookEx.
On NT/XP/2003 etc the first param to CallNextHookEx is ignored. See the documentation for CallNextHookEx:
http://msdn.microsoft.com/en-us/library/ms644974%28VS.85%29.aspx
hth