返回首页

简介
您好,这是我在这里的第一篇文章,有怜悯。
本文介绍一个非常简单的方法,采取照顾可调整大小的对话框的MFC应用程序,使用Visual Studio 6日至2005年(我不知道2008或更新的版本,但)。背景
我喜欢MFC。不管你信不信,我做的。但是,我不喜欢的方式,你要小心,当你想要一个可调整大小的对话框。你必须手动编程到你计划每一个对话框的OnSize方法为每个子窗口的位置。所以,我花了一个下午的调查,这可能是如何简化。
所以,开始从我知道一个CDialog,我可以得到当前窗口的大小(即在资源编辑器中设置)对话框OnInitialUpdate()方法。商店,得到调整大小,以便在下一次对话,你可以确保它不会比这个小OnGetMinMaxInfo()方法,。

void Init(CDialog* pDialog);

容易,请参阅。您只需通过quot;指针从您的对话; thisquot。
我还可以得到当前位置的子窗口,所以我可以利用这些信息后左/右和顶部/底部边界的调整对话框获取时保持距离。
的所有子窗口默认情况下,坚持自己的立场上方,左上角自动的,如果你不动他们。但是,如果你想拥有它们移动,使用此功能的大小调整一个规则来移动你的孩子:{C}
对于对准标志,我选择了DrawText的API函数,常量,因为他们(违反TA_常数为的TextOut API)DT_VCENTER常数。所以,是的,你可以有子窗口对话框的中心对齐,太。
的标志quot; keep_dxquot;和"keep_dyquot;告诉是否允许舒展子窗口,或保持大小调整大小助手。对于一个按钮,主要是要保留的大小,而你想主编辑控制捉襟见肘,最有可能的。
这是在这里:
// ---------------------------------------------------

// OnSize handling of the Child Ctrls

// ---------------------------------------------------

void GFResizeDialogHelper::OnSize(int cx, int cy)

{

    m_CurSize.cx = cx;

    m_CurSize.cy = cy;



    for(int i=0; i<(int)m_Ctrls.size(); ++i)

    {

        CTRL_ALIGN& ctrl = m_Ctrls[i];



        int x = ctrl.place.left;

        int width = ctrl.place.Width();

        if(!ctrl.keep_dx)

        {

            width += (cx - m_OrigSize.cx);

            // new size increment = dialog increment

        }

        if(ctrl.align & DT_RIGHT)

        {

            x = ctrl.place.right - width + cx-m_OrigSize.cx;

        }

        else if(ctrl.align & DT_CENTER)

        {

            // ctrl center

            int xcenter = (ctrl.place.left+ctrl.place.right)/2;

            // dialog offset

            xcenter += (cx-m_OrigSize.cx)/2;

            x = xcenter-width/2;

        }

        

        int y = ctrl.place.top;

        int height = ctrl.place.Height();

        if(!ctrl.keep_dy)

        {

            height+=(cy-m_OrigSize.cy);

        }

        if(ctrl.align & DT_BOTTOM)

        {

            // y += cy-m_OrigSize.cy;

            y = ctrl.place.bottom - height + cy-m_OrigSize.cy;

        }

        else if(ctrl.align & DT_VCENTER)

        {

            // ctrl center

            int ycenter = (ctrl.place.top + ctrl.place.bottom)/2;

            // dialog offset

            ycenter += (cy-m_OrigSize.cy)/2;

            y = ycenter - height/2;

        }

        width = max(width, 10);

        height = max(height, 10);

        x = max(0,x);

        y = max(0,y);



        m_pDialog->GetDlgItem(ctrl.idWnd)->MoveWindow(x,y,width, height, FALSE);

        // ::MoveWindow(ctrl.pWnd->GetSafeHwnd(), x,y,width, height, TRUE);

    }

    if(m_pDialog && m_pDialog->GetSafeHwnd() && 

                ::IsWindow(m_pDialog->GetSafeHwnd()))

        m_pDialog->RedrawWindow();

}

接下来,我发现,每一个对话框中有一个国际长途电话的常量,它是的对话框资源ID。好!我们可以使用存储在对话框的大小关闭注册表中的时间这个ID,我想,但然后我发现,说:m_pDialog - GT; GetRuntimeClass()- GT; m_lpszClassName返回的对话框类的名称为可读的字符串,和我把那一个。使用代码
的代码是使用一块蛋糕。您只包括上述两个项目中的文件。然后,打开mydialog.h的文件,并添加以下两行:
include "gfresizehelper.h" // include header



// and add a member variable to your CDialog derived class:

GFResizeDialogHelper    m_Resizer;

下一步是向大家介绍一下您的子窗口,以及如何你想让他们的行为时,调整大小帮手:
BOOL CMyDialog::OnInitDialog()

{

    // ...

    m_Resizer.Init(this);

    m_Resizer.AddCtrl(IDOK, DT_BOTTOM|DT_RIGHT);

    // ... more controls

    // optionally - read and write position and size to registy

    m_Resizer.ReadWriteToRegistry();

}

/*

// Usage of AddCtrl(int id, int align, BOOL keep_dx, BOOL keep_dy)

int id:

    The ID of the control (IDC_...)

int align:

    The alignment of the control. If you align it

    Horizontally:

        DT_LEFT,    the left-coordinate will stay where it is.

        DT_CENTER,    the center of the control will stay where it was,

                    relative to the dialog.

        DT_RIGHT,    the right border of the control will keep the distance

                    to the right border of the dialog.

    Vertically:

        DT_TOP,        the top position will stay

        DT_VCENTER,    the vertical center will stay where it was relative

                    to the dialog.

        DT_BOTTOM,    the controll will keep the distance to the bottom of

                    the dialog

BOOL keep_dx

    Should the control keep its width?

BOOL keep_dy

    Should the control keep its height?

*/
上课的时候​​销毁,通常是后一个的OnOK()或OnCancel()
ReadWriteToRegistry()的调​​用将尝试获得最后从注册表中存储的大小和位置,并且将存储的规模从去年的WM_SIZE消息。
然后,使用应用程序向导或对话框的属性,为OnSize(WM_SIZE消息)得到一个消息处理程序,并告诉调整帮手照顾你的孩子。
void CMyDialog::OnSize(UINT nType, int cx, int cy)

{

    CDialog::OnSize(nType, cx, cy);

    m_Resizer.OnSize(cx,cy);

}

最后,你可以处理WM_GETMINMAXINFO消息告诉程序不小于你在对话框编辑器设计窗口:
void CMyDialog::OnGetMinMaxInfo(MINMAXINFO* lpMMI)

{

    m_Resizer.GetMinMaxInfo(lpMMI);

}

我希望这篇文章是一些有人使用。我用这个类,现在很多,我真的很喜欢我与可调整大小的对话框方案的新面貌。

回答

评论会员:米赞拉赫曼 时间:2012/01/24
{A}

/米赞
评论会员:乔治Kofman 时间:2012/01/24
喜Gernot;

不错的方案!谢谢!我有一个问题要问你 - [如何]我可以使用您的图像缩放,使我的孩子认为=对话框的大小,我在程序的开始开放?我有一个SDI应用程序,并希望有一个对话窗口自动想出占领整个客户区[和理想的"粘"在客户区中,直到对话框退出]。这是真的只需要在初始对话(有点像一堆调用其他对话框的按钮,"快速启动")。
谢谢。乔治(非常的MFC新手)
评论会员:维克托Nijegorodov 时间:2012/01/24
你有没有听到(或可能读的东西)大约]保罗墨西拿
什么是使用你的类比较优势,与保罗墨西拿的类
评论会员:?Gernot弗里希 时间:2012/01/24
不,我没有。但据我可以看到他的定义自己的派生类从CDialog和喜欢我的解决方案,这就造成一些打字开销。煤矿仅仅是在实现文件中的4行代码
评论会员:。维克多Nijegorodov 时间:2012/01/24
"键入开销"你的意思吗? {S0}
我使用他的图书馆属性表/页,过去八年以来,从来没有看到任何"开销"。
相反,ResizableLib更强大,因为它有10个选项,锚子控件与你只有五个的
比较
评论会员:。SBJ 时间:2012/01/24
我喜欢聚集的行为,而不是继承它
评论会员:k777 时间:2012/01/24
如何嚣张!
你应该鼓励,而不是像这样的行为"一书的作者
评论会员:chenyu2202863 时间:2012/01/24
是否在CFormView的使用
评论会员:Gernot弗里希 时间:2012/01/24
我不知道肯定。我从来没有使用一个FormView。但它可能是肯定的。
虽然,init函数需要一个CDialog *.