我一直在使用标准方法来包装对话框程序,在类中使用静态对话框程序,以及稍后派生的纯虚拟对话框程序。这很好用,但我有一些设计问题。考虑我的静态对话过程的定义:
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);
}
在基类中我只需重新定义虚拟“on ...”命令?我还注意到:: EndDialog(thisPtr-&gt; _dlg,0)仅适用于WM_CLOSE?我还需要像这样从thisPtr分配_dlg:thisPtr-&gt; _dlg = dlg?
感谢您提供任何帮助。
答案 0 :(得分:2)
这使您的灵活性降低 - 最好从虚拟对话框过程调用事件处理程序,允许您覆盖各个子类的行为。如果您希望默认情况下为ModalDialog的所有子类调用这些“事件处理程序”,只需不要将虚拟对话框程序设为纯虚拟 - 也可以为ModalDialog实现它,并从子类显式调用它。
ModalDialog::dialogProc(...) {
switch (...) {
case ...: onInitDialog(...); break;
}
}
ModalDialogSubClass::dialogProc(...) {
switch (...) {
case ...: break;
default: return ModalDialog::dialogProc(...);
}
鉴于这种情况,您可以决定不调用onInitDialog
,以获取该基类的dialogProc
中的特定基类。
通常,您希望在静态过程中执行的操作只是:
if (is first message) {
SetWindowLong...
}
((ModalDialog *) GetWindowLong())->dialogProc(); // Also for the initial message