 |
在普通的Win32应用程序中,创建窗口后处理WM_PAINT消息时,一般都在主窗口的客户区域绘图。 然而,在MFC单文档应用程序中,CView类为主窗口单独创建了一个没有标题栏的子窗口,在该类的OnDraw(CDC* pDC)方法中绘图时,实际上是在给这个子窗口绘图,而不是主窗口的客户区域。
|
 |
这主要是因为,工具栏和状态栏必须位于主窗口的客户区域,显示后会把主窗口的客户区域覆盖掉一部分,使得主窗口的WM_PAINT消息获得的hdc的左上角坐标(0, 0)不再位于白色绘图区域的最左上角的顶点,而是位于工具栏最左上角的顶点了。 所以,MFC不得不再建立一个子窗口,放在工具栏和状态栏的中间充当绘图区域。。。。
另外,菜单栏一般都是绑在窗口上的,只能位于主窗口的非客户区域。因此,一个Win32程序,如果只有菜单栏,没有工具栏和状态栏的话,一般不用再建立一个子窗口来充当绘图区域。
|
 |
要是使用了工具栏或状态栏但又没有为绘图区域专门建立一个子窗口,那么就是这种效果:  工具栏和状态栏将会把绘图区域的一部分给遮住,并且滚动条也会出现在工具栏和状态栏的右边。
|
 |
然而,通常我们要求的是,滚动条只出现在客户区域旁边: 
|
 |
 如果不为绘图区创建子窗口的话,那么水平滚动条就会出现在状态栏的下面,显然这是很不符合要求的。
|
 |
这是1楼所示MFC程序的部分代码: void CMFCApplication2View::OnDraw(CDC* pDC) { CMFCApplication2Doc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return;
// TODO: 在此处为本机数据添加绘制代码 pDC->TextOut(0, 0, TEXT("在此处为本机数据添加绘制代码"));
TCHAR text[100]; RECT rect; ::GetClientRect(::GetParent(m_hWnd), &rect); _stprintf_s(text, TEXT("父窗口客户区大小: %d x %d"), rect.right - rect.left, rect.bottom - rect.top); pDC->TextOut(0, 16, text);
GetClientRect(&rect); _stprintf_s(text, TEXT("子窗口客户区大小: %d x %d"), rect.right - rect.left, rect.bottom - rect.top); pDC->TextOut(0, 32, text);
RECT rcParentWnd; ::GetWindowRect(::GetParent(m_hWnd), &rcParentWnd); GetWindowRect(&rect); _stprintf_s(text, TEXT("子窗口相对于父窗口的位置: (%d, %d)"), rect.left - rcParentWnd.left, rect.top - rcParentWnd.top); pDC->TextOut(0, 48, text); }
void CMFCApplication2View::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: 在此添加消息处理程序代码和/或调用默认值 ::SetWindowText(::GetParent(m_hWnd), TEXT("yes")); ::SetWindowText(m_hWnd, TEXT("no")); // 子窗口根本就没有标题栏,所以这句毫无作用
CView::OnLButtonDown(nFlags, point); }
|