Handling the focusing click using Raw Input - c++

I wish to handle mouse clicks in my game with the Raw Input API using the WM_INPUT messages.
I'm only interested in the mouse clicks while my app is active.
When the window is inactive and I click into the window putting it in focus no WM_INPUT message is generated for that click. I can handle every other click except the one that brings my window to focus.
With the RIDEV_INPUTSINK flag I can catch that one missing event but then I would have to somehow ignore every other message that I get while my app is inactive.
Most apps and windowed programs process the "activating click" just like a normal one, they don't ignore it. They probably use the "legacy" messages, as they arrive correctly.
Should I mix raw input with the legacy mouse handling? Should I use INPUTSINK flag and ignore messages selectively? If so, how?
Since Microsoft recommends raw input for games, I hope there is a common solution to this problem that I just couldn't find so far.
Relevant snippet from code:
Registering the raw input device
RAWINPUTDEVICE Rid[1];
Rid[0].usUsagePage = 0x01;
Rid[0].usUsage = 0x02;
Rid[0].dwFlags = 0; // adds HID mouse
Rid[0].hwndTarget = 0;
RegisterRawInputDevices(Rid, 1, sizeof(Rid[0]))
For convenience here's a full sample program that showcases my problem.
#include <windows.h>
#include <strsafe.h>
const char g_szClassName[] = "myWindowClass";
// Step 4: the Window Procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_INPUT:
{
UINT dwSize;
GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &dwSize,
sizeof(RAWINPUTHEADER));
LPBYTE lpb = new BYTE[dwSize];
if (lpb == NULL)
{
return 0;
}
if (GetRawInputData((HRAWINPUT)lParam, RID_INPUT, lpb, &dwSize,
sizeof(RAWINPUTHEADER)) != dwSize)
OutputDebugString(TEXT("GetRawInputData does not return correct size !\n"));
RAWINPUT* raw = (RAWINPUT*)lpb;
size_t const cchDest = 1000;
TCHAR pszDest[cchDest];
if (raw->header.dwType == RIM_TYPEMOUSE && raw->data.mouse.ulButtons)
{
auto hResult = StringCchPrintf(pszDest, STRSAFE_MAX_CCH, TEXT("Mouse: usFlags=%04x ulButtons=%04x usButtonFlags=%04x usButtonData=%04x ulRawButtons=%04x lLastX=%04x lLastY=%04x ulExtraInformation=%04x\r\n"),
raw->data.mouse.usFlags,
raw->data.mouse.ulButtons,
raw->data.mouse.usButtonFlags,
raw->data.mouse.usButtonData,
raw->data.mouse.ulRawButtons,
raw->data.mouse.lLastX,
raw->data.mouse.lLastY,
raw->data.mouse.ulExtraInformation);
if (FAILED(hResult))
{
// TODO: write error handler
}
OutputDebugString(pszDest);
}
delete[] lpb;
}
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hwnd;
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 = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = g_szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if (!RegisterClassEx(&wc))
{
MessageBox(NULL, "Window Registration Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
// Step 2: Creating the Window
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
"The title of my window",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,
NULL, NULL, hInstance, NULL);
if (hwnd == NULL)
{
MessageBox(NULL, "Window Creation Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
RAWINPUTDEVICE Rid[1];
Rid[0].usUsagePage = 0x01;
Rid[0].usUsage = 0x02;
Rid[0].dwFlags = 0; // adds HID mouse
Rid[0].hwndTarget = 0;
if (RegisterRawInputDevices(Rid, 1, sizeof(Rid[0])) == FALSE) {
//registration failed. Call GetLastError for the cause of the error
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
// Step 3: The Message Loop
while (GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
UPDATE
For now I found a workaround by mixing legacy and raw input. In the WM_ACTIVATE message I check if the wParam is 2. If so it means that the window was activated using a mouse click.
In this case I actually process the next WM_LBUTTONDOWN, but only one time (and the other buttons as well).
This is a terrible hack so I'm still looking for a proper solution.

Related

Why is this call to CreateWindow failing, and how can I fix it?

I'm following a tutorial for directx12 and can't even get over the creation of window D: There is an implemented error window which tells me that there was an error when creating the window i actually want to create.
It's supposed to mean that it was "unsuccessful in getting a window handle"...
I don't have anything as much as a clue of what that would mean but i would GREATLY appreciate some help about that.
#include "stdafx.h"
//Handle to the window
HWND hwnd = NULL;
//Name of the window
LPCTSTR WindowName = L"GameEngineApp";
//Title of the window
LPCTSTR WindowTitle = L"My Game Engine";
//Width and height of the window
int Width = 800;
int Height = 600;
//Toggle for fool screen
bool FullScreen = false;
//Toggle for window creation
bool InitializeWindow(HINSTANCE hInstance,
int ShowWnd, int width, int height, bool fullscreen);
//Main application loop
void mainLoop()
{
//The message var hold any windows message received through the
//PeekMessage function
MSG msg;
ZeroMemory(&msg, sizeof(MSG));
while (true)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
//If there is a message, it is translated
//then dispatched so Windows
//knows the program hasn't stopped working
if (msg.message = WM_QUIT) {
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else {
//If there is no message the game
//code will run and the loop will continue
}
}
}
}
//Callback function for windows messages
LRESULT CALLBACK WndProc(HWND hWnd,
UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_KEYDOWN:
if (wParam == VK_ESCAPE) {
if (MessageBox(0, L"Are you sure you want to exit?",
L"Really?", MB_YESNO | MB_ICONQUESTION) == IDYES)
DestroyWindow(hwnd);
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd,
msg, wParam, lParam);
}
//Main Windows function
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmd)
{
//Toggle window creation
if (!InitializeWindow(hInstance, nShowCmd, Width, Height, FullScreen))
{
MessageBox(0, L"Window Initialization - Failed",
L"Error", MB_OK);
return 0;
}
mainLoop(); //Call main loop to start
return 0;
}
bool InitializeWindow(HINSTANCE hInstance,
int ShowWnd, int width, int height, bool fullscreen)
{
//Check if fullscreen is needed and set to fullscreen if so
if (fullscreen)
{
HMONITOR hmon = MonitorFromWindow(hwnd,
MONITOR_DEFAULTTONEAREST);
MONITORINFO mi = { sizeof(mi) };
GetMonitorInfo(hmon, &mi);
width = mi.rcMonitor.right - mi.rcMonitor.left;
height = mi.rcMonitor.bottom - mi.rcMonitor.top;
}
//Window class structure
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = NULL;
wc.cbWndExtra = NULL;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 2);
wc.lpszMenuName = NULL;
wc.lpszClassName = WindowName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
//Registering the window class
if (!RegisterClassEx(&wc))
{
MessageBox(NULL, L"Error registering class",
L"Error", MB_OK | MB_ICONERROR);
return false;
}
//Create the window with the now registered window class
hwnd = CreateWindowEx(NULL,
WindowName,
WindowTitle,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
width, height,
NULL,
NULL,
hInstance,
NULL);
//Return error msg if unsuccessful in getting a window handle
if (!hwnd)
{
MessageBox(NULL, L"Error creating window",
L"Error", MB_OK | MB_ICONERROR);
return false;
}
//Removing the style from the window when fullscreen
if (fullscreen)
{
SetWindowLong(hwnd, GWL_STYLE, 0);
}
//Showing and updating the window
ShowWindow(hwnd, ShowWnd);
UpdateWindow(hwnd);
return true;
}
I've tried to change CreateWIndowEx to CreateWindowA and that's really the only thing that seemed to possibly have an effect but i did not see any results.
I've tried printing the error but there is no error.
Creating a window in Windows with the C++ code so i can make a game engine.
Though shalt not abuse global variables.
You're calling DefWndProc in your WndProc with hwnd as the handle argument. But that isn't set until the return of CreateWindowEx, and there are plenty very important messages that are rifled through WndProc during window stand-up. Those messages need the window handle, and you're not passing it along. Instead you're just passing NULL (the startup value of hwnd).
Change all hwnd to hWnd (the parameter name) in your WndProc
The remainder of the problems mentioned in comments I leave for you to address.

How to stop Direct3D from flicker on release on multihead setup?

Have a kiosk system with a small touchscreen and a large display, and I have an app that works well playing video on the large display. For some reason, when Direct3D stops (app quits), both screens flicker (turn black, then recover).
I simplified the problem down to a program that simply opens a focus window, initializes a Direct3D device, then releases it. On release (or stopping the program without releasing), both screens flicker.
Can someone who's familiar with Direct3D look at this and tell me if I'm doing something wrong?
#include <iostream>
#include <windows.h>
#include <d3d9.h>
const char g_szClassName[] = "myWindowClass";
LRESULT CALLBACK WndProc(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);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = g_szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if (!RegisterClassEx(&wc)) {
MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
HWND hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
"Focus Window",
WS_POPUP | WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,
NULL, NULL, hInstance, NULL);
if (hwnd == NULL) {
MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
IDirect3D9* m_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
if (m_pD3D == NULL) {
MessageBox(NULL, "Failed to initialize direct3D!", "Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
// second display is 1920 x 1080
D3DPRESENT_PARAMETERS m_param;
ZeroMemory(&m_param, sizeof(m_param));
m_param.BackBufferWidth = 1920;
m_param.BackBufferHeight = 1080;
m_param.BackBufferFormat = D3DFMT_X8R8G8B8;
m_param.BackBufferCount = 1;
m_param.MultiSampleType = D3DMULTISAMPLE_NONE;
m_param.SwapEffect = D3DSWAPEFFECT_COPY;
m_param.hDeviceWindow = hwnd;
m_param.Windowed = FALSE;
m_param.Flags = D3DPRESENTFLAG_VIDEO;
m_param.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
m_param.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
HRESULT hr;
IDirect3DDevice9* m_pD3DD;
hr = m_pD3D->CreateDevice(
1,
D3DDEVTYPE_HAL,
hwnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED,
&m_param,
&m_pD3DD
);
if (hr != S_OK) {
MessageBox(NULL, "Failed to create direct3D device!", "Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
Sleep(3000);
// flicker occurs here
m_pD3DD->Release();
m_pD3D->Release();
return 0;
}
NOTE: This program should run on any setup with 2 screens on the same video card, but the second screen's width/height might need to be adjusted (it's hardcoded in BackBufferWidth and BackBufferHeight)
Not sure if that is workable for you, but in trying various examples around the interwebs, it seems the only way to avoid the flicker is to use windowed mode with a borderless window:
...
HWND hwnd = CreateWindowEx(
0,
g_szClassName,
"Focus Window",
WS_POPUP | WS_VISIBLE, // <-- borderless window
800, 0, // <-- position on 2nd screen
1920, 1080, // <-- fill entire 2nd screen
NULL, NULL, hInstance, NULL);
...
D3DPRESENT_PARAMETERS m_param;
ZeroMemory(&m_param, sizeof(m_param));
m_param.BackBufferWidth = 1920;
m_param.BackBufferHeight = 1080;
m_param.BackBufferFormat = D3DFMT_X8R8G8B8;
m_param.BackBufferCount = 1;
m_param.MultiSampleType = D3DMULTISAMPLE_NONE;
m_param.SwapEffect = D3DSWAPEFFECT_COPY;
m_param.hDeviceWindow = hwnd;
m_param.Windowed = TRUE; // <-- use windowed mode
m_param.Flags = D3DPRESENTFLAG_VIDEO;
m_param.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
m_param.PresentationInterval = D3DPRESENT_INTERVAL_ONE;

Why does the window never show up, although all required functions are present?

I have been trying to make a universal DLL to where I can inject it into a process & a window would pop up. I have all required functions such as WinMain (I named mine Initiate and called it manually), DllWindowProcedure, and DllMain. However, after compilation, there is one warning and no errors - I believe it is a logical error. If you spot any issues, or anything I can improve, please let me know!
Warning:
1>Main.cpp(43): warning C4060: switch statement contains no 'case' or 'default' labels
Code:
#include <Windows.h>
HINSTANCE InjectedModuleHandle;
LRESULT CALLBACK DllWindowProcedure(HWND, UINT, WPARAM, LPARAM);
DWORD WINAPI DllThreadProcedure(void * Data)
{
MessageBoxA(NULL, (LPCSTR)"Welcome to Flames v1.1!", (LPCSTR)"Startup Message", NULL);
MSG Messages;
WNDCLASSEX WindowClass;
WindowClass.hInstance = InjectedModuleHandle;
WindowClass.lpszClassName = L"DllWindowClass";
WindowClass.lpfnWndProc = DllWindowProcedure;
WindowClass.style = CS_DBLCLKS;
WindowClass.cbSize = sizeof(WNDCLASSEX);
WindowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WindowClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
WindowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
WindowClass.lpszMenuName = NULL;
WindowClass.cbClsExtra = 0;
WindowClass.cbWndExtra = 0;
WindowClass.hbrBackground = (HBRUSH)RGB(255, 255, 255);
RegisterClassEx(&WindowClass);
HWND Window = CreateWindowEx(0, L"DllWindowClass", L"Flames v1.1 - By XenoSaga3000", (WS_SYSMENU | WS_MINIMIZEBOX), 200, 200, 500, 450, FindWindow(NULL, L"ROBLOX"), CreateMenu(), InjectedModuleHandle, NULL);
ShowWindow(Window, SW_SHOWNORMAL);
while (GetMessage(&Messages, NULL, 0, 0))
{
TranslateMessage(&Messages);
DispatchMessage(&Messages);
};
return 1;
};
LRESULT CALLBACK DllWindowProcedure(HWND Window, UINT Message, WPARAM WParameter, LPARAM LParameter)
{
switch (Message)
{
case WM_COMMAND:
switch(WParameter)
{
//Check for commands here.
};
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(Window, Message, WParameter, LParameter);
};
return 0;
};
bool APIENTRY DllMain(HMODULE DllInstance, DWORD Reason, LPVOID Reserved)
{
if(Reason == DLL_PROCESS_ATTACH)
{
InjectedModuleHandle = DllInstance;
CreateThread(0, NULL, DllThreadProcedure, NULL, NULL, NULL);
};
return TRUE;
};
You can look at this blog for an example for your case.
One of the differences is that it uses DllMain's provided HINSTANCE as the instance handle for the window class. GetModuleHandle(NULL) returns the instance handle of the calling process instead of the DLL.
Note that Windows API calls like CreateThread from DllMain are not recommended, see here.

c++ ShutdownBlockReasonCreate return "1" and GetLastError return "2"

I have a non visible application that should block log off.
I tried this code:
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow){if (!FindWindow("MyWind", NULL))
{
// Ensure that the common control DLL is loaded.
ghInstance = hInstance;
WNDCLASS wc;
HWND hwnd;
MSG msg;
wc.style = 0; // Class style
wc.lpfnWndProc = (WNDPROC) WndProc; // Window procedure address
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon (NULL, IDI_WINLOGO);
wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = "MyWind";
RegisterClass (&wc);
hwnd = CreateWindow (
"MyWind", // WNDCLASS name
"MyWind", // Window title
NULL, // Window style
0, // Horizontal position
200, // Vertical position
10, // Initial width
15, // Initial height
HWND_DESKTOP, // Handle of parent window
NULL, // Menu handle
hInstance, // Application's instance handle
NULL // Window-creation data
);
ShowWindow(hwnd, SW_HIDE);
UpdateWindow (hwnd);
int i = ShutdownBlockReasonCreate(hwnd, L"Block Shutdown");
DWORD dwRealErrorCode = GetLastError();
char sreason[50];
sprintf(sreason,"%d - %ld",i,dwRealErrorCode);
if(dwRealErrorCode != 0)
MessageBox(NULL,sreason,"FAIL!",MB_OK);
while (GetMessage (&msg, NULL, 0, 0)) {
TranslateMessage (&msg);
DispatchMessage (&msg);
}
ShutdownBlockReasonDestroy(hwnd);
return Helper64::WParamTo<int>(msg.wParam);
}
else
return 0;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam,
LPARAM lParam){ switch (message) {
//------------------------------------
case WM_QUERYENDSESSION :
{
return FALSE;
}
break;
case WM_ENDSESSION:
{
return TRUE;
}
}
the Return value of the function "ShutdownBlockReasonCreate" is "1" where the return value of GetLastError is "2"
Is there somme specific ustall or updates on windows that makes this run or no, because in other VirtualMachines (with the same configuration as my physical machine)this works perfectly.

How to duplicate a window's clientarea to another window?

I want to create a simple project (the language doesn't really matter/but I prefer C++) which simply takes a window title as it's input and duplicate it's visual part, bit by bit, to a new window. just like a mirror better I'd say.
As far as I remember there was a win32 API for this but I can't remember, so would you please tell me how can I achieve this?
And please tell me, will your answers work with DirectX/Open-GL applications as well or not?
You can get DC of first window, and get DC of second window. And after this do BitBlt or StretchBlt. It has to work... But I don't know what about DirectX/Open-Gl... I think it has to work too. But anyway. It won't take much time to check it.
Here is the source code for a program that will mirror other apps, you can use StretchBlt() instead of BitBlt(), this will not copy Menubars or popups.
Some apps like chrome, calculator, and camera use child windows for the visual part, and FindWindow() only scans through top-level windows for the title, so you can use FindWindowEx() with it to make that work!
#include <windows.h>
HWND sourceWindow;
void Mirror(HWND hwndSource, HWND hwndDst)
{
HDC source = GetDC(hwndSource);
HDC dst = GetDC(hwndDst);
RECT srcSiz;
GetClientRect(hwndSource, &srcSiz);
SetWindowPos(hwndDst, NULL, 0, 0, srcSiz.right, srcSiz.bottom, SWP_NOMOVE | SWP_NOZORDER);
BitBlt(dst, 0, 0, srcSiz.right, srcSiz.bottom, source, 0, 0, SRCCOPY);
ReleaseDC(hwndSource, source);
ReleaseDC(hwndDst, dst);
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
switch (Message)
{
case WM_CREATE:
SetTimer(hwnd, 1, 500, (TIMERPROC) NULL);//This will refresh after every 500 ms
break;
case WM_TIMER:
Mirror(sourceWindow, hwnd);
break;
case WM_DESTROY:
KillTimer(hwnd, 1);
break;
default:
return DefWindowProc(hwnd, Message, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hwnd;
MSG msg;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(CreateSolidBrush(RGB(0, 0, 0)));
wc.lpszMenuName = NULL;
wc.lpszClassName = "MyWindow";
wc.hIconSm = LoadIcon(hInstance, IDI_APPLICATION);
if (!RegisterClassEx(&wc))
{
MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
hwnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW, "MyWindow", "MyTitle", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 500,
NULL, NULL, hInstance, NULL);
if (!hwnd)
{
MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
sourceWindow = FindWindowA(NULL, "<WindowTitle>");//or you can use class name
while(GetMessage(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}