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;
}
Related
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.
I am trying to move the mouse (on Windows 10) using SendInput when I perform a physical mouse click. It works fine if I click once or twice, but if clicking for examples 6 times in quick succession the mouse lags for a few seconds then the program stops responding.
Is there any obvious reason why this is happening?
(Edited)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
LRESULT CALLBACK MouseHook(int, WPARAM, LPARAM);
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR, int)
{
HHOOK hook = SetWindowsHookEx(WH_MOUSE_LL, MouseHook, NULL, 0);
MessageBox(NULL, L"Hello", L"Hello", MB_OK);
UnhookWindowsHookEx(hook);
return 0;
}
LRESULT CALLBACK MouseHook(int nCode, WPARAM wParam, LPARAM lParam) {
if (nCode == HC_ACTION) {
switch (wParam) {
case WM_RBUTTONUP:
INPUT buffer;
ZeroMemory(&buffer, sizeof(buffer));
buffer.type = INPUT_MOUSE;
buffer.mi.dx = 0;
buffer.mi.dy = 10;
buffer.mi.mouseData = 0;
buffer.mi.dwFlags = MOUSEEVENTF_MOVE;
buffer.mi.time = 0;
buffer.mi.dwExtraInfo = 0;
SendInput(1, &buffer, sizeof(INPUT));
}
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
Using Raw Input sample:
#include <windows.h>
#include <iostream>
using namespace std;
BOOL registerTouchpadForInput(HWND hWnd)
{
RAWINPUTDEVICE rid;
rid.dwFlags = RIDEV_NOLEGACY | RIDEV_INPUTSINK;
rid.usUsagePage = 1;
rid.usUsage = 2;
rid.hwndTarget = hWnd;
return RegisterRawInputDevices(&rid, 1, sizeof(rid));
}
void getinputdata(LPARAM lparam)
{
HRAWINPUT hInput = (HRAWINPUT)lparam;
RAWINPUT input = { 0 };
UINT size = sizeof(RAWINPUT);
GetRawInputData(hInput, RID_INPUT,&input, &size,sizeof(RAWINPUTHEADER));
if (RIM_TYPEMOUSE == input.header.dwType)
{
if (input.data.mouse.usButtonFlags & RI_MOUSE_RIGHT_BUTTON_DOWN)
{
INPUT buffer;
ZeroMemory(&buffer, sizeof(buffer));
buffer.type = INPUT_MOUSE;
buffer.mi.dx = 0;
buffer.mi.dy = 10;
buffer.mi.mouseData = 0;
buffer.mi.dwFlags = MOUSEEVENTF_MOVE;
buffer.mi.time = 0;
buffer.mi.dwExtraInfo = 0;
SendInput(1, &buffer, sizeof(INPUT));
}
}
return;
}
static LRESULT CALLBACK NVTouch_WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
BOOL registrationStatus = false;
switch (message)
{
case WM_CREATE:
registrationStatus = registerTouchpadForInput(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_INPUT:
getinputdata(lParam);
return DefWindowProc(hwnd, message, wParam, lParam);
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
}
int main()
{
WNDCLASSEX wndclass = {
sizeof(WNDCLASSEX),
CS_DBLCLKS,
NVTouch_WindowProc,
0,
0,
GetModuleHandle(0),
LoadIcon(0,IDI_APPLICATION),
LoadCursor(0,IDC_ARROW),
HBRUSH(COLOR_WINDOW + 1),
0,
L"myclass",
LoadIcon(0,IDI_APPLICATION)
};
bool isClassRegistered = false;
isClassRegistered = RegisterClassEx(&wndclass);
if (isClassRegistered)
{
HWND window = CreateWindow(wndclass.lpszClassName, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, GetModuleHandle(0), NULL);
if (window)
{
ShowWindow(window, SW_SHOWDEFAULT);
MSG msg;
while (GetMessage(&msg, 0, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
}
The window title in the title bar is not setting to the variable and string i assign it.
I have show my code below but the problem is app::Window * wnd = new app::Window(L"Window Title"); constructor does seem to be 'tstring mWindowName;' but this mhWnd = CreateWindowEx(NULL, className.c_str(), mWindowName.c_str(), WS_OVERLAPPEDWINDOW, 100, 200, mScreenWidth, mScreenHeight, nullptr, nullptr, mhInstance, this); is not setting the title.
Window.h
#ifndef _ST_Window_H_
#define _ST_Window_H_
// include files
//#include "s-window.h"
#include "s-platform.h"
#include "s-safe-delete-and-release.h"
#include "s-iostream.h"
#include "s-strings.h"
#ifndef _WINDOWS_
#include <windows.h>
#endif //_WINDOWS_
namespace app
{
class Window
{
protected:
HINSTANCE mhInstance;
HWND mhWnd;
tstring mWindowName;
bool mRunState;
long int mScreenWidth;
long int mScreenHeight;
public:
Window(void);
Window(tstring windowName);
~Window(void);
int Setup(long int width, long int height);
LRESULT MessageProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
static LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
int Run(void);
inline HINSTANCE GetInstance(void) { return mhInstance; }
inline HWND GetHwnd(void) { return mhWnd; }
inline long GetWidth(void) { return mScreenWidth; }
inline long GetHeight(void) { return mScreenHeight; }
inline tstring GetWindowName(void) { return mWindowName; }
inline bool GetRunState(void) { return mRunState; }
protected:
int Create(void);
};
}
#endif //!_ST_Window_H_
Window.cpp
// include files
#include "sit-window.h"
using namespace std;
namespace app
{
Window::Window(void) : mhInstance(GetModuleHandle(0)), mhWnd(nullptr), mWindowName(nullptr),
mRunState(true), mScreenWidth(0), mScreenHeight(0)
{
}
Window::Window(tstring windowName) : mhInstance(GetModuleHandle(0)), mhWnd(nullptr),
mWindowName(windowName), mRunState(true), mScreenWidth(0), mScreenHeight(0)
{
}
Window::~Window(void)
{
}
int Window::Setup(long int width, long int height)
{
mScreenWidth = width;
mScreenHeight = height;
return Create();
}
LRESULT Window::MessageProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
}
LRESULT CALLBACK Window::WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
Window * wnd;
if (msg == WM_NCCREATE)
{
CREATESTRUCT * pcs = (CREATESTRUCT*)lParam;
wnd = (Window*)pcs->lpCreateParams;
wnd->mhWnd = hwnd;
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pcs->lpCreateParams);
return TRUE;
}
else
{
wnd = (Window*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
}
if (wnd)
return wnd->MessageProc(hwnd, msg, wParam, lParam);
return DefWindowProc(hwnd, msg, wParam, lParam);
}
int Window::Run(void)
{
MSG msg = { 0 };
while (msg.message != WM_QUIT)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
};
int Window::Create(void) {
WNDCLASSEX wnd;
SecureZeroMemory(&wnd, sizeof(WNDCLASSEX));
wnd.cbClsExtra = NULL;
wnd.cbSize = sizeof(WNDCLASSEX);
wnd.cbWndExtra = NULL;
wnd.hbrBackground = (HBRUSH)(COLOR_WINDOW + 3);
wnd.hCursor = LoadCursor(NULL, IDC_ARROW);
wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wnd.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
wnd.hInstance = mhInstance;
wnd.lpfnWndProc = WindowProc;
tstring className = mWindowName;
className.append(L" - WndCls");
wnd.lpszClassName = className.c_str();
wnd.lpszMenuName = nullptr;
wnd.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
if (!RegisterClassEx(&wnd))
{
std::wcout << L"Window class not registered!" << std::endl;
mRunState = false;
return 0x0;
}
RECT rect = { 0, 0, mScreenWidth, mScreenHeight };
if (!AdjustWindowRectEx(&rect, WS_OVERLAPPEDWINDOW, false, NULL))
{
std::wcout << L"Failed to adjust window rect!" << std::endl;
mRunState = false;
return 0x0;
}
else
{
mScreenWidth = rect.right;
mScreenHeight = rect.bottom;
}
mhWnd = CreateWindowEx(NULL, className.c_str(), mWindowName.c_str(),
WS_OVERLAPPEDWINDOW, 100, 200, mScreenWidth, mScreenHeight,
nullptr, nullptr, mhInstance, this);
if (!mhWnd)
{
std::wcout << L"Window not created!" << std::endl;
mRunState = false;
return 0x0;
}
if (ShowWindow(mhWnd, SW_SHOW))
{
std::wcout << L"Failed to show window!" << std::endl;
mRunState = false;
return 0x0;
}
if (!UpdateWindow(mhWnd))
{
std::wcout << L"Failed to update window!" << std::endl;
mRunState = false;
return 0x0;
}
if (!SetForegroundWindow(mhWnd))
{
std::wcout << L"Failed to set to foreground!" << std::endl;
mRunState = false;
return 0x0;
}
return 0x0;
}
}
Main.cpp
// include files
//#include "s-safe-delete-and-release.h"
//#include "s-window.h"
#include "sit-window.h"
#include <iostream>
#include <string>
#include <windows.h>
#include <assert.h>
#pragma comment(lib, "serenity-core.lib")
// namespaces
using namespace std;
// statics
//long int srnty::Window::mScreenWidth = 1024;
//long int srnty::Window::mScreenHeight = 768;
// win main entry point
namespace win {
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
wcout << L"WinMain() called..." << endl;
app::Window * wnd = new app::Window(L"Window Title");
wnd->Setup(1024, 768);
int result = wnd->Run();
SafeDelete(wnd);
return result;
}
}
// main entry point
int main(int argv, char argc[])
{
// detect memory leaks in the application
#if defined(DEBUG) | defined(_DEBUG)
HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0);
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
_CrtSetBreakAlloc(0);
int mlCount = _CrtDumpMemoryLeaks();
wcout << L"Number of memory Leaks: " << to_wstring(mlCount) << endl;
assert(mlCount == 0);
#endif
wcout << L"main() called..." << endl;
win::WinMain(GetModuleHandle(0), nullptr, nullptr, SW_SHOW);
wchar_t title[1024];
wchar_t titleBuffer[1024];
GetConsoleTitle(titleBuffer, 1024);
//wsprintf(title, L"%d", GetCurrentProcessId());
SetConsoleTitle(title);
Sleep(40);
HWND hwndFound = FindWindow(NULL, title);
SetForegroundWindow(hwndFound);
system("pause");
return 0x0;
}
I expect tstring mWindowName; to set the window Title in the title bar when used here mhWnd = CreateWindowEx(NULL, className.c_str(), mWindowName.c_str(), WS_OVERLAPPEDWINDOW, 100, 200, mScreenWidth, mScreenHeight, nullptr, nullptr, mhInstance, this);. The initialization of the tstring mWindowName; is through the constructor in Main.cpp app::Window * wnd = new app::Window(L"Window Title");
As Raymond Chen above clearly pointed out. This was an oversight on my behalf.
In the Window.cpp file LRESULT CALLBACK Window::WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) never returned control the DefWindowProc function there for the never sets the title.
The fucntion should look like this:
LRESULT CALLBACK Window::WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
Window * wnd;
if (msg == WM_NCCREATE)
{
CREATESTRUCT * pcs = (CREATESTRUCT*)lParam;
wnd = (Window*)pcs->lpCreateParams;
wnd->mhWnd = hwnd;
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pcs->lpCreateParams);
//return TRUE;
return DefWindowProc(hwnd, msg, wParam, lParam);
}
else
{
wnd = (Window*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
}
if (wnd)
return wnd->MessageProc(hwnd, msg, wParam, lParam);
return DefWindowProc(hwnd, msg, wParam, lParam);
}
Thank you i hope this helps someone else.
So is there a way to make my Win32 application "think" that the mouse is moving over its window and making some clicks when the actual window is hidden (i mean ShowWindow(hWnd, SW_HIDE);)?
I tried to simulate mouse moving with PostMessage and SendMessage but no luck so far.
int x = 0;
int y = 0;
while (true)
{
SendMessage(hwnd, WM_MOUSEMOVE, 0, MAKELPARAM(x, y));
x += 10;
y += 10;
Sleep(100);
}
Is this even possible?
Yes it's possible. This is a test hidden window:
#define UNICODE
#include <Windows.h>
#include <Strsafe.h>
#include <Windowsx.h>
LRESULT CALLBACK WndProc(HWND Hwnd, UINT Msg, WPARAM WParam, LPARAM LParam);
INT CALLBACK
WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
INT nCmdShow)
{
WNDCLASSEX WndClass;
ZeroMemory(&WndClass, sizeof(WNDCLASSEX));
WndClass.cbSize = sizeof(WNDCLASSEX);
WndClass.lpfnWndProc = WndProc;
WndClass.hInstance = hInstance;
WndClass.lpszClassName = L"HiddenWinClass";
if(RegisterClassEx(&WndClass))
{
HWND Hwnd;
MSG Msg;
Hwnd = CreateWindowEx(0, L"HiddenWinClass", L"Nan",
0, 0, 0, 0, 0, NULL, NULL, hInstance, NULL);
if(Hwnd)
{
UpdateWindow(Hwnd);
ShowWindow(Hwnd, SW_HIDE);
while(GetMessage(&Msg, 0, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
}
}
return 0;
}
LRESULT CALLBACK
WndProc(HWND Hwnd,
UINT Msg,
WPARAM WParam,
LPARAM LParam)
{
TCHAR Message[255];
switch(Msg)
{
case WM_MOUSEMOVE:
StringCbPrintf(Message, sizeof(Message), L"(%d, %d)",
GET_X_LPARAM(LParam), GET_Y_LPARAM(LParam));
MessageBox(NULL, Message, L"WM_MOUSEMOVE", MB_OK);
break;
default:
return DefWindowProc(Hwnd, Msg, WParam, LParam);
}
return 0;
}
and this is your code:
#define UNICODE
#include <Windows.h>
int
main(int argc, char **argv)
{
HWND Hwnd;
if((Hwnd = FindWindow(L"HiddenWinClass", L"Nan")))
{
int x, y;
for(x = y = 0 ; ; x += 10, y += 10)
{
SendMessage(Hwnd, WM_MOUSEMOVE, 0, MAKELPARAM(x, y));
Sleep(100);
}
}
return 0;
}
It works nicely.
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!