CreateWindowsEx fails when creating window - c++

I am new to win32 API GUI programming in C++. When the program is compiled and executed, It always fails at CreateWindowsEx. Sorry but this only what I can explain at this moment.
Aside from that, It passes the window registration, which is good. But from the time Windows Creation executed, it always return NULL.
Here's my C++ code:
#include <windows.h>
LRESULT CALLBACK WindowProcedure(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR args, int ncmdshow){
//MessageBox(NULL, "Hello ", " H", MB_OK);
WNDCLASSEX wc = {0};
//memset(&wc,0,sizeof(wc));
//wc.cbSize = sizeof(WNDCLASSEX);
memset(&wc,0,sizeof(wc));
wc.cbSize = sizeof(WNDCLASSEX);
wc.lpfnWndProc = WindowProcedure; /* This is where we will send messages to */
wc.hInstance = hInst;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
/* White, COLOR_WINDOW is just a #define for a system color, try Ctrl+Clicking it */
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszClassName = "WindowClass";
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); /* Load a standard icon */
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); /* use the name "A" to use the project icon */
if(! RegisterClassEx(&wc) ){
MessageBox(NULL, "Error 1", " H", MB_OK);
return -1;
}
HWND hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,"WindowClass","Caption",WS_VISIBLE|WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, /* x */
CW_USEDEFAULT, /* y */
640, /* width */
480, /* height */
NULL,NULL,hInst,NULL);
//returns 0x0
//return GetLastError();
if( hwnd == NULL){
MessageBox(NULL, "Error 2", " H", MB_OK);
return GetLastError();
}
MSG msg = {0};
while( GetMessage(&msg, NULL, 0, 0) ){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WindowProcedure(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp){
switch(msg){
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProcW(hWnd, msg, wp, lp);
}
return 0;
}
Please approach in the level of a novice, so it easy for me to understand what should be done.

The reason why the CreatewindowEx fails is because of DefWindowProcW should be DefWindowProc.
DefwindowProcW is used with CreateWindowW, but since it is using CreateWindowEx, DefWindowProc should be the correct one to use.

Related

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.

Failed CreateWindowEx. How do I get my window (with the button) to actually pop up for once?

I can only assume most of this works because I can't get past the CreateWindowEx check.
If someone would double check all of my fun button code that would be great too.
#include <windows.h>
#include <tchar.h> //I was told I needed this line but I don't believe I do.
#define ID_BTNENCRYPT 0
const char g_szClassName[] = "MyWindowClass";
HWND button;
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch(msg) { //Fun button stuff
case WM_CREATE: {
button = CreateWindow("button",
"Encrypt Message",
WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
450, 620, 200, 30,
hwnd, (HMENU) ID_BTNENCRYPT, GetModuleHandle(NULL), NULL);
break;
}
case WM_COMMAND: { //More fun button stuff
switch (LOWORD(wParam)){
case ID_BTNENCRYPT: {
::MessageBox(hwnd, "This will be your message once I get my $h!t together", "Encrypted Message", MB_OK);
}
}
break;
}
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
FreeConsole();
WNDCLASSEX wc;
HWND hwnd;
MSG Msg;
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.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = g_szClassName;
if (!RegisterClassEx(&wc)) {
::MessageBox(NULL, "Window Registration Status: Hopelessly F***ed", "", MB_OK);
return 0;
} //No apparent error in Window Registration
Here's where I need help
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
"Great Window",
WS_OVERLAPPEDWINDOW,
300, 300,
350, 350,
NULL, NULL, hInstance, NULL);
if (hwnd == NULL) {
::MessageBox(NULL,"Window Creation Status: Gone to $h!t", "", MB_OK);
}
I unfortunately get the error message that yes, my window creation has failed.
ShowWindow(hwnd, nCmdShow); //Just the end of my code from here on out.
UpdateWindow(hwnd); //Hopefully there aren't any fatal errors.
while(GetMessage(&Msg, NULL, 0, 0) > 0) {
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
Your WndProc() is not returning the return value of DefWindowProc() for unhandled messages. There is a missing return statement, so you end up falling to return 0 for all messages. When WM_NCCREATE returns 0, CreateWindowEx() fails:
If an application processes this message, it should return TRUE to continue creation of the window. If the application returns FALSE, the CreateWindow or CreateWindowEx function will return a NULL handle.
You need to change this:
default:
DefWindowProc(hwnd, msg, wParam, lParam);
To this:
default:
return DefWindowProc(hwnd, msg, wParam, lParam);

Simple WinAPI app has an additional console window [duplicate]

This question already has answers here:
How to stop a program compiled with MinGW (g++) from opening a console window in windows
(2 answers)
Closed 9 years ago.
I've copy-pasted following skeleton of a simple C++ WinAPI application. It works, but creates an additional console window along with GUI one. How to get rid of it? I am using GCC from MinGW.
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
static char sClassName[] = "MyClass";
static HINSTANCE zhInstance = NULL;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
WNDCLASSEX WndClass;
HWND hwnd;
MSG Msg;
zhInstance = hInstance;
WndClass.cbSize = sizeof(WNDCLASSEX);
WndClass.style = NULL;
WndClass.lpfnWndProc = WndProc;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hInstance = zhInstance;
WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
WndClass.lpszMenuName = NULL;
WndClass.lpszClassName = sClassName;
WndClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&WndClass)) {
MessageBox(0, "Error Registering Class!", "Error!", MB_ICONSTOP | MB_OK);
return 0;
}
hwnd = CreateWindowEx(WS_EX_STATICEDGE, sClassName, "db Tutorial", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
320, 240, NULL, NULL, zhInstance, NULL);
if(hwnd == NULL) {
MessageBox(0, "Error Creating Window!", "Error!", MB_ICONSTOP | MB_OK);
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&Msg, NULL, 0, 0)) {
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) {
switch(Message) {
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, Message, wParam, lParam);
}
return 0;
}
Just use the -mwindows option to compile a GUI application. The default, -mconsole, creates a console application.
The default heuristic used by the MS linker is: if your program has a main function it is a console program but if it has a WinMain function it is a GUI one. But that is not used by the GNU tools. They create a console program by default.

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).

DirectX and C++

I am having trouble with the following CPP code: http://ideone.com/XZXZJ .
I am receiving the following errors:
(1) Warning 1 warning LNK4042: object specified more than once; extras ignored c:\Users\jabbott\documents\visual studio 2010\Projects\DirectX9_Tutorial\DirectX9_Tutorial\Debug\WinMain.obj 1
(2) Error 2 error LNK1561: entry point must be defined c:\Users\jabbott\documents\visual studio 2010\Projects\DirectX9_Tutorial\DirectX9_Tutorial\LINK
No Entry Point setting isn't set. I've tried to set this to WinMain with no luck.
// WinMain.h
#ifndef APP_HPP_
#define APP_HPP_
#include <Windows.h> // Windows API Library
#include <d3d9.h> // Include DirectX 9 Library
#include <d3d10_1.h> // Include DirectX 10 Library
#include <d3d11.h> // Include DirectX 11 Library
/* Global Functions */
// Handle any messages from MS Windows
LRESULT CALLBACK WndProc(HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam);
// Main Entry Point
int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmd);
/* Global Variables */
IDirect3D9 *g_pD3D; // DirectX 3D v9 Instance
IDirect3DDevice9 *g_pD3DDevice; // DX3D9: Representation of Graphics Card
LPCTSTR ClsName = "g_szInterfaceClass";
//IDirect3D10 *g_pD3D10; // DirectX 3D v10 Instance
//IDirect3DDevice10 *g_pD3DDevice10; // DX3D10: Representation of Graphics Card
//IDirect3D11 *g_pD3D11; // DirectX 3D v11 Instance
//IDirect3DDevice11 *g_pD3DDevice11; // DX3D11: Representation of Graphics Card
#define WINDOW_WIDTH 200
#define WINDOW_HEIGHT 200
/* Error Macro for Debugging */
//#define ERROR(msg) { MessageBox(NULL, msg, L"Error", MB_OK|MB_ICONEXCLAMATION); }
#endif // WINMAIN_H
WinMain.cpp:
// WinMain.cpp
#include "WinMain.h"
LRESULT CALLBACK WndProc(HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
switch (uMsg)
{
case WM_CLOSE:
PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd,
uMsg,
wParam,
lParam);
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); /* Predeclaration of WinProc() */
int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmd)
{
// The WNDCLASSEX structure contains window class information
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = (WNDPROC) 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 = ClsName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
// rect structure to define the window dimensions
RECT rect;
rect.top = (long) 0;
rect.left = (long) 0;
rect.right = (long) WINDOW_WIDTH;
rect.bottom = (long) WINDOW_HEIGHT;
// Register the window to MS Windows
if(!RegisterClassEx(&wc))
{
MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
// calculate the required size of the window rectangle, based on the desired size of the client rectangle
AdjustWindowRectEx( &rect,
WS_OVERLAPPEDWINDOW,
FALSE,
WS_EX_APPWINDOW | WS_EX_WINDOWEDGE);
// create the target window of the application
HWND hWindow = CreateWindowEx(NULL,
ClsName,
"Name of Window",
WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
0, 0,
rect.right-rect.left,
rect.bottom-rect.top,
NULL, NULL,
hInstance,
NULL);
if (!hWindow)
{
DestroyWindow(hWindow);
UnregisterClass(ClsName, hInstance);
MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hWindow, SW_SHOW);
UpdateWindow(hWindow);
SetForegroundWindow(hWindow);
SetFocus(hWindow);
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = true;
d3dpp.hDeviceWindow = hWindow;
d3dpp.BackBufferCount = 1;
d3dpp.BackBufferWidth = WINDOW_WIDTH;
d3dpp.BackBufferHeight = WINDOW_HEIGHT;
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
// Identify current version of Direct3D
g_pD3D =Direct3DCreate9(D3D_SDK_VERSION);
// Create the Direct3D Interface Device. Thisisanabstracted version of
if(FAILED(g_pD3D->CreateDevice( D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hWindow,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp,
&g_pD3DDevice)))
{
MessageBox(NULL, "Failed to create Direct3D InterfaceDevice.", "Error!", MB_ICONEXCLAMATION | MB_OK);
}
/* Main Game Boot */
// Enter the message loop
MSG msg;
while(GetMessage(&msg, NULL, 0, 0))
{
// Clear the target render buffer black
g_pD3DDevice->Clear( 0,
0,
D3DCLEAR_TARGET,
D3DCOLOR_XRGB(0, 0, 0),
1.0f,
(DWORD) 0.0f);
// Send the buffer to the computer monitor
g_pD3DDevice->Present(NULL, NULL, NULL, NULL);
//Send any messages to WndProc function
TranslateMessage(&msg);
DispatchMessage(&msg);
}
g_pD3D->Release();
return 1;
}
Your first problem can be solved by deleting this line:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); /* Predeclaration of WinProc() */
You already have the implementation of the function directly above it. You only need the above if the implementation of the function occurs after the point the function is called or the implementation is in a different translation unit (source file). Generally, try to avoid the 'predeclaration' of functions if you can, use the function itself as the declaration, it will reduce the amount of maintenance required.
The second problem might be because you are compiling a console application (entry point main) rather than a windows application (entry point WinMain).