包装对话框过程 [英] Wrapping the Dialog Procedure

查看:86
本文介绍了包装对话框过程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在使用标准方法来包装对话框过程,方法是在类中使用静态对话框过程,然后再使用派生的纯虚拟对话框过程.这很完美,但是我有一些设计问题.考虑一下我的静态对话框过程的定义:

I've been using the standard method for wrapping dialog procedures, by using a static dialog procedure in a class, and pure virtual dialog procedure that is derived later on. This works perfectly, but I have some design questions. Consider the definition of my static dialog procedure:

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基类中添加以下虚拟方法:

Lets say I want to add the following virtual methods to the ModalDialog base class:

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

如果我放弃了虚拟对话框过程,并且像这样更改了静态对象,那可以吗?

Would it be all right if I abandoned the virtual dialog procedure, and changed the static like so:

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-> _ dlg,0)仅适用于WM_CLOSE?我仍然需要像这样从thisPtr分配_dlg:thisPtr-> _ dlg = dlg吗?

That way in the base class I only have to redefine the virtual "on..." commands? I also noticed that ::EndDialog(thisPtr->_dlg,0) only works on WM_CLOSE? Do I still need to assign the _dlg from the thisPtr like this: thisPtr->_dlg = dlg?

感谢您提供的任何帮助.

Thank you for any help you can give.

推荐答案

这给您带来了更少的灵活性-最好从虚拟对话框过程中调用事件处理程序,从而允许您覆盖各个子类的行为.如果您希望默认情况下为ModalDialog的所有子类调用这些事件处理程序",则只需不要使虚拟对话框过程成为纯虚拟的-还要为ModalDialog实现它,并从子类中显式调用它.

This gives you less flexibility - It'd be better to call event handlers from the virtual dialog procedure, allowing you to override the behavior for individual subclasses. If you want these "event handlers" to be called by default for all subclasses of ModalDialog, simply don't make the virtual dialog procedure pure virtual - implement it also for ModalDialog, and explicitly call it from subclasses.

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

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

在这种情况下,您可以决定在该基类的dialogProc中为特定基类调用onInitDialog.

Given this scenario, you could make the decision to not call onInitDialog for a specific base class in the dialogProc for that base class.

通常,您要在静态过程中执行的操作很简单:

Typically, what you want to do in the static procedure is simply:

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

这篇关于包装对话框过程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆