[英]How to move a control while resizing dialog size in MFC?
I've made a view on dialog in MFC. 我已经在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? 我该怎么做才能解决这个问题?
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(); 首先,我将滑块'CSliderCtrl sss'的成员变量添加到对话框类,然后我在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. BTW,问题在于调整对话框后调整滑块的第一个位置。
So I want to know that how to set first position of slider in InitialDialog. 所以我想知道如何在InitialDialog中设置滑块的第一个位置。
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 我在这里更新了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;
};
I have updated. 我已经更新了。 but it does not stll work well.
但它并不适用。 When I resize the dialog to left a little.
当我调整对话框的大小时留下一点。
Try this. 试试这个。
CResizableDialog in codeproject codeproject中的CResizableDialog
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;
声明一个成员变量如下:
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. 如果只需要水平/垂直偏移中的一个,则
dx
或dy
可以为零。
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: 在我们处理它时,您可能还需要将
ON_WM_GETMINMAXINFO
添加到消息映射以防止对话框变得太小:
void CMyDialog::OnGetMinMaxInfo(MINMAXINFO *mx)
{
mx->ptMinTrackSize.x = 400; //minimum 400x300 size
mx->ptMinTrackSize.y = 300;
CDialogEx::OnGetMinMaxInfo(mx);
}
Edit 2 编辑2
Edit 3 编辑3
Copy/Paste these 2 functions OffsetChildWindow
and Cmfc_test5Dlg::OnSize
and remove the old functions. 复制/粘贴这两个函数
OffsetChildWindow
和Cmfc_test5Dlg::OnSize
并删除旧函数。 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);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.