Question

I can't seem to find this on msdn been searching for a bit (described below).

Please forgive the amount of code posted, I will paste in order. You can really skip most of it. But I just want to put it all out there so my request is clear.

Lets say I wanted to make a really simple MFC. So I have the following abstract and concrete classes (pasted below) that I want in my really crappy framework.

I am also assuming (though not implemented yet) that WinMain will call a users defined main function (like Qt). What do I need to do so I can reuse my code in every other small crappy Win32 program I try to write. To be more clear, I am wondering if I compile it into a DLL, or a Library. If so how do I go about doing this? How do you include a WinMain function in a DLL?

    #ifndef IAPPLICATION_H_
    #define IAPPLICATION_H_

    #include <Windows.h>

    namespace nApplication
    {
        class IController;
        class IWindow;

        class IApplication
        {
        public:
            virtual int Run( ) = 0;
            virtual HINSTANCE gethInstance( ) = 0;
            virtual int getnCmdShow( ) = 0;
            virtual IController* getMainControl( ) = 0;
        protected:
            IWindow *main_window;
            IController *main_control;
        private:
            virtual int MessageLoop() = 0;
        };
    }

    #endif /* IAPPLICATION */

-

    #ifndef APPLICATION_H_
    #define APPLICATION_H_

    #include <Windows.h>
    #include "IApplication.h"
    #include "IWindow.h"
    #include "IController.h"
    #include "Controller.h"

    namespace nApplication
    {
        class Application : public IApplication
        {
        public:
            Application( HINSTANCE hInstance, int nCmdShow );
            virtual ~Application( );
            virtual int Run( );
            virtual int getnCmdShow( ) { return mnCmdShow; }
            virtual HINSTANCE gethInstance( ) { return mhInstance; }
            virtual IController* getMainControl( ) { return main_control; }
        private:
            int mnCmdShow;
            HINSTANCE mhInstance;
            int MessageLoop();
            Application( Application &app );
            Application& operator= ( const Application &app );
        };

    }

    #endif /* IAPPLICATION */

-

    #include "Application.h"
    #include "MainWindow.h"

    namespace nApplication
    {
        Application::Application( HINSTANCE hInstance, int nCmdShow )
            : mhInstance( hInstance ), mnCmdShow( nCmdShow )
        {
        }

    Application::~Application( )
    {
    }


    int Application::Run( )
    {
        main_window = new MainWindow( this );
        main_control = new Controller( this );
        main_window->Init( );
        main_window->Display( );
        MessageLoop( );
        delete main_window;
        return 0;
    }

    int Application::MessageLoop()
    {
        MSG msg;

        while(GetMessage(&msg, NULL, 0, 0) != 0) 
        {
            TranslateMessage(&msg);


        DispatchMessage(&msg);
        }
        return (int)msg.wParam;
    }
}

-

    #ifndef IWINDOW_H_
    #define IWINDOW_H_

    #include <Windows.h>
    #include "IController.h"

    namespace nApplication
    {
        class IWindow
        {
        public:
            virtual void Init() = 0;
            virtual void Display( ) = 0;


    private:
    };
    }
    #endif /* IWINDOW_H_ */

-

    #ifndef MAINWINDOW_H_
    #define MAINWINDOW_H_

    #include <windows.h>
    #include "IWindow.h"
    #include "IController.h"
    #include "IApplication.h"

    namespace nApplication
    {
        class MainWindow : public IWindow
        {
        public:
            MainWindow( IApplication *iApp);
            ~MainWindow();
            void Init();
            void Display( );
        private:
            WNDCLASSEX wc;
            HWND hWnd;
            IApplication *iApp;
        };
    }

    #endif //MAINWINDOW_H_

-

    #include "MainWindow.h"

    namespace nApplication
    {
        namespace 
        {
            LRESULT CALLBACK MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
            {
                HDC hDC;
                PAINTSTRUCT ps;

                static IController *cntrl;
                cntrl = (IController*)::GetWindowLongPtr(hWnd, GWL_USERDATA);

                if(uMsg == WM_NCCREATE)
                {
                    cntrl = (IController*)(((CREATESTRUCT*)lParam)->lpCreateParams);
                    ::SetWindowLongPtr(hWnd, GWL_USERDATA, (LONG_PTR)cntrl);
                    cntrl->CheckStatus();
                    return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
                }

                switch(uMsg) 
                {
                    case WM_CREATE:
                    {
                    }
                    case WM_PAINT:
                    {            
                        hDC = BeginPaint( hWnd, &ps );
                        TextOut( hDC, 10, 10, TEXT("Hello, Windows!"), 15 );
                        EndPaint( hWnd, &ps );
                        return 0;
                    }
                    case WM_DESTROY:
                    {
                        PostQuitMessage( 0 );
                        return 0;
                    }
                    default:
                    {
                        return DefWindowProc( hWnd, uMsg, wParam, lParam );
                    }
                }
            }
        }

        MainWindow::MainWindow( IApplication* iApp ) : iApp( iApp )
        {
            wc.cbSize        = sizeof(WNDCLASSEX);
            wc.style         = 0;
            wc.lpfnWndProc   = MainWndProc;
            wc.cbClsExtra    = 0;
            wc.cbWndExtra    = 0;
            wc.hInstance     = iApp->gethInstance( );
            wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
            wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
            wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
            wc.lpszMenuName  = TEXT( "GenericAppMenu");
            wc.lpszClassName = TEXT( "myWindowClass" );
            wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);
        }

        MainWindow::~MainWindow()
        {
        }

        void MainWindow::Init()
        {
            if( !RegisterClassEx(&wc) )
            {
                MessageBox(NULL, TEXT( "Window Registration Failed!" ), TEXT( "Error!" ), MB_ICONEXCLAMATION | MB_OK);
                exit(0);
            }
        }

        void MainWindow::Display( )
        {
            hWnd = ::CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("myWindowClass"), 
            TEXT("The title of my window"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 
            240, 120, NULL, NULL, iApp->gethInstance( ), iApp->getMainControl( ) );

            if(hWnd == NULL)
            {
                ::MessageBox( NULL, TEXT( "Window Creation Failed!" ), 
                    TEXT( "Error!" ), MB_ICONEXCLAMATION | MB_OK );
                exit(0);
            }

        ::ShowWindow( hWnd, iApp->getnCmdShow( ) );
        ::UpdateWindow(hWnd);
    }
}

-

        #ifndef ICONTROLLER_H_
        #define ICONTROLLER_H_

        #include <windows.h>

        namespace nApplication
        {
            class IController
            {
            public:
                virtual int CheckStatus() = 0;
            };
    }

    #endif ICONTROLLER_H_

-

    #ifndef CONTROLLER_H_
    #define CONTROLLER_H_

    #include <windows.h>
    #include "IController.h"
    #include "IApplication.h"

    namespace nApplication
    {
        class Controller : public IController
        {
        public:
            Controller( IApplication *iApp );
            virtual ~Controller();
            virtual int CheckStatus();
        private:
            Controller( Controller &c );
            Controller& operator= ( Controller &c );
            IApplication *iApp;
        };
    }

    #endif //CONTROLLER_H_

-

    #include "Controller.h"

    namespace nApplication
    {
        Controller::Controller( IApplication *iApp ) : iApp( iApp )
        {

        }

        Controller::~Controller()
        {
        }

        int Controller::CheckStatus()
        {
            return 0;
        }
    }

-

#include <windows.h>
#include "Application.h"

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    nApplication::Application app( hInstance, nCmdShow );
    return app.Run( );
}

-

main.exe : main.cpp 
    cl /EHsc main.cpp Application.cpp Controller.cpp MainWindow.cpp user32.lib gdi32.lib
    del *.obj
#/link /SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup
Was it helpful?

Solution

If you are making a library, you don't have a WinMain, you have a DllMain for dynamic libraries, or nothing for static libraries.

In your case, you'd need to export all the classes functionality from your dll, then in any apps that use your library, you'd include the headers of your project and link to the .lib of the library, then have this in your app where you need the GUI functionality:

nApplication::Application app( hInstance, nCmdShow );
return app.Run( );

Of course this ignores all the side details like registering event callbacks and setup along those lines, however Qt is free and open source, you you might want to look into that before reinventing the wheel, or to help make your own wheel a little rounder.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top