
這個界面
if (pWnd)
{
CRect rect;
pWnd->GetWindowRect(&rect); //獲取控制元件變化前的大小
ScreenToClient(&rect);//將控制元件大小轉換為在對話框中的區域坐標
rect.left=rect.left*cx/m_rect.Width();//調整控制元件大小 ,cx/m_rect.Width()為對話框在橫向的變化比例
rect.right=rect.right*cx/m_rect.Width(); //cx存盤的是變化后的寬度,cy存盤的是變化后的高度
rect.top=rect.top*cy/m_rect.Height(); //m_rect.height()表示的是變化前主表單的高度
rect.bottom=rect.bottom*cy/m_rect.Height();
pWnd->MoveWindow(rect);//設定控制元件大小
}
這樣的話縮小的時候控制元件會亂
用easysize的話控制元件太多不好處理關系
應該怎樣做到控制元件隨視窗變化大小。
uj5u.com熱心網友回復:
onsize中計算相對位置 然后movewindow挪過去uj5u.com熱心網友回復:
上面那個不就是嗎,縮小時問題很大應該怎么計算啊uj5u.com熱心網友回復:
“這樣的話縮小的時候控制元件會亂”不明白 !
uj5u.com熱心網友回復:

就是會變成這個樣子
uj5u.com熱心網友回復:
WPF ?uj5u.com熱心網友回復:
其實可以自己實作一個布局管理器,如盒子布局HBoxLayout,VBoxLayout,其作用就是調整它所管理的控制元件坐標,內部實作是SetWindowPos,每添加一個控制元件就手動AddWidget(HWND)當然這些介面都需要你自己實作,很簡單。uj5u.com熱心網友回復:
SetWindowPos;MoveWindow
uj5u.com熱心網友回復:
OnSize里面 SetWindowPos的引數用Rect 的長跟寬uj5u.com熱心網友回復:
這是MFC比較蛋疼的地方,沒有布局管理器,你可以參考下duilib的布局管理器,自己寫一個uj5u.com熱心網友回復:
pWnd->MoveWindow(rect);//這個 rect 必須是 Screen 坐標,你 ScreenToClient(&rect); 后 沒有 再 轉回去!uj5u.com熱心網友回復:
加上ClientToScreen(&rect);之后就直接沒有控制元件了
uj5u.com熱心網友回復:
http://www.codeproject.com/Articles/125068/MFC-C-Helper-Class-for-Window-Resizinghttp://www.codeproject.com/Articles/34292/Helper-Class-for-Resizable-MFC-Dialogs
uj5u.com熱心網友回復:
ScreenToClient(&rect);//將控制元件大小轉換為在對話框中的區域坐標這句沒錯。
你的 代碼 要 放 OnSize 中,
pWnd->GetWindowRect(&rect); //獲取控制元件變化前的大小 要在 init 里
OnSize (的 cx,cy)是 當前客戶區。
如 OnInitDialog()
CRect rc;
GetClientRect(&rc);
// 對話框 原 W H
m_dlgW=rc.Width();
m_dlgH=rc.Height();
afxDump << m_dlgW << ";" << m_dlgH << "\n";// 720;450
// 按鈕 原 rect
m_Button1.GetWindowRect(m_btRectOrig);
afxDump << m_btRectOrig << "\n";// (L 244, T 148, R 460, B 240)
ScreenToClient(&m_btRectOrig); //
afxDump << m_btRectOrig << "\n";// (L 239, T 115, R 455, B 207)
。。。
uj5u.com熱心網友回復:
對話框只有一個 按鈕:
init:
//
CRect rc;
GetClientRect(&rc);
m_dlgW=rc.Width();
m_dlgH=rc.Height();
afxDump << m_dlgW << ";" << m_dlgH << "\n";// 720;450
m_Button1.GetWindowRect(m_btRectOrig);
afxDump << m_btRectOrig << "\n";// (L 244, T 148, R 460, B 240)
ScreenToClient(&m_btRectOrig); //
afxDump << m_btRectOrig << "\n";// (L 239, T 115, R 455, B 207)
。。。。。
void CScalerDlg::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
double xRate=(double)cx/(double)m_dlgW;
double yRate=(double)cy/(double)m_dlgH;
// afxDump << xRate << ";" << xRate << "\n";
if(::IsWindow(m_Button1.m_hWnd))
{
CRect rcNow;
rcNow.left=(int)(m_btRectOrig.left*xRate);
rcNow.right=(int)(m_btRectOrig.right*xRate);
rcNow.top=(int)(m_btRectOrig.top*yRate);
rcNow.bottom=(int)(m_btRectOrig.bottom*yRate);
afxDump << rcNow << "\n";
//
m_Button1.MoveWindow(&rcNow);
}
}
uj5u.com熱心網友回復:
簡單點弄,一個界面初始大小顯示和一個最大化顯示,設定兩種控制元件的擺放和大小,不一定弄漸變顯示uj5u.com熱心網友回復:
推薦ETSLayout類 http://www.codeproject.com/Articles/116/Layout-Manager-for-Dialogs-Formviews-DialogBars-an翻譯過來的文章 視窗排列類——ETSLayout的使用
uj5u.com熱心網友回復:
在啟動時獲取所有控制元件的大小及位置,這個稱為原始值A,以及視窗大小B,后面視窗大小改變時,全部以此為基礎進行變化:m_btn1.GetWindowRect(&rect);
ScreenToClient(&rect);
rect = A * cx(cy) / B;
MoveWindow( rect );
uj5u.com熱心網友回復:
當然這種簡單的變化可能會導致你不想看到的效果,所以實際上,你需要對控制元件進行分類,對不同型別的控制元件進行不同的處理,比如通常來說文本框只會變長或者變短,而高低不會變化,按鈕大小不變,但是位置可能會改變,富文本框或者用于顯示多行內容的控制元件會大小改變uj5u.com熱心網友回復:
用movewindow沒有問題,但是有沒有想過,控制元件大小改變了,而控制元件上的文字是否也做需要改變,不然自適應的變動只會造成視覺的沖突。uj5u.com熱心網友回復:
#define USE_CLIENT
void CScalerDlg::GetCtrlClientRects()
{
int iCount = 0;
// right and bottom not used
CWnd* pWnd = GetTopWindow();// child window
CRect rc;
while(pWnd != NULL)
{
pWnd->GetWindowRect(&rc);
#ifdef USE_CLIENT
ScreenToClient(&rc); // Screen dlg's window to dlg's Client.
#endif
m_CtrlRcOrig[iCount++]=rc;
pWnd = pWnd->GetNextWindow();
}
}
//
BOOL CScalerDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// 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)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
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
// get dlg orignal W H
CRect rc;
GetClientRect(&rc);
m_dlgW=rc.Width();
m_dlgH=rc.Height();
// afxDump << m_dlgW << ";" << m_dlgH << "\n";// 720; 450
GetWindowRect(&rc);// (L 0, T 0, R 730, B 488)
// afxDump << rc << "\n";
m_s2cOffsetX=(rc.Width()-m_dlgW)/2;
m_s2cOffsetY=rc.Height()-m_s2cOffsetX-m_dlgH;
// afxDump << m_s2cOffsetX << ";" << m_s2cOffsetY << "\n";// 5;33
// 5=Border; 33=caption height=28+border=5
m_pStatic= new CStatic;
m_pStatic->Create(TEXT("Hello"),WS_CHILD|WS_VISIBLE|SS_LEFT, CRect(10,10,200,100),this,0x0201);
m_pStatic->ModifyStyle(0,SS_OWNERDRAW);
m_pStatic->ShowWindow(SW_SHOW);//TRUE);
// init rects
GetCtrlClientRects();
//
return TRUE; // return TRUE unless you set the focus to a control
}
//
void CScalerDlg::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
double xRate=(double)cx/(double)m_dlgW;
double yRate=(double)cy/(double)m_dlgH;
int iCount=0;
CRect rcNow(0);
CWnd* pWnd = GetTopWindow();
while(pWnd != NULL)
{
#ifndef USE_CLIENT
rcNow.left =(int)((m_CtrlRcOrig[iCount].left-m_s2cOffsetX)*xRate);
rcNow.right =(int)((m_CtrlRcOrig[iCount].right-m_s2cOffsetX)*xRate);
rcNow.top =(int)((m_CtrlRcOrig[iCount].top-m_s2cOffsetY)*yRate);
rcNow.bottom=(int)((m_CtrlRcOrig[iCount].bottom-m_s2cOffsetY)*yRate);
#else // has ScreenToClient(&rc); // Screen dlg's window to dlg's Client.
rcNow.left = (int)(m_CtrlRcOrig[iCount].left*xRate);
rcNow.right = (int)(m_CtrlRcOrig[iCount].right*xRate);
rcNow.top = (int)(m_CtrlRcOrig[iCount].top*yRate);
rcNow.bottom= (int)(m_CtrlRcOrig[iCount].bottom*yRate);
#endif
pWnd->MoveWindow(&rcNow,TRUE);
pWnd = pWnd->GetNextWindow();
iCount++;
}
}
// in .h
protected:
HICON m_hIcon;
int m_dlgW;
int m_dlgH;
int m_s2cOffsetX;
int m_s2cOffsetY;
CRect m_CtrlRcOrig[10];
CStatic *m_pStatic;
uj5u.com熱心網友回復:
CRect m_CtrlRcOrig[10];可以 到 10個 控制元件。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/123960.html
標籤:界面
