C++ Win API window mouse busy on x64 platform - c++

I created in C++ a window with the Win API.
If I set the target platform to x86 in Visual Studio (2015) all works fine.
But if I set the target platform to x64 all works fine too except that I get a busy cursor for the first 4-5 seconds when the window popped up.
This isn't that bad but I am just wondering what is causing this.
I saw this behavior when using GLFW too so it seems to be not a programming error.
Maybe someone know what is causing this?
#include <windows.h>
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}
break;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
HWND hWnd;
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
wc.lpszMenuName = NULL;
wc.lpszClassName = "MainWindowClass";
wc.hIconSm = NULL;
RegisterClassEx(&wc);
RECT wr = { 0, 0, 800, 800 };
AdjustWindowRectEx(&wr, WS_OVERLAPPEDWINDOW, FALSE, 0);
hWnd = CreateWindowEx(0, "MainWindowClass", "DirectX Lab", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, wr.right - wr.left, wr.bottom - wr.top, NULL, NULL, hInstance, NULL);
ShowWindow(hWnd, nCmdShow);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0) != 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}

Related

SetWindowRgn changes window theme to Classic

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?

why my window has been closed, but the application sometimes is still running background

main.cpp:
#include <Windows.h>
LRESULT CALLBACK WndProc(HWND hWnd,
UINT msgID,
WPARAM wParam,
LPARAM lParam)
{
return DefWindowProc(hWnd, msgID, wParam, lParam);
}
int CALLBACK WinMain(_In_ HINSTANCE hIns,
_In_opt_ HINSTANCE hPreIns,
_In_ LPSTR lpCmdLine,
_In_ int nCmdShow)
{
WNDCLASS wc = { 0 };
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hIns;
wc.hIcon = NULL;
wc.hCursor = NULL;
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = "MAINWINDOW";
RegisterClass(&wc);
HWND hWnd = CreateWindow("MAINWINDOW",
"mainwindow",
WS_OVERLAPPEDWINDOW,
100, 100, 500, 500,
NULL, NULL, hIns, NULL);
ShowWindow(hWnd, SW_SHOW);
MSG nMsg = { 0 };
while (GetMessage(&nMsg, NULL, 0, 0))
{
TranslateMessage(&nMsg);
DispatchMessage(&nMsg);
}
return 0;
}
I think that if I closed window, the application should also be closed too.
However, sometimes it worked as I thought, and sometimes the window is closed but the application was still running.
Why and how to make sure that the application is definitely exited after I close the window

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.

putting text to static control registered at runtime

I would like to register a static control in a main window and then fill it with some text.
Here's the full code:
#include <windows.h>
#include "resource.h"
#include <commctrl.h>
void RegisterCommonControls();
#pragma comment(lib, "comctl32.lib")
HINSTANCE hInstance;
HINSTANCE hPrevInstance;
int nCmdShow;
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
switch (Msg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
}
LRESULT CALLBACK LblStateProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
void RegisterCommonControls()
{
INITCOMMONCONTROLSEX iccex;
iccex.dwSize = sizeof(INITCOMMONCONTROLSEX);
iccex.dwICC = ICC_TREEVIEW_CLASSES | ICC_LISTVIEW_CLASSES;
InitCommonControlsEx(&iccex);
}
bool RegisterWindow(void)
{
if (hPrevInstance)
return false;
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = MainWndProc;
wc.cbClsExtra = wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(0, IDI_APPLICATION);
wc.hCursor = LoadCursor(0, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
wc.lpszMenuName = MAKEINTRESOURCE(IDC_WIN_API);
wc.lpszClassName = L"Class1";
if (!RegisterClass(&wc))
return false;
return true;
}
bool RegisterEdit(void)
{
if (hPrevInstance)
return false;
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = LblStateProc;
wc.cbClsExtra = wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = wc.hCursor = NULL;
wc.hbrBackground = (HBRUSH)(GetStockObject(WHITE_BRUSH));
wc.lpszMenuName = NULL;
wc.lpszClassName = L"STATIC";
if (!RegisterClass(&wc))
return false;
return true;
}
int CALLBACK wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
{
const int size = 600;
MSG msg;
RegisterWindow();
HWND hMainWnd = CreateWindow(L"Class1", L"Main Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, size, size, 0, 0, hPrevInstance, NULL);
RegisterCommonControls();
RegisterEdit();
HWND hLblState = CreateWindow(L"STATIC", L"1", WS_CHILD | WS_VISIBLE | SS_SIMPLE | SS_OWNERDRAW, 200, 200, 100, 50, hMainWnd, 0, NULL, NULL);
ShowWindow(hMainWnd, nCmdShow);
UpdateWindow(hMainWnd);
SendMessage(hLblState, WM_SETTEXT, NULL, (LPARAM)L"Rectangle");
while(GetMessage(&msg, 0, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
So, I get a white "static" window inside the main window (the control is at correct coordinates) with no text inside (neither "1" nor "Rectangle"). What's broken in my code?
You are registering a window class called "STATIC". This is used in preference to the built-in "STATIC" window class, so your window doesn't behave like a static control.
To fix it, don't register a window class called "STATIC". The standard one will be used instead.

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