CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 4 of 4
  1. #1
    Join Date
    Oct 2005
    Location
    England
    Posts
    803

    Encapsulation of the Window

    Here's my window creation code.

    Code:
    #include <windows.h>
    
    // Declare WndProcedure
    
    
    
    
    LRESULT CALLBACK WndProcedure(HWND hWnd, UINT uMsg,
    			   WPARAM wParam, LPARAM lParam);
    
    INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine, int nCmdShow)
    {
    	MSG        Msg;
    	HWND       hWnd;
    	HRESULT	   hRet;
    	WNDCLASSEX WndClsEx;
    
    	// Populate the WNDCLASSEX structure
    	WndClsEx.cbSize        = sizeof(WNDCLASSEX);
    	WndClsEx.style         = CS_HREDRAW | CS_VREDRAW;
    	WndClsEx.lpfnWndProc   = WndProcedure;
    	WndClsEx.cbClsExtra    = 0;
    	WndClsEx.cbWndExtra    = 0;
    	WndClsEx.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    	WndClsEx.hCursor       = LoadCursor(NULL, IDC_ARROW);
    	WndClsEx.hbrBackground = (HBRUSH)(COLOR_HIGHLIGHT+1);//(HBRUSH)GetStockObject(WHITE_BRUSH);
    	WndClsEx.lpszMenuName  = NULL;
    	WndClsEx.lpszClassName = "MyWindow";
    	WndClsEx.hInstance     = hInstance;
    	WndClsEx.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);
    
    	
     /* COLOURS :)
    COLOR_ACTIVEBORDER
    COLOR_ACTIVECAPTION
    COLOR_APPWORKSPACE
    COLOR_BACKGROUND
    COLOR_BTNFACE
    COLOR_BTNSHADOW
    COLOR_BTNTEXT
    COLOR_CAPTIONTEXT
    COLOR_GRAYTEXT
    COLOR_HIGHLIGHT
    COLOR_HIGHLIGHTTEXT
    COLOR_INACTIVEBORDER
    COLOR_INACTIVECAPTION
    COLOR_MENU
    COLOR_MENUTEXT
    COLOR_SCROLLBAR
    COLOR_WINDOW
    COLOR_WINDOWFRAME
    COLOR_WINDOWTEXT 
    */
     
     
     
     // Register the class
    	RegisterClassEx(&WndClsEx);
    
    
    
    
    
    	// Create the window object
    	hWnd = CreateWindow("MyWindow",
    			  "Rich's Window",
    			  WS_OVERLAPPEDWINDOW,
    			  CW_USEDEFAULT,
    			  CW_USEDEFAULT,
    			  CW_USEDEFAULT,
    			  CW_USEDEFAULT,
    			  NULL,
    			  NULL,
    			  hInstance,
    			  NULL);
    			  
    
    
    
    
    			  
    			  
    	
    	// Verify window creation
    	if( !hWnd ) // If the window was not created,
    		return 0; // stop the application
    
    	// Show the window
    	ShowWindow(hWnd, SW_SHOWNORMAL);
    	UpdateWindow(hWnd);
    
    	//  message pump
    	while( (hRet = GetMessage( &Msg, NULL, 0, 0 )) != 0)
    	{ 
    		if (hRet == -1)
    		{
            // handle the error and possibly exit
    		}
    		else
    		{
    			TranslateMessage(&Msg); 
    			DispatchMessage(&Msg); 
    		}
    	}
    
    return 0;
    
    }
    
    
    
    LRESULT CALLBACK WndProcedure(HWND hWnd, UINT Msg,
    			   WPARAM wParam, LPARAM lParam)
    {
        switch(Msg)
        {
        case WM_DESTROY:
            // user wants to exit
            PostQuitMessage(WM_QUIT);
            break;
        default:
            // Hand off unprocessed messages to DefWindowProc
            return DefWindowProc(hWnd, Msg, wParam, lParam);
        }
        
        return 0;
    }
    I am unsure of how to put it in a class so I can create as many windows as i want in an application.

    -What do i do with the message handler? Do i declare it static
    -Once classed to i added member functions like set window caption, using sendmessage.

    A description of how to do it would be fantastic , i want to try and do as much myself, its the only way i learn.
    Rich

    Visual Studio 2010 Professional | Windows 7 (x64)
    Ubuntu

  2. #2
    Join Date
    Feb 2000
    Location
    San Diego, CA
    Posts
    10,354

    Re: Encapsulation of the Window

    If you add a class , then the minimum data you keep there would be the HWND. Now, once you have that and have a static wndproc, you have to find a way to get to the C++ object for a particular window and there are many ways to do it.

    One way is to make a framework where the framework maintains a mapping of HWNDs to the C++ objects. ( MFC style )
    Another way could be to , in case they are your own registered classes, to store the C++ object pointer as data for the window using SetWindowLong ( beware that if you overwrite this area ), it will be messy.

    You can come up with any other way..

  3. #3

    Re: Encapsulation of the Window

    Below is a simple implementation of a C++ encapsulation of the window process.

    It uses a window property (SetPropA, GetPropA) to store the window objects pointer. (Create all windows on the heap to be sure it's valid. Also, in WM_NCDESTROY, you can 'delete this' so when a window is destroyed the destructor gets called.

    Code:
    class Window
    {
    public:
        // Normal
    protected:
        HWND Handle;
        virtual INT_PTR WindowProcess(UINT message,WPARAM wParam,LPARAM lParam) throw();
    private:
        static INT_PTR __stdcall HandleWindowProcess(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) throw();
    };
    
    /////////////////////////////////////////////////////////////
    //// HandleWindowProcess
    
    INT_PTR __stdcall Window::HandleWindowProcess(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) throw()
    {
        // pass your this pointer as the last parameter to CreateWindowEx
        if (message == WM_NCCREATE)
        {
            LPCREATESTRUCT lpCreate = reinterpret_cast<LPCREATESTRUCT>(lParam);
    
            Window * pWindow = reinterpret_cast<Window *>(lpCreate->lpCreateParams);
            /* Comment out above line and uncomment the below for an MDI Child Window
    
            LPMDICREATESTRUCT lpMdiCreate = reinterpret_cast<LPMDICREATESTRUCT>(lpCreate->lpCreateParams);
            Window * pWindow = reinterpret_cast<Window *>(lpMdiCreate->lParam);
    
            */
    
            pWindow->Handle = hWnd;
    
            // Set a window property to store the window object pointer
            ::SetPropA(hWnd,"WindowObject",reinterpret_cast<HANDLE>(pWindow));
    
            return pWindow->WindowProcess(message,wParam,lParam);
        }
        else
        {
            // try to obtain a pointer to the window object
            Window * pWindow = reinterpret_cast<Window *>(::GetPropA(hWnd,"WindowObject"));
             if (pWindow != NULL)
             {
                 return pWindow->WindowProcess(message,wParam,lParam);
             }
             else
             {
                 // not a window object
                 return ::DefWindowProc(hWnd,message,wParam,lParam);
             }
        }
    }

  4. #4
    Join Date
    Oct 2005
    Location
    England
    Posts
    803

    Re: Encapsulation of the Window

    Thanks, I'll book mark this thread and give it a shot sometime soon.

    Hmm looking at james example maybe I should finish learning OPP for C++ first, I see type casting and throws, haven't looked at them yet.
    Rich

    Visual Studio 2010 Professional | Windows 7 (x64)
    Ubuntu

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured