How to set global hook WH_CBT in winapi - c++

I would like to create global WH_CBT hook using winapi. I create dll with this hook. When I using this
dll in other application ( this app load dll and start hook - let it name be abc.exe ) I can load that dll, get functions ( with hook and unhook ) and see the output, but only from that abc.exe's thread. I would like to see messages like HCBT_CREATEWND from other windows ( not only from abc.exe window ). I set the fourth arg in SetWindowsHookEx to 0, so I except to set the global hook.
In abc.h:
HINSTANCE hDll;
typedef void( * MYPROC )( void );
MYPROC funHook, funUnhook;
In abc.exe window constructor (abc.cpp):
hDll = LoadLibrary( L"probaHook" );
if( hDll )
{
funHook =( MYPROC ) GetProcAddress( hDll, (LPCSTR) "hook" );
funUnhook = ( MYPROC ) GetProcAddress( hDll, (LPCSTR) "unhook" );
qDebug()<<funHook<<funUnhook;
if( funHook )
{
funHook();
}
}
In abc.exe window destructor (abc.cpp):
if( funUnhook )
{
funUnhook();
}
FreeLibrary( hDll );
In probahook.h ( file with dll declaration functions ):
#ifndef PROBAHOOK_H
#define PROBAHOOK_H
#include "probaHook_global.h"
#include "windows.h"
LRESULT CALLBACK cbtHookProc( int code, WPARAM wParam, LPARAM lParam );
extern "C" PROBAHOOK_EXPORT void hook( void );
extern "C" PROBAHOOK_EXPORT void unhook( void );
class PROBAHOOK_EXPORT ProbaHook
{
public:
ProbaHook();
};
#endif // PROBAHOOK_H
In probaHook_global.h:
#ifndef PROBAHOOK_GLOBAL_H
#define PROBAHOOK_GLOBAL_H
#include <QtCore/qglobal.h>
#if defined(PROBAHOOK_LIBRARY)
# define PROBAHOOK_EXPORT Q_DECL_EXPORT
#else
# define PROBAHOOK_EXPORT Q_DECL_IMPORT
#endif
#endif // PROBAHOOK_GLOBAL_H
In probahook.cpp:
#include "probahook.h"
#include <QDebug>
#include <QFile>
HHOOK hhook = NULL;
HINSTANCE hInst = NULL;
LRESULT CALLBACK cbtHookProc( int code, WPARAM wParam, LPARAM lParam )
{
if( code < 0 ) return CallNextHookEx( 0, code, wParam, lParam );
qDebug()<<code;
if( code == HCBT_CREATEWND )
{
QFile file(R"(C:\Users\tom\Desktop\def.txt)");
file.open(QIODevice::WriteOnly | QIODevice::Append);
file.write(QString::number(GetCurrentThreadId()).toStdString().c_str());
file.write("\n");
file.close();
return 0;
}
return CallNextHookEx( 0, code, wParam, lParam );
}
ProbaHook::ProbaHook(){}
BOOLEAN APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved )
{
hInst = hModule;
switch( ul_reason_for_call )
{
case DLL_PROCESS_ATTACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
void hook( void )
{
hhook = SetWindowsHookEx( WH_CBT, cbtHookProc, hInst, 0 );
}
void unhook(void)
{
UnhookWindowsHookEx( hhook );
}
The output from def.txt is:
17192
17192
17192
17192
17192
17192
17192 is my abc.exe thread. Of course when abc.exe is running I try open other windows.
qDebug() in cbtHookProc of course produce output like: 4,6,0, but only from abc.exe window.

Related

Programmatically delete item from Windows Recycle Bin without UI dialog

I'm using IContextMenu with "delete" verb to erase items from recycle bin, but it brings up the UI dialog even if I useCMIC_MASK_FLAG_NO_UI flag. Is there another way to delete files from recycle bin without showing the dialog?
IContextMenu* contextMenu;
recycleBin->GetUIObjectOf(0, 1, (LPCITEMIDLIST*)(&pidl), IID_IContextMenu, 0, (LPVOID *)&contextMenu);
CMINVOKECOMMANDINFO ci;
memset(&ci, 0, sizeof(ci));
ci.fMask = CMIC_MASK_FLAG_NO_UI;
ci.cbSize = sizeof(CMINVOKECOMMANDINFO);
ci.lpVerb = "delete";
contextMenu->InvokeCommand(&ci);
contextMenu->Release();
The full code including recycle bin object initialization and items enumeration is on gist
You can install a WH_CBT hook, and in its callback watch for an nCode of HCBT_CREATEWND. If you get a matching class name ('#32770 (Dialog)' ?) and a matching title either return a nonzero value from the callback, you can send BM_CLICK to click Yes button and the dialog will be closed automatically.
Code Sample:
main.cpp
#include <iostream>
#include <windows.h>
#include <Ole2.h>
#include <shlobj.h>
#include <shlwapi.h>
#include <string>
#pragma comment(lib,"Shlwapi.lib")
HHOOK g_hhook;
int main()
{
OleInitialize(0);
HINSTANCE hinstDLL = LoadLibrary(TEXT("D:\\xxx\\Dll_WH_CBT\\Debug\\Dll_WH_CBT.dll"));
HHOOK(*AttachHookProc)(DWORD);
AttachHookProc = (HHOOK(*)(DWORD)) GetProcAddress(hinstDLL, "AttachHook");
void(*RemoveHooks)(DWORD);
RemoveHooks = (void(*)(DWORD))GetProcAddress(hinstDLL, "RemoveHooks");
IShellFolder* desktop;
if (FAILED(SHGetDesktopFolder(&desktop))) {
std::cerr << "Failed to get desktop fodler" << std::endl;
return -1;
}
...
IEnumIDList* enumFiles;
if (FAILED(recycleBin->EnumObjects(0, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS |
SHCONTF_INCLUDEHIDDEN, &enumFiles)))
{
std::cerr << "Could not enumerate recycle bin objects" << std::endl;
recycleBin->Release();
return -1;
}
AttachHookProc(0);
...
RemoveHooks(0);
enumFiles->Release();
recycleBin->Release();
OleUninitialize();
return 0;
}
Dll:
// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
#include <Windows.h>
HMODULE thisModule;
HHOOK g_hhook;
LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
{
switch (nCode)
{
case HCBT_CREATEWND:
{
HWND File_Window = FindWindow(L"#32770", L"Delete File");
HWND Folder_Window = FindWindow(L"#32770", L"Delete Folder");
if (File_Window)
{
HWND yes = FindWindowEx(File_Window, NULL, L"Button", L"&Yes");
SendMessage(yes, BM_CLICK, 0, 0);
SendMessage(yes, BM_CLICK, 0, 0);
}
if (Folder_Window)
{
HWND yes = FindWindowEx(Folder_Window, NULL, L"Button", L"&Yes");
SendMessage(yes, BM_CLICK, 0, 0);
SendMessage(yes, BM_CLICK, 0, 0);
}
break;
}
default:
break;
}
return CallNextHookEx(g_hhook, nCode, wParam, lParam);
}
#ifdef __cplusplus //If used by C++ code.
extern "C" { //we need to export the C interface
#endif
_declspec(dllexport) HHOOK AttachHook(DWORD threadID) {
g_hhook = SetWindowsHookEx(WH_CBT, CBTProc, thisModule, threadID);
return g_hhook;
}
#ifdef __cplusplus
}
#endif
extern "C" { //we need to export the C interface
__declspec(dllexport) void RemoveHooks(DWORD)
{
UnhookWindowsHookEx(g_hhook);
}
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
thisModule = hModule;
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

About WH_CBT hook

I'm trying to use SetWindowsHookEx to install WH_CBT hook on global to inject the DLL into other process. Now I have the inject.exe, ExampleWindow.exe, inject.dll, let me show you the code.
1.code piece of inject.exe
#include <windows.h>
int main()
{
HHOOK hhook = NULL;
HMODULE dll = LoadLibrary(_T("D:\\projects\\CppDemon\\Release\\HookDemoDll.dll"));
HOOKPROC pfn = (HOOKPROC)GetProcAddress(dll, "MyCBTProc");
if (pfn == NULL)
{
printf("can not get MyCBTProc,press any key to exit\n");
getchar();
return 0;
}
printf("press any key to continue hook\n");
getchar();
hhook = SetWindowsHookEx(WH_CBT, pfn, dll, 0);
if (NULL == hhook)
{
printf("%d\n", GetLastError());
}
printf("press any key to unhook\n");
getchar();
UnhookWindowsHookEx(hhook);
return 0;
}
2.code piece of inject.dll
#ifdef __cplusplus
extern "C"
{
#endif
extern "C" __declspec(dllexport) LRESULT MyCBTProc(_In_ int nCode, _In_ WPARAM wParam, _In_ LPARAM lParam);
#ifdef __cplusplus
}
#endif
LRESULT MyCBTProc(_In_ int nCode, _In_ WPARAM wParam, _In_ LPARAM lParam)
{
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
DWORD pid = 0;
TCHAR buffer[128] = { 0 };
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
pid = GetCurrentProcessId();
_stprintf_s(buffer, 128, _T("[+] PID = %d"), pid);
OutputDebugString(buffer);
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
The ExampleWindow.exe is a test case for inject when the named window is created.
When I run inject.exe and everything goes well, the inject.dll has been loaded and the the debug message is output correct, and the PCHUNTER(this is an ARK tool) can detect the WH_CBT message hook in module inject.exe. Then, I run the ExampleWindow.exe, there also can output the debug message.
After this action, I refresh the message hook windows in PCHUNTER ,the WH_CBT hook message has disappeared from the control, and the inject.dll not injected in the ExampleWindow.exe at all.THis is not my expect result.
I don't know how this happens. I hope someone can help me find the cause of this problem.

Title Name not showing and background color not changing

I have code for a C++ Win32 Wrapper Class which i am fiddling with. Since I'm just trying to use handler's, i removed the WindowProcedure and just used a message router. And somehow things are getting buggy.
Now with just the message router the title of the WindowClass which i have tired to make doesn't display the title name of the window.
And somehow i can't seem to get the background color to change.
Main.cpp
#include "BaseWindow.h"
#include "GameWindow.h"
int APIENTRY WinMain ( HINSTANCE h_instance, HINSTANCE h_prev_instance, LPSTR lp_cmd_line, int n_cmd_show ) {
// Create the Game Window
GameWindow game_window ( h_instance, TEXT ( "GameWindow" ) );
game_window.Register ();
// Create the Base Window
BaseWindow base_window ( TEXT ( "BaseWindow" ), game_window.ClassName () );
base_window.Create ();
base_window.Show ();
// Pump Messages
MSG messages;
int status;
while ( ( status = GetMessage ( &messages, 0, 0, 0 ) ) != 0 ) {
if ( status == -1 ) {
// Break;
break;
}
TranslateMessage ( &messages );
DispatchMessage ( &messages );
}
return messages.wParam;
}
AbstractWindow.h
#pragma once
#ifndef __ABSTRACT_WINDOW_H__
#define __ABSTRACT_WINDOW_H__
#include <Windows.h>
class AbstractWindow {
public:
AbstractWindow ();
~AbstractWindow ();
virtual bool Create ();
static LRESULT CALLBACK MessageRouter ( HWND, UINT, WPARAM, LPARAM );
protected:
HWND hwnd_;
DWORD style_ex_;
LPCTSTR class_name_;
LPCTSTR window_name_;
DWORD style_;
int x_;
int y_;
int width_;
int height_;
HWND parent_;
HMENU menu_;
HINSTANCE h_instance_;
LPVOID param_;
// Default Handlers
virtual bool OnCreate ( HWND ) = 0;
virtual bool OnCommand ( int, int ) = 0;
virtual bool OnDestroy () = 0;
virtual bool EraseBackground ( HWND, WPARAM ) = 0;
virtual bool LeftButtonUp () = 0;
};
#endif // !__ABSTRACT_WINDOW_H__
AbstractWindow.cpp
#include "AbstractWindow.h"
AbstractWindow::AbstractWindow () {}
AbstractWindow::~AbstractWindow () {}
bool AbstractWindow::Create () {
hwnd_ = CreateWindowEx (
style_ex_,
class_name_,
window_name_,
style_,
x_,
y_,
width_,
height_,
parent_,
menu_,
h_instance_,
this // Pointer to this class instance
);
return ( !hwnd_ ? false : true );
}
LRESULT CALLBACK AbstractWindow::MessageRouter ( HWND hwnd, UINT message, WPARAM w_param, LPARAM l_param ) {
AbstractWindow* abstract_window = 0;
if ( message == WM_NCCREATE ) {
abstract_window = ( AbstractWindow* ) ( ( LPCREATESTRUCT ( l_param ) )->lpCreateParams );
SetWindowLong ( hwnd, GWL_USERDATA, long ( abstract_window ) );
abstract_window->OnCreate ( hwnd );
}
else {
abstract_window = ( AbstractWindow* ) ( GetWindowLong ( hwnd, GWL_USERDATA ) );
if ( abstract_window ) {
switch ( message ) {
case WM_COMMAND:
return abstract_window->OnCommand ( LOWORD ( w_param ), HIWORD ( w_param ) );
case WM_DESTROY:
return abstract_window->OnDestroy ();
case WM_ERASEBKGND:
return abstract_window->EraseBackground ( hwnd, w_param );
case WM_LBUTTONUP:
return abstract_window->LeftButtonUp ();
default:
return DefWindowProc ( hwnd, message, w_param, l_param );
}
}
else {
return DefWindowProc ( hwnd, message, w_param, l_param );
}
}
}
BaseWindow.h
#pragma once
#ifndef __BASE_WINDOW_H__
#define __BASE_WINDOW_H__
#include <Windows.h>
#include "AbstractWindow.h"
class BaseWindow : public AbstractWindow {
public:
BaseWindow ();
~BaseWindow ();
BaseWindow ( const TCHAR*, const TCHAR* );
// Display the window onto the screen while updating the client area
void Show ();
private:
virtual bool OnCreate ( HWND );
virtual bool OnCommand ( int, int );
virtual bool OnDestroy ();
virtual bool EraseBackground ( HWND, WPARAM );
virtual bool LeftButtonUp ();
};
#endif // !__BASE_WINDOW_H__
BaseWindow.cpp
#include "BaseWindow.h"
BaseWindow::BaseWindow () {}
BaseWindow::~BaseWindow () {}
BaseWindow::BaseWindow ( const TCHAR* window_name, const TCHAR* class_name ) : AbstractWindow () {
// Member variables are declaried in AbstractWindow as Protected
window_name_ = window_name;
class_name_ = class_name;
// Get the module handle for the window currently running
h_instance_ = GetModuleHandle ( NULL );
style_ = WS_OVERLAPPEDWINDOW | WS_VISIBLE;
x_ = CW_USEDEFAULT;
y_ = CW_USEDEFAULT;
width_ = CW_USEDEFAULT;
height_ = CW_USEDEFAULT;
parent_ = NULL;
menu_ = NULL;
}
void BaseWindow::Show () {
// hwnd_ is from AbstractWindow Class
ShowWindow ( hwnd_, SW_SHOW );
UpdateWindow ( hwnd_ );
}
// Handlers
bool BaseWindow::OnCreate (HWND hwnd) {
MessageBox ( hwnd, TEXT ( "[BaseWindow] Window has been successfully created!" ), TEXT ( "SUCCESS" ), MB_OK );
return true;
}
bool BaseWindow::OnCommand ( int ctrl_id, int notify_code ) {
// Lower 16 bits specifies the element the mouse was used on
// Upper 16 bits specifies the mouse properties
// ctrl_id = Lower
// notify_code = Upper
return true;
}
bool BaseWindow::OnDestroy () {
PostQuitMessage ( 0 );
return true;
}
bool BaseWindow::EraseBackground ( HWND hwnd, WPARAM w_param) {
RECT rect;
GetClientRect ( hwnd, &rect );
FillRect ( ( HDC ) w_param, &rect, GetSysColorBrush ( COLOR_BTNFACE ) );
return true;
}
bool BaseWindow::LeftButtonUp () {
return true;
}
GameWindow.h
#pragma once
#ifndef __GAME_WINDOW_H__
#define __GAME_WINDOW_H__
#include <Windows.h>
#include "AbstractWindow.h"
class GameWindow : protected WNDCLASSEX {
public:
GameWindow ();
~GameWindow ();
GameWindow ( HINSTANCE, const TCHAR* );
virtual bool Register ();
virtual const TCHAR* ClassName () const;
protected:
UINT cb_size_;
UINT style_;
WNDPROC lpfn_wnd_proc_;
int cb_cls_extra_;
int cb_wnd_extra_;
HINSTANCE h_instance_;
HICON h_icon_;
HCURSOR h_cursor_;
HBRUSH hbr_background_;
LPCTSTR lpsz_menu_name_;
LPCTSTR lpsz_class_name_;
HICON h_icon_sm_;
};
#endif // !__GAME_WINDOW_H__
GameWindow.cpp
#include "GameWindow.h"
GameWindow::GameWindow () {}
GameWindow::~GameWindow () {}
GameWindow::GameWindow ( HINSTANCE h_instance, const TCHAR* class_name ) {
// All messages belonging to this Window Class will get sent to MsgRouter
hInstance = h_instance;
lpszClassName = class_name;
lpfnWndProc = AbstractWindow::MessageRouter;
lpszMenuName = NULL;
cbSize = sizeof ( WNDCLASSEX );
cbClsExtra = NULL;
cbWndExtra = NULL;
style = CS_HREDRAW | CS_VREDRAW;
hIcon = LoadIcon ( NULL, IDI_APPLICATION );
hIconSm = LoadIcon ( NULL, IDI_APPLICATION );
hCursor = LoadCursor ( NULL, IDC_HAND );
hbrBackground = ( HBRUSH ) GetStockObject ( COLOR_BTNFACE );
}
const TCHAR* GameWindow::ClassName () const {
return lpszClassName;
}
bool GameWindow::Register () {
return ( ( RegisterClassEx ( this ) ) ? true : false );
}
Your MessageRouter is missing default processing. Add DefWindowProc as shown
LRESULT CALLBACK AbstractWindow::MessageRouter ( HWND hwnd, UINT message, WPARAM w_param, LPARAM l_param ) {
AbstractWindow* abstract_window = 0;
if ( message == WM_NCCREATE ) {
abstract_window = ( AbstractWindow* ) ( ( LPCREATESTRUCT ( l_param ) )->lpCreateParams );
SetWindowLong ( hwnd, GWL_USERDATA, long ( abstract_window ) );
abstract_window->OnCreate ( hwnd );
return DefWindowProc(hwnd, message, w_param, l_param);//ADD THIS LINE
}
...
For background, you can either handle WM_ERASEBKGND or you can set hbrBackground
Method 1: handle WM_ERASEBKGND
virtual LRESULT EraseBackground(HWND hwnd, WPARAM w_param)
{
RECT rect;
GetClientRect(hwnd, &rect);
FillRect((HDC)w_param, &rect, GetSysColorBrush(COLOR_BTNFACE));
return 1;
}
Method 2: set hbrBackground and let window do the rest
hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
virtual LRESULT EraseBackground(HWND hwnd, WPARAM w_param)
{
//let window do this
return DefWindowProc(hwnd, WM_ERASEBKGND, w_param, 0);
}
.........
Edit #2
class AbstractWindow
{
virtual void OnPaint()=0;
...
};
AbstractWindow::MessageRouter()
{
case WM_PAINT:
abstract_window->OnPaint();
return 0;
...
}
void GameWindow::OnPaint()
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
TextOut(hdc, 0, 0, "Hello, Windows!", 15);
EndPaint(hwnd, &ps);
}

Global Keyhook for 32/64 bit application 64-Bit Windows

I am trying to install global keyboard hook and on every DLL_PROCESS_ATTACH Notification try to subclass foreground window. I have separate exe and dll for both 64 bit and 32 bit application. I works ok if only one type (32 or 64 bit) exe and dll pair but not working for both at a time. I was not getting DLL_ATTACH_NOTIFICATION for 32 bit applications if I use 32 bit hook first and then 64 bit.Due to this i was unable to subclass 32 bit application.
sample code for DLL both for 32 and 64 bit with different name
`//#include "stdafx.h"
#include <tchar.h>
#include <process.h>
#pragma data_seg(".HOOKDATA")//Shared data among all instances.
HHOOK g_hKbdHook = NULL;
#pragma data_seg()
#pragma comment(linker, "/SECTION:.HOOKDATA,RWS")//linker directive
#pragma data_seg(".HOOKDATA32")//Shared data among all instances.
HHOOK g_hKbdHook32 = NULL;
#pragma data_seg()
#pragma comment(linker, "/SECTION:.HOOKDATA32,RWS")//linker directive
HINSTANCE g_hInstance = NULL;
HINSTANCE g_hInstance32 = NULL;
HWND hwndKeyFocused = NULL;
static HWND hwndOld;
static HWND hwndFocused;
static WNDPROC oldWindowProc;
BOOL APIENTRY
DllMain(
HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
DWORD dw;
int iRet;
HWND hwnd;
BOOL boIs32bit;
DWORD dwProcID;
HANDLE hProcess;
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
dwProcID = GetCurrentProcessId();
hProcess = OpenProcess(
PROCESS_VM_READ |
PROCESS_VM_WRITE |
PROCESS_VM_OPERATION |
PROCESS_CREATE_THREAD |
PROCESS_QUERY_INFORMATION,
FALSE,
dwProcID
);
IsWow64Process(
hProcess,
&boIs32bit
);
if (TRUE == boIs32bit)
{
g_hInstance32 = (HINSTANCE)hModule;;
}
else
{
g_hInstance = (HINSTANCE)hModule;
}
hwnd = GetForegroundWindow();
oldWindowProc =(WNDPROC) SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)HackingWndProc);
dw = GetLastError();
hwndOld = hwnd;
break;
case DLL_PROCESS_DETACH:
SetWindowLongPtr(hwndOld, GWLP_WNDPROC, (LONG_PTR)oldWindowProc );
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
}
g_hKbdHook = NULL;
return TRUE;
}
BOOLEAN __stdcall
Init(
)
{
g_hKbdHook = NULL;
g_hKbdHook = SetWindowsHookEx(WH_KEYBOARD, ProcessKey, g_hInstance, NULL);
if(g_hKbdHook==NULL)
{
return FALSE;
}
return TRUE;
}
BOOLEAN __stdcall
Init32(
)
{
g_hKbdHook32 = NULL;
g_hKbdHook32 = SetWindowsHookEx(WH_KEYBOARD, ProcessKey32, g_hInstance32, NULL);
if(g_hKbdHook32 == NULL)
{
return FALSE;
}
return TRUE;
}
BOOLEAN __stdcall
DeInit(
)
{
UnhookWindowsHookEx(g_hKbdHook);
if (NULL != g_hKbdHook32)
{
UnhookWindowsHookEx(g_hKbdHook32);
}
return TRUE;
}
LRESULT CALLBACK
ProcessKey(
int ncode,
WPARAM wparam,
LPARAM lparam
)
{
return (CallNextHookEx(g_hKbdHook, ncode, wparam, lparam));//pass control to next hook in the hook chain.
}
LRESULT CALLBACK HackingWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
return CallWindowProc(
oldWindowProc,
hWnd,
message,
wParam,
lParam
);
}
LRESULT CALLBACK
ProcessKey32(
int ncode,
WPARAM wparam,
LPARAM lparam
)
{
return (CallNextHookEx(g_hKbdHook32, ncode, wparam, lparam));//pass control to next hook in the hook chain.
}
enter code here
`

How properly hook WM_COMMAND

I'm trying to hook a button click in a mfc window.And I used WM_COMMAND and WM_NOTIFY.For test, if the button is clicked, the hook must create a messagebox. The problem is that it doesn't react to button clicks.
Here's the code for reacting to WM_COMMAND and WM_NOTIFY:
LPMSG msg = (LPMSG)lParam;
switch( msg->message )
{
case WM_COMMAND:
MessageBox( NULL,"HOOK","YOOOO",MB_ICONEXCLAMATION );
break;
case WM_NOTIFY:
MessageBox( NULL,"HOOK","YOOOOO",MB_ICONEXCLAMATION );
break;
}
And here's the code to hole dll:
#include <Windows.h>
#include "FindingWindow.h"
#pragma comment( linker,"/SECTION:.SHARED,RWS" )
#pragma data_seg( ".SHARED" )
CaptureTextWindow* ctw;
HHOOK hook = 0;
HMODULE hInstance = 0;
HWND hWndServer = NULL;
#pragma data_seg()
static LRESULT CALLBACK msghook(int nCode, WPARAM wParam, LPARAM lParam);
__declspec(dllexport) BOOL clearMyHook(HWND hWnd);
BOOL APIENTRY DllMain( HINSTANCE hInst, DWORD ul_reason_for_call, LPVOID lpReserved )
{
switch( ul_reason_for_call )
{
case DLL_PROCESS_ATTACH:
hInstance = hInst;
return TRUE;
case DLL_PROCESS_DETACH:
if(hWndServer != NULL)
clearMyHook(hWndServer);
return TRUE;
}
return TRUE;
}
__declspec(dllexport) BOOL WINAPI setMyHook(HWND hWnd)
{
if(hWndServer != NULL)
return FALSE;
hook = SetWindowsHookEx(
WH_CALLWNDPROC,
(HOOKPROC)msghook,
hInstance,
0);
if(hook != NULL)
{ /* success */
hWndServer = hWnd;
return TRUE;
} /* success */
return FALSE;
}
__declspec(dllexport) BOOL clearMyHook(HWND hWnd)
{
if(hWnd != hWndServer)
return FALSE;
BOOL unhooked = UnhookWindowsHookEx(hook);
if(unhooked)
hWndServer = NULL;
return unhooked;
}
static LRESULT CALLBACK msghook( int nCode, // hook code
WPARAM wParam , // message identifier
LPARAM lParam )
{
if( nCode < 0 )
{
CallNextHookEx( hook, nCode, wParam, lParam );
return 0;
}
LPMSG msg = (LPMSG)lParam;
switch( msg->message )
{
case WM_COMMAND:
MessageBox( NULL,"HOOK","YOOOO",MB_ICONEXCLAMATION );
break;
case WM_NOTIFY:
MessageBox( NULL,"HOOK","YOOOOO",MB_ICONEXCLAMATION );
break;
}
return CallNextHookEx( hook, nCode, wParam, lParam );
}
I used not only WM_COMMAND cause I thought mb it will work, but it didn't.Thanks for answer.
The lParam for a WH_CALLWNDPROC hook is of type CWPSTRUCT. Your CallWndProc should look like this:
// ...
const CWPSTRUCT& cwps = *(CWPSTRUCT*)lParam;
switch ( cwps.message ) {
case WM_COMMAND:
MessageBox( ... );
break;
// ...