Thư viện tri thức trực tuyến
Kho tài liệu với 50,000+ tài liệu học thuật
© 2023 Siêu thị PDF - Kho tài liệu học thuật hàng đầu Việt Nam

Visual C++ and MFC Fundamentals programming phần 7 pot
Nội dung xem thử
Mô tả chi tiết
Chapter 15: Fundamental Controls Visual C++ and MFC Fundamentals
426 © FunctionX, Inc.
GetClientRect() function is called to get the dimensions of the view’s client area of a
frame -based application and use the resulting rectangle to paint that area:
void CCView1View::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
CRect Recto;
CBrush SelectedBrush(SelectedColor);
CPen SelectedBlue(PS_SOLID, 1, SelectedColor);
GetClientRect(&Recto);
CBrush *pOldBrush = dc.SelectObject(&SelectedBrush);
CPen *pOldPen = dc.SelectObject(&SelectedBlue);
dc.Rectangle(Recto);
dc.SelectObje ct(pOldBrush);
// Do not call CView::OnPaint() for painting messages
}
Once the control is already positioned on the client area, to get its location and
dimensions, you can call the CWnd::GetWindowRect() method. Here is an example:
void CTabDlg::OnBtnInfo()
{
// TODO: Add your control notification handler code here
CRect Recto;
char LocDim[80];
m_Panel.GetWindowRect(&Recto);
sprintf(LocDim, " - Panel Information -\nLeft: %d,"
"\nTop: %d,\nWidth: %d,\nHeight: %d",
Recto.left, Recto.top, Recto.Width(), Recto.Height());
MessageBox(LocDim);
}
Practical Learning: Using the Client Area
1. Open the Geometry application you were working on earlier
2. Open the Quadrilateral.cpp source file and change its OnPaint() event as follows:
Visual C++ and MFC Fundamentals Chapter 15: Fundamental Controls
© FunctionX, Inc. 427
void CQuadrilateral::OnPaint()
{
CPaintDC dc(this); // device context for painting
CRect Recto;
// Create a light green brush
CBrush BrushLightGreen(RGB(212, 235, 235));
// Create a navy pen
CPen PenNavy(PS_SOLID, 1, RGB(0, 0, 128));
// Create a green brush
CBrush BrushGreen(RGB(100, 175, 180));
// Create a dark green pen
CPen PenGreen(PS_SOLID, 2, RGB(0, 115, 115));
// Get the location and dimensions of the client rectangle
GetClientRect(&Recto);
// Select the light green brush
CBrush *pOldBrush = dc.SelectObject(&BrushLightGreen);
// Select the navy pen
CPen *pOldPen = dc.SelectObject(&PenNavy);
// Draw a rectangular shape on the left side of the property page
dc.Rectangle(0, 0, 162, Recto.Height());
// Select the green brush
pOldBrush = dc.SelectObject(&BrushGreen);
// Select the dark green pen
pOldPen = dc.SelectObject(&PenGreen);
// Draw the square
dc.Rectangle(40, 40, 120, 100);
// Draw the rectangle
dc.Rectangle(20, 170, 140, 240);
// Set the back mode to transparent for the text
dc.SetBkMode(TRANSPARENT);
// Display indicative labels
dc.TextOut(60, 105, "Square");
dc.TextOut(45, 250, "Rectangle");
// Restore the old GDI tools
dc.SelectObject(pOldPen);
dc.SelectObject(pOldBrush);
if (IsIconic())
{
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;
Chapter 15: Fundamental Controls Visual C++ and MFC Fundamentals
428 © FunctionX, Inc.
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CPropertyPage::OnPaint();
}
}
3. Test the application:
4. Close the application and return to MSVC
14.2.3 The Screen and Client Coordinates
When calling either the GetClientRect() or the GetWindowRect() methods to get the
location and the dimensions of a control or another object, it is important to know the
origin of the produced rectangle. By default, the rectangle returned by the
GetWindowRect() method called by a control has its origin on the top left corner of the
monitor and not on the top-left corner of the parent window. Consider the following
event. It gets the location and dimensions of a control and stores them in a CRect
variable. Then it paints a rectangle (it is supposed to paint the control) located on, and
equal to the dimensions of, the control:
void CTabDlg::OnBtnInfo()
{
// TODO: Add your control notification handler code here
CRect Recto;
m_Panel.GetWindowRect(&Recto);
CClientDC dc(this);
CBrush BlueBrush(RGB(0, 128, 192));
CBrush *pOldBrush = dc.SelectObject(&BlueBrush);
dc.Rectangle(Recto);
Visual C++ and MFC Fundamentals Chapter 15: Fundamental Controls
© FunctionX, Inc. 429
dc.SelectObject(pOldBrush);
}
After executing the program and moving the dialog box somewhere to the middle center
of the screen and clicking the button, the result is as follows:
After moving the dialog box close to the top-left section of the screen and clicking the
button again, the result is the following:
This demonstrates that, although the control is a child of the dialog box, the rectangle
returned by the GetWindowRect() method is based on the screen and not the client
coordinates of the parent window. This is not an anomaly. It is purposely done so you can
specify what origin you want to consider.
As seen in previous lessons, the origin of the screen is positioned on the top-left corner of
the monitor. This is referred to as, or is said that the location uses, screen coordinates.
The origin of a client area is placed on its top-left corner. This is referred to as, or is said
that the location uses, client coordinates. For example, the origin used by the above
GetWindowRect() method is based on the screen. If you want the rectangle resulting
from a call to either the GetClientRect() or the GetWindowRect() methods to be based
on the client area (on client coordinates) of the control that called it, you can transfer the
origin from the screen to the client. This is conveniently done with a call to the
CWnd::ClientToScreen() method. It is overloaded as follows:
void ClientToScreen(LPPOINT lpPoint) const;
void ClientToScreen(LPRECT lpRect) const;
If the location you had requested is a point, pass its POINT or its CPoint variable to the
ClientToScreen() method. If the value you requested is a rectangle, pass its RECT or its
CRect variable. Here is an example:
void CTabDlg::OnBtnInfo()
{
// TODO: Add your control notification handler code here
Chapter 15: Fundamental Controls Visual C++ and MFC Fundamentals
430 © FunctionX, Inc.
CRect Recto;
m_Panel.GetWindowRect(&Recto);
CClientDC dc(this);
CBrush BlueBrush(RGB(0, 128, 192));
CBrush *pOldBrush = dc.SelectObject(&BlueBrush);
ScreenToClient(Recto);
dc.Rectangle(Recto);
dc.SelectObject(pOldBrush);
}
This time, even if the dialog box moves, the GetWindowRect() method returns the same
rectangle.
If the location and/or dimension are given in client coordinates, to convert them to screen
coordinates, call the ScreenToClient() method. It is overloaded as follows:
void ScreenToClient(LPPOINT lpPoint) const;
void ScreenToClient(LPRECT lpRect) const;
This method follows the opposite logic of the ClientToScreen() method.
Practical Learning: Using Client and Screen Coordinates
1. The Geometry application should still be opened.
From the Resource View tab open the IDD_CIRCULAR dialog box
2. On the Controls toolbox, click the Picture control and draw a rectangular shape
on the left side of the dialog box
Visual C++ and MFC Fundamentals Chapter 15: Fundamental Controls
© FunctionX, Inc. 431
3. Change the ID of the new control to IDC_SHP_CIRCULAR and Add a Control
Variable for it named m_ShapeCircular
4. Access the OnPaint event of the CCircular class and implement it as follows:
void CCircular::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
// Do not call CPropertyPage::OnPaint() for painting messages
// The location and dimension variable for the control
CRect ShapeRect;
// Create a cream color brush
CBrush BrushCream(RGB(255, 230, 205));
// Create an orange brush
CBrush BrushOrange(RGB(255, 128, 64));
// Create a brown pen
CPen PenBrown(PS_SOLID, 2, RGB(128, 0, 0));
// Get the location and dimension of the control
m_ShapeCirc.GetWindowRect(&ShapeRect);
// Convert the location and dimensions to client coordinates
ScreenToClient(&ShapeRect);
// Select the cream brush to use
CBrush *pOldBrush = dc.SelectObject(&BrushCream);
// Paint the control's background to light blue
dc.Rectangle(ShapeRect);
// Select the brown pen to paint
CPen *pOldPen = dc.SelectObject(&PenBrown);
// Select an orange brush
pOldBrush = dc.SelectObject(&BrushOrange);
// Draw the circle
dc.Ellipse(40, 30, 120, 110);
Chapter 15: Fundamental Controls Visual C++ and MFC Fundamentals
432 © FunctionX, Inc.
// Draw the ellipse
dc.Ellipse(20, 170, 140, 240);
// Set the back mode to transparent for the text
dc.SetBkMode(TRANSPARENT);
// Display indicative labels
dc.TextOut(60, 115, "Circle");
dc.TextOut(55, 250, "Ellipse");
// Dismiss the GDI objects and restore the originals
dc.SelectObject(pOldBrush);
dc.SelectObject(pOldPen);
}
5. Test the application
6. Close it and return to MSVC
14.2.4 The Window: Its Location and Dimensions
We have reviewed various ways of specifying a control’s location and its dimensions,
eitther at design or run time. Once a window or a control has been positioned on the
screen or in its confined client area, it keeps these attributes until specified otherwise.
When dealing with a main window, such as the frame of an application, a dialog box, a
property sheet, or a wizard, the user can move it around the screen as necessary and if
possible. This is usually done by dragging the title bar.
When the user grabs the title bar of a window and starts dragging to move it, the window
sends the WM_MOVING message as we saw in Lesson 4. The WM_MOVING event
fires the OnMoving() event. This event is usually left alone as it allows the user to use an
application as regularly as possible. The syntax of the OnMoving() event is:
afx_msg void OnMoving(UINT nSide, LPRECT lpRect);
The OnMoving() event fires while the window is being moved. The nSide argument
specifies the side of window that is moving. As the window is moving, this event returns
its location and dimensions as the values of the lpRect member variables.