MFC 如何将一个对话框嵌入到视图中

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MFC 如何将一个对话框嵌入到视图中相关的知识,希望对你有一定的参考价值。

我创建了一个单文档程序

按照下面的教程操作:
///////////////////////////////////////////////////////教程///////////////////////////////////////////
1.资源管理器中编辑你要的对话框资源/属性设为child,还有Title Bar去掉比较 好看
2.建立你的对话框类
3.在视中添加你定义的对话框类为成员变量:m_YourDlg.
4.在视图的OnCreate中:
m_YourDlg.Create(IDD_YourDLG,this);

////////////////////////////////////////////////////////////////////////////////////////////////////
可是到第四步时就出现了错误 :
1>d:\my documents\visual studio 2008\projects\mfc\mfc\mainfrm.cpp(47) : error C2065: “m_YourDlg”: 未声明的标识符

1>d:\my documents\visual studio 2008\projects\mfc\mfc\mainfrm.cpp(47) : error C2228: “.Create”的左边必须有类/结构/联合

请问该怎样去修改呢????????

1、资源管理器中编辑要的对话框资源/属性设为child。
2、建立对话框类
3、在视中添加定义的对话框类为成员变量:m_YourDlg.
4、在视图的OnCreate中:
m_YourDlg.Create(IDD_YourDLG,this);
//设置显示位置和方式
m_YourDlg.setWindowPos(......);
参考技术A 在view类中增加包含那个对话框的头文件。 参考技术B 你有没有将你的对话框类的头文件 #include 到 View 类的头文件当中
也就是说,这个子对话框,它具有一个类,要使用它,必须在另外的要使用的地方包含的头文件

在你贴出来的错误中,第二个错误可不用理会,因为它直接是由第一个错误引起的,解决了第一个错误,第二个错误便不会有了。

第一个错误,说是未声明的标识符,当然,VS是不会知道你的这个 m_YourDlg 是什么类的,要你自己去指明它的类本回答被提问者采纳

C++/CLI:将 MFC 嵌入 WinForm

【中文标题】C++/CLI:将 MFC 嵌入 WinForm【英文标题】:C++/CLI: Embedding MFC into WinForm 【发布时间】:2017-09-01 15:03:33 【问题描述】:

你好,

几周以来,我们一直在尝试将 MFC 对话框“转换”为可以嵌入到 WinForm 用户控件中的“MFC 表单”。

我们已经成功地做到了:

我们制作了一个 WinForm 用户控件,名为 Dlg_WU_MFC_Container 创建时,UC 会创建名为 CDlgEdgeType 的 MFC 表单 然后,每次调整 UC 的大小或移动时,我们也会移动和调整 MFC 窗体的大小

这是代码(我试图删除很多不必要的东西..):

Dlg_WU_MFC_Container.h:

#pragma once

public ref class Dlg_WU_MFC_Container : public System::Windows::Forms::UserControl

private:
    CDlgEdgeType* _dialog;
    CWnd *_wnd;

    private: //---Local Controls
    System::ComponentModel::IContainer^  components;

public: 
    Dlg_WU_MFC_Container();
    ~Dlg_WU_MFC_Container();
    !Dlg_WU_MFC_Container();

    template<class T, class HP>
    void InitializeContainer() 
        CDlgEdgeType = 
    

private:
    void RefreshEmbeddedSize();

#pragma region Windows Form Designer generated code 
         /// <summary>
         /// Required method for Designer support - do not modify
         /// the contents of this method with the code editor.
         /// </summary>
         void InitializeComponent(void)
         
             this->SuspendLayout();
             // 
             // Dlg_WU_MFC_Container
             // 
             this->AutoScaleDimensions = System::Drawing::SizeF(96, 96);
             this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Dpi;
             this->ForeColor = System::Drawing::SystemColors::WindowText;
             this->Margin = System::Windows::Forms::Padding(0);
             this->Name = L"Dlg_WU_MFC_Container";
             this->Size = System::Drawing::Size(816, 480);
             this->SizeChanged += gcnew System::EventHandler(this, &Dlg_WU_MFC_Container::evSizeChanged);
             this->VisibleChanged += gcnew System::EventHandler(this, &Dlg_WU_MFC_Container::evVisibleChanged);
             this->ResumeLayout(false);

         
#pragma endregion
private: System::Void evSizeChanged(System::Object^  sender, System::EventArgs^  e);
private: System::Void evVisibleChanged(System::Object^  sender, System::EventArgs^  e);
;

Dlg_WU_MFC_Container.cpp:

    #include "Dlg_WU_MFC_Container.h"
    #include "DlgEdgeType.h"

    Dlg_WU_MFC_Container::Dlg_WU_MFC_Container()
    
        InitializeComponent();

        _wnd = NULL;
        _dialog = new CDlgEdgeType();
    

    Dlg_WU_MFC_Container::~Dlg_WU_MFC_Container()
    
        if (components)
        
            delete components;
        
        this->!Dlg_WU_MFC_Container();
    

    Dlg_WU_MFC_Container::!Dlg_WU_MFC_Container()
    
        // We need to detach the handle to free it for other usage
        if (_wnd) 
            _wnd->Detach();

            delete _wnd;

            _wnd = NULL;
        

        if (_dialog) 
            delete _dialog;

            _dialog = NULL;
        
    

    System::Void Dlg_WU_MFC_Container::evSizeChanged(System::Object^  sender, System::EventArgs^  e)   
        RefreshEmbeddedSize();
    

    // Inform the embedded form to adapt to its new size
    void Dlg_WU_MFC_Container::RefreshEmbeddedSize() 
        if (_dialog && _isShown) 
            CRect containerWnd;

            containerWnd.left = this->Left;
            containerWnd.right = this->Right;
            containerWnd.top = this->Top;
            containerWnd.bottom = this->Bottom;

            _dialog->ReplaceEmbeddedForm(containerWnd);
        
    

    System::Void Dlg_WU_MFC_Container::evVisibleChanged(System::Object^  sender, System::EventArgs^  e) 
// _isShown basically useless.. !
        if (Visible != _isShown) 
            _isShown = Visible;

            if (_dialog) 
                if (Visible) 
                    void *handle = Handle.ToPointer();

                    if (handle) 
                        // We need to create a new CWnd which will contain
                        // the handle of the current WinForm control where
                        // the embedded MFC will be contained
                        _wnd = new CWnd();

                        _wnd->Attach((HWND)handle);

                        _dialog->Create(_wnd);

                        RefreshEmbeddedSize();
                    
                 else 
                    // When the control is not shown anymore, we need to free
                    // the handle so another control can use it (the handle
                    // is stored in the MFC permanent map)
                    _wnd->Detach();

                    _dialog->DestroyWindow();

                    delete _wnd;

                    _wnd = NULL;
                
            
        
    

CDlgEdgeType.cpp:

void CDlgEdgeType::ReplaceEmbeddedForm(CRect &rect) 
    if (!GetSafeHwnd()) 
        return;
    

    SetWindowPos(NULL, rect.left, rect.top, rect.Width(), rect.Height(), SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);

这些东西“非常好”:CDlgEdgeType 在我们的应用程序中得到了很好的显示,当应用程序调整大小或移动时,一切正常。

这是我的问题: CDlgEdgeTypeDlg_WU_MFC_Container 作为父级,太好了。但后者不知道 MFC 表单是“子”.. 所以焦点有点丢失,箭头键和 Tab 键根本不起作用。

您应该知道的是 Dlg_WU_MFC_Container 被添加到自定义 TabControlTabPages 中。因此,如果用户尝试浏览 MFC 表单的控件,或者他尝试使用箭头键浏览 TreeView,TabControl 似乎会接管焦点并会更改选项卡。这不方便 D:

我不知道如何解决这个问题,我的同事也不知道。

也许我们集成 MFC 的方式是错误的,但并没有真正的主题(我们看到更多“将 WinForm 表单嵌入 MFC”..)。此外,由于我们的软件历史悠久,我们不能简单地重新创建 CDlgEdgeType。这是一个很大的对话框,事实上,我们有 7 个这样的对话框,代码实现了模板,但为了清楚起见,我删除了它们..

谢谢!

Sbizz。

【问题讨论】:

这只是一个非常基本的问题,每当您混合 GUI 框架时都会发生。键盘快捷键处理是由消息循环完成的,您在程序中激活了错误的快捷键。 MFC 循环对 Winforms 的行为一无所知。曾经有一篇关于它的知识库文章,但我找不到它。投票离岛,也许没有人认为使用 ShowDialog() 是一个很好的解决方法。 【参考方案1】:

好吧,我们找到了出路.. 这可能不是最好的方法,但它正在工作(或者至少,它似乎工作!)。

起初,我设法将密钥发送到 MFC 表单:

bool Dlg_WU_MFC_Container::ProcessDialogKey(Keys keyData) 
    ::SendMessage(CWnd::GetFocus()->GetSafeHwnd(), WM_KEYDOWN, (WPARAM)keyData, (LPARAM)0);

    return true;

由于 TabControl 通过 WM_ACTIVATE 获取控件,我们尝试通过将 WM_ACTIVATE 发送到 MFC 表单来“覆盖”它,因此结果如下:

bool Dlg_WU_MFC_Container::ProcessDialogKey(Keys keyData) 
    ::SendMessage(CWnd::GetFocus()->GetSafeHwnd(), WM_ACTIVATE, MAKEWPARAM(WA_ACTIVE, 0), (LPARAM)0);
    ::SendMessage(CWnd::GetFocus()->GetSafeHwnd(), WM_KEYDOWN, (WPARAM)keyData, (LPARAM)0);

    return true;

唯一的问题是“Tab”键似乎不起作用,但经过调查,我们的用户不需要它,所以... :D 但我认为它只是与 WM_ACTIVATE 的第三个参数有关(以前的控制)。它必须用于知道按下 Tab 后必须聚焦哪个控件。

Sbizz

【讨论】:

以上是关于MFC 如何将一个对话框嵌入到视图中的主要内容,如果未能解决你的问题,请参考以下文章

MFC如何在切换视图时关闭无模式对话框

C++/CLI:将 MFC 嵌入 WinForm

将焦点放在托管在 MFC 视图中的无模式对话框上

如何将滑块连接到 MFC 中的变量

选项卡控件中的嵌入式对话框不能在第二个对话框中工作,MFC

如何在 MFC 的不同视图中调用其他函数?