2013-03-10 114 views
1

我下面MSDN上的教程:http://msdn.microsoft.com/en-us/library/windows/desktop/ff381400(v=vs.85).aspx純虛擬方法調用,終止

它展示瞭如何使一個類中WINAPI創建窗口。

我做了與他們完全相同的事情,除了我把創造代碼放在構造函數中。

運行時,它會給出純虛擬方法,稱爲錯誤,並終止沒有解釋的程序。

template<typename T> 
class Form 
{ 
    public: 
     Form(std::string Title, std::string Class, /*All other params*/); 

    private: 
     static LRESULT __stdcall WindowProcedure(HWND Hwnd, UINT Msg, WPARAM wParam, LPARAM lParam); 

    protected: 
     HWND WindowHandle = nullptr; 
     virtual LRESULT HandleMessages(UINT Msg, WPARAM wParam, LPARAM lParam) = 0; 
}; 



template<typename T> 
Form<T>::Form(std::string Title, std::string Class, /*All Other Params*/) 
{ 
    WNDCLASSEX WndClass = {/*Filled in with other params*/}; 

    RegisterClassEx(&WndClass); 
    WindowHandle = CreateWindowEx(/*Other params*/, this); 
} 

template<typename T> 
LRESULT __stdcall Form<T>::WindowProcedure(HWND Hwnd, UINT Msg, WPARAM wParam, LPARAM lParam) 
{ 
    T* Data = nullptr; 

    switch (Msg) 
    { 
     case WM_NCCREATE: 
     { 
      CREATESTRUCT* pCreate = (CREATESTRUCT*)lParam; 
      Data = reinterpret_cast<T*>(pCreate->lpCreateParams); 
      SetWindowLongPtr(Hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(Data)); 
      break; 
     } 

     default: 
     { 
      Data = reinterpret_cast<T*>(GetWindowLongPtr(Hwnd, GWLP_USERDATA)); 
      return Data ? Data->HandleMessages(Msg, wParam, lParam) : DefWindowProc(Hwnd, Msg, wParam, lParam); 
     } 
    } 
    return 0; 
} 

那麼我的主要窗口:

class MainWindow : public Form<MainWindow> 
{ 
    public: 
     MainWindow(std::string Title, /*Other params*/); 
     LRESULT HandleMessages(UINT Msg, WPARAM wParam, LPARAM lParam); 

     HWND WindowHandle() {return Form::WindowHandle;} 
}; 

MainWindow::MainWindow(std::string Title, std::string Class, /*Other params*/) {} 

LRESULT MainWindow::HandleMessages(UINT Msg, WPARAM wParam, LPARAM lParam) 
{ 
    switch(Msg) 
    { 
     case WM_CREATE: 
     { 
     } 
     break; 

     case WM_DESTROY: 
      PostQuitMessage(0); 
      break; 

     default: 
      return DefWindowProc(WindowHandle(), Msg, wParam, lParam); 
    } 

    return 0; 
} 

這是所有。爲什麼它會給我這個錯誤,我該如何解決?

回答

1

我做了與他們完全相同的事情,除了我把創造代碼放在構造函數中。

這就是爲什麼。從構造函數調用virtual方法不會達到您所期望的效果 - 除非您期望它從層次結構中的當前類調用該方法。當基類構造函數執行時,該對象還不是派生類型。如果您從該類的構造函數中調用當前類中純粹的virtual方法,則會出現該錯誤。