Programming with Microsoft Visual C++.NET 6ed [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Programming with Microsoft Visual C++.NET 6ed [Electronic resources] - نسخه متنی

George Shepherd, David Kruglinski

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
توضیحات
افزودن یادداشت جدید








Chapter 6: Classic GDI Functions, Fonts, and Bitmaps



Overview


Chapter 33.

The GDI provides functions for drawing points, lines, rectangles, polygons, ellipses, bitmaps, and text. You can draw circles and squares intuitively once you study the available functions, but text programming is more difficult. This chapter gives you the information you need to start using the GDI effectively in the Microsoft Visual C++ .NET environment. You'll also learn how to use fonts and bitmaps on the display and the printer.


The Device Context Classes


In Chapter 3 and Chapter 5, we passed the view class's OnDraw member function a pointer to a device context object. OnDraw selected a brush and then drew an ellipse. The Microsoft Windows device context is the key GDI element that represents a physical device. Each C++ device context object has an associated Windows device context, which is identified by a 32-bit handle of type HDC.

The Microsoft Foundation Class (MFC) library provides a number of device context classes. The base class CDC has all the member functions (including some virtual functions) that you'll need for drawing. Except for the oddball CMetaFileDC class, derived classes are distinct only in their constructors and destructors. If you (or the application framework) construct an object of a derived device context class, you can pass a CDC pointer to a function such as OnDraw.

For the display, the usual derived classes are CClientDC and CWindowDC. For other devices, such as printers or memory buffers, you construct objects of the base class CDC.

The "virtualness" of the CDC class is an important feature of the application framework. In Chapter 17, you'll see how easy it is to write code that works with both the printer and the display. A statement in OnDraw such as

pDC->TextOut(0, 0, "Hello"); 

sends text to the display, the printer, or the Print Preview window, depending on the class of the object referenced by the CView::OnDraw function's pDC parameter.

For display and printer device context objects, the application framework attaches the handle to the object. For other device contexts, such as the memory device context that you'll see in later chapters, you must call a member function after construction in order to attach the handle.



The CClientDC and CWindowDC Display Context Classes


Recall that a window's client area excludes the border, the caption bar, and the menu bar. If you create a CClientDC object, you have a device context that is mapped only to this client area—you can't draw outside it. The point (0, 0) usually refers to the upper left corner of the client area. As you'll see later, an MFC CView object corresponds to a child window that is contained inside a separate frame window, often along with a toolbar, a status bar, and scroll bars. The client area of the view therefore does not include these other windows. If the window contains a docked toolbar along the top, for example, (0, 0) refers to the point immediately under the left edge of the toolbar.

If you construct an object of class CWindowDC, the point (0, 0) is at the upper left corner of the nonclient area of the window. With this whole-window device context, you can draw in the window's border, in the caption area, and so forth. Don't forget that the view window doesn't have a nonclient area, so CWindowDC is more applicable to frame windows than it is to view windows.



Constructing and Destroying CDC Objects


If you construct a CDC object, it is important to destroy it as soon as you're done with it. Windows limits the number of available device contexts, and if you fail to release a Windows device context object, a small amount of memory will be lost until your program exits. You'll usually construct a device context object inside a message handler function such as OnLButtonDown. The easiest way to ensure that the device context object is destroyed (and that the underlying Windows device context is released) is to construct the object on the stack in the following way:

void CMyView::OnLButtonDown(UINT nFlags, CPoint point) 
{
CRect rect;
CClientDC dc(this); // constructs dc on the stack
dc.GetClipBox(rect); // retrieves the clipping rectangle
} // dc automatically released

Notice that the CClientDC constructor takes a window pointer as a parameter. The destructor for the CClientDC object is called when the function returns. You can also get a device context pointer by using the CWnd::GetDC member function, as shown in the following code. You must be careful here to call the ReleaseDC function to release the device context.

void CMyView::OnLButtonDown(UINT nFlags, CPoint point)
{
CRect rect;
CDC* pDC = GetDC(); // a pointer to an internal dc
pDC->GetClipBox(rect); // retrieves the clipping rectangle
ReleaseDC(pDC); // Don't forget this
}





Warning

Do not destroy the CDC object passed by the pointer to OnDraw. The application framework will handle the destruction for you.




The State of the Device Context


You already know that a device context is required for drawing. When you use a CDC object to draw an ellipse, for example, what you see on the screen (or on hard copy) depends on the current "state" of the device context. The state includes the following:



    Attached GDI drawing objects such as pens, brushes, and fonts.



    The mapping mode that determines the scale of items when they are drawn. (You already experimented with the mapping mode in Chapter 5.)



    Various details such as text alignment parameters and polygon filling mode.



You've seen, for example, that selecting a gray brush before drawing an ellipse results in the ellipse having a gray interior. When you create a device context object, it has certain default characteristics, such as a black pen for shape boundaries. All other state characteristics are assigned through CDC class member functions. GDI objects are selected into the device context by means of the overloaded SelectObject functions. A device context can, for example, have one pen, one brush, or one font selected at any given time.



The CPaintDC Class


You'll need the CPaintDC class only if you override your view's OnPaint function. The default OnPaint calls OnDraw with a properly set up device context, but sometimes you'll need display-specific drawing code. The CPaintDC class is special because its constructor and destructor do housekeeping unique to drawing to the display. Once you have a CDC pointer, however, you can use it as you would any other device context pointer.

Here's a sample OnPaint function that creates a CPaintDC object:

void CMyView::OnPaint() 
{
CPaintDC dc(this);
OnPrepareDC(&dc); // explained later
dc.TextOut(0, 0, "for the display, not the printer");
OnDraw(&dc); // stuff that's common to display and printer
}








For Win32 Programmers


The CPaintDC constructor calls BeginPaint for you, and the destructor calls EndPaint. If you construct your device context on the stack, the End- Paint call is completely automatic.













/ 319