Thread: Using class member functions to initialise a window

  1. #1
    Registered User
    Join Date
    Jan 2010
    Posts
    206

    Exclamation Using class member functions to initialise a window

    Hi there,

    I always thought (probably wrongly) that all the relevant stuff you declare for creating a window was done in the main .cpp file for the application.

    Recently however I've come across a very different way of doing it and it's raised a few questions. The project I'm referring to defines a base class and also a derived class. The base class's constructor initializes a HINSTANCE data member with the applications HINSTANCE. Like so:

    Code:
    class D3DApp
    {
        D3DApp(HINSTANCE hInstance);
        ....
        HINSTANCE mhAppInst = nullptr; // application instance handle
    }
    
    D3DApp::D3DApp(HINSTANCE hInstance)
    :mhAppInst(hInstance)
    {
        ....unrelated  code
    }
    The WinMain function makes an instance of that class and passes the HINSTANCE into it like so:

    Code:
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance,
    				   PSTR cmdLine, int showCmd)
    {
    try
        {
            BoxApp theApp(hInstance);
            if(!theApp.Initialize())
                return 0;        
        }
        .... 
    }
    BoxApp class is the derived class of the base class D3DApp. Has a few virtual functions in it (some of which are not re-defined) and some new functions too for solutions specific to a given demo, like this one which just shows a box on a screen.

    The derived class BoxApp then calls the base class's Initialize() function, which in turn calls the base class's InitMainWindow() function to register the window class and show the window, and of course also declare which function will handle the window messages:

    Code:
    bool D3DApp::InitMainWindow()
    {
        WNDCLASS wc;
        wc.lpfnWndProc   = MainWndProc; 
        wc.hInstance     = mhAppInst;
        wc.lpszClassName = L"MainWnd";
    
        ....other wc registering code not shown
    
        mhMainWnd = CreateWindow(L"MainWnd", MainWndCaption.c_str(),
                                                    WS_OVERLAPPEDWINDOW, 
                                                    CW_USEDEFAULT,
                                                    CW_USEDEFAULT,
                                                    width,
                                                    height, 0, 0, mhAppInst, 0); 
        if( !mhMainWnd )
        {
            MessageBox(0, L"CreateWindow Failed.", 0, 0);
    	return false;
        }
    
        ShowWindow(mhMainWnd, SW_SHOW);
        UpdateWindow(mhMainWnd);
    
        return true;
    }
    The MainWndProc() is defined in the .cpp file that includes the header file but isn't actually part of either the base or derived class (if that makes any difference).

    So it seems to me ultimately the only thing that really makes it as far as the part where the window is registered and shown, is the original HINSTANCE from the application that the class constructor set one of its data members to.

    Can you do that? I mean it does all work it just seems a bit unusual. I didn't realize windows was as tolerant as this when it comes to where you can register and create a window. So provided the HINSTANCE is good all the way through the process, then wherever and however you create the window it will still be bound to the original application's HINSTANCE and thus it works?

    Thanks
    Last edited by shrink_tubing; 10-11-2023 at 04:27 AM.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    > I always thought (probably wrongly) that all the relevant stuff you declare for creating a window was done in the main .cpp file for the application.
    There is nothing inherently special about main, other than it's the first thing in your program to be called.

    There's certainly no restriction saying that certain functions can only be called from main.

    > So provided the HINSTANCE is good all the way through the process, then wherever and however you create the window it will still be bound to the original application's HINSTANCE and thus it works?
    Well you create a class instance within main, which contains the instance.
    So naturally, the scope of 'theApp' persists for the duration of main (well the try block).

    So long as ultimately the right API functions get called in the right order, however you choose to organise the code doesn't matter.

    You can have a ball-of-mud 1000+ line main with everything inlined.
    You can have a 10-line main that bumps everything into a top-level class, from which other classes hang off of.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Jan 2010
    Posts
    206
    Ok! Hey thanks again Salem

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 5
    Last Post: 08-02-2017, 04:15 AM
  2. Help with Class Member Functions
    By JJohnson in forum C++ Programming
    Replies: 8
    Last Post: 05-08-2011, 12:11 PM
  3. Member functions as child window procedures
    By filler_bunny in forum Windows Programming
    Replies: 28
    Last Post: 03-15-2004, 09:45 AM
  4. Class member variables only readable by member functions?
    By _Elixia_ in forum C++ Programming
    Replies: 4
    Last Post: 10-10-2003, 03:52 PM
  5. DLL class member functions
    By nickname_changed in forum C++ Programming
    Replies: 1
    Last Post: 07-11-2003, 06:59 AM

Tags for this Thread