2011-08-18 19 views
1

我似乎無法找到這在msdn上搜索了一下(如下所述)。我個人的個人MFC

請原諒我貼的代碼量,我會按順序粘貼。你真的可以跳過大部分。但我只是想把它放在那裏,所以我的要求很明確。

可以說我想做一個非常簡單的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 

回答

1

如果你是一個圖書館,你沒有一個WinMain,你有一個動態庫,或者什麼都不爲靜態庫一個DllMain

對於您的情況,您需要使用DLL的所有類功能export,然後在任何使用您的庫的應用程序中,包含項目的標題並鏈接到庫的.lib,然後有這個在您的應用程序,你需要的GUI功能:

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

當然,這忽略了所有的側面細節,如沿着這些線路的註冊事件回調和設置,但是Qt是免費的,開源的,你可能會想在重新發明方向盤之前仔細研究一下,或者讓自己的方向盤變圓。

+0

我在Qt表單上有兩個線程來解決這個問題,那裏的成員說通過鏈接到類似於MFC的Qts DLL「包含」了WinMain。例如,請參閱http://developer.qt.nokia.com/forums/viewthread/8908/#51775最後幾篇文章。在我通過源代碼工作時,我仍然有點困惑。這是我正在嘗試理解的第一個開源項目。這是我做我所做事情的主要動機。 –

+0

@Matthew:Qt的工作原理與多平臺用戶界面dev有所不同:它使用'main'作爲程序入口點(在你的代碼中),但在widows上它會創建自己的僞「WinMain」 (儘管它實際上不需要,但它只需要確保沒有控制檯被創建,如果沒有請求) – Necrolis

+0

我現在有兩個相互衝突的解釋。我知道#/ link/SUBSYSTEM:WINDOWS/ENTRY:nmake Makefile中的mainCRTStartup允許你在非控制檯應用程序中指定入口點爲main()。但是,當你設置你的WndClassEx時,你需要一個hInstance,如果你使用main,這個hInstance是不提供的。沒有其他方法可以創建窗口。另外,如果你在Qt中查看源代碼,你會發現WinMain實際上調用了你的主函數。所以main不是程序的入口點,它只是非Windows程序員的習慣。這不是在linux中被稱爲條目。 –