Мой личный МФЦ - PullRequest
       51

Мой личный МФЦ

1 голос
/ 18 августа 2011

Я не могу найти это на msdn, который искал немного (описано ниже).

Пожалуйста, прости количество отправленного кода, я буду вставлять по порядку.Вы можете пропустить большую часть этого.Но я просто хочу изложить все это, чтобы мой запрос был ясен.

Допустим, я хотел сделать действительно простой MFC.Таким образом, у меня есть следующие абстрактные и конкретные классы (вставленные ниже), которые я хочу в моей действительно дрянной структуре.

Я также предполагаю (хотя и не реализовал), что WinMain будет вызывать пользовательскую основную функцию (например, Qt).Что мне нужно сделать, чтобы я мог повторно использовать свой код в любой другой маленькой дрянной Win32-программе, которую я пытаюсь написать.Чтобы быть более понятным, мне интересно, если я скомпилирую его в DLL или библиотеку.Если да, то как мне это сделать?Как включить функцию WinMain в 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

1 Ответ

1 голос
/ 18 августа 2011

Если вы делаете библиотеку, у вас нет WinMain, у вас есть DllMain для динамических библиотек или ничего для статических библиотек.

В вашем случае вам нужно экспортировать все функциональные возможности классов из вашей dll, а затем во всех приложениях, которые используют вашу библиотеку, вы должны будете включить заголовки вашего проекта и ссылку на .lib библиотеки, затем добавьте это в свое приложение, где вам нужна функциональность графического интерфейса:

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

Конечно, при этом игнорируются все дополнительные детали, такие как регистрация обратных вызовов событий и настройка по этим линиям, однако Qt является бесплатным и открытым исходным кодом, вам может понадобиться изучить это, прежде чем изобретать велосипед, или помогите сделать свое колесо немного круглее.

...