如何在MFC中调整对话框大小时移动控件? [英] How to move a control while resizing dialog size in MFC?

查看:764
本文介绍了如何在MFC中调整对话框大小时移动控件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我可以从下面的图片看到(像滑块控制和编辑框等)

p>

在调整对话框大小时,这些控件不会移动。





当我调整对话框的大小时,我得到了



如您所见,滑块已消失。



我在这里更新了MyDlg.cpp

  // mfc_test5Dlg.cpp:implementation file 
//

#includestdafx.h
#includemf​​c_test5.h
#includemf​​c_test5Dlg.h
#includeafxdialogex.h
#includeTestview.h
#include< Magick ++。h>
extern CTestview * global_TestView;
char * fileposition;


#ifdef _DEBUG
#define new DEBUG_NEW
#endif


//用于App的CAboutDlg对话框关于

class CAboutDlg:public CDialogEx
{
public:
CAboutDlg();

//对话框数据
枚举{IDD = IDD_ABOUTBOX};

protected:
virtual void DoDataExchange(CDataExchange * pDX); // DDX / DDV支持

//实现
protected:
DECLARE_MESSAGE_MAP()
};

CAboutDlg :: CAboutDlg():CDialogEx(CAboutDlg :: IDD)
{
}

void CAboutDlg :: DoDataExchange(CDataExchange * pDX)
{
CDialogEx :: DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg,CDialogEx)
END_MESSAGE_MAP()


// Cmfc_test5Dlg对话框




Cmfc_test5Dlg :: Cmfc_test5Dlg(CWnd * pParent / * = NULL * /)
:CDialogEx(Cmfc_test5Dlg :: IDD,pParent)
,m_CString ))
{
m_hIcon = AfxGetApp() - > LoadIcon(IDR_MAINFRAME);
fileposition =(char *)this;
m_pTestView = NULL;
}

void Cmfc_test5Dlg :: DoDataExchange(CDataExchange * pDX)
{
CDialogEx :: DoDataExchange(pDX);
DDX_Control(pDX,IDC_SLIDER1,m_CSliderCtrl);
DDX_Text(pDX,IDC_EDIT1,m_CString);
}

BEGIN_MESSAGE_MAP(Cmfc_test5Dlg,CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_NOTIFY(NM_RELEASEDCAPTURE,IDC_SLIDER1, & Cmfc_test5Dlg :: OnNMReleasedcaptureSlider1)
ON_WM_DROPFILES()
ON_WM_CREATE()
ON_WM_SIZE()
END_MESSAGE_MAP()



BOOL Cmfc_test5Dlg :: OnInitDialog()
{

CDialogEx :: OnInitDialog();
GetClientRect(& m_SaveRect);

//将About ...菜单项添加到系统菜单。


CRuntimeClass * pObject;
pObject = RUNTIME_CLASS(CTestview);
m_pTestView =(CTestview *)pObject-> CreateObject();
CRect crt;
GetClientRect(& crt);
int x,y;
x = crt.Width();
y = crt.Height();
//http://stackoverflow.com/questions/33653087/how-to-move-a-control-while-resizing-dialog-size-in-mfc
// m_CSliderCtrl.SetWindowPos(0 ,x-293,y-125,x-293,y-125,SWP_NOSIZE / * SWP_NOZORDER * /)

if(!m_pTestView-> Create(NULL,NULL,AFX_WS_DEFAULT_VIEW,CRect(0,0,x-200,y),this,AFX_IDW_PANE_FIRST,NULL))
{
TRACE0(无法创建视图窗口\\\
);
return -1;
}


// IDM_ABOUTBOX必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX& 0xFFF0)== IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX< 0xF000);

CMenu * pSysMenu = GetSystemMenu(FALSE);
如果(pSysMenu!= NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if(!strAboutMenu.IsEmpty())
{
pSysMenu-> AppendMenu(MF_SEPARATOR);
pSysMenu-> AppendMenu(MF_STRING,IDM_ABOUTBOX,strAboutMenu);
}
}

//设置此对话框的图标。框架自动
//当应用程序的主窗口不是对话框时
SetIcon(m_hIcon,TRUE); // Set big icon
SetIcon(m_hIcon,FALSE); //设置小图标

// TODO:在此处添加额外的初始化
m_CSliderCtrl.SetRange(0,255); // Reference Here(http://system.tistory.com/13)
m_CSliderCtrl.SetRangeMin(0);
m_CSliderCtrl.SetRangeMax(255);
m_CSliderCtrl.SetPos(128);
m_CSliderCtrl.SetLineSize(1);
m_CString.Format(_T(%d),0); // Reference here(http://depts.washington.edu/cmmr/biga/chapter_tutorials/1.C++_MFC_D3DOGL/1.StepByStepGuide/tutorial_3.html)


return TRUE ; //返回TRUE,除非将焦点设置为控件
}

void Cmfc_test5Dlg :: OnSysCommand(UINT nID,LPARAM lParam)
{
if( & 0xFFF0)== IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialogEx :: OnSysCommand(nID,lParam);
}
}

//如果您在对话框中添加了一个最小化按钮,您将需要
//下面的代码来绘制图标。对于使用文档/视图模型的MFC应用程序,
//这是由框架自动完成的。

void Cmfc_test5Dlg :: OnPaint()
{
if(IsIconic())
{
CPaintDC dc(this); //用于绘画的设备上下文

SendMessage(WM_ICONERASEBKGND,reinterpret_cast< WPARAM>(dc.GetSafeHdc()),0);

//客户端矩形中的中心图标
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(& rect);
int x =(rect.Width() - cxIcon + 1)/ 2;
int y =(rect.Height() - cyIcon + 1)/ 2;

//绘制图标
dc.DrawIcon(x,y,m_hIcon);
}
else
{
CDialogEx :: OnPaint();
}
}

//当用户拖动
//最小化窗口时,系统调用此函数获取要显示的游标。
HCURSOR Cmfc_test5Dlg :: OnQueryDragIcon()
{
return static_cast< HCURSOR>(m_hIcon);
}



void Cmfc_test5Dlg :: OnNMReleasedcaptureSlider1(NMHDR * pNMHDR,LRESULT * pResult)
{
// TODO:控制通知处理程序代码在这里
int value = m_CSliderCtrl.GetPos(); // Reference Here(http://depts.washington.edu/cmmr/biga/chapter_tutorials/1.C++_MFC_D3DOGL/1.StepByStepGuide/tutorial_3.html)
m_CString.Format(_T(%d ),value);
UpdateData(FALSE);

* pResult = 0;
}


void Cmfc_test5Dlg :: OnDropFiles(HDROP hDropInfo)
{

int nFiles;
static char szPathName [MAX_PATH]; //파일경로면이들어간다
CString strFileName;

:: DragQueryFile(hDropInfo,0,szPathName,MAX_PATH);

:: DragFinish(hDropInfo);
CDialog :: OnDropFiles(hDropInfo);
CDialogEx :: OnDropFiles(hDropInfo);

fileposition = szPathName
if(m_pTestView!= NULL)
m_pTestView-> DoDisplayImage();


}


int Cmfc_test5Dlg :: OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if(CDialogEx :: OnCreate lpCreateStruct)== -1)
return -1;

// TODO:在这里添加专门的创建代码


return 0;
}

void OffsetChildWindow(CWnd * child,int dx,int dy,int dw,int dh)
{
if(!child)
{
return; //添加错误处理,控制不退出
}

if(!child-> GetParent())
{
return;
}

//查找子窗口相对于父对象左上角的坐标
CRect rc;
child-> GetClientRect(& rc);
CPoint p(0,0);
ScreenToClient(child-> GetParent() - > GetSafeHwnd(),& p);
rc.OffsetRect(p);

//防止负大小
if((rc.Width()+ dw)< 0)dw = -rc.Width
if((rc.Height()+ dh)< 0)dh = -rc.Height();

child-> SetWindowPos(0,rc.left + dx,rc.top + dy,rc.Width()+ dw,rc.Height()+ dh,SWP_NOZORDER);


child->无效(FALSE);
}

void Cmfc_test5Dlg :: OnSize(UINT nType,int cx,int cy)
{
CDialogEx :: OnSize(nType,cx,cy);

// TODO:在这里添加消息处理程序代码

if(!cx ||!cy)
return;


if(m_pTestView)
{
m_pTestView-> MoveWindow(0,0,cx-200,cy);
}


int dx = cx - m_SaveRect.right;
int dy = cy - m_SaveRect.bottom;

OffsetChildWindow(GetDlgItem(IDC_SLIDER1),0,dy,dx,0);
GetClientRect(& m_SaveRect);

}

这里是头文件。

  // mfc_test5Dlg.h:头文件
//

#pragma once
#include afxcmn.h
#includeTestview.h
#includeatltypes.h



// Cmfc_test5Dlg对话框
class Cmfc_test5Dlg:public CDialogEx
{
// Construction
public:
Cmfc_test5Dlg(CWnd * pParent = NULL); //标准构造函数

//对话框数据
枚举{IDD = IDD_MFC_TEST5_DIALOG};

protected:
virtual void DoDataExchange(CDataExchange * pDX); // DDX / DDV支持


//实现
protected:
HICON m_hIcon;

//生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID,LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
CSliderCtrl m_CSliderCtrl;
private:
CString m_CString;
public:
afx_msg void OnNMReleasedcaptureSlider1(NMHDR * pNMHDR,LRESULT * pResult);
afx_msg void OnDropFiles(HDROP hDropInfo);
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
CTestview * m_pTestView;
afx_msg void OnSize(UINT nType,int cx,int cy);
CRect m_SaveRect
};



更新3



但它不stll工作很好。
当我调整对话框的大小左。



当我调整对话框的大小留下这么多。



当我将对话框调整到右边。

< a href =http://i.stack.imgur.com/uTxbU.png =nofollow>



------------------------- ------------------------------



编辑2



复制/粘贴这两个函数

code> OffsetChildWindow 和 Cmfc_test5Dlg :: OnSize 并删除旧的函数。我已更新。

  void OffsetChildWindow(CWnd * child,int dx,int dy,int dw,int dh)
{
if(!child)return;
if(!child-> GetParent())return;
if(!IsWindow(child-> m_hWnd))return;

//查找子窗口相对于父对象左上角的坐标
CRect rc;
child-> GetWindowRect(& rc);
CPoint p(0,0);
ScreenToClient(child-> GetParent() - > GetSafeHwnd(),& p);
rc.OffsetRect(p);

//防止负大小
if((rc.Width()+ dw)< 0)dw = -rc.Width
if((rc.Height()+ dh)< 0)dh = -rc.Height();

child-> SetWindowPos(0,rc.left + dx,rc.top + dy,rc.Width()+ dw,rc.Height()+ dh,SWP_NOZORDER);
child-> Invalidate(FALSE);
}

void Cmfc_test5Dlg :: OnSize(UINT nType,int cx,int cy)
{
CDialogEx :: OnSize(nType,cx,cy);
if(!cx ||!cy)return;

int dx = cx - m_SaveRect.right;
int dy = cy - m_SaveRect.bottom;

OffsetChildWindow(m_pTestView,0,0,dx,dy);
OffsetChildWindow(GetDlgItem(IDC_SLIDER1),dx,dy,0,0);
OffsetChildWindow(GetDlgItem(IDC_EDIT1),dx,dy,0,0);
GetClientRect(& m_SaveRect);
}


I've made a view on dialog in MFC.

You can see well from the following image.(like slider control and edit box, etc)

These controls are not moved when I resize a dialog size.

enter image description here

I'd like to move the controls to fit dialog. but not need to resize of controls.

What should I do for solving for this problem?

update 1

Especially, I want to set the slider position.

So firstly, I add member variable of slider 'CSliderCtrl sss' to dialog class then I made this in OnSize();

 OnSize()
{
....
sss.MoveWindow(10, 10,cx-20,cy-60);
....

}

BTW, the problem is that the first position of slider difference between after resize of dialog.

So I want to know that how to set first position of slider in InitialDialog.

update 2

I've got followed up with your source. but it's difference working between you and me.

When I run first I got this

When I resize the dialog a very little I got this

As you can see, the slider is disappeared.

I have update here the MyDlg.cpp

// mfc_test5Dlg.cpp : implementation file
//

#include "stdafx.h"
#include "mfc_test5.h"
#include "mfc_test5Dlg.h"
#include "afxdialogex.h"
#include "Testview.h"
#include <Magick++.h>
extern CTestview *global_TestView;
char * fileposition;


#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CAboutDlg dialog used for App About

class CAboutDlg : public CDialogEx
{
public:
    CAboutDlg();

    // Dialog Data
    enum { IDD = IDD_ABOUTBOX };

protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support

    // Implementation
protected:
    DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()


// Cmfc_test5Dlg dialog




Cmfc_test5Dlg::Cmfc_test5Dlg(CWnd* pParent /*=NULL*/)
    : CDialogEx(Cmfc_test5Dlg::IDD, pParent)
    , m_CString(_T(""))
{
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    fileposition = (char*)this;
    m_pTestView = NULL;
}

void Cmfc_test5Dlg::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_SLIDER1, m_CSliderCtrl);
    DDX_Text(pDX, IDC_EDIT1, m_CString);
}

BEGIN_MESSAGE_MAP(Cmfc_test5Dlg, CDialogEx)
    ON_WM_SYSCOMMAND()
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    ON_NOTIFY(NM_RELEASEDCAPTURE, IDC_SLIDER1, &Cmfc_test5Dlg::OnNMReleasedcaptureSlider1)
    ON_WM_DROPFILES()
    ON_WM_CREATE()
    ON_WM_SIZE()
END_MESSAGE_MAP()



BOOL Cmfc_test5Dlg::OnInitDialog()
{

    CDialogEx::OnInitDialog();
     GetClientRect(&m_SaveRect);

    // Add "About..." menu item to system menu.


    CRuntimeClass *pObject;
    pObject = RUNTIME_CLASS(CTestview);
    m_pTestView = (CTestview*)pObject->CreateObject();
    CRect crt;
    GetClientRect(&crt);
    int x,y;
     x = crt.Width();
     y  = crt.Height();
     //http://stackoverflow.com/questions/33653087/how-to-move-a-control-while-resizing-dialog-size-in-mfc
//   m_CSliderCtrl.SetWindowPos(0,x-293,y-125,x-293,y-125,SWP_NOSIZE /*SWP_NOZORDER*/);

    if (!m_pTestView->Create(NULL, NULL, AFX_WS_DEFAULT_VIEW, CRect(0, 0,x-200 ,y), this, AFX_IDW_PANE_FIRST, NULL))
    {
        TRACE0("Failed to create view window\n");
        return -1;
    }


    // IDM_ABOUTBOX must be in the system command range.
    ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
    ASSERT(IDM_ABOUTBOX < 0xF000);

    CMenu* pSysMenu = GetSystemMenu(FALSE);
    if (pSysMenu != NULL)
    {
        BOOL bNameValid;
        CString strAboutMenu;
        bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
        ASSERT(bNameValid);
        if (!strAboutMenu.IsEmpty())
        {
            pSysMenu->AppendMenu(MF_SEPARATOR);
            pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
        }
    }

    // Set the icon for this dialog.  The framework does this automatically
    //  when the application's main window is not a dialog
    SetIcon(m_hIcon, TRUE);         // Set big icon
    SetIcon(m_hIcon, FALSE);        // Set small icon

    // TODO: Add extra initialization here
    m_CSliderCtrl.SetRange(0,255); //Reference Here (http://system.tistory.com/13)
    m_CSliderCtrl.SetRangeMin(0);
    m_CSliderCtrl.SetRangeMax(255);
    m_CSliderCtrl.SetPos(128);
    m_CSliderCtrl.SetLineSize(1);
    m_CString.Format(_T("%d"), 0); //Reference here (http://depts.washington.edu/cmmr/biga/chapter_tutorials/1.C++_MFC_D3DOGL/1.StepByStepGuide/tutorial_3.html)


    return TRUE;  // return TRUE  unless you set the focus to a control
}

void Cmfc_test5Dlg::OnSysCommand(UINT nID, LPARAM lParam)
{
    if ((nID & 0xFFF0) == IDM_ABOUTBOX)
    {
        CAboutDlg dlgAbout;
        dlgAbout.DoModal();
    }
    else
    {
        CDialogEx::OnSysCommand(nID, lParam);
    }
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void Cmfc_test5Dlg::OnPaint()
{
    if (IsIconic())
    {
        CPaintDC dc(this); // device context for painting

        SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

        // Center icon in client rectangle
        int cxIcon = GetSystemMetrics(SM_CXICON);
        int cyIcon = GetSystemMetrics(SM_CYICON);
        CRect rect;
        GetClientRect(&rect);
        int x = (rect.Width() - cxIcon + 1) / 2;
        int y = (rect.Height() - cyIcon + 1) / 2;

        // Draw the icon
        dc.DrawIcon(x, y, m_hIcon);
    }
    else
    {
        CDialogEx::OnPaint();
    }
}

// The system calls this function to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR Cmfc_test5Dlg::OnQueryDragIcon()
{
    return static_cast<HCURSOR>(m_hIcon);
}



void Cmfc_test5Dlg::OnNMReleasedcaptureSlider1(NMHDR *pNMHDR, LRESULT *pResult)
{
    // TODO: Add your control notification handler code here
    int value = m_CSliderCtrl.GetPos(); //Reference Here (http://depts.washington.edu/cmmr/biga/chapter_tutorials/1.C++_MFC_D3DOGL/1.StepByStepGuide/tutorial_3.html)
    m_CString.Format(_T("%d"), value);
    UpdateData(FALSE);

    *pResult = 0;
}


void Cmfc_test5Dlg::OnDropFiles(HDROP hDropInfo)
{

    int nFiles;
    static char szPathName[MAX_PATH]; // 파일 경로면이 들어간다.
    CString strFileName;

    ::DragQueryFile(hDropInfo, 0, szPathName, MAX_PATH);

    ::DragFinish(hDropInfo);
    CDialog::OnDropFiles(hDropInfo);
    CDialogEx::OnDropFiles(hDropInfo);

    fileposition = szPathName;
    if (m_pTestView != NULL)
        m_pTestView->DoDisplayImage();


}


int Cmfc_test5Dlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CDialogEx::OnCreate(lpCreateStruct) == -1)
        return -1;

    // TODO:  Add your specialized creation code here


    return 0;
}

void OffsetChildWindow(CWnd* child, int dx, int dy, int dw, int dh)
{
    if (!child)
    {
        return; //Add error handling, control does not exits
    }

    if (!child->GetParent()) 
    {
        return;
    }

    //find child window's coordinates relative to top-left of parent
    CRect rc;
    child->GetClientRect(&rc);
    CPoint p(0, 0);
    ScreenToClient(child->GetParent()->GetSafeHwnd(), &p);
    rc.OffsetRect(p);

    //prevent negative size
    if ((rc.Width() + dw) < 0) dw = -rc.Width();
    if ((rc.Height() + dh) < 0) dh = -rc.Height();

   child->SetWindowPos(0, rc.left + dx, rc.top + dy, rc.Width() + dw, rc.Height() + dh, SWP_NOZORDER);


    child->Invalidate(FALSE);
}

void Cmfc_test5Dlg::OnSize(UINT nType, int cx, int cy)
{
    CDialogEx::OnSize(nType, cx, cy);

    // TODO: Add your message handler code here

    if (!cx || !cy)
        return;


    if (m_pTestView)
    {
        m_pTestView->MoveWindow(0, 0, cx-200, cy);
    }


    int dx = cx - m_SaveRect.right;
    int dy = cy - m_SaveRect.bottom;

    OffsetChildWindow(GetDlgItem(IDC_SLIDER1), 0,dy,dx,0);
    GetClientRect(&m_SaveRect);

}

and here is header file.

// mfc_test5Dlg.h : header file
//

#pragma once
#include "afxcmn.h"
#include "Testview.h"
#include "atltypes.h"



// Cmfc_test5Dlg dialog
class Cmfc_test5Dlg : public CDialogEx
{
// Construction
public:
    Cmfc_test5Dlg(CWnd* pParent = NULL);    // standard constructor

// Dialog Data
    enum { IDD = IDD_MFC_TEST5_DIALOG };

    protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support


// Implementation
protected:
    HICON m_hIcon;

    // Generated message map functions
    virtual BOOL OnInitDialog();
    afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
    afx_msg void OnPaint();
    afx_msg HCURSOR OnQueryDragIcon();
    DECLARE_MESSAGE_MAP()
public:
    CSliderCtrl m_CSliderCtrl;
private:
    CString m_CString;
public:
    afx_msg void OnNMReleasedcaptureSlider1(NMHDR *pNMHDR, LRESULT *pResult);
    afx_msg void OnDropFiles(HDROP hDropInfo);
    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
    CTestview *m_pTestView;
    afx_msg void OnSize(UINT nType, int cx, int cy);
    CRect m_SaveRect;
};

update 3

I have updated. but it does not stll work well. When I resize the dialog to left a little.

when I resize the dialog to left so many.

When I resize the dialog to right.

解决方案

Another method, use this function:

void OffsetChildWindow(CWnd* child, int dx, int dy, int dw, int dh)
{
    if (!child) return;
    if (!child->GetParent()) return;
    if (!IsWindow(child->m_hWnd)) return;

    //find child window's coordinates relative to top-left of parent
    CRect rc;
    child->GetWindowRect(&rc);
    CPoint p(0, 0);
    ScreenToClient(child->GetParent()->GetSafeHwnd(), &p);
    rc.OffsetRect(p);

    //prevent negative size
    if ((rc.Width() + dw) < 0) dw = -rc.Width();
    if ((rc.Height() + dh) < 0) dh = -rc.Height();

    child->SetWindowPos(0, rc.left + dx, rc.top + dy, rc.Width() + dw, rc.Height() + dh, SWP_NOZORDER);
    child->Invalidate(FALSE);
}

Declare a member variable as follows: CRect m_SaveRect;

//Initialize
BOOL CMyDialog::OnInitDialog()
{
    CDialogEx::OnInitDialog();
    GetClientRect(&m_SaveRect);
    ...
}

void CMyDialog::OnSize(UINT f, int cx, int cy)
{
    CDialogEx::OnSize(f, cx, cy);

    if (!cx || !cy)
        return;

    //(this error check is needed on at least one child control)
    if (!GetDlgItem(IDOK)) return; //not ready yet

    int dx = cx - m_SaveRect.right;
    int dy = cy - m_SaveRect.bottom;

    OffsetChildWindow(GetDlgItem(IDCANCEL), dx, dy, 0, 0);
    OffsetChildWindow(GetDlgItem(IDOK), dx, dy, 0, 0);
    OffsetChildWindow(GetDlgItem(IDC_SLIDER1), 0, dy, dx, 0);
    OffsetChildWindow(GetDlgItem(IDC_EDIT1), 0, 0, dx, dy);

    GetClientRect(&m_SaveRect);
}

dx or dy can be zero if you need only one of horizontal/vertical offset.

While we are at it, you may also need to add ON_WM_GETMINMAXINFO to message map to prevent the dialog from becoming too small:

void CMyDialog::OnGetMinMaxInfo(MINMAXINFO *mx)
{
    mx->ptMinTrackSize.x = 400; //minimum 400x300 size
    mx->ptMinTrackSize.y = 300;
    CDialogEx::OnGetMinMaxInfo(mx);
}

-------------------------------------------------------

Edit 2

Edit 3

Copy/Paste these 2 functions OffsetChildWindow and Cmfc_test5Dlg::OnSize and remove the old functions. I have made updates.

void OffsetChildWindow(CWnd* child, int dx, int dy, int dw, int dh)
{
    if (!child) return;
    if (!child->GetParent()) return;
    if (!IsWindow(child->m_hWnd)) return;

    //find child window's coordinates relative to top-left of parent
    CRect rc;
    child->GetWindowRect(&rc);
    CPoint p(0, 0);
    ScreenToClient(child->GetParent()->GetSafeHwnd(), &p);
    rc.OffsetRect(p);

    //prevent negative size
    if ((rc.Width() + dw) < 0) dw = -rc.Width();
    if ((rc.Height() + dh) < 0) dh = -rc.Height();

    child->SetWindowPos(0, rc.left + dx, rc.top + dy, rc.Width() + dw, rc.Height() + dh, SWP_NOZORDER);
    child->Invalidate(FALSE);
}

void Cmfc_test5Dlg::OnSize(UINT nType, int cx, int cy)
{
    CDialogEx::OnSize(nType, cx, cy);
    if (!cx || !cy) return;

    int dx = cx - m_SaveRect.right;
    int dy = cy - m_SaveRect.bottom;

    OffsetChildWindow(m_pTestView, 0,0,dx,dy);
    OffsetChildWindow(GetDlgItem(IDC_SLIDER1), dx,dy,0,0);
    OffsetChildWindow(GetDlgItem(IDC_EDIT1), dx,dy,0,0);
    GetClientRect(&m_SaveRect);
}

这篇关于如何在MFC中调整对话框大小时移动控件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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