I was working through a book which shows me how to create a windows application. I have written the code, however when I compile and run it, it says that it was successfuly built but it doesn't show a window where it should write "Hello World". I am using Visual Studio 2010 with C++, what might be the problem?
Thanks
Here is the code;
//Header Files
#include <windows.h>
#include <stdlib.h>
#include <time.h>
//Application Title
#define APPTITLE L"Hello World"
//function prototypes (forward declarations)
BOOL InitInstance( HINSTANCE, int);
ATOM MyRegisterClass( HINSTANCE);
LRESULT CALLBACK WinProc( HWND, UINT, WPARAM, LPARAM);
//The window event callback function
LRESULT CALLBACK WinProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
//char *szHello = "Hello World!";
RECT rt;
int x, y, n;
COLORREF c;
switch(message)
{
case WM_PAINT:
//get the dimensions of the window
GetClientRect( hWnd, &rt);
//Start drawing on device context
hdc = BeginPaint( hWnd, &ps);
//Draw some text
DrawText( hdc, L"Hello World!", strlen( "Hello World!"), &rt, DT_CENTER);
//Draw 1000 random pixels
for( n=0; n < 3000; n++)
{
x = rand() % (rt.right - rt.left);
y = rand() % (rt.bottom - rt.top);
c = RGB( rand()%256, rand()%256, rand()%256);
SetPixel( hdc, x, y, c);
}
//Stop drawing
EndPaint( hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
//helper function to set up the window properties
ATOM MyRegisterClass(HINSTANCE hInstance)
{
//create the window class structure
WNDCLASSEX wc;
wc.cbSize = sizeof( WNDCLASSEX);
//FILL THE STRUCT WITH INGO
wc.cbSize = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)WinProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = APPTITLE;
wc.hIconSm = NULL;
//set up the window with the class info
return RegisterClassEx(&wc);
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
//create a new window
hWnd = CreateWindow(
APPTITLE, //Window class
APPTITLE, //title bar
WS_OVERLAPPEDWINDOW, //window Style
CW_USEDEFAULT, //x position of window
CW_USEDEFAULT, //y postion of window
500, //width of the window
400, //height of the window
NULL, //parent window
NULL, //menu
hInstance, //application instance
NULL); //window parameters
//was there an error creating the window?
if( !hWnd)
return FALSE;
//Display the window
ShowWindow( hWnd, nCmdShow);
UpdateWindow( hWnd);
return TRUE;
}
//Entry point for a Windows program
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
//declare varuables
MSG msg;
//register the class
MyRegisterClass( hInstance);
//Initialize application
if( !InitInstance(hInstance, nCmdShow))
return FALSE;
//set random number seed
srand(time(NULL));
//Main message loop
while( GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage( &msg);
DispatchMessage( &msg);
}
return msg.wParam;
}
This line is wrong:
wc.cbSize = CS_HREDRAW | CS_VREDRAW;
You mean
wc.style = CS_HREDRAW | CS_VREDRAW;
In fact I would change the window class initialisation code so that you make it very clear in the code that the entire struct is initialised.
WNDCLASSEX wc = { 0 };//initialise struct to 0
wc.cbSize = sizeof( WNDCLASSEX);
//FILL THE STRUCT WITH INGO
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)WinProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszClassName = APPTITLE;
And you were missing some error checking:
if (!MyRegisterClass( hInstance))
return FALSE;
Stepping through under the debugger will allow you to see where in the process things are going wrong.
Related
I'm trying to make a window for DirectX, but for some reason, when the window is created, it can't be closed after pressing X and it becomes a zombie process. I found that the GetMessage loop did not call WndProc at all after pressing X. I tried to find a solution, but unsuccessfully, so I want to ask the community. Please advise me.
#include <Windows.h>
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int
nCmdShow)
{
//register windows class
const wchar_t* pClassName = L"Senko Interaction";
WNDCLASSEX wc = { 0 };
wc.cbSize = sizeof(wc);
wc.style = CS_OWNDC;
wc.lpfnWndProc = DefWindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = nullptr;
wc.hCursor = nullptr;
wc.hbrBackground = nullptr;
wc.lpszMenuName = nullptr;
wc.lpszClassName = pClassName;
wc.hIconSm = nullptr;
RegisterClassEx(&wc);
//create window instance
HWND hWnd = CreateWindowEx(
0,
pClassName,
L"Senko Interaction",
WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU,
0, 0, 1280, 720,
nullptr, nullptr, hInstance, nullptr
);
ShowWindow(hWnd, SW_SHOW);
//create message loop
MSG msg;
BOOL gResult;
while ((gResult = GetMessage(&msg, nullptr, 0, 0)) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if (gResult == -1)
{
return -1; //return -1
}
else
{
return msg.wParam; //return 0
}
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CLOSE:
PostQuitMessage(1);
break;
}
return DefWindowProc(hWnd, message, wParam, lParam); //return 1
}
You set your window class to use DefWindowProc() instead of WndProc() for the lpfnWndProc, so it makes sense why WndProc() is never called:
wc.lpfnWndProc = DefWindowProc; // WRONG
That should be:
wc.lpfnWndProc = WndProc; // CORRECT
I don't manage to display the label ( static control ) at the same time that the parent windows appears.
The label appears only in the main window if I move the window with the mouse.
Can you help me ?
This is the code :
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg, WPARAM keyPressed, LPARAM lParam)
{
switch (uMsg)
{
case WM_CREATE:
{
addControls(hwnd);
return 0;
}
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}
case WM_PAINT:
{
return 0;
}
default:
return DefWindowProc(hwnd, uMsg, keyPressed, lParam);
}
return 0;
}
void addControls(HWND hwnd)
{
hwndLabel = CreateWindowW(L"static", L"Choose a resolution:", WS_VISIBLE|WS_CHILD|SS_LEFT,10, 40, 250, 200,hwnd, NULL, NULL, NULL);
}
int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
HWND hwnd;
//HWND hwndParamWindow;
MSG msg;
WNDCLASS wc;
RECT rc;
GetWindowRect(GetDesktopWindow(), &rc);
HANDLE processHandle = GetCurrentProcess();
wc.style = 0;
wc.lpfnWndProc = MainWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hinstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(1 + COLOR_BTNFACE);
wc.lpszMenuName = NULL;
wc.lpszClassName = (LPCSTR)"WinClass";
if(!RegisterClass(&wc))
return FALSE;
hwnd = CreateWindowW(L"WinClass", L"title", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 200, 200, 900, 900, NULL, NULL, NULL, NULL);
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;
}
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.
I want to switch my win32 console application to graphics mode to use SetPixel function to draw lines:
#include "stdafx.h"
int _tmain(int argc, _TCHAR* argv[])
{
//code to switch to graphics mode
return 0;
}
please advice :)
Here's a fine SetPixel() example.
Create a win32 application project , paste the code and compile it
//header files to include
#include<windows.h>
#include<stdlib.h>
#include<time.h>
//application title
#define APPTITLE "Hello World"
//function prototypes (forward declarations)
BOOL InitInstance(HINSTANCE, int);
ATOM MyRegisterClass(HINSTANCE);
LRESULT CALLBACK WinProc(HWND, UINT, WPARAM, LPARAM);
//the window event callback function
LRESULT CALLBACK WinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
char *szHello = "SetPixel";
RECT rt;
int x=0, y=0, n=0;
COLORREF c;
int j;
switch (message)
{
case WM_PAINT:
//get the dimensions of the window
GetClientRect(hWnd, &rt);
//start drawing on devicce context
hdc = BeginPaint (hWnd, &ps);
//draw some text
DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER);
j = (rand()*100);
c = RGB(0, 0, 0);
while( x<25000)
{
SetPixel(hdc, rand()%400, rand()%400, rand()%255);
x++;
}
//stop drawing
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
//helper function to set up the window properties
ATOM MyRegisterClass(HINSTANCE hInstance)
{
//create the window class structure
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
//fill the struct with info
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)WinProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = APPTITLE;
wc.hIconSm = NULL;
//set up the window with the class info
return RegisterClassEx(&wc);
}
//helper function to create the window and refresh it
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
//create a new window
hWnd = CreateWindow(
APPTITLE, //window class
APPTITLE, //title bar
WS_OVERLAPPEDWINDOW, //window style
CW_USEDEFAULT, //x position of window
CW_USEDEFAULT, //y position of window
400, //width of the window
400, //height of the window
NULL, //parent window
NULL, //menu
hInstance, //application instance
NULL); //window parameters
//was there an error creating the window?
if(!hWnd)
return FALSE;
//display the window
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//entry point for a Windows program
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
//declare variables
MSG msg;
//register the class
MyRegisterClass(hInstance);
//initialize application
if(!InitInstance (hInstance, nCmdShow))
return FALSE;
//set random number seed
srand(time(NULL));
//main message loop
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
you can switch to "graphich mode" means to windows forms application mode using project setting. but you'll have to change the main function to winMain
PROJECT SETTINGS >
LINKER > SYSTEM > SUBSYSTEM > Windows (/SUBSYSTEM:WINDOWS)
C/C++ > PREPROCESSOR > PREPROCESSOR DEFINITIONS >
WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)
and this is how your function in this case should look:
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR lpCmdLine, int nCmdShow)
{
///....
}