WINAPI Window, not being created - c++

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.

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?

Win32 Inconsistent CreateWindowEx Call

I'm trying to wrap my head around the Win32 API, and when creating the window I get inconsistent results. The call to CreateWindowEx will fail and the result from GetLastError() yields the ERROR_NOT_ENOUGH_MEMORY error code. But sometimes the application successfully creates the window and runs fine. This has left me rather confused.
// Standard Includes
#include <windows.h>
#include <iostream>
#ifndef UNICODE
#define UNICODE
#endif
#ifndef _UNICODE
#define _UNICODE
#endif
#define UNUSED_PARAM(x) (void)(x)
const char szWindowClass[] = "Program";
const char szTitle[] = "Program Desc";
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow) {
UNUSED_PARAM(hPrevInstance);
UNUSED_PARAM(lpCmdLine);
WNDCLASSEX wcex;
HWND hWnd;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, IDI_APPLICATION);
if(!RegisterClassEx(&wcex)) {
MessageBox(NULL, "Call to RegisterClassEx failed!", szWindowClass, MB_ICONEXCLAMATION | MB_OK);
return 1;
}
hWnd = CreateWindowEx( WS_EX_CLIENTEDGE, // dwExStyle
szWindowClass, // lpClassName
szTitle, // lpWindowName
WS_OVERLAPPEDWINDOW, // dwStyle
CW_USEDEFAULT, CW_USEDEFAULT, // x, y
240, 120, // width, height
NULL, NULL, // hWndParent, hMenu
hInstance, NULL); // hInstance, lpParam
std::cout << GetLastError();
if(hWnd == NULL) {
MessageBox(NULL, "Call to CreateWindow failed!", szWindowClass, MB_ICONEXCLAMATION | MB_OK);
return 1;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
// Main message loop
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int) msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch(uMsg) {
case WM_CLOSE:
DestroyWindow(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
You're not initializing WNDCLASSEX.cbWndExtra which defines how many extra bytes of storage your window class needs.
You should add:
wcex.cbWndExtra = 0;
Before your call to RegisterClassEx. Alternatively you could start with this:
WNDCLASSEX wcex = { sizeof(wcex) };
Which will initialize the cbSize member to the size of the structure and all other members to 0 (or NULL) for you.

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 doesn't respond to keypress

I recently decided to learn a bit of WinApi, but I hit a snag. I want to display a massage in my window after a keypress, but it doesn't seem to work. If I press the key multiple times or if I hold it down, still nothing happens. Can you tell me what I'm doing wrong?
This is the full code:
#include <windows.h>
#include <string.h>
#include <stdlib.h>
#include <tchar.h>
LRESULT CALLBACK WndProc (HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
LPCWSTR display_str = L"hello";
switch(uMsg)
{
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
if(GetAsyncKeyState(VK_UP))
{
TextOut(hdc,
15, 15,
display_str,
_tcslen(display_str));
}
EndPaint(hwnd, &ps);
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
HWND hwnd;
MSG uMsg;
HINSTANCE hInst;
WNDCLASSEX wcex;
LPCWSTR class_name = L"myWindowClass";
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = class_name;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
if(!RegisterClassEx(&wcex))
{
MessageBox(NULL, L"Call to RegisterClassEx failed!", L"Win32 Guided Tour!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
hInst = hInstance;
hwnd = CreateWindowEx(
NULL,
class_name,
L"Test",
WS_OVERLAPPEDWINDOW,
200, 200,
740, 540,
NULL,
NULL,
hInstance,
NULL
);
if(!hwnd)
{
MessageBox(NULL, L"Window Creation Failed!", L"Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&uMsg, NULL, 0, 0) > 0)
{
TranslateMessage(&uMsg);
DispatchMessage(&uMsg);
}
return uMsg.wParam;
}
Windows sends WM_KEYDOWN message when a key is pressed. In WndProc handle WM_KEYDOWN message, call InvalidateRect with the Client rect of the window and draw the text you want to display in WM_PAINT message handler.
Here's my example, if pressed F11 key, print in console string.:
case WM_KEYDOWN:
if(wParam==VK_F11)
{
std::cout << "Hello in my example!";
}
break;

Creating a window doesn't work but gives no error messages

I'm trying to create a window, none appear but I don't get an error message anywhere except for the one I put in testing hWnd.
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include "entity.h"
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 APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc= (WNDPROC)WndProc;
wcex.cbClsExtra= 0;
wcex.cbWndExtra= 0;
wcex.hInstance= hInstance;
wcex.hIcon= 0;
wcex.hCursor= LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground= (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName= 0;
wcex.lpszClassName= "Extt";
wcex.hIconSm= 0;
if(!RegisterClassEx(&wcex))
{
MessageBox(NULL, "FAILED TO REGISTER WINDOW CLASS", "ERROR", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
HWND hWnd = CreateWindow("WinD", "Chair", WS_OVERLAPPEDWINDOW, 480, 480, 480, 480, NULL, NULL, hInstance, NULL);
if (hWnd == NULL)
{
MessageBox(NULL, "FAILED TO CREATE WINDOW", "ERROR", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
I just don't know what to do anymore.
I did everything like the guy said, I've read and re-read the page several times and can not understand why this won't work.
Your classname parameters do not match. If you had used GetLastError() it would have returned 1407, which is:
ERROR_CANNOT_FIND_WND_CLASS
1407 (0x57F)
Cannot find window class.
Either change wcex.lpszClassName = "Extt"; to wcex.lpszClassName = "WinD"; or change the first parameter to CreateWindow to "Extt".