C++ 包装对话框过程
我一直在使用包装对话框过程的标准方法,在类中使用静态对话框过程,以及以后派生的纯虚拟对话框过程。这很好,但我有一些设计问题。考虑我的静态对话过程的定义:C++ 包装对话框过程,c++,winapi,modal-dialog,C++,Winapi,Modal Dialog,我一直在使用包装对话框过程的标准方法,在类中使用静态对话框过程,以及以后派生的纯虚拟对话框过程。这很好,但我有一些设计问题。考虑我的静态对话过程的定义: INT_PTR __stdcall ModalDialog::router(HWND dlg, UINT msg, WPARAM wp, LPARAM lp) { ModalDialog *thisPtr = 0; if (msg == WM_INITDIALOG) { thisPtr = reinte
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);
}
如果我放弃虚拟对话框过程,并像这样更改静态,是否可以:
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);
}
INT\u PTR\u stdcall ModalDialog::router(HWND dlg、UINT msg、WPARAM wp、LPARAM lp)
{
ModalDialog*thisPtr=0;
if(msg==WM_INITDIALOG)
{
该PTR=重新解释铸造(lp);
::SetWindowLongPtr(dlg、DWLP_用户、重新解释_cast(thisPtr));
这个ptr->_dlg=dlg;
//增加
onInitDialog(dlg);
返回static_cast(TRUE);
}
其他的
thisPtr=reinterpret_cast(::GetWindowLongPtr(dlg,DWLP_用户));
//增加
开关(msg)
{
case WM_命令:
if(thisPtr&&thisPtr->onCommand(dlg、HIWORD(wp)、LOWORD(lp)))
返回static_cast(TRUE);
打破
案例WM_结束:
if(thisPtr&&thisPtr->onClose(dlg))
返回static_cast(TRUE);
打破
解散:
返回静态\u cast(假);
//如果(本PTR)
//返回此PTR->proc(消息、wp、lp);
//否则
//返回静态\u cast(假);
}
这样,在基类中,我只需要重新定义虚拟的“on…”命令?我还注意到::EndDialog(thisPtr->\u dlg,0)只在WM_CLOSE上工作?我是否仍然需要像这样分配thisPtr中的_dlg:thisPtr->\u dlg=dlg
感谢您提供的任何帮助。这会降低灵活性-最好从虚拟对话框过程调用事件处理程序,允许您覆盖单个子类的行为。如果您需要这些“事件处理程序”要在默认情况下为ModalDialog的所有子类调用,只需不要使虚拟对话框过程纯虚拟-也为ModalDialog实现它,并从子类显式调用它
ModalDialog::dialogProc(...) {
switch (...) {
case ...: onInitDialog(...); break;
}
}
ModalDialogSubClass::dialogProc(...) {
switch (...) {
case ...: break;
default: return ModalDialog::dialogProc(...);
}
在这种情况下,您可以决定在该基类的dialogProc
中不调用特定基类的onInitDialog
通常,您希望在静态过程中执行的操作很简单:
if (is first message) {
SetWindowLong...
}
((ModalDialog *) GetWindowLong())->dialogProc(); // Also for the initial message
是的,我也是这样做的,总是调用
GetWindowLongPtr
,如果为空,则调用SetWindowLongPtr
,无论第一条消息是什么。但是,这对我来说很有效,因为我是新的(std::nothrow)类实例在内部,而不是通过LPRAM传递,这可能不适用于rem45acp的方法,因为他似乎在外部创建类并传入指针,并且收到的第一条消息可能不是WM_INITDIALOG,它具有来自CreateDialogParam的数据指针。
if (is first message) {
SetWindowLong...
}
((ModalDialog *) GetWindowLong())->dialogProc(); // Also for the initial message