如何在MDI MFC C ++ Windows应用程序中动态更改CFormView的宽度或高度? [英] How to change dynamically CFormView WIDTH or HEIGHT in MDI MFC C++ windows application?

查看:129
本文介绍了如何在MDI MFC C ++ Windows应用程序中动态更改CFormView的宽度或高度?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

1997年,我使用C ++创建了MDI MFC程序.

In 1997, I have used C++ to create an MDI MFC program.

我创建了一个名为XFormFiew的类,该类扩展了MFC CFormView类.

I have created a Class named XFormFiew that extends MFC CFormView class.

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

In OnInitialUpdate() event method, I have written some codes to modify automatically the zooming of the view.

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

In the past, the majority of screen resolution are 800x600, but now the resolution is higher. In zooming automatically in XFormView, I avoid to made some modifications in all my views.

缩放代码会修改活动CFormView

代码如下

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);
    }

该代码运行良好,但对于某些视图,缺少垂直和水平滚动条.

The code work well but for some views, the vertical and horizontal scrollbar are missing.

窗口始终加载为MAXIMIZED.如果我未最大化窗口,则滚动条将始终丢失.

The Window is always loaded MAXIMIZED. If I unmaximize Window, the scrollbars are always missing.

如果我减小WIDTH或HEIGHT,则当宽度或高度达到RC Resource文件中定义的高度时,将显示滚动条.

If I reduce WIDTH or HEIGHT the scrollbar is displayed WHEN width or height reaches what has been defined in RC Resource file.

示例:

IDD_OVFORM DIALOGEX 0, 0, 370, 297

其中370是Form的宽度,297是高度.

where 370 is the width of Form and 297 is height.

如果我减小子窗口"的宽度,则只有将宽度减小到370时,什么都不会发生.这时会自动显示水平滚动条.

If I reduce Child Window width, nothing happens until width is reduced to 370. At this moment an horizontal scrollbar is automatically displayed.

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

My problem is how to change dynamically (not in RC file) the width and height of IDD_OVFORM to correspond to zoom level so that horizontal and vertical scrollbar are displayed correctly ?

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

I have already try to change these properties in OnInitialUpdate() method but nothing is working.

如果我更改了RC Resource FILE中的Width和Height,则缩放对于特定的缩放级别(而不是所有缩放级别)可以正常工作.

If I change Width and Height in RC Resource FILE, the zoom work correctly for a specific zoom level (but not for all zoom level).

在Internet上,我找到了一些有关删除滚动条的解决方案,而不是有关使用MDI MFC Form删除缩放和滚动条缺失的解决方案.

On Internet, I find a some solutions about removing Scrollbars but not about zooming and Scrollbars missing using MDI MFC Form.

有人已经找到解决此问题的方法了吗?

Is there somebody that has already found a solution to this problem ?

2019-02-12:感谢Barmak Shemirani的完美解决方案(选项3).

推荐答案

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

Call SetScrollSizes to show the scrollbars at specific sizes:

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());

但这通常不是正确的方法.

But this is not the right method in general.

选项1:

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

You can just go to resource editor, select the dialog, select dialog's properties, and change the dialog's default font size. Increase the font size to 9 or higher, this will automatically make the dialog and its controls bigger, as well as using larger font.

选项2:

在对话框的属性中,您还将看到一个名为动态布局"的部分.这样一来,您可以缩放控件的大小,也可以上下左右移动它们.

In dialog's properties, you will also see a section called "Dynamic Layout". This lets you zoom the controls on resize, or move them up/down and left/right.

选项3:

在运行时更改对话框模板中的字体.为此,您必须覆盖CFormView::Create,后者依次调用CreateDlg.这些函数名称必须完全如下声明.

Change the font in dialog template during run time. To do so, you must override CFormView::Create, which in turn calls CreateDlg. These function names have to be declared exactly as below.

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

Note that the font in dialog template can be changed only once, before the dialog is load.

Visual Studio 2017示例(此代码可能与旧版MFC不兼容)

Example for Visual Studio 2017 (this code may not be compatible with older MFC versions)

BOOL XFormView::CreateDlg(LPCTSTR lpszTemplateName, CWnd* pParentWnd)
{
    CDialogTemplate dlt;
    if(dlt.Load(lpszTemplateName)))
    {
        // set your own font
        dlt.SetFont(L"Arial", 20);

        HINSTANCE hInst = AfxFindResourceHandle(lpszTemplateName, RT_DIALOG);

        LPCDLGTEMPLATE dlgtemplate = (LPCDLGTEMPLATE)GlobalLock(dlt.m_hTemplate);

        // create a modeless dialog
        BOOL bSuccess = CreateDlgIndirect(dlgtemplate, pParentWnd, hInst);

        GlobalUnlock(dlt.m_hTemplate);
        return bSuccess;
    }

    return CFormView::CreateDlg(lpszTemplateName, pParentWnd);
}

BOOL XFormView::Create
    ( LPCTSTR lpszClassName
    , LPCTSTR lpszWindowName
    , DWORD dwRequestedStyle
    , const RECT& rect
    , CWnd* pParentWnd
    , UINT nID
    , CCreateContext* pContext
    );
{
    ASSERT(pParentWnd != NULL);
    ASSERT(m_lpszTemplateName != NULL);

    m_pCreateContext = pContext;    // save state for later OnCreate

    // call PreCreateWindow to get prefered extended style
    CREATESTRUCT cs; 
    memset(&cs, 0, sizeof(CREATESTRUCT));
    if(dwRequestedStyle == 0)
        dwRequestedStyle = AFX_WS_DEFAULT_VIEW;
    cs.style = dwRequestedStyle;
    if(!PreCreateWindow(cs))
        return FALSE;

    // create a modeless dialog
    if(!CreateDlg(m_lpszTemplateName, pParentWnd))
        return FALSE;

    m_pCreateContext = NULL;

    ModifyStyle(WS_BORDER | WS_CAPTION, cs.style & (WS_BORDER | WS_CAPTION));
    ModifyStyleEx(WS_EX_CLIENTEDGE, cs.dwExStyle & WS_EX_CLIENTEDGE);

    SetDlgCtrlID(nID);

    CRect rectTemplate;
    GetWindowRect(rectTemplate);
    SetScrollSizes(MM_TEXT, rectTemplate.Size());

    // initialize controls etc
    if(!ExecuteDlgInit(m_lpszTemplateName))
        return FALSE;

    // force the size requested
    SetWindowPos(NULL, rect.left, rect.top,
        rect.right - rect.left, rect.bottom - rect.top,
        SWP_NOZORDER | SWP_NOACTIVATE);

    // make visible if requested
    if(dwRequestedStyle & WS_VISIBLE)
        ShowWindow(SW_NORMAL);

    return TRUE;
}

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

and class definition in XFormView.h MUST contains following lines

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声明是绝对必要的.

没有此声明,什么也不会发生!

Without this declaration, nothing happens !!!

OnCreate仅在包含文件中声明,而未在CPP文件中定义.

OnCreate is only declared in include file but is not defined in CPP file.

这篇关于如何在MDI MFC C ++ Windows应用程序中动态更改CFormView的宽度或高度?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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