Thread: processing window messages w/out DispatchMessage ()

  1. #1
    Registered User
    Join Date
    Mar 2006
    Posts
    150

    processing window messages w/out DispatchMessage ()

    I was wondering if it is possible to dispatch messages using the UINT message parameter of the MSG structure to avoid having to use a window procedure to do the processing. Something like:

    Code:
    while (GetMessage (&Msg, NULL, 0, 0))
    {
      TranslateMessage (&Msg);
    
      if (Msg.message == WM_CLOSE)
       PostQuitMessage (0);
    }
    if it is, how can i do it?
    HA! I WIN!

  2. #2
    Work in Progress..... Jaken Veina's Avatar
    Join Date
    Mar 2005
    Location
    Missouri. Go Imos Pizza!
    Posts
    256
    It's certainly possible, yes. Whether or not you want to do it depends on the type of program you're writing. If your program uses just a single window, for example, there's really no difference between doing all your message processing in a Window Procedure or in the message loop itself. I'm pretty sure DispatchMessage() is the only function that actually calls a Window's Procedure, so you could probably even get away with setting the WndProc value to NULL, although, I'm not completely sure about that. If you do so and crash, that's probably why. Now that I think about it, it would probably be better to just set it to DefWindowProc.

    In any application, it really makes no difference. With the proper code, you could handle all the messages from all windows within a single big switch() structure, but then you get into needing to worry about telling different windows apart. Using separate Window Procedure functions, which are called separately, eliminates the need to tell windows apart, abstracting the process. It makes it very easy, for example, to run and managed multiple instances of the same window.

    It also makes for much neater code, to have each window's decision tree within a separate function, and most programmers like that kind of neat design.

    If you're only processing a couple messages, though, that would probably be a good case to do all message processing from within the message loop itself. There's nothing to say you can't. It might also be a good idea to move just some of the more general processing out of the Window Procedures. It all depends on your program, and your own style, too, I suppose.
    Code:
    void function(void)
     {
      function();
     }

  3. #3
    Registered User
    Join Date
    Mar 2006
    Posts
    150
    For some reason when I try to capture the events like that, it doesnt process right. It wont, for instance, end the program for some reason.
    HA! I WIN!

  4. #4
    Work in Progress..... Jaken Veina's Avatar
    Join Date
    Mar 2005
    Location
    Missouri. Go Imos Pizza!
    Posts
    256
    Well, the program ends when you tell it to end. Generally, the idea is to end the program on WM_QUIT, which translates to
    Code:
    if(GetMessage(&Msg, NULL, 0, 0) > 0)
    And the message is usually generated by
    Code:
    PostQuitMessage(0);
    Code:
    void function(void)
     {
      function();
     }

  5. #5
    Registered User
    Join Date
    Mar 2006
    Posts
    150
    Here's the exact code that I'm using for the loop:

    Code:
    while (GetMessage(&Msg, NULL, 0, 0) != 0)
     {
    	 if (Msg.message == 273)
    		 MessageBox (NULL, "Hi", "Guys", MB_OK);
    
    	 TranslateMessage (&Msg);
    	 DispatchMessage  (&Msg);
     }
    See, I still want the window procedures that I do have to capture events and process them, but i want to be able to modify variables within main () or a class from within the window procedure. is there any way to pass data into and out of the window procedure without externs?
    HA! I WIN!

  6. #6
    Work in Progress..... Jaken Veina's Avatar
    Join Date
    Mar 2005
    Location
    Missouri. Go Imos Pizza!
    Posts
    256
    So, you want to add more data/parameters to messages before they get passed to the Window Procedures?
    Code:
    void function(void)
     {
      function();
     }

  7. #7
    Registered User
    Join Date
    Mar 2006
    Posts
    150
    No, not to the messages... I'm trying to write classes to make windows gui easier for me to work with. Here is the library i have designed so far. Its a work in progress, and alot of it is REALLY sloppy and nowhere near finished, so dont judge my code too harshly!

    Code:
    #ifndef WINDOW_CLASSES_H
    #define WINDOW_CLASSES_H
    
    #include <windows.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    LRESULT CALLBACK Default (HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
    {
    	return 0;
    }
    
    HWND defaultWnd;
    HINSTANCE instance;
    WNDCLASSEX wc;
    
    int InitWindowClasses (HINSTANCE progInstance)
    {
     instance = progInstance;
    
     wc.cbSize        = sizeof(WNDCLASSEX);
     wc.style         = 0;
     wc.lpfnWndProc   = Default;
     wc.cbClsExtra    = 0;
     wc.cbWndExtra    = 0;
     wc.hInstance     = progInstance;
     wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
     wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
     wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND+15);
     wc.lpszMenuName  = NULL;
     wc.lpszClassName = "WindowClass";
     wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);
    
     return 0;
    }
    
    class WINDOW
    {
     private:
      
      HWND *controls;
      HWND winCreated;
      int index, count;
      bool firstControl;
    
     public:
    
      int MakeWindow (const char *WinTitle, int xPos, int yPos, int xSize, int ySize, WNDPROC wndproc)
      {
    	wc.lpfnWndProc = wndproc;
    	if (!RegisterClassEx (&wc))
    		return -1;
       
       winCreated = CreateWindow (
                    "WindowClass",
    	            WinTitle,
    	            WS_OVERLAPPEDWINDOW,
    	            xPos,
    	            yPos,
    	            xSize,
    	            ySize,
    	            NULL,
    	            NULL,
    	            instance,
    	            NULL);
       index = 0;
       count = 1;
       controls = (HWND *) malloc (1);
       firstControl = true;
    
       UnregisterClass ("WindowClass", instance);
    
       return 0;
      }
      int  AddButton (const char *ButtonText, int xPos, int yPos, int xSize, int ySize, int id)
      {
       HWND button;
       HWND *temp;
    
       button = CreateWindow (
                "BUTTON",
    	        ButtonText,
    	        WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
    	        xPos,
    	        yPos,
    	        xSize,
    	        ySize,
    	        winCreated,
                (HMENU) id,
    	        instance,
    	        NULL);
    
       controls[index] = button;
       ++index;
       ++count;
       temp = (HWND *) realloc (controls, count * sizeof (HWND));
       if (temp == NULL)
       {
        return -1;
       }
       controls = temp;
       return 0;
      }
      int  AddTextBox     (const char *starttext, int xPos, int yPos, int xSize, int ySize, int id)
      {
       HWND textbox;
       HWND *temp;
    
       textbox = CreateWindow (
                "EDIT",
    	        starttext,
    	        WS_CHILD | WS_VISIBLE | WS_BORDER |ES_AUTOHSCROLL | WS_GROUP | WS_TABSTOP,
    	        xPos,
    	        yPos,
    	        xSize,
    	        ySize,
    	        winCreated,
                (HMENU) id,
    	        instance,
    	        NULL);
    
       controls[index] = textbox;
       ++index;
       ++count;
       temp = (HWND *) realloc (controls, count * sizeof (HWND));
       if (temp == NULL)
       {
        return -1;
       }
       controls = temp;
       return 0;
      }
      int  AddComboBox    (const char *data[], int arrayItems, int xPos, int yPos, int xSize, int ySize, int id)
      {
       HWND combobox;
       HWND *temp;
    
       combobox = CreateWindow (
                "COMBOBOX",
    	        "",
    	        WS_CHILD | WS_VISIBLE | WS_VSCROLL | CBS_HASSTRINGS | CBS_DROPDOWNLIST | WS_TABSTOP,
    	        xPos,
    	        yPos,
    	        xSize,
    	        ySize,
    	        winCreated,
                (HMENU) id,
    	        instance,
    	        NULL);
    
       for (int added = 0; added < arrayItems; added++)
       {
        SendMessage (combobox, CB_ADDSTRING, 0, (LPARAM) data[added]);
       }
    
       controls[index] = combobox;
       ++index;
       ++count;
       temp = (HWND *) realloc (controls, count * sizeof (HWND));
       if (temp == NULL)
       {
        return -1;
       }
       controls = temp;
       return 0;
      }
      int  AddStaticText  (const char *text, int xPos, int yPos, int xSize, int ySize, int id)
      {
       HWND statictext;
       HWND *temp;
    
       statictext = CreateWindow (
                "STATIC",
    	        text,
    	        WS_CHILD | WS_VISIBLE,
    	        xPos,
    	        yPos,
    	        xSize,
    	        ySize,
    	        winCreated,
                (HMENU) id,
    	        instance,
    	        NULL);
    
       controls[index] = statictext;
       ++index;
       ++count;
       temp = (HWND *) realloc (controls, count * sizeof (HWND));
       if (temp == NULL)
       {
        return -1;
       }
       controls = temp;
       return 0;
      }
      void visible (int show)
      {
       ShowWindow (winCreated, show);
       UpdateWindow (winCreated);
      }
      HWND GetHandle (void)
      {
       return winCreated;
      }
      int destroy ()
      {
       while (index >= 0)
       {
        DestroyWindow (controls[index]);
        --index;
       }
       DestroyWindow (winCreated);
      }
    };
    
    #endif
    that is the class so far, and believe it or not, it actually works. Now, here is what i want to add to it. I want to make it so that in the main loop you can do something like:

    Code:
    #define BUT_1 0x100
    #define BUT_2 0x200
    
    int main ()
    {
     Window Win1;
    
     Win1.MakeWindow ("Test", 10, 10, 10, 10); 
     Win1.AddButton     ("Hi", 5, 5, 5, 5, BUT_1);
     Win1.AddButton     ("Exit", 10, 10, 5, 5, BUT_2);
    
     while (GetMessage (&msg, NULL, 0, 0))
     {
      if (Win1.ButtonPressed (BUT_1))
        MessageBox (NULL, "Hi", "All", MB_OK;
    
      else if (Win1.ButtonPressed (BUT_2))
        PostQuitMessage (0);
     }
    }
    I have too many thoughts chasing in my head to think clearly on this one. if you can steer me in the right direction, i would be very appreciative. i know there are open source libraries for this sort of thing, but i would really like to do it myself and i know that my code is very inefficient at this point, but i need a guiding hand. I figured on doing something like making variables within the class that track the events, but i just cant work out how it's all going to work for some reason. i hit a mental block here
    Last edited by xixpsychoxix; 01-17-2009 at 08:04 PM. Reason: realized a few errors
    HA! I WIN!

  8. #8
    'Allo, 'Allo, Allo
    Join Date
    Apr 2008
    Posts
    639
    The general way its done is to add the class pointer into the windows' user data area which your dummy WndProc retrieves to call the class's WndProc. It's explained here, along with other design details: Creating a Win32 Window Wrapper Class

  9. #9
    Registered User
    Join Date
    Mar 2006
    Posts
    150
    Thanks for the link. its really helpful. im gonna go ahead and read this and see what i can learn, but expect me back!!!
    HA! I WIN!

  10. #10
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,195
    Quote Originally Posted by Jaken Veina View Post
    Well, the program ends when you tell it to end. Generally, the idea is to end the program on WM_QUIT, which translates to
    Code:
    if(GetMessage(&Msg, NULL, 0, 0) > 0)
    And the message is usually generated by
    Code:
    PostQuitMessage(0);
    WM_QUIT
    WM_CLOSE

    there are a few others as well, particularly with WM_DESTROY on single window apps.

  11. #11
    Registered User
    Join Date
    Mar 2006
    Posts
    150
    Umm... this tutorial completely confuses me. Is the class i have made already a good start towards what im working to? I'm really not quite sure if what i have is worth anything in a good sense, i just wanted to wrap the Win32 GUI in a way that I could make a fast GUI program. Can anyone give me any advice as to what i should be working towards? Or should i just scrap this class and start over?
    HA! I WIN!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. creating a child window
    By rakan in forum Windows Programming
    Replies: 2
    Last Post: 01-23-2007, 03:22 PM
  2. Button positioning
    By Lionmane in forum Windows Programming
    Replies: 76
    Last Post: 10-21-2005, 05:22 AM
  3. Adding colour & bmps to a Win 32 Window??
    By carey_sizer in forum Windows Programming
    Replies: 4
    Last Post: 09-04-2004, 05:55 PM
  4. Edit controls not sending messages to parent window
    By EMiller in forum Windows Programming
    Replies: 5
    Last Post: 11-13-2001, 11:03 PM