Catching screen saver event with foreground application - c++

I'm trying to catch the event when screen saver is turned off.
Actually, for now, I'm not getting any event of the screen saver (also not when it is launched).
I'm testing it when the application is in focus (foreground).
This is my code:
#include "stdafx.h"
#include "windows.h"
LRESULT CALLBACK wndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
static void RegisterWindowClasses() {
WNDCLASS wndClass;
memset(&wndClass, 0, sizeof(WNDCLASS));
wndClass.style = CS_HREDRAW | CS_VREDRAW;
wndClass.hInstance = NULL;
wndClass.lpszClassName = _T("Plugin-Video");
wndClass.hbrBackground = (HBRUSH) GetStockObject (DKGRAY_BRUSH);
wndClass.lpfnWndProc = wndProc;
RegisterClass(&wndClass);
}
LRESULT CALLBACK wndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (msg)
{
case WM_SYSCOMMAND:
{
switch (LOWORD(wParam))
{
case SC_SCREENSAVE:
{
FILE *fl = fopen("this_is_a_event_test.txt","a");
fputs("SC_SCREENSAVE\n",fl);
fclose(fl);
}
break;
case SC_MONITORPOWER:
{
FILE *fl = fopen("this_is_a_event_test.txt","a");
fputs("SC_MONITORPOWER\n",fl);
fclose(fl);
}
break;
default:
{
}
}
}
break;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
int _tmain(int argc, _TCHAR* argv[])
{
RegisterWindowClasses();
while(1){}
return 0;
}
Any suggestions?
Thanks!

Related

Textbox not active (responsive)

I'm trying to write a code of a c++ project that consists of a main window and a child window that works as a properties window that is used to enter some information for the some engine .I tried to add a textbox "Edit" window_style but the textbox is not responsive unless the child window style is without title bar .What is wrong here?
#include<iostream>
#include<cmath>
using namespace std;
LRESULT CALLBACK WNDProc(HWND hwnd, UINT uMsg, WPARAM wparam, LPARAM lparam);
LRESULT CALLBACK ChWNDProc(HWND hwnd, UINT uMsg, WPARAM wparam, LPARAM lparam);
int main()
{
WNDCLASSEXW m_wc = { 0 };
m_wc.lpszClassName = L"MianWindowClass";
m_wc.lpfnWndProc = WNDProc;
m_wc.cbSize = sizeof(WNDCLASSEXW);
m_wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
m_wc.hIcon = LoadIconW(NULL, IDC_ICON);
m_wc.hIconSm = m_wc.hIcon;
m_wc.hCursor = LoadCursorW(NULL, IDC_ARROW);
RegisterClassExW(&m_wc);
WNDCLASSEXW c_wc = { 0 };
c_wc.lpszClassName = L"ChildWindowClass";
c_wc.lpfnWndProc = ChWNDProc;
c_wc.cbSize = sizeof(WNDCLASSEXW);
c_wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
c_wc.hIcon = LoadIconW(NULL, IDC_ICON);
c_wc.hIconSm = c_wc.hIcon;
c_wc.hCursor = LoadCursorW(NULL, IDC_ARROW);
RegisterClassExW(&c_wc);
HWND mw_hwnd = CreateWindowExW(NULL, L"MianWindowClass", L"Main Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 800, 600, NULL, NULL, NULL, NULL);
if (!mw_hwnd) { cout << "Creation of Main Window Failed" << endl; return -1; }
HWND cw_hwnd = CreateWindowExW(NULL, L"ChildWindowClass", L"Child Window", WS_CHILD|WS_VISIBLE|WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 500, mw_hwnd, NULL, NULL, NULL);
if (!cw_hwnd) { cout << "Creation of Main Window Failed" << endl; return -1; }
ShowWindow(mw_hwnd, SW_SHOWDEFAULT);
UpdateWindow(mw_hwnd);
ShowWindow(cw_hwnd, SW_SHOWDEFAULT);
UpdateWindow(cw_hwnd);
MSG msg;
while(GetMessageW(&msg, mw_hwnd, NULL, NULL)>0)
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
return 0;
}
LRESULT CALLBACK WNDProc(HWND hwnd, UINT uMsg, WPARAM wparam, LPARAM lparam)
{
switch (uMsg)
{
case WM_CREATE:
{
cout << "Main Window Created." << endl;
break;
}
default:
return DefWindowProc(hwnd, uMsg, wparam, lparam);
break;
}
return 0;
}
LRESULT CALLBACK ChWNDProc(HWND hwnd, UINT uMsg, WPARAM wparam, LPARAM lparam)
{
switch (uMsg)
{
case WM_CREATE:
{
cout << "Child Window Created." << endl;
CreateWindowExW(NULL, L"Edit", L"Text Box 1", WS_CHILD|WS_VISIBLE|WS_BORDER|ES_MULTILINE, 200, 200, 100, 20, hwnd, NULL, NULL, NULL);
break;
}
default:
return DefWindowProc(hwnd, uMsg, wparam, lparam);
break;
}
return 0;
}```

Window theme changes unintentionally

When I first run the program, the window's theme is Windows 11 (as intended):
However, after a few frame updates, the theme changes to a previous version of Windows, and the title text also disappears:
This is my Framework class:
#include "Framework.h"
LRESULT CALLBACK Framework::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
Framework* pThis = nullptr;
if (msg == WM_CREATE)
{
CREATESTRUCT* pcs = reinterpret_cast<CREATESTRUCT*>(lParam);
pThis = reinterpret_cast<Framework*>(pcs->lpCreateParams);
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pThis);
}
else
{
pThis = reinterpret_cast<Framework*>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
}
if (pThis)
return pThis->OnProcessMessage(hwnd, msg, wParam, lParam);
else
return DefWindowProc(hwnd, msg, wParam, lParam);
}
LRESULT Framework::OnProcessMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
if(mRenderer)
return mRenderer->OnProcessMessage(hwnd, msg, wParam, lParam);
return NULL;
}
void Framework::Run()
{
RECT r;
GetClientRect(mWinHandle, &r);
mWidth = r.right - r.left;
mHeight = r.bottom - r.top;
std::atexit(ReportLiveObjects);
ShowWindow(mWinHandle, SW_SHOWNORMAL);
mRenderer = make_shared<DX12Renderer>();
mRenderer->Init(mWinHandle, mWidth, mHeight);
mRenderer->BuildObjects();
MsgLoop();
DestroyWindow(mWinHandle);
}
void Framework::Init(const string& winTitle, uint32_t width, uint32_t height)
{
const WCHAR* className = L"Main Window";
// Register the window class
WNDCLASSEX wc = {};
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = GetModuleHandle(NULL);
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = className;
wc.hIconSm = LoadIcon(wc.hInstance, IDI_APPLICATION);
if (RegisterClassEx(&wc) == 0)
{
return;
}
// Window size we have is for client area, calculate actual window size
RECT r{ 0, 0, (LONG)width, (LONG)height };
int windowWidth = r.right - r.left;
int windowHeight = r.bottom - r.top;
// create the window
wstring wTitle = stringTowstring(winTitle);
mWinHandle = CreateWindow(className, wTitle.c_str(),
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
windowWidth, windowHeight, NULL, NULL,
GetModuleHandle(NULL), this);
if (mWinHandle == nullptr)
{
return;
}
}
void Framework::MsgLoop()
{
MSG msg{};
while (msg.message != WM_QUIT)
{
if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
mRenderer->Update();
mRenderer->Draw();
}
}
}
And this is my WinMain() function:
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR, int mCmdShow)
{
#if defined(DEBUG) || defined(_DEBUG)
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endif
try
{
Framework app;
app.Init("Chulsu Renderer");
app.Run();
}
catch (std::exception& ex)
{
MessageBoxA(nullptr, ex.what(), "ERROR", MB_OK);
return -1;
}
return 0;
}
Lastly, message input processing functions:
LRESULT DX12Renderer::OnProcessMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_ACTIVATE:
break;
case WM_SIZE:
mSwapChainSize.x = LOWORD(lParam);
mSwapChainSize.y = HIWORD(lParam);
if (wParam == SIZE_MAXIMIZED)
{
OnResize();
}
else if (wParam == SIZE_RESTORED)
{
if (mDevice) {
OnResize();
}
}
break;
case WM_ENTERSIZEMOVE:
break;
case WM_EXITSIZEMOVE:
OnResize();
break;
case WM_GETMINMAXINFO:
reinterpret_cast<MINMAXINFO*>(lParam)->ptMinTrackSize = { 200, 200 };
break;
case WM_LBUTTONDOWN:
case WM_MBUTTONDOWN:
case WM_RBUTTONDOWN:
OnProcessMouseDown(wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
break;
case WM_LBUTTONUP:
case WM_MBUTTONUP:
case WM_RBUTTONUP:
OnProcessMouseUp(wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
break;
case WM_MOUSEMOVE:
OnProcessMouseMove(wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
break;
case WM_KEYDOWN:
case WM_KEYUP:
if (wParam == VK_ESCAPE)
{
PostQuitMessage(0);
return 0;
}
OnProcessKeyInput(msg, wParam, lParam);
break;
case WM_MENUCHAR:
return MAKELRESULT(0, MNC_CLOSE);
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
void DX12Renderer::OnResize()
{
}
void DX12Renderer::OnProcessMouseDown(WPARAM buttonState, int x, int y)
{
}
void DX12Renderer::OnProcessMouseUp(WPARAM buttonState, int x, int y)
{
}
void DX12Renderer::OnProcessMouseMove(WPARAM buttonState, int x, int y)
{
}
void DX12Renderer::OnProcessKeyInput(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
}
void DX12Renderer::Update()
{
}
If you need full codes, here's a GitHub page:
https://github.com/kcjsend2/Chulsu
It's a DirectX12 + Win32 application, but I think the DirectX12 layer probably has nothing to do with this problem.
UPDATE:
Seriously, this problem is really odd.
When I replace Framework::OnProcessMessage() like this:
LRESULT Framework::OnProcessMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch (msg) {
case WM_KEYDOWN:
case WM_KEYUP:
if (wParam == VK_ESCAPE) {
PostQuitMessage(0);
return 0;
}
break;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
Then it works well.
But no matter what's in the function, if I return mRenderer->OnProcessMessage(), it just makes the bug above.
LRESULT Framework::OnProcessMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
if (mRenderer)
return mRenderer->OnProcessMessage(hwnd, msg, wParam, lParam);
return DefWindowProc(hwnd, msg, wParam, lParam);
}
problem was because of OnProcessMessage returns few NULLs when Renderer is not initialized.
change it to return DefWindowProc, it fixed problem.

CreateWindow() returns nullptr and GetLastError() returns 1400

Hello I have recently decided to learn graphics programming through DirectX11 and for that I'm learning how to use the Windows API. I managed to create a window by following an online tutorial and later successfully created one by myself. However, the problem starts when I tried to make a framework to create the Window, I ran into a few errors but by studying the documentation and looking up examples most of them were solved, except for one involving the CreateWindow() function.
Whenever I try to get the handle for the window it returns nullptr, I tried getting the error code through GetLastError(), but all I get is 1400, which according to MSDN is "Invalid window handle". I don't know what I'm doing wrong and I haven't found any threads that solved the issue. It compiles successfully, but no window appears.
Window.hpp
#pragma once
#include "WindowsHeader.hpp"
class Window
{
public:
Window(int width, int height, const char* name);
~Window();
Window(const Window&) = delete;
Window& operator=(const Window&) = delete;
private:
class WindowClass
{
public:
static const char* GetName() noexcept;
static HINSTANCE GetInstance() noexcept;
private:
WindowClass() noexcept;
~WindowClass();
WindowClass(const WindowClass&) = delete;
WindowClass& operator=(const WindowClass&) = delete;
static constexpr const char* window_class_name{ "HardwareAccelerated3D" };
static WindowClass window_class;
HINSTANCE hinst;
};
static LRESULT CALLBACK HandleMsgSetup(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) noexcept;
static LRESULT CALLBACK HandleMsgInvoke(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) noexcept;
LRESULT HandleMsg(HWND, UINT msg, WPARAM wparam, LPARAM lparam) noexcept;
int width;
int height;
HWND hwnd;
};
Window.cpp
#include "Window.hpp"
#include <sstream>
//Window Class
Window::WindowClass Window::WindowClass::window_class;
Window::WindowClass::WindowClass() noexcept
: hinst(GetModuleHandle(NULL))
{
WNDCLASSEX window_class{ {0} };
window_class.cbSize = sizeof(window_class);
window_class.style = CS_OWNDC;
window_class.lpfnWndProc = &HandleMsgSetup;
window_class.cbClsExtra = NULL;
window_class.cbWndExtra = NULL;
window_class.hInstance = GetInstance();
window_class.hIcon = NULL;
window_class.hCursor = NULL;
window_class.hbrBackground = NULL;
window_class.lpszMenuName = NULL;
window_class.lpszClassName = GetName();
window_class.hIconSm = NULL;
RegisterClassEx(&window_class);
}
Window::WindowClass::~WindowClass()
{
UnregisterClass(GetName(), GetInstance());
}
const char* Window::WindowClass::GetName() noexcept
{
return window_class_name;
}
HINSTANCE Window::WindowClass::GetInstance() noexcept
{
return window_class.hinst;
}
//Window
Window::Window(int width, int height, const char* name)
: width(width), height(height)
{
RECT wndrec;
wndrec.left = 100;
wndrec.right = wndrec.left + width;
wndrec.top = 100;
wndrec.bottom = wndrec.top + height;
if (!AdjustWindowRect(&wndrec, WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU, false))
{
std::ostringstream oss;
oss << GetLastError();
OutputDebugString(oss.str().c_str());
}
hwnd = CreateWindow(WindowClass::GetName(), name, WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU,
CW_USEDEFAULT, CW_USEDEFAULT, wndrec.right - wndrec.left, wndrec.bottom - wndrec.top, NULL,
NULL, WindowClass::GetInstance(), this);
if (!hwnd)
{
std::ostringstream oss;
oss << GetLastError();
OutputDebugString(oss.str().c_str());
}
ShowWindow(hwnd, SW_SHOWDEFAULT);
}
Window::~Window()
{
DestroyWindow(hwnd);
}
LRESULT WINAPI Window::HandleMsgSetup(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) noexcept
{
if (msg == WM_NCCREATE)
{
const CREATESTRUCTW* const pcreate = reinterpret_cast<CREATESTRUCTW*>(lparam);
Window* const pwnd = static_cast<Window*>(pcreate->lpCreateParams);
SetWindowLongPtr(hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(pwnd));
SetWindowLongPtr(hwnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(&Window::HandleMsgInvoke));
return pwnd->HandleMsg(hwnd, msg, wparam, lparam);
}
return DefWindowProc(hwnd, msg, wparam, lparam);
}
LRESULT WINAPI Window::HandleMsgInvoke(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) noexcept
{
Window* const pwnd = reinterpret_cast<Window*>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
return pwnd->HandleMsg(hwnd, msg, wparam, lparam);
}
LRESULT Window::HandleMsg(HWND, UINT msg, WPARAM wparam, LPARAM lparam) noexcept
{
switch (msg)
{
case WM_CLOSE:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, msg, wparam, lparam);
}
WinMain.cpp
#include "WindowsMessageMap.hpp"
#include "Window.hpp"
int CALLBACK WinMain(_In_ HINSTANCE hInstance, _In_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd)
{
Window window(640, 480, "HardwareAccelerated3D");
MSG msg;
BOOL gresult;
while (gresult = GetMessage(&msg, NULL, NULL, NULL) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if (gresult == -1)
return -1;
return msg.wParam;
}
WindowsHeader.hpp is just a few defines and Windows.h to avoid some windows macros, and WindowsMessageMap.hpp just prints windows messages to the debug console (I use it to see what messages are being called).
P.S.: this is my first post here, so feel free to point out any issues with the post itself, so that I can be more clear next time.
Thanks in advance! :-)
The hwnd you used in the code is the same as it in Window.hpp:
LRESULT Window::HandleMsg(HWND, UINT msg, WPARAM wparam, LPARAM lparam) noexcept
{
switch (msg)
{
case WM_CLOSE:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, msg, wparam, lparam);
}
The last line of Window.hpp:
HWND hwnd;
When you call HandleMsg, hwnd of Window.hpp is not initialized:
You may use hwnd in HandleMsgSetup, just add the hwnd param like the following code:
LRESULT Window::HandleMsg(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) noexcept
{
switch (msg)
{
case WM_CLOSE:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, msg, wparam, lparam);
}
And it works for me:

How to detect drag in a mouse hook procedure

I've successfully set up a mouse hook for a window, and I'd like to detect a drag operation when the left mouse button is clicked. I've tried using DragDetect, as shown below, but it never returns TRUE, and it never suppresses the subsequent mouse-up event (in this code, hwnd is the target window):
LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode < 0)
{
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
switch (wParam)
{
case WM_LBUTTONDOWN:
{
// Get the click point
LPMOUSEHOOKSTRUCT pMouseHookStruct = reinterpret_cast<LPMOUSEHOOKSTRUCT>(lParam);
CPoint ptClick = pMouseHookStruct->pt;
// Drag detect
BOOL fDrag = DragDetect(hwnd, ptClick);
if (fDrag)
{
MessageBox(NULL, L"Drag", NULL, MB_OK);
}
break;
}
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
Does DragDetect not work within hook procedures, or am I just doing something wrong?
As comments pointed, DragDetect does not predict the future. But you can compare the POINT of WM_LBUTTONDOWN and WM_MOUSEMOVE in a click-time.
Sample:
#include <windows.h>
#include <iostream>
using namespace std;
typedef BOOL(*SETHOOK)(HWND hWnd);
typedef BOOL(*UNHOOK)();
LRESULT CALLBACK WndProcFunc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
int main(int argc, char* argv[])
{
WNDCLASS wc{};
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProcFunc;
wc.hInstance = GetModuleHandle(NULL);
wc.lpszClassName = L"Class_Name";
wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
RegisterClass(&wc);
HWND hWnd = CreateWindow(L"Class_Name", L"Test", WS_OVERLAPPEDWINDOW, 0, 0, 1000, 500, NULL, NULL, GetModuleHandle(NULL), NULL);
SETHOOK SetHook;
UNHOOK UnHook;
HMODULE h = LoadLibraryA("PATH\\DLL4.dll");
SetHook = (SETHOOK)GetProcAddress(h, "SetHook");
UnHook = (UNHOOK)GetProcAddress(h, "UnHook");
BOOL i = SetHook(hWnd);
ShowWindow(hWnd, 1);
UpdateWindow(hWnd);
MSG Msg;
while (GetMessage(&Msg, NULL, 0, 0))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
UnHook();
return 0;
}
DLL:
// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#define PRESS TRUE
#define RELEASE FALSE
HHOOK tHook;
HMODULE hinstDLL;
BOOL button = RELEASE;
BOOL Drag = FALSE;
HWND hWnd;
POINT pt = { 0 };
LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam) {
if (nCode < 0)
{
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
LPMOUSEHOOKSTRUCT pMouseHookStruct = reinterpret_cast<LPMOUSEHOOKSTRUCT>(lParam);
if (pMouseHookStruct->hwnd != hWnd)
{
button = RELEASE;
Drag = FALSE;
}
else {
switch (wParam)
{
case WM_LBUTTONDOWN:
{
button = PRESS;
Drag = FALSE;
printf("WM_LBUTTONDOWN\n");
printf("%d , %d\n", pMouseHookStruct->pt.x, pMouseHookStruct->pt.y);
pt.x = pMouseHookStruct->pt.x;
pt.y = pMouseHookStruct->pt.y;
break;
}
case WM_LBUTTONUP:
{
button = RELEASE;
Drag = FALSE;
printf("WM_LBUTTONUP\n");
break;
}
case WM_MOUSEMOVE:
{
if (button == PRESS)
{
printf("%d , %d\n", pMouseHookStruct->pt.x, pMouseHookStruct->pt.y);
if (Drag == FALSE && (abs(pt.x - pMouseHookStruct->pt.x) >= GetSystemMetrics(SM_CXDRAG) || abs(pt.y - pMouseHookStruct->pt.y) >= GetSystemMetrics(SM_CYDRAG)))
{
printf("Drag\n");
Drag = TRUE;
}
}
break;
}
}
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
extern "C" __declspec(dllexport) BOOL SetHook(HWND hwnd)
{
hWnd = hwnd;
tHook = SetWindowsHookEx(WH_MOUSE, MouseProc, hinstDLL, 0);
if (tHook == NULL)
return FALSE;
else
return TRUE;
}
extern "C" __declspec(dllexport) BOOL UnHook()
{
return UnhookWindowsHookEx(tHook);
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
hinstDLL = hModule;
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

Win32. Hook. Intercept WM_MOUSEWHEEL by child windows

I am trying to intercept mouse wheel by child windows under cursor. But something is wrong. It seems like message sends many times. What did I do wrong?
LRESULT CALLBACK MouseProc(__in int nCode,
__in WPARAM wParam,
__in LPARAM lParam)
{
LRESULT ret = 0;
static BOOL b = TRUE;
if (wParam == WM_MOUSEWHEEL)
{
if (b)
{
MOUSEHOOKSTRUCTEX *pMhs = (MOUSEHOOKSTRUCTEX *)lParam;
short zDelta = HIWORD(pMhs->mouseData);
POINT pt;
GetCursorPos(&pt);
LPARAM lParam = MAKELPARAM(pt.x, pt.y);
HWND hWnd = WindowFromPoint(pt);
b = FALSE;
SendMessage(hWnd, WM_MOUSEWHEEL, zDelta, lParam);
}
else
{
b = TRUE;
}
ret = 1;
}
else
{
CallNextHookEx(0, nCode, wParam, lParam);
}
return ret;
}