Click here to Skip to main content
6,595,854 members and growing! (17,880 online)
Email Password   helpLost your password?
Platforms, Frameworks & Libraries » Win32/64 SDK & OS » General     Intermediate

A Simple Win32 Window Wrapper Class

By Jason Henderson

How to make a Win32 application object oriented, without using MFC.
VC6, VC7Win2K, WinXP, Dev
Posted:10 Jul 2002
Updated:11 Jul 2002
Views:107,504
Bookmarked:36 times
Announcements
Loading...
 
Search    
Advanced Search
Add to IE Search
printPrint   add Share
      Discuss Discuss   Broken Article?Report  
35 votes for this article.
Popularity: 6.04 Rating: 3.91 out of 5
3 votes, 10.0%
1

2
1 vote, 3.3%
3
4 votes, 13.3%
4
22 votes, 73.3%
5

Introduction

I like object-oriented programming. In my professional C++ career, I have used nothing but MFC. So, when I want to make a good ole' fashioned Win32/SDK application, I cringe at the thought of not using the OO paradigm. If you're like me and you want to get away from the old C programming style, here is some code that will help you write your own window wrapper class.

Where are all of the examples?

It's nearly impossible to find good examples of a window wrapper class. None of my game development books have one. None of my general Windows programming books do either. Conducting a Google search only gave me one good example, Creating a Win32 Window Wrapper Class. You would think more people would be doing this. Unfortunately, there aren't more examples because its not easy to get it working.

The main problem

When you create a WNDCLASSEX structure you need to give the structure a pointer to your window procedure in the lpfnWndProc member. The window procedure is a callback, a special kind of function called directly by Windows when needed.

To make callbacks work correctly, strict typedefs are defined in the Windows header files. If you try to use a class member as a callback, the compiler will give you an error, saying that the member prototype does not match the required typedef.

The solution

To get around this compiler error, we need to make the window procedure static. From this static method we then call another method of the class to actually handle the messages.

To call the message handler of the correct window, we need to get the pointer of the window class using the SetWindowLong and GetWindowLong API functions. We send the this pointer to the window procedure via the CreateWindow function's LPVOID lpParam // window-creation data parameter.

When the WM_NCCREATE message is received, the window procedure sets the window long value to the pointer and is then able to call the correct message handler.

class CBaseWindow
{
public:
    // there are more members and methods

    // but you can look at the code to see them


    // static message handler to put in WNDCLASSEX structure

    static LRESULT CALLBACK stWinMsgHandler(HWND hwnd, 
                UINT uMsg, WPARAM wParam, LPARAM lParam);
protected:
    // the real message handler

    virtual LRESULT CALLBACK WinMsgHandler(HWND hwnd, 
                UINT uMsg, WPARAM wParam, LPARAM lParam)=0;

    // returns a pointer the window (stored as the WindowLong)

    inline static CBaseWindow *GetObjectFromWindow(HWND hWnd)
    {
        return (CBaseWindow *)GetWindowLong(hWnd, GWL_USERDATA);
    }
};

LRESULT CALLBACK CBaseWindow::stWinMsgHandler(HWND hwnd, 
                   UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    CBaseWindow* pWnd;

    if (uMsg == WM_NCCREATE)
    {
        // get the pointer to the window from

        // lpCreateParams which was set in CreateWindow

        SetWindowLong(hwnd, GWL_USERDATA, 
           (long)((LPCREATESTRUCT(lParam))->lpCreateParams));
    }

    // get the pointer to the window

    pWnd = GetObjectFromWindow(hwnd);

    // if we have the pointer, go to the message handler of the window

    // else, use DefWindowProc

    if (pWnd)
        return pWnd->WinMsgHandler(hwnd, uMsg, wParam, lParam);
    else
        return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

BOOL CBaseWindow::Create(DWORD dwStyles, RECT* rect)
{ 
    // Create the window


    // send the this pointer as the window creation parameter

    m_hwnd = CreateWindow(szClassName, szWindowTitle, dwStyles, 
        rect->left, rect->top, rect->right - rect->left, 
        rect->bottom - rect->top, NULL, NULL, hInstance, 
        (void *)this);

    return (m_hwnd != NULL);
}

Conclusion

Although, the demo (and source) is a very simple and crude example of what you can do with a window wrapper class, I hope it will help make your Win32 programming projects easier to understand and your code more reusable.

If you can find more information on this subject, I would gladly add a links section to the article.

Credit where credit is due

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Jason Henderson


Member
I live in the middle of nowhere in Illinois, United States, and I am married and have three kids (all boys).
Occupation: Software Developer (Senior)
Location: United States United States

Other popular Win32/64 SDK & OS articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 25 of 40 (Total in Forum: 40) (Refresh)FirstPrevNext
Generalwhat are you.. 12 ?? Pinmembertrinium12:41 2 Aug '06  
GeneralRe: what are you.. 12 ?? PinmemberJason Henderson18:05 2 Aug '06  
GeneralRe: what are you.. 12 ?? PinmemberDavid Nash22:52 15 Sep '07  
GeneralWhy MS did'nt do it that way? PinmemberPolite Programmer2:03 2 Aug '06  
GeneralGood idea PinmemberPerry Zh0:05 12 Jul '05  
GeneralExcellent PinmemberDavid Nash19:08 15 Feb '05  
GeneralRe: Excellent PinmemberJason Henderson4:29 16 Feb '05  
GeneralOops PinmemberDavid Nash15:03 1 May '05  
GeneralOff Topic : This is really sick ! PinmemberTomKat0:27 20 Dec '04  
GeneralYou are the sick one... PinmemberJason Henderson3:40 20 Dec '04  
GeneralRe: You are the sick one... PinmemberTomKat7:34 20 Dec '04  
GeneralRe: You are the sick one... PinmemberJason Henderson7:54 20 Dec '04  
Generalmy project Pinmembermehdic++1:05 18 Jul '04  
GeneralWont Compile, Cant get it to work PinmemberdrunkenZim11:15 2 May '04  
GeneralRe: Wont Compile, Cant get it to work PinmemberJason Henderson20:01 2 May '04  
GeneralRe: Wont Compile, Cant get it to work PinmemberJason Henderson20:06 2 May '04  
GeneralRe: Wont Compile, Cant get it to work PinmemberdrunkenZim21:52 2 May '04  
GeneralRe: Wont Compile, Cant get it to work PinmemberJason Henderson3:39 3 May '04  
GeneralRe: Wont Compile, Cant get it to work PinmemberLonelyTower22:01 12 May '05  
GeneralMDI error!!!! Pinmembermzmzmz18:43 12 Mar '04  
Generalvery fine Pinmemberskaanji15:43 10 Oct '03  
Generalexactly what I needed! PinmemberScott Miller14:57 6 Jun '03  
GeneralRe: exactly what I needed! PinmemberJason Henderson17:47 6 Jun '03  
GeneralRe: exactly what I needed! PinmemberGroba3:49 10 Oct '06  
Generalgrreat stuff, I got it working but... PinmemberGnosticMan13:32 4 Mar '03  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 11 Jul 2002
Editor: Smitha Vijayan
Copyright 2002 by Jason Henderson
Everything else Copyright © CodeProject, 1999-2009
Web21 | Advertise on the Code Project