How to start coding once you get WinMain working?

I'm creating a program using Dev-C++ with a WinMain function.

How do you link WinMain with main()?

Thank you for your help:)

#include <windows.h>

/* Declare Windows procedure */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

/* Make the class name into a global variable */
char szClassName[ ] = "WindowsApp";

int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nFunsterStil)

{
HWND hwnd; /* This is the handle for our window */
MSG messages; /* Here messages to the application are saved */
WNDCLASSEX wincl; /* Data structure for the windowclass */

/* The Window structure */
wincl.hInstance = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */
wincl.style = CS_DBLCLKS; /* Catch double-clicks */
wincl.cbSize = sizeof (WNDCLASSEX);

/* Use default icon and mouse-pointer */
wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL; /* No menu */
wincl.cbClsExtra = 0; /* No extra bytes after the window class */
wincl.cbWndExtra = 0; /* structure or the window instance */
/* Use Windows's default color as the background of the window */
wincl.hbrBackground = GetSysColorBrush(COLOR_3DFACE);

/* Register the window class, and if it fails quit the program */
if (!RegisterClassEx (&wincl))
return 0;

/* The class is registered, let's create the program*/
hwnd = CreateWindowEx (
0, /* Extended possibilites for variation */
szClassName, /* Classname */
"CPIC Criminal Record DataBase", /* Title Text */
WS_SYSMENU, /* default window */
CW_USEDEFAULT, /* Windows decides the position */
CW_USEDEFAULT, /* where the window ends up on the screen */
544, /* The programs width */
375, /* and height in pixels */
HWND_DESKTOP, /* The window is a child-window to desktop */
NULL, /* No menu */
hThisInstance, /* Program Instance handler */
NULL /* No Window Creation data */
);

/* Make the window visible on the screen */
ShowWindow (hwnd, nFunsterStil);

/* Run the message loop. It will run until GetMessage() returns 0 */
while (GetMessage (&messages, NULL, 0, 0))
{
/* Translate virtual-key messages into character messages */
TranslateMessage(&messages);
/* Send message to WindowProcedure */
DispatchMessage(&messages);
}

/* The program return-value is 0 - The value that PostQuitMessage() gave */
return messages.wParam;
}


/* This function is called by the Windows function DispatchMessage() */

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) /* handle the messages */
{
case WM_CREATE:{

HMENU hMenubar = CreateMenu();
HMENU hFile = CreateMenu();
HMENU hOption = CreateMenu();

AppendMenu(hMenubar, MF_POPUP, (UINT_PTR)hFile, "File");

AppendMenu(hMenubar, MF_POPUP, NULL, "Edit");
AppendMenu(hMenubar, MF_POPUP, (UINT_PTR)hOption, "Option");

//drop-down
AppendMenu(hFile, MF_STRING, NULL, "Exit");
AppendMenu(hOption, MF_STRING, NULL, "Option1");
AppendMenu(hOption, MF_STRING, NULL, "Option2");

SetMenu(hwnd, hMenubar);

break;

}

case WM_DESTROY:
PostQuitMessage (0); /* send a WM_QUIT to the message queue */
break;
default: /* for messages that we don't deal with */
return DefWindowProc (hwnd, message, wParam, lParam);
}

return 0;
}
Last edited on
WinMain is a replacement for main. Many different api's and libraries that deal with specific development environments utilize their own main functions to interact with the API's / libraries. With the windows API it's generally (Type definition (int usually)) (function call (winapi, winsocks, apientry, etc) and (WinMain).

You should take a look at some tutorials for working with the windows API, such as forgers. While it can be confusing and tedious to read through, it should at least give you enough of a basic understanding to slowly learn on your own with google/msdn resources.
Last edited on
May I make one suggestion... If you're doing anything in real-time (such as a game), you'll want to replace the message loop with something that lets you use your precious time wisely...

The evil brother
1
2
3
4
5
6
7
MSG msg;
while(GetMessage(&msg, NULL, 0, 0)){
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}
//Clean up any used resources
return 0;


GetMessage(...) is an evil function because it waits until a message is available, if your program has any graphic or any other intensive scripts to execute, they won't be run until this function get's a message and returns (which depending on what your programs for could be quite a while)

However it's wonderfly kind twin PeekMessage(...) will take a look to see if there's a message in the windows message queue, if there is you can execute what you need to, if not your program should continue to do it's stuff.

1
2
3
4
5
6
7
8
9
10
11
while(true){
    while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }//Will get messages until queue is clear
    if(msg == WM_QUIT)
        break;
    //Do a tick of any intensive stuff here such as graphics processing
}
//Clean up any used resources
return 0;


The PM_REMOVE macro tells PeekMessage(...) to remove messages once we've asked for them, other options are PM_NOREMOVE and PM_NOYIELD, there are also other macros defined by Microsoft that let you limit what kind of messages you want to receive, if you're curious then all the info on PeekMessage is at the MSDN.
http://msdn.microsoft.com/en-gb/library/windows/desktop/ms644943(v=vs.85).aspx
Last edited on
No! GetMessage() isn't evil. It's exactly what you need in the main thread of a windows program. PeekMessage() is almost always a cheap workaround. And the way it's used in SatsumaBenji example creates a lot of load on the system because the execution isn't handed back to the scheduler. Consider at least a Sleep(0); at the end of the outer while() loop.

But if you need a rendering loop create another thread with an endless loop and a nice Sleep(0); (at least 0) at the end of the loop to keep the load as low as possible.

If you want/have to control the thread there's plenty of possibilities (events, mutexes, critical sections) to do that.

Last edited on
Two things:

Neither GetMessage or PeekMessage themselves are Evil, they are the base for every windowed program.

But, talking about gaming:

You should either:
- Use GetMessage and SetTimer
or
- Use PeekMessage and your main() loop

Also @SatsumaBenji you have a little error there:

1
2
if(msg == WM_QUIT)
        break;

Should be
1
2
if(msg.message == WM_QUIT)
        break;



Also, instead of

while(GetMessage(&msg, NULL, 0, 0)) { /*...*/ }

It should be

while(GetMessage(&msg, NULL, 0, 0) > 0) { /*...*/ }

or

while(GetMessage(&msg, hwnd, 0, 0) > 0) { /*...*/ }


BUT
For this program:
USE GetMessage! DO NOT USE PeekMessage as it WASTES PERFORMANCE.

To the OP's problem:
Try changing your project's settings to a GUI project.

Also you should use code tags in a post where C++ code is involved, like:

[code]int a = 0; float b = 0.f;[/code]

becomes:
int a = 0; float b = 0.f;
Last edited on
I will start using code tags from now on :)) Thanks everyone :)!
Guys please, no sane programmer runs time critical code in the main thread of a GUI program.
Create another thread and control the timing by SetWaitableTimer() and WaitForSingleObject().

Actually I've seen some cases (which I can't remember offhand) where GetMessage or PeekMessage return negative values for errors... If you have my version of the code you should be able to handle any errors if you know what you're looking for...
But yeas I do suppose that if you're not going to check any errors or if you're new to the loop stuff then checking if the return is > 0 would be best.
SatsumaBenji wrote:
GetMessage or PeekMessage return negative values for errors

^ That.
Well I wasn't trying to contradict you there, I just thought I'd give a little extra info if the asker wanted to-do a little further research so he/she's got a good starting point.
And at the end I did say to use your method.
SatsumaBenji wrote:
Well I wasn't trying to contradict you there, I just thought I'd give a little extra info if the asker wanted to-do a little further research so he/she's got a good starting point.
And at the end I did say to use your method.

^ That.
:D

(Let me show you I didn't contradict you for the usage of PeekMessage. If you read you can clearly notice how I said that it's good for gaming, but not for casual programs. And I wasn't thinking of you being contraddicting me in that post: I was just quoting you, lol.)
Would this be considered a decent method for regulating cpu intensity?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int FRAME_LIMIT = 30;
int SINGLE_FRAME_LIMIT = 1 / FRAME_LIMIT;

float time1, time2 = 0;
while(true){
    frametime = floor((time2 - time1) / ((float)CLOCKS_PER_SEC * 1000));
    if(frameTime < SINGLE_FRAME_LIMIT)
        Sleep(SINGLE_FRAME_LIMIT - frameTime);
    time1 = (float)clock();
    while(PeekMessage(//args)){
        //Windows messages
    }
    if(msg.message == WM_QUIT)
        break;
    // Do gamey stuff here like graphics processing
    time2 = (float)clock();
}
Last edited on
I'm not sure about writing just an Yes or a No, it may still be good.
Anyways, if I'm about to program some time-sensitive operation, my solution could be like:

IF you were to use Sleep:
use Sleep(0) instead.

> A value of zero causes the thread to relinquish the remainder of its time slice to any other thread that is ready to run.

And, going into physics processing, you should use your Delta Time to handle speed-indipendent movement.

This breaks the need for a frame limited environment.

An example could be:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
DWORD LastTime = 0;
DWORD ThisTime = 0;
double ThisDelta = 0.0;
bool FirstIteration = 1;
while(1)
{
    /*
        PeekMessage stuff here
    */
    if(FirstIteration)
    {
        FirstIteration = 0;
        LastTime = GetTickCount();
    }
    else
    {
        ThisTime = GetTickCount();
        ThisDelta = double(ThisTime - LastTime) * 0.001; // Delta time in Seconds
        LastTime = ThisTime;
        /*
            Game stuff here
        */
    }
}


As an example, now, to constantly move an object 1 unit per second, you can simply put this in place of "Game stuff here" (declare required things):
LinearlyMovingObject += ThisDelta;
To move it TWO units per seconds,
LinearlyMovingObject += ThisDelta * 2.0;

It should be fairly simple, I hope I didn't mistake anything.

Sleep: http://msdn.microsoft.com/en-us/library/windows/desktop/ms686298(v=vs.85).aspx
GetTickCount: http://msdn.microsoft.com/en-us/library/windows/desktop/ms724408(v=vs.85).aspx
Last edited on
Thanks a lot... *takes note*
Topic archived. No new replies allowed.