qq_41945416 2025-10-22 17:33 采纳率: 90.6%
浏览 4
已结题

怎么在对话框里使用 CFrameWndEx 和CScrollView类呢?

怎么在对话框里使用 CFrameWndEx 和CScrollView类呢?我已经分别写成子类 CUSERFramWnd和CUSERView了,那怎么像打开对话框一样去使用这些类呢?

  • 写回答

4条回答 默认 最新

  • 宝码香车 优质创作者: JavaScript技术领域 2025-10-22 17:37
    关注

    让【宝码香车】来帮您解答,本回答参考DeepSeek编写,并整理提供。

    如果答案让您满意,请采纳、点赞、关注,非常感谢!
    .
    每日一句正能量,让它带给您好心情:过去的已经过去,未来的还未到来,珍惜现在就好。
    .

    在MFC中,将 CFrameWndExCScrollView 结合使用在对话框中需要一些特殊的处理。以下是详细的实现步骤:

    1. 创建自定义框架窗口类

    // UserFrameWnd.h
    class CUserFrameWnd : public CFrameWndEx
    {
    public:
        CUserFrameWnd();
        
    protected:
        DECLARE_DYNCREATE(CUserFrameWnd)
        DECLARE_MESSAGE_MAP()
        
    public:
        virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext);
        virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
        
        afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
        afx_msg void OnSize(UINT nType, int cx, int cy);
    };
    
    // UserFrameWnd.cpp
    IMPLEMENT_DYNCREATE(CUserFrameWnd, CFrameWndEx)
    
    
    BEGIN_MESSAGE_MAP(CUserFrameWnd, CFrameWndEx)
        ON_WM_CREATE()
        ON_WM_SIZE()
    END_MESSAGE_MAP()
    
    
    CUserFrameWnd::CUserFrameWnd()
    {
    }
    
    
    BOOL CUserFrameWnd::PreCreateWindow(CREATESTRUCT& cs)
    {
        if (!CFrameWndEx::PreCreateWindow(cs))
            return FALSE;
            
        cs.style = WS_OVERLAPPEDWINDOW | WS_VISIBLE;
        return TRUE;
    }
    
    
    int CUserFrameWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
        if (CFrameWndEx::OnCreate(lpCreateStruct) == -1)
            return -1;
        
        return 0;
    }
    
    
    BOOL CUserFrameWnd::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
    {
        return CFrameWndEx::OnCreateClient(lpcs, pContext);
    }
    
    
    void CUserFrameWnd::OnSize(UINT nType, int cx, int cy)
    {
        CFrameWndEx::OnSize(nType, cx, cy);
    }
    

    2. 创建自定义视图类

    // UserView.h
    class CUserView : public CScrollView
    {
    public:
        CUserView();
        
    protected:
        DECLARE_DYNCREATE(CUserView)
        DECLARE_MESSAGE_MAP()
        
    public:
        virtual void OnDraw(CDC* pDC);
        virtual void OnInitialUpdate();
        
        afx_msg void OnSize(UINT nType, int cx, int cy);
    };
    
    // UserView.cpp
    IMPLEMENT_DYNCREATE(CUserView, CScrollView)
    
    
    BEGIN_MESSAGE_MAP(CUserView, CScrollView)
        ON_WM_SIZE()
    END_MESSAGE_MAP()
    
    
    CUserView::CUserView()
    {
    }
    
    
    void CUserView::OnDraw(CDC* pDC)
    {
        // 在这里实现绘制逻辑
        CRect rect;
        GetClientRect(&rect);
        
        pDC->FillSolidRect(rect, RGB(255, 255, 255));
        pDC->TextOut(10, 10, _T("这是自定义滚动视图"));
    }
    
    
    void CUserView::OnInitialUpdate()
    {
        CScrollView::OnInitialUpdate();
        
        // 设置滚动范围
        CSize sizeTotal(1000, 1000);
        SetScrollSizes(MM_TEXT, sizeTotal);
    }
    
    
    void CUserView::OnSize(UINT nType, int cx, int cy)
    {
        CScrollView::OnSize(nType, cx, cy);
    }
    

    3. 在对话框中使用框架窗口和视图

    // YourDialog.h
    class CYourDialog : public CDialogEx
    {
    public:
        CYourDialog(CWnd* pParent = nullptr);
        
    protected:
        virtual void DoDataExchange(CDataExchange* pDX);
        
        CUserFrameWnd* m_pFrameWnd;
        CUserView* m_pView;
        
    protected:
        virtual BOOL OnInitDialog();
        afx_msg void OnDestroy();
        
        DECLARE_MESSAGE_MAP()
    };
    
    // YourDialog.cpp
    BEGIN_MESSAGE_MAP(CYourDialog, CDialogEx)
        ON_WM_DESTROY()
    END_MESSAGE_MAP()
    
    
    CYourDialog::CYourDialog(CWnd* pParent)
        : CDialogEx(IDD_YOUR_DIALOG, pParent)
        , m_pFrameWnd(nullptr)
        , m_pView(nullptr)
    {
    }
    
    
    void CYourDialog::DoDataExchange(CDataExchange* pDX)
    {
        CDialogEx::DoDataExchange(pDX);
    }
    
    
    BOOL CYourDialog::OnInitDialog()
    {
        CDialogEx::OnInitDialog();
        
        // 创建框架窗口
        m_pFrameWnd = new CUserFrameWnd();
        
        CRect rect;
        GetDlgItem(IDC_FRAME_CONTAINER)->GetWindowRect(&rect); // IDC_FRAME_CONTAINER 是容器控件的ID
        ScreenToClient(&rect);
        
        CString strFrameClass = AfxRegisterWndClass(
            CS_HREDRAW | CS_VREDRAW,
            ::LoadCursor(NULL, IDC_ARROW),
            (HBRUSH)::GetStockObject(WHITE_BRUSH),
            NULL);
        
        if (!m_pFrameWnd->Create(strFrameClass, _T("自定义框架"), 
                               WS_CHILD | WS_VISIBLE, rect, this))
        {
            TRACE0("创建框架窗口失败\n");
            return FALSE;
        }
        
        // 创建视图
        CCreateContext context;
        context.m_pNewViewClass = RUNTIME_CLASS(CUserView);
        context.m_pCurrentFrame = m_pFrameWnd;
        context.m_pCurrentDoc = NULL;
        context.m_pLastView = NULL;
        
        m_pView = (CUserView*)m_pFrameWnd->CreateView(&context);
        if (m_pView == NULL)
        {
            TRACE0("创建视图失败\n");
            return FALSE;
        }
        
        m_pView->ShowWindow(SW_SHOW);
        m_pFrameWnd->RecalcLayout();
        
        return TRUE;
    }
    
    
    void CYourDialog::OnDestroy()
    {
        if (m_pFrameWnd)
        {
            m_pFrameWnd->DestroyWindow();
            delete m_pFrameWnd;
            m_pFrameWnd = nullptr;
        }
        
        CDialogEx::OnDestroy();
    }
    

    4. 资源文件中的对话框定义

    // 在资源文件中定义对话框模板
    IDD_YOUR_DIALOG DIALOGEX 0, 0, 400, 300
    STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
    CAPTION "包含框架和视图的对话框"
    FONT 8, "MS Shell Dlg", 0, 0, 0x1
    BEGIN
        DEFPUSHBUTTON   "确定",IDOK,340,10,50,14
        PUSHBUTTON      "取消",IDCANCEL,340,30,50,14
        CONTROL         "",IDC_FRAME_CONTAINER,"Static",SS_ETCHEDFRAME,10,10,320,240
    END
    

    关键要点

    1. 动态创建:使用 DYNCREATE 宏支持运行时创建
    2. 消息映射:正确处理窗口消息
    3. 创建上下文:使用 CCreateContext 连接框架和视图
    4. 资源管理:在对话框销毁时正确清理框架窗口

    这样你就可以在对话框中像使用普通控件一样使用自定义的框架窗口和滚动视图了。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 10月31日
  • 已采纳回答 10月23日
  • 创建了问题 10月22日