Stuck with WIN32 API

Started by
28 comments, last by Aardvajk 17 years, 4 months ago
Basiaclly the assigment is as follows I need to make a Console prompt where the entire program starts up with. Then whenever the user wants a additional window he just presses 1 or types in new window where a Window starts up that basically renders a scene on the screen. The idea is basically that the Kernel.cpp is capable of running a infinite amount of windows on the screen in either DirectX or OPENGL.

If you close the console though the entire program should close. The idea is that basically your making multiple windows which can be rendering a completly different scene, or the same one, albeit in DirectX and OpenGL.

Advertisement
As EasilyConfused points out, if you're to have one WndProc for all the windows (and this really is the easiest way), you'll need a way to determine the windows from each other.

I achieve this by having a static map of HWNDs to pointers-to-windows, so my WndProc can iterate through the whole list of HWNDs, find the window it belongs to, and call the appropriate function.
[ search: google ][ programming: msdn | boost | opengl ][ languages: nihongo ]
but if you make it a static map wouldn't that mean you are restricting the amount of windows you can generate?

Not at all. If you take your existing WindowManager which maintains a list of Window classes, you can just do:

psuedocode
int WndProc(HWND Hw,MSG M,etc){    for_each(Window W in List)        {        if(W.Hw==Hw) W.OnMessage(M);        }}
hmmm ok, but how would I create the windows and then put it all in a message queue? as I assume each window still needs its own emssage queue then? and the linke dlist would basically not be neccesary anymore?
Each window has its own message queue, maintained by the OS behind the scenes. However, your program only has one message loop regardless of how many windows there are.

When you call DispatchMessage(), Windows takes care of making sure that the message is sent to the correct WndProc for the window whose message it is.

I think that is what you were asking, anyway.
allright, well I need to head to my parents,when I am there i will plug in my laptop and try to code what has been suggested although I have tro admit it sounds complicated. So basically all I have to do is keep track of each WNDPROC its memory address in a linked list for example?

So whenever I make a new WNDPROC class i just need to make sure before I register it that its assigned into the linked list so I can loop it through in the Messageloop?

Quote:Original post by wijnand
allright, well I need to head to my parents,when I am there i will plug in my laptop and try to code what has been suggested although I have tro admit it sounds complicated. So basically all I have to do is keep track of each WNDPROC its memory address in a linked list for example?

So whenever I make a new WNDPROC class i just need to make sure before I register it that its assigned into the linked list so I can loop it through in the Messageloop?


Sorry. Didn't understand a word of that.

What is being suggested is that you could use the same WNDCLASSEX and the same WndProc for all the windows that you create. When you create a window, you thread it into a list of Window classes, as you do at the moment in your WindowManager's list.

You need this list to be statically visible to the WndProc function that you use, either by declaring a static WindowManager or having the WindowManager class use a static list outside of it.

Your WndProc can then go through this list, and compare the HWND first parameter to the HWND's stored for each Window class (again, you are already storing these).

When a match is found, you then know within the WndProc which of the windows the message is intended for and you can act upon it accordingly.

So, for a very simple, incomplete and bad example:

class Window{public:    Window(){ Hw=CreateWindow(...); }    int OnMessage(MSG M){ /* perform processing specific to the window */ }    HWND Hw;};std::list<Window*> Ws;class WindowManager{public:    void AddWindow(){ Ws.push_back(new Window()); }};int GeneralWndProc(HWND H,MSG M,etc){    std::list<Window*>::iterator i=Ws.begin();    while(i!=Ws.end())        {        if(i.Hw==H) return i.OnMessage(M);        ++i;        }    return 0;}int WinMain(){    WNDCLASSEX Ws;    // regsiter ONE window class here    WindowManager Wm;    Wm.AddWindow();    Wm.AddWindow();    while(true)       {       // Message loop       }    return 0;}


With the above, as a message is dispatched to the WndProc for a given window, the loop in the WndProc identifies which of your Window classes corresponds to the window being sent the message, then calls that Window's specific OnMessage member function, rather than processing the message for all the windows.
Bleh Sometimes I just type too fast for my own good when I am in a hurry ;)

Basically my question was if i should put each WNDPROC I declare in the linked lost for it to keep track of everything, but i noticed you made a example for me to read. Sadly I had a lot of delays, hopefully I will be able to take a peek at it now.

I am assuming that the Messageloop gets handled by the WINDOW_MANAGER and that I do not leave any of it in the Window.cpp. Is it actually possible to make a console before a Windows program runs? I managed to get a messagebox to display but I will have to take look.

Thank you for all your help so far Easilyconfused, I already rated you wish i could do it again ;)

Wijnand
Quote:Original post by wijnand
Is it actually possible to make a console before a Windows program runs? I managed to get a messagebox to display but I will have to take look.


Yeah. I think (from memory) you just do

#include <windows.h>int main(int,const char **av){    HINSTANCE HIn=GetModuleHandle(NULL);    // now you have the HINSTANCE and can proceed as if this were a WinMain}


You need to compile as a console application as well, rather than a Windows application, so the linker looks for main instead of WinMain as the entry point and the OS will create a console at start up.

Obviously you'll get a console appearing before any of your windows, but this sounds like what you want in this case. You can get rid of the console later on with FreeConsole() if you want.

[EDIT]

Alternatively, you can just start with a WinMain as usual, but just call:

AllocConsole();

at the start. Sorry. Should have suggested that first. Getting too complicated.

This topic is closed to new replies.

Advertisement