2011-04-01 77 views
1

我一直使用标准方法来包装对话框过程,通过在类中使用静态对话框过程以及稍后派生的纯虚拟对话框过程。这很好,但我有一些设计问题。考虑我的静态对话过程的定义:包装对话框过程

INT_PTR __stdcall ModalDialog::router(HWND dlg, UINT msg, WPARAM wp, LPARAM lp) 
{ 
    ModalDialog *thisPtr = 0; 

    if (msg == WM_INITDIALOG) 
    { 
     thisPtr = reinterpret_cast< ModalDialog *>(lp); 

     ::SetWindowLongPtr(dlg, DWLP_USER, reinterpret_cast<LONG_PTR>(thisPtr)); 

     thisPtr->_dlg = dlg; 

     return static_cast<INT_PTR>(TRUE); 
    } 
    else 
     thisPtr = reinterpret_cast< ModalDialog *>(::GetWindowLongPtr(dlg, DWLP_USER)); 

    if (thisPtr) 
     //the virtual procedure from which to derive from 
     return thisPtr->proc(msg, wp, lp); 
    else 
     //return false when not processing a message, look we should 
     return static_cast<INT_PTR>(FALSE); 
} 

可以说,我想添加下列虚拟方法到ModalDialog基类:

virtual bool onInitDialog(HWND dlg) = 0; 
virtual bool onCommand(HWND dlg, int high_word, int low_word) = 0; 
virtual bool onClose(HWND dlg) = 0; 

难道是所有权利,如果我放弃了虚拟对话程序,以及改变像这样的静:

INT_PTR __stdcall ModalDialog::router(HWND dlg, UINT msg, WPARAM wp, LPARAM lp) 
{ 
    ModalDialog *thisPtr = 0; 

    if (msg == WM_INITDIALOG) 
    { 
     thisPtr = reinterpret_cast< ModalDialog *>(lp); 

     ::SetWindowLongPtr(dlg, DWLP_USER, reinterpret_cast<LONG_PTR>(thisPtr)); 

     thisPtr->_dlg = dlg; 

     //ADDED 
     onInitDialog(dlg); 

     return static_cast<INT_PTR>(TRUE); 
    } 
    else 
     thisPtr = reinterpret_cast< ModalDialog *>(::GetWindowLongPtr(dlg, DWLP_USER)); 

    //ADDED 
    switch (msg) 
    { 
    case WM_COMMAND: 
     if (thisPtr && thisPtr->onCommand(dlg, HIWORD(wp), LOWORD(lp))) 
      return static_cast<INT_PTR>(TRUE); 
     break; 
    case WM_CLOSE: 
     if (thisPtr && thisPtr->onClose(dlg)) 
      return static_cast<INT_PTR>(TRUE); 
     break; 
    defualt: 
     return static_cast<INT_PTR>(FALSE); 

    //if (thisPtr) 
    // return thisPtr->proc(msg, wp, lp); 
    //else 
    // return static_cast<INT_PTR>(FALSE); 
} 

在基类这样,我只需要重新定义虚拟“上......”的命令?我还注意到:: EndDialog(thisPtr - > _ dlg,0)仅适用于WM_CLOSE?我是否还需要像这样分配thisPtr中的_dlg:thisPtr - > _ dlg = dlg?

谢谢你给予的任何帮助。

回答

2

这给你更少的灵活性 - 最好是从虚拟对话框过程中调用事件处理程序,这样可以覆盖单个子类的行为。如果您希望默认调用这些“事件处理程序”以用于ModalDialog的所有子类,那么不要使虚拟对话框过程是纯虚拟的 - 也可以为ModalDialog实现它,并从子类明确调用它。

ModalDialog::dialogProc(...) { 
    switch (...) { 
    case ...: onInitDialog(...); break; 
    } 
} 

ModalDialogSubClass::dialogProc(...) { 
    switch (...) { 
    case ...: break; 
    default: return ModalDialog::dialogProc(...); 
} 

鉴于这种情况,你可以做出决定呼吁onInitDialogdialogProc一个特定的基类的基类。

通常情况下,你要在静态的过程做的是简单的:

if (is first message) { 
    SetWindowLong... 
} 
((ModalDialog *) GetWindowLong())->dialogProc(); // Also for the initial message 
+0

是啊,这就是我做太多,随时调用'GetWindowLongPtr'如果nullptr,调用'SetWindowLongPtr'无论第一条消息是。然而,这适用于我,因为我内部使用了新的(std :: nothrow)类实例,而不是通过LPARAM传递,并且它可能不适用于rem45acp的方法,因为他似乎在外部创建类并传入指针,并且收到的第一条消息可能不是WM_INITDIALOG,它具有CreateDialogParam的数据指针。 – 2015-07-13 22:05:52