PDA

Click to See Complete Forum and Search --> : C/C++ - Simple Win32 App


BeholderOf
Sep 18th, 2003, 09:58 AM
This is just a simple setup for a simple win32 app. I didnt really do much explaining but i did include some comments on whats going on at a particular place. I will hopefully get a simple opengl tutorial up soon, building off this framework. If want a more in-depth explaination on how all this code works do a search on google.com.


#define WIN32_LEAN_AND_MEAN //cut down on windows

#include <windows.h> //our windows library


//================================================================================
//event handler
//the event handler processes messages from windows
//ex. Key Press,MouseMove, Close, ETC ...
//================================================================================

LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam, LPARAM lParam)
{

switch(message)
{
case WM_CLOSE:
PostQuitMessage(0); //send message to close program
return 0;
break;

}

return DefWindowProc(hwnd,message,wParam,lParam);
}

//================================================================================
//program entry point
//This is where the program actually starts
//We need to setup up a windows class then register it
//after you register it you can create your window
//================================================================================

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nShowCmd)
{
WNDCLASSEX winClass; //windows class
HWND hwnd; //windows handle
MSG msg; //message
bool done; //status of app

//window class structure
winClass.cbSize = sizeof(WNDCLASSEX);
winClass.style = CS_HREDRAW | CS_VREDRAW;
winClass.lpfnWndProc = WndProc;
winClass.cbClsExtra = 0;
winClass.cbWndExtra = 0;
winClass.hInstance = hInstance;
winClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
winClass.hCursor = LoadCursor(NULL,IDC_ARROW);
winClass.hbrBackground = NULL;
winClass.lpszMenuName = NULL;
winClass.lpszClassName = "MyClass";
winClass.hIconSm = LoadIcon(NULL, IDI_WINLOGO);

//register our windows class
if (!RegisterClassEx(&winClass))
return 0;

//once class is registered create window
hwnd = CreateWindowEx(NULL, //extended style
"MyClass", //class name
"Win32 App",//app name
WS_OVERLAPPEDWINDOW | WS_VISIBLE| //style
WS_SYSMENU | WS_CLIPCHILDREN |
WS_CLIPSIBLINGS,
100,100, //x y coordinates
400,400, //height and width
NULL, //handle to parent
NULL, //handle to menu
hInstance, //app instance
NULL); //no extra params

//check to see if hwnd failed or not
if (!hwnd)
return 0;

ShowWindow(hwnd,SW_SHOW); //show window
UpdateWindow(hwnd); //update the window

done = false; //start of loop
//================================================================================
//Message Loop
//This loop is specially setup for something like Directx/Opengl Render functions but it can but used for a normal app too
//================================================================================




while (!done)
{
PeekMessage(&msg,hwnd,NULL,NULL,PM_REMOVE);

if (msg.message == WM_QUIT)
{
done = true;
}
else
{
//do what you want
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}

parksie
Sep 18th, 2003, 01:02 PM
I thought PeekMessage returned immediately, using a return value to indicate the presence of a message in the queue.

From first looks this looks more suitable for a full-screen graphical program like a game, as you mentioned, but inefficient for a normal program.

Something like this could be more appropriate:while(GetMessage(&msg, hwnd, NULL, NULL) > 0) {
Translate...
Dispatch...
}GetMessage() returns 0 on WM_QUIT, and -1 on error. MSDN says:Warning

Because the return value can be nonzero, zero, or -1, avoid code like this:

while (GetMessage( lpMsg, hWnd, 0, 0)) ...

The possibility of a -1 return value means that such code can lead to fatal application errors. Instead, use code like this:

BOOL bRet;

while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)
{
if (bRet == -1)
{
// handle the error and possibly exit
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}I usually treat -1 or 0 as cause for quitting, however you may wish to attempt to correct any error states.

BeholderOf
Sep 18th, 2003, 02:22 PM
yea i should of mentioned that. thanks for letting me know.

Explaination(cause im bored):

PeekMessage() basically continues even if there is no message in the queue, perfect for functions like Rendering.

GetMessage() basically stalls your app until there is a message. So there would work, if like your app was event based.

Maven
Nov 4th, 2003, 06:12 PM
You might want to move a few things around.

Replace this:


done = false; //start of loop
//================================================================================
//Message Loop
//This loop is specially setup for something like Directx/Opengl Render functions but it can but used for a normal app too
//================================================================================




while (!done)
{
PeekMessage(&msg,hwnd,NULL,NULL,PM_REMOVE);

if (msg.message == WM_QUIT)
{
done = true;
}
else
{
//do what you want
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}



with This:


While (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

return msg.wParam;



And add this to your window proc function:


case WM_DESTROY:
PostQuitMessage(0);
return 0;



Good Day!