1

我似乎在 msdn 上找不到这个一直在搜索(如下所述)。

请原谅发布的代码量,我将按顺序粘贴。你真的可以跳过大部分。但我只是想把它全部放在那里,这样我的要求就很清楚了。

假设我想做一个非常简单的 MFC。所以我有以下抽象和具体的类(粘贴在下面),我想要在我非常糟糕的框架中。

我还假设(尽管尚未实现)WinMain 将调用用户定义的主函数(如 Qt)。我需要做什么才能在我尝试编写的所有其他小的蹩脚 Win32 程序中重用我的代码。更清楚地说,我想知道是否将其编译为 DLL 或库。如果是这样,我该怎么做?如何在 DLL 中包含 WinMain 函数?

    #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
4

1 回答 1

1

如果你正在创建一个库,你没有WinMain,你有一个DllMain用于动态库的,或者没有用于静态库的。

在您的情况下,您需要从您的 dll 中导出所有类功能,然后在使用您的库的任何应用程序中,您将包含项目的标题并链接到.lib库的链接,然后在您的应用程序中使用它您需要 GUI 功能的地方:

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

当然,这忽略了所有的细节,比如注册事件回调和沿着这些线设置,但是Qt是免费和开源的,你可能想在重新发明轮子之前研究一下,或者帮助你自己的轮子更圆一点。

于 2011-08-18T10:49:50.610 回答