如何在MDI MFC+中动态更改视图宽度或高度+;windows应用程序? 1997,我用C++创建了MDI MFC程序。

如何在MDI MFC+中动态更改视图宽度或高度+;windows应用程序? 1997,我用C++创建了MDI MFC程序。,c++,mfc,scrollbar,zooming,C++,Mfc,Scrollbar,Zooming,我创建了一个名为xformView的类,它扩展了MFC CFormView类 在OnInitialUpdate()事件方法中,我编写了一些代码来自动修改视图的缩放 过去,大多数屏幕分辨率为800x600,但现在分辨率更高。在XFormView中自动缩放时,我避免在所有视图中进行一些修改 缩放代码修改活动视图中包含的每个CWnd的左侧和底部以及宽度和高度 代码如下 void XFormView::OnInitialUpdate() { CFormView::OnInitialUpd

我创建了一个名为xformView的类,它扩展了MFC CFormView类

OnInitialUpdate()
事件方法中,我编写了一些代码来自动修改视图的缩放

过去,大多数屏幕分辨率为800x600,但现在分辨率更高。在
XFormView
中自动缩放时,我避免在所有视图中进行一些修改

缩放代码修改活动视图中包含的每个
CWnd
的左侧和底部以及宽度和高度

代码如下

void XFormView::OnInitialUpdate()
    {
    CFormView::OnInitialUpdate();

    pLogFont = new LOGFONT;
    CFont* pDialogFont = GetFont();
    pDialogFont->GetObject(sizeof(LOGFONT),pLogFont);
    pLogFont->lfHeight = MulDiv(pLogFont->lfHeight, Config.GetDstH(), Config.GetSrcH());
    pLogFont->lfWeight = FW_NORMAL;

    pFont = new CFont;
    pFont->CreateFontIndirect(pLogFont);
    SetFont(pFont);

    CWnd* pWnd;
    pWnd = GetWindow(GW_CHILD);
    while (pWnd != NULL)
        {
        ZoomWnd(pWnd);
        pWnd = pWnd->GetWindow(GW_HWNDNEXT);
        }

    // TRY to modify WIDTH and HEIGTH of CFormView    
    ZoomWnd(this);
    }        

void XFormView::ZoomWnd(CWnd* pWnd)
    {
    CRect rect;
    pWnd->GetWindowRect(&rect);
    ScreenToClient(&rect);
    rect.left   = (int)((long)rect.left   * Config.GetDstH() / Config.GetSrcH());
    rect.top    = (int)((long)rect.top    * Config.GetDstV() / Config.GetSrcV());
    rect.right  = (int)((long)rect.right  * Config.GetDstH() / Config.GetSrcH());
    rect.bottom = (int)((long)rect.bottom * Config.GetDstV() / Config.GetSrcV());

    pWnd->MoveWindow(&rect);
    pWnd->SetFont(pFont);
    }
代码运行良好,但对于某些视图,缺少垂直和水平滚动条

窗口总是最大化加载。如果我不最大化窗口,滚动条总是丢失

如果减小宽度或高度,当宽度或高度达到RC资源文件中定义的值时,将显示滚动条

例如:

IDD_OVFORM DIALOGEX 0, 0, 370, 297
其中370为模板宽度,297为高度

若我减小子窗口的宽度,在宽度减小到370之前不会发生任何事情。此时会自动显示一个水平滚动条

我的问题是如何动态地(而不是在RC文件中)更改IDD_OVFORM的宽度和高度以对应缩放级别,从而正确显示水平和垂直滚动条

我已经尝试在OnInitialUpdate()方法中更改这些属性,但没有任何效果

如果我在RC资源文件中更改宽度和高度,缩放将在特定缩放级别(但不是所有缩放级别)下正常工作

在互联网上,我找到了一些关于删除滚动条的解决方案,但没有关于使用MDI MFC表单缩放和滚动条丢失的解决方案

有没有人已经找到了解决这个问题的办法


2019-02-12:感谢Barmak Shemirani的解决方案(选项3),该解决方案运行良好。

在确定是否需要后,您可能需要手动调用每个滚动条的
启用滚动条

您可能需要调用
setScrolInfo
,然后设置总大小


这两个调用都需要在
CFormView
的父窗口上完成,该窗口应为
CChildFrame

调用
SetScrollSizes
以特定大小显示滚动条:

CRect rect;
GetClientRect(rect);

//this multiplication is to make sure the scrollbar is visible
//remove it in actual code.
rect.right *= 2;
rect.bottom *= 2;

SetScrollSizes(MM_TEXT, rect.Size());
但总的来说,这不是正确的方法

备选案文1:

您只需转到资源编辑器,选择对话框,选择对话框的属性,然后更改对话框的默认字体大小。将字体大小增加到9或更大,这将自动使对话框及其控件变大,并使用更大的字体

备选案文2:

在对话框的属性中,您还将看到一个名为“动态布局”的部分。这使您可以在调整控件大小时缩放控件,或上/下和左/右移动控件

备选案文3:

在运行时更改对话框模板中的字体。为此,必须重写
CFormView::Create
,后者依次调用
CreateDlg
。这些函数名必须完全按照以下方式声明

请注意,在加载对话框之前,对话框模板中的字体只能更改一次

Visual Studio 2017示例(此代码可能与较早的MFC版本不兼容)

XFormView.h中的类定义必须包含以下行

protected:

    BOOL Create
        ( LPCTSTR lpszClassName
        , LPCTSTR lpszWindowName
        , DWORD dwRequestedStyle
        , const RECT& rect
        , CWnd* pParentWnd
        , UINT nID
        , CCreateContext* pContext
        );

    BOOL CreateDlg(LPCTSTR lpszTemplateName, CWnd* pParentWnd);

    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
OnCreate
声明是绝对必要的

没有这个声明,什么都不会发生


OnCreate
仅在include文件中声明,但未在CPP文件中定义。

感谢您的回答,但我已经尝试使用EnableScrollBars启用滚动条,在阅读我的说明时,您可以看到滚动条已启用,因为它们在表单大小减小时出现。我已经尝试固定(缩放)父窗口的高度和宽度。我将调查SetScrolInfo(),这对我来说是一个新路径。我发现您是一个新用户。我有一点意见。您的答案不能作为答案发布,而是作为评论发布,因为它是一个建议,而不是一个解决方案。当我开始使用StackOverflow时,我犯了同样的错误,因为我认为它是一个论坛:-)谢谢你的建议。我不知道两者之间有着深刻的区别。另外,我无法在另一个帖子上发表这样的评论,我想评论一个不同的答案(与被接受的答案不同)实际上帮助了我。对不起,我忘记了新用户不可能写评论!是的,我确实不同意这个系统,但它脱离了主题。我曾尝试实现您的解决方案,但当我重载OnCreate()并放入您的代码时,OnCreate()事件函数从未被调用。在我的例子中,CDialog链接到一个文档,并使用OnInitialUpdate()创建。关于信息,我在问题的源代码中添加了最后添加的代码,以便正确格式化代码。我说的是
Create
,而不是
OnCreate
。重写
Create
可能取决于MFC版本。您正在使用哪个版本的Visual Studio?如果是较新的版本,我可以发布代码。我正在使用Visual Studio 2017。感谢您的帮助。这是一个非常好的工作,因为即使在MSDN上,我也没有在这个问题上找到任何帮助。仅供参考,我更改了您的答案以反映我的实验,因为OnCreate声明是绝对必要的。
protected:

    BOOL Create
        ( LPCTSTR lpszClassName
        , LPCTSTR lpszWindowName
        , DWORD dwRequestedStyle
        , const RECT& rect
        , CWnd* pParentWnd
        , UINT nID
        , CCreateContext* pContext
        );

    BOOL CreateDlg(LPCTSTR lpszTemplateName, CWnd* pParentWnd);

    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);