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.
Related
I have been trying to create a Window whose title bar could be in any language. But I am getting something like ▯*. I writing as escape characters as of now. I am attesting the entirity of the code.
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <string>
LRESULT CALLBACK WindowProc(HWND Window, UINT Message, WPARAM WParam, LPARAM LParam) {
switch(Message) {
case WM_KEYDOWN: {
switch(WParam) {
case 'O': {
DestroyWindow(Window);
} break;
}
} break;
case WM_DESTROY: {
PostQuitMessage(0);
} break;
default: {
return DefWindowProc(Window, Message, WParam, LParam);
}
}
return 0;
}
int WINAPI WinMain(HINSTANCE Instance, HINSTANCE PrevInstance, PSTR CmdLine, int CmdShow) {
WNDCLASSW WindowClass = {0};
const wchar_t* ClassName = L"MyWindowClass";
WindowClass.lpfnWndProc = WindowProc;
WindowClass.hInstance = Instance;
WindowClass.lpszClassName = ClassName;
WindowClass.hCursor = LoadCursor(NULL, IDC_CROSS);
MessageBoxW(0, L"\u0906\u092a", L"\u0906\u092a", 0);
if(!RegisterClassW(&WindowClass)) {
MessageBoxW(0, L"RegisterClass failed", 0, 0);
return GetLastError();
}
HWND Window = CreateWindowExW(0, ClassName, L"\u0906\u092a",
WS_OVERLAPPEDWINDOW|WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
0, 0, Instance, 0);
if(!Window) {
MessageBoxW(0, L"CreateWindowEx failed", 0, 0);
return GetLastError();
}
int Running = 1;
while(Running) {
MSG Message;
while(GetMessageW(&Message, NULL, 0, 0)) {
if(Message.message == WM_QUIT) Running = 0;
TranslateMessage(&Message);
DispatchMessage(&Message);
}
}
return 0;
}
I was expecting the title bar to be something like 'आप'
I'm trying to learn how to create a message-only window inside of a dll, but the process being injected by this dll 'hangs'/never exits when I close it.
I get the message box DLL_PROCESS_DETACH, but it remains open in the task manager.
It only happens when I call the function Main(), I'm probably doing something wrong.
Source code of the dll:
// Global variables.
HWND processhWnd = nullptr;
bool disableHooks = false;
class std::future<void> wndproc_thread;
class std::future<void> wm_copydata_thread;
LRESULT(WINAPI* DefWindowProcW_Hook)(HWND, UINT, WPARAM, LPARAM) = DefWindowProcW;
LRESULT WINAPI HookedDefWindowProcW(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
if (disableHooks)
return DefWindowProcW_Hook(hWnd, Msg, wParam, lParam);
switch (Msg)
{
}
return DefWindowProcW_Hook(hWnd, Msg, wParam, lParam);
}
#pragma region getprocessHWND
struct handle_data {
unsigned long process_id;
HWND window_handle;
};
BOOL Is_Main_Window(HWND handle)
{
return GetWindow(handle, GW_OWNER) == (HWND)0 && IsWindowVisible(handle);
}
BOOL CALLBACK Enum_Windows_Callback(HWND handle, LPARAM lParam)
{
//static wchar_t title[200]; how to print the window title?
//GetWindowText(handle, title, 200);
//doPrint("title: ", title);
handle_data& data = *(handle_data*)lParam;
unsigned long process_id = 0;
GetWindowThreadProcessId(handle, &process_id);
if (data.process_id != process_id || !Is_Main_Window(handle))
return TRUE;
data.window_handle = handle;
return FALSE;
}
HWND Find_Main_Window(unsigned long process_id)
{
handle_data data;
data.process_id = process_id;
data.window_handle = 0;
EnumWindows(Enum_Windows_Callback, (LPARAM)&data);
return data.window_handle;
}
#pragma endregion
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
Sleep(1000);
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)DefWindowProcW_Hook, HookedDefWindowProcW);
LONG lError = DetourTransactionCommit();
if (lError != NO_ERROR) {
MessageBox(HWND_DESKTOP, L"Failed to detour", L"", MB_OK);
return FALSE;
}
wndproc_thread = std::async(std::launch::async, []
{ Main(); });
}
break;
case DLL_PROCESS_DETACH:
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)True_WriteFile, HookedWriteFile);
LONG lError = DetourTransactionCommit();
if (lError != NO_ERROR) {
MessageBox(HWND_DESKTOP, L"DLL_PROCESS_DETACH", L"", MB_OK);
return FALSE;
}
}
break;
}
return TRUE;
}
void WM_COPYDATA(std::wstring data)
{
}
// Step 4: the Window Procedure.
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_COPYDATA:
{
PCOPYDATASTRUCT pcds = reinterpret_cast<PCOPYDATASTRUCT>(lParam);
std::wstring received_data = (wchar_t*)pcds->lpData;
std::wstring data = received_data;
wm_copydata_thread = std::async(std::launch::async, [data]
{ WM_COPYDATA(data); });
doPrint("WM_COPYDATA: ", data);
return 1;
}
case WM_CLOSE:
DestroyWindow(hWnd);
break;
case WM_DESTROY:
case WM_QUIT:
//OutputDebugString(L"WM_QUIT");
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, msg, wParam, lParam);
}
return 0;
}
// Step 1-3 Creating a window procedure.
int Main()
{
WNDCLASSEX wc{};
HWND hWnd = nullptr;
MSG Msg;
//Step 1: Registering the Window Class
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = 0;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
DWORD PID = GetCurrentProcessId();
HWND processhWnd = Find_Main_Window(PID);
// The class name of the message-only window will be the
// window title of the process being injected.
std::wostringstream ss;
ss << std::hex << processhWnd;
std::wstring ClassName = ss.str();
wc.lpszClassName = ClassName.c_str();
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if (!RegisterClassEx(&wc))
{
DWORD err = GetLastError();
std::wstring error = L"Window Registration Failed.\nError: " + std::to_wstring(int(err));
MessageBox(NULL, error.c_str(), L"Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
// Step 2: Creating the Window
// Message-only window (HWND_MESSAGE).
// https://learn.microsoft.com/en-us/windows/win32/winmsg/window-features#message-only-windows
hWnd = CreateWindowEx(
WS_EX_TOOLWINDOW,
ClassName.c_str(), // name of the class, as passed to the RegisterClass function
NULL,
NULL,
CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, // X,Y,W,H
HWND_MESSAGE,
NULL, 0, NULL);
if (hWnd == NULL)
{
std::wstring error = L"Window creation failed.\nError: " + std::to_wstring(int(err));
MessageBox(NULL, error.c_str(), L"Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
doPrint("\nprocesshWnd: ", processhWnd);
doPrint("HWND_MESSAGE: ", hWnd, "\n");
ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);
// Step 3: The Message Loop
while (GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return 0; // Msg.wParam;
}
The way I'm creating/calling the WndProcedure using threads, etc, is it 'correctly'?
My goal is to send data to the dll using WM_COPYDATA.
I am creating a window wrapper class in c++ but I cannot seem to fix this bug.
it seems that when my window process callback gets called it is not retrieving the this pointer I inputted for the extra information when creating the window. I did a little bit of debugging to find out that when I reinterpret it to a Window* it is NULL and every variable is uninitialized.
here is Window.h
#pragma once
#include <Windows.h>
#include <string>
class Window
{
private:
class WindowClass
{
private:
static WindowClass wndClass;
WindowClass();
HINSTANCE hInst;
const char* className = "Sadie Game Engine";
WindowClass(WindowClass&) = delete;
WindowClass operator=(WindowClass&) = delete;
~WindowClass();
public:
static WindowClass& getInstance();
HINSTANCE getHInstance();
const char* getClassName();
};
private:
const char* windowTitle;
int width, height;
int windowX, windowY;
HWND windowHandle;
public:
bool keyStates[256];
Window(int width, int height, int x, int y, const char* title);
void setWindowTitle(std::string str);
static LRESULT CALLBACK handleMsgCallBack(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
LRESULT handleMsg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
~Window();
};
and here is Window.cpp
#include "Window.h"
///
/// WindowClass
///
Window::WindowClass Window::WindowClass::wndClass;
Window::WindowClass::WindowClass()
{
hInst = GetModuleHandleA(nullptr);
WNDCLASSEXA wc = { 0 };
wc.cbSize = sizeof(wc);
wc.style = CS_OWNDC;
wc.lpfnWndProc = handleMsgCallBack;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInst;
wc.lpszClassName = className;
wc.hIcon = nullptr;
wc.hIconSm = nullptr;
wc.hCursor = nullptr;
wc.hbrBackground = nullptr;
wc.lpszMenuName = nullptr;
RegisterClassExA(&wc);
}
Window::WindowClass::~WindowClass()
{
UnregisterClassA(className, hInst);
}
Window::WindowClass& Window::WindowClass::getInstance()
{
return wndClass;
}
HINSTANCE Window::WindowClass::getHInstance()
{
return hInst;
}
const char* Window::WindowClass::getClassName()
{
return className;
}
///
/// Window
///
Window::Window(int _width, int _height, int x, int y, const char* title)
{
width = _width;
height = _height;
windowX = x;
windowY = y;
windowTitle = title;
RECT wr;
wr.left = 100;
wr.right = width + wr.left;
wr.top = 100;
wr.bottom = height + wr.top;
AdjustWindowRect(&wr, WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU, FALSE);
windowHandle = CreateWindowExA(0l, WindowClass::getInstance().getClassName(),
windowTitle, WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
windowX, windowY, width, height, nullptr, nullptr, WindowClass::getInstance().getHInstance(), this);
ShowWindow(windowHandle, SW_SHOW);
}
void Window::setWindowTitle(std::string str)
{
SetWindowTextA(windowHandle, str.c_str());
}
LRESULT Window::handleMsgCallBack(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
Window* const windowPtr = reinterpret_cast<Window*>(GetWindowLongPtrA(hWnd, GWLP_USERDATA));
return windowPtr->handleMsg(hWnd, msg, wParam, lParam);
}
LRESULT Window::handleMsg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_SYSKEYDOWN:
case WM_KEYDOWN:
keyStates[wParam] = true;
break;
case WM_SYSKEYUP:
case WM_KEYUP:
keyStates[wParam] = false;
break;
case WM_CHAR:
break;
case WM_CLOSE:
PostQuitMessage(0);
return 0;
}
return DefWindowProcA(hWnd, msg, wParam, lParam);
}
Window::~Window()
{
DestroyWindow(windowHandle);
}
Any help would be appreciated.
As RbMm said, You did not call the SetWindowLongPtr function
Just add the following code:
case WM_NCCREATE:
{
LPCREATESTRUCT pcs = (LPCREATESTRUCT)lParam;
Window* w = (Window*)pcs->lpCreateParams;
::SetWindowLongPtr(hWnd,GWLP_USERDATA,reinterpret_cast<LONG_PTR>(w));
break;
}
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);
}
}
}
}
I have two questions.
First, I wrote a little program to catch all mouse events. I start it in a separate thread, and I get a error which I can not debug:
#include <windows.h>
#include <iostream>
#include <thread>
HHOOK hookHandle;
LRESULT CALLBACK callBackHook(int nCode, WPARAM wParam, LPARAM lParam) {
if(nCode == HC_ACTION) {
std::cout << "Something!" << std::endl;
}
return CallNextHookEx(hookHandle, nCode,
wParam, lParam);
}
int mouseHook() {
hookHandle = SetWindowsHookEx(WH_MOUSE_LL , callBackHook, NULL, 0);
if(hookHandle == NULL) {
std::cout << "ERROR CREATING HOOK: ";
std::cout << GetLastError() << std::endl;
return 0;
}
MSG msg;
while(GetMessage(&msg, NULL, 0, 0) != 0) {
std::cerr << "message!" << std::endl;
}
UnhookWindowsHookEx(hookHandle);
return 0;
}
int main(int argc, char *argv[])
{
std::thread mouse(mouseHook);
return 0;
}
Error Message (the german buttons say "Cancel", "Retry", "Ignore"):
Second, is it possible to get the raw data input from lParam of the callBackHook function? I don't know how to register an input device without an HWND.
First, you needs to wait the thread exit, use mouse.join(). If the main process returns directly, the thread it owns will also be terminated, which will cause this issue.
int main(int argc, char* argv[])
{
std::thread mouse(mouseHook);
mouse.join();
return 0;
}
Second,
I don't know how to register an input device without an HWND
Don't worry, you could create a Message-Only Window for that.
Sample (remove some error checking):
#include <windows.h>
#include <iostream>
using namespace std;
LRESULT CALLBACK WindProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
if (Msg == WM_INPUT)
{
cout << "Something!" << endl;
HRAWINPUT hRawInput = (HRAWINPUT)lParam;
}
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
int main()
{
WNDCLASSEX wcx = { 0 };
wcx.cbSize = sizeof(WNDCLASSEX);
wcx.lpfnWndProc = WindProc;
wcx.hInstance = GetModuleHandle(NULL);
wcx.lpszClassName = TEXT("RawInputClass");
RegisterClassEx(&wcx);
HWND hWnd = CreateWindowEx(0, TEXT("RawInputClass"), NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL);
RAWINPUTDEVICE rid = { 0 };
rid.usUsagePage = 0x01;
rid.usUsage = 0x02; //mouse
rid.dwFlags = RIDEV_INPUTSINK;
rid.hwndTarget = hWnd;
RegisterRawInputDevices(&rid, 1, sizeof(RAWINPUTDEVICE));
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}