SetWindowRgn changes window theme to Classic - c++

When i use the SetWindowRgn function in my windows api code, the created windows style changes from Modern to Classic.
Minumum code to reproduce problem here:
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;
HWND hwnd;
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 = CreateWindowEx(
WS_EX_TOPMOST | WS_EX_CLIENTEDGE,
g_szClassName,
"Capture Screen",
WS_OVERLAPPEDWINDOW,
10, 100, 800, 600,
NULL, NULL, hInstance, NULL);
if(hwnd == NULL)
{
MessageBox(NULL, "Window Creation Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hwnd, SW_NORMAL);
UpdateWindow(hwnd);
HRGN WindowRgn = CreateRectRgn(0,0,800,600);
SetWindowRgn(hwnd,WindowRgn,TRUE); // <===== comment, uncomment this line to observe difference
MSG Msg;
while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
Commenting and uncommenting the line below will demonstrate the problem
SetWindowRgn(hwnd,WindowRgn,TRUE); // <===== comment, uncomment this line to observe difference
Modern (commenting the line) :
Classic (uncommenting the line) :
Any idea what exactly in the function causes the problem here? And any fixes for this?

Related

How to assign a window procedure to a child window?

Having such a simple Win32 app:
#include <windows.h>
#include <gdiplus.h>
#include <stdio.h>
#include <tchar.h>
#pragma comment(lib, "gdiplus.lib")
using namespace Gdiplus;
const wchar_t g_szClassName[] = L"Skeleton";
const wchar_t g_szChildClassName[] = L"Child";
wchar_t msgbuf[100];
void Example_DrawImage9(HDC hdc) {
Graphics graphics(hdc);
Image image(L"C:/Users/Darek/Fallout2_older/data/art/iface/armor_info.bmp");
graphics.DrawImage(&image, 0, 0);
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg) {
case WM_PAINT:
swprintf_s(msgbuf, _T("WM_PAINT - PARENT - hwnd: %02X\n"), (int)hwnd);
OutputDebugString(msgbuf);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
LRESULT CALLBACK WndProcChild(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg) {
case WM_PAINT:
swprintf_s(msgbuf, _T("WM_PAINT - CHILD - hwnd: %02X\n"), (int)hwnd);
OutputDebugString(msgbuf);
return 0;
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;
HWND hwnd;
MSG Msg;
ULONG_PTR token;
GdiplusStartupInput input = { 0 };
input.GdiplusVersion = 1;
GdiplusStartup(&token, &input, NULL);
//Step 1: Registering the Window Class
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(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, L"Window Registration Failed!", L"Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
hwnd = CreateWindowEx(0, g_szClassName, L"Skeleton", WS_POPUP | WS_BORDER, 0, 0, 190, 110, 0, 0, hInstance, 0);
SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED);
SetLayeredWindowAttributes(hwnd, 0, 128, LWA_ALPHA);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
// ---------------
HWND hwnd_child;
wc.lpfnWndProc = WndProcChild; // 1
wc.lpszClassName = g_szChildClassName;
if (!RegisterClassEx(&wc)) {
MessageBox(NULL, L"Window Registration Failed!", L"Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
hwnd_child = CreateWindowEx(0, g_szClassName, L"Child", /*WS_POPUP |*/ WS_BORDER, 200, 0, 190, 110, hwnd, 0, hInstance, 0);
swprintf_s(msgbuf, _T("hwnd_child: %02X\n"), (int)hwnd_child);
OutputDebugString(msgbuf);
SetWindowLong(hwnd_child, GWL_EXSTYLE, GetWindowLong(hwnd_child, GWL_EXSTYLE) | WS_EX_LAYERED);
SetLayeredWindowAttributes(hwnd_child, 0, 128, LWA_ALPHA);
ShowWindow(hwnd_child, nCmdShow);
UpdateWindow(hwnd_child);
// ---------------
while (GetMessage(&Msg, NULL, 0, 0) > 0) {
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
GdiplusShutdown(token);
return Msg.wParam;
}
I've expected that the child window will run it's own WndProcChild window procedure but I get:
WM_PAINT - PARENT - hwnd: C0996
hwnd_child: C0998
WM_PAINT - PARENT - hwnd: C0998
what implies that the child window runs parent's procedure (WndProc) even if I've clearly assigned (line #1) a separate procedure for it.

Error using RegisterClassEx

I am trying to learn Win32 through msdn but I am having problems with RegisterClassEx, I checked other threads stating that maybe not all members are initialized but I am sure they are.
#include <Windows.h>
#include <tchar.h>
static const TCHAR windowclass_sz[] = _T("WindowClass1");
static const TCHAR windowtitle_sz[] = _T("DirectX 12 Demo");
bool Stop = true;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
lParam)
{
switch (message)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE PrevhInstance, LPSTR
lpCmdLine, int nCmdShow)
{
MSG msg;
HWND hWnd;
WNDCLASSEX wcex;
ZeroMemory(&wcex, sizeof(WNDCLASSEX));
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
wcex.hIconSm = LoadIcon(wcex.hInstance, IDI_APPLICATION);
wcex.hInstance = hInstance;
wcex.lpfnWndProc = WndProc;
wcex.lpszClassName = windowclass_sz;
wcex.lpszMenuName = nullptr;
wcex.style = CS_HREDRAW | CS_VREDRAW;
RegisterClassEx(&wcex);
if (!RegisterClassEx(&wcex))
{
GetLastError();
MessageBox(NULL, _T("RegisterClassEx Call Error!"), _T("ERROR"),
MB_ICONERROR && MB_OK );
return 1;
}
hWnd = CreateWindowEx(NULL, windowclass_sz, windowtitle_sz,
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
800, 600, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
MessageBox(NULL, _T("CreateWindowEx Call Error!"), _T("ERROR"),
MB_ICONERROR && MB_OK);
return 1;
}
else
{
Stop = false;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
while (Stop == false)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int)msg.wParam;
}
As you can see, the RegisterClassEx error is triggered but I have no clue what is wrong.
A message box pops up with "RegisterClassEx Call Error!" and so the program ends there, what is the problem here?
You are calling RegisterClassEx twice with the same argument. The second call will fail, since the class already exists, and GetLastError returns error code 1410 (ERROR_CLASS_ALREADY_EXISTS)1).
Solution: Register any given window class at most once.
1) You can convert error codes into human-readable representations by calling FormatMessage. Working sample code is available in this answer.

WINAPI Window, not being created

I have been trying very hard to get my window to work. I am looking at the MSDN Page on how to make a window and i can't see the difference. When i run my program, it comes up with the message box saying NO WINDOW.
Code:
#include <windows.h>
static const LPSTR CLASSNAME = "Win32Window";
LRESULT CALLBACK WndProc(HWND window, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
DefWindowProc(window, msg, wParam, lParam);
break;
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR cmdLine, int nCmdShow)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.hCursor = LoadCursor(hInstance, MAKEINTRESOURCE(IDC_ARROW));
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
wcex.hIconSm = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
wcex.hInstance = hInstance;
wcex.lpfnWndProc = WndProc;
wcex.lpszClassName = CLASSNAME;
wcex.lpszMenuName = NULL;
wcex.style = CS_HREDRAW | CS_VREDRAW;
if (!RegisterClassEx(&wcex))
{
MessageBox(NULL, "Failed to register window class", "ERROR", MB_ICONERROR);
return 1;
}
HWND window = CreateWindow(CLASSNAME, "title", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 800, 600, NULL, NULL, hInstance, NULL);
if (!window)
{
MessageBox(NULL, "NO WINDOW", "ERROR", MB_ICONERROR); // THIS IS BEING CALLED!!!! WHY??
return 1;
}
ShowWindow(window, nCmdShow);
UpdateWindow(window);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.lParam;
}
If someone can tell me what is wrong here that would be great.
Your window procedure (WndProc) needs to return the value returned by DefWindowProc. At the moment you're just returning 0 for all unhandled messages, which has side effects like (in response to WM_NCCREATE) causing your window creation to fail.

C++ executable opens a command window

I have this very simple C++ class which just opens a blank Windows window, but I've noticed that everytime I double click the .exe, it opens the window, but it also opens a command prompt window too.
Is there a quick easy & simple way to stop this command prompt window from happening?
Cheers in advance,
KS.
#include <windows.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_LBUTTONDOWN:
{
char szFileName[MAX_PATH];
HINSTANCE hInstance = GetModuleHandle(NULL);
GetModuleFileName(hInstance, szFileName, MAX_PATH);
MessageBox(hwnd, szFileName, "This program is:", MB_OK | MB_ICONINFORMATION);
}
break;
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;
HWND hwnd;
MSG Msg;
//Step 1: Registering the Window Class
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 1;
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,
"WinApp-2",
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;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
// Step 3: The Message Loop
while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
Just link with the /SUBSYSTEM:WINDOWS option instead of /SUBSYSTEM:CONSOLE.
If you're currently letting the compiler call the linker, you may want to pass /c to cl.exe to compile only, and then call link.exe /SUBSYSTEM:WINDOWS on the resulting object file(s).

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;
}