我正在编写一个程序,它有两个窗格(通过CSplitter
),但是我遇到了调整每个框架中控件大小的问题。为简单起见,有人能告诉我如何在具有单个CEdit
控件的基本框架中完成吗?
我相当确定这与CEdit::OnSize()
函数有关...但是我真的没有取得任何进展...
谢谢!:)
窗口在被调整大小后立即接收 WM_SIZE 消息(由 MFC 中的 OnSize 处理程序处理),因此 CEdit::OnSize 并不是您要寻找的内容。
您应该在框架类中添加 OnSize 处理程序,在此处理程序内部,如 Rob pointed out 所述,您将获得框架客户区的宽度和高度,然后应添加调整控件大小和位置的代码。
类似于这样
void MyFrame::OnSize(UINT nType, int w, int h)
{
// w and h parameters are new width and height of your frame
// suppose you have member variable CEdit myEdit which you need to resize/move
myEdit.MoveWindow(w/5, h/5, w/2, h/2);
}
当您的框架接收到OnSize消息时,它会向您提供新的宽度和高度 - 您只需调用CEdit SetWindowPos方法并传递这些值。
假设CMyPane是您的分离器窗格,并且其中包含一个您在OnCreate中创建的CEdit,称为m_wndEdit:
void CMyPane::OnSize(UINT nType, int cx, int cy)
{
m_wndEdit.SetWindowPos(NULL, 0, 0, cx, cy, SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
}
GetDlgItem(IDC_your_slidebar)->SetWindowPos(...) // 实际上你可以移动、调整大小等
对于此目的,SetWindowPos 功能有些过于复杂。MoveWindow 则正好符合需求。
其他人指出,WM_SIZE是您应该处理并在此时调整子控件大小的消息。 WM_SIZE在调整大小完成后发送。
您可能还希望处理WM_SIZING消息,该消息在调整大小过程中发送。这将使您能够在用户拖动鼠标时主动调整子窗口的大小。虽然不严格需要处理WM_SIZING,但它可以提供更好的用户体验。
我使用CodeGuru的CResize类来自动调整所有控件的大小。您可以告诉它如何调整每个控件的大小,它会为您完成工作。
调整大小的范例是指定对话框调整大小时每个控件的每个边将移动多少。
SetResize(IDC_EDIT1, 0, 0, 0.5, 1);
SetResize(IDC_EDIT2, 0.5, 0, 1, 1);
当您拥有大量对话框控件时非常方便。
当涉及到窗口大小的更改时,您可能会对三个窗口消息感兴趣:ON_WM_SIZE()
、ON_WM_SIZING()
和ON_WM_GETMINMAXINFO()
。
正如官方文档所述:
ON_WM_SIZE
其消息处理程序为 ::OnSize()
,在 CWnd 的大小更改后触发;ON_WM_SIZING
其消息处理程序为 ::OnSizing()
,在剪贴板查看器窗口的客户区大小更改时触发;ON_WM_GETMINMAXINFO
其消息处理程序为 ::OnGetMinMaxInfo()
,在窗口需要知道最大化位置或尺寸,或最小或最大跟踪大小时触发。如果你想限制的大小在某个范围内,可以参考消息ON_WM_GETMINMAXINFO
; 如果你想实时检索大小变化,可以参考另外两个消息。
最好使用每个控件在属性部分的动态布局功能。
假设您想要一个特定的控件,比如标题,始终位于视图/对话框的中心,那么您只需选择控件的动态布局属性,将移动类型设置为水平,将移动X设置为50,但保持大小设置为无。这样,当您调整视图大小时,标题始终保持在中心位置。您必须记住,调整大小/移动的最小值是在资源视图中设计控件时在对话框/视图内的大小/位置。
这样,您就可以节省几何和变换的负担。