Sun Xin C ++ video note (11) image storage and re-painting

Source: Internet
Author: User

Write the drawing Code, set an identifier, save the mouse-down point in onlbuttondown, capture the point with the mouse popping up in onlbuttonup, and draw images using the switch statement.

When you drag a window, the previously painted image disappears because dragging the window causes the window to be repainted. The solution is to use the array class cptrarray to save three variables: m_ndrawtype, m_ptorigin, m_ptend.

Create a common class named cgraph to construct a constructor with Parameters
Cgraph (uint m_ndrawtype, cpoint m_porigin, cpoint m_pend); used to receive three required variables

Add three member variables uint m_ndrawtype, cpoint m_porigin, and cpoint m_pend in cgraph and initialize them in the constructors without parameters. The following code receives the variable in the parameter constructor:
Cgraph: cgraph (uint m_ndrawtype, cpoint m_porigin, cpoint m_pend)
{
This-> m_ndrawtype = m_ndrawtype;
This-> m_porigin = m_porigin;
This-> m_pend = m_pend;
}

In onlbuttonup, store the variables in the array. Note:
It cannot be saved as follows:
Cgraph (m_ndrawtype, m_ptorigin, point)
M_ptrarray.add (& graph );
This is because the object address is saved in the array. The object address is invalid when the structure is generated. Although the address is saved, it is invalid when we index the object.
Solution:
Cgraph * pgraph = new cgraph (m_ndrawtype, m_ptorigin, point );
The object will still be destructed, but the relationship between the object and the address is removed, while the object created by new is on the stack. If the objects allocated in the heap are not released using Delete, the lifecycle of an object is the same as that of an application. When the Destructor is executed, the memory of the variable is released, but the value of the variable is still saved in the heap.

The window re-painting calls the ondraw function, so you need to add the drawing code to this function.

Use m_ptrarray.getsize () to obtain the array length and construct a for loop.

Use (cgraph *) m_ptrarray.getat (I)-> to get the variables of the cgraph class. m_ptrarray.getat (I) returns cobject *, so it must be forcibly converted to cgraph *.

The source code is as follows:

Void cgraphyicview: ondraw (CDC * PDC)
{
Cgraphyicdoc * pdoc = getdocument ();
Assert_valid (pdoc );
// Todo: Add draw code for native data here
Cclientdc DC (this );
Cpen pen (ps_solid, 1, RGB (255, 0, 255 ));
PDC-> SelectObject (& pen );
 
Cbrush * Brush = cbrush: fromhandle (hbrush) getstockobject (null_brush ));
PDC-> SelectObject (Brush );

For (INT I = 0; I <m_ptrarray.getsize (); I ++)
{
Switch (cgraph *) m_ptrarray.getat (I)-> m_ndrawtype)
{
Case 0:
PDC-> setpixel (cgraph *) m_ptrarray.getat (I)-> m_pend, RGB (255,255, 0 ));
Break;
Case 1:
PDC-> moveTo (cgraph *) m_ptrarray.getat (I)-> m_porigin );
PDC-> lineto (cgraph *) m_ptrarray.getat (I)-> m_pend );
Break;
Case 2:
PDC-> rectangle (crect (cgraph *) m_ptrarray.getat (I)-> m_porigin,
(Cgraph *) m_ptrarray.getat (I)-> m_pend ));
Break;
Case 3:
PDC-> ellipse (crect (cgraph *) m_ptrarray.getat (I)-> m_porigin,
(Cgraph *) m_ptrarray.getat (I)-> m_pend ));
Break;
}
}
}

The ondraw function is not the corresponding function of wm_paint. why can it be called during window repainting?

Void cview: onpaint ()
{
// Standard paint routine
Cpaintdc DC (this );
Onpreparedc (& DC );
Ondraw (& DC );
}
When responding to wm_paint, if you want to obtain the DC handle, you can only use beginpaint (). If you want to release the DC handle, call endpaint ()
The
Cpaintdc class is a device-context class derived from CDC. It performs
A cwnd: beginpaint at construction time and cwnd: endpaint
Destruction time.
Cpaintdc can only be used in onpaint.

Cclientdc objects encapsulate working with a device context that
Represents only the client area of a window. The cclientdc Constructor
Callthe getdc function, and the Destructor callthe releasedc
Function. cwindowdc objects encapsulate a device context that
Represents the whole window, including its frame.
If you want to obtain the DC handle outside onpaint, call getdc to release releasedc.

If you want to replace all the words or words that you want to replace in the file, you can choose edit-> replace, and then select
Match Whole word only

In Microsoft Windows, programs use coordinate space and conversion to scale, translate, rotate, slice, and reflect the image output.
A coordinate space is a two-dimensional space. A two-dimensional object is defined by connecting an axis that is perpendicular to each other and has the same length.

Coordinate Space
The API uses four types of coordinate spaces: World coordinate space, page space, device space, and physical device space. The application uses the world coordinate system space to rotate, slice, or reflect the graphic output.

Win32
API calls the world coordinate system space and page space Logical space. The last coordinate space (physical device space) usually refers to the customer Area of the application window; but it also includes the entire desktop, the complete window (Package
Frame, title bar, and menu bar) or a page of a printer or a widget. The size of the physical device varies with the size set for the display, printer, and plotter.

Conversion
If you want to draw an output on a physical device, Windows copies (or maps) a rectangular area from a coordinate space to (or mapped to) Another coordinate space, until the final complete output is displayed on a physical device (usually a screen or printer)

If the application calls the setworldtransform function, the ing starts from the world coordinate system space of the application. Otherwise, the ing starts in the page space. In
When Windows copies each point in a rectangle area from one space to another, it adopts a conversion algorithm, conversion changes when an object is copied from one coordinate space to another.
(Or transformation) the size, orientation, and form of the object. Although the conversion regards the object as a whole, it also applies to every vertex or line of the object.

Conversion from page space to device space
When the page is blank, the conversion of the device space is part of the original windows program interface. This conversion determines the ing of all the graphic outputs related to a specific device description table.
A ing method is a measure conversion that determines the unit size used for drawing operations. A ing method is a device environmental attribute that affects drawing in almost any customer area. There are also four types of device environment attributes: the origin, origin, range, and range of the window. These four attributes are closely related to the ing relationship.
The ratio of width to height of the two rectangles is used for converting the page space to the device space. The rectangles in the page space are called windows, and the rectangles in the device space are called sdks. Windows maps the window origin to the view origin, and maps the window range to the View Source to complete the conversion.

Device space to physical space conversion
Device space to physical space conversion: limited to translation, and controlled by Windows Management, the only purpose of this conversion is to ensure that the origin of the device space is mapped to an appropriate point on the physical device. No function can set this type of conversion, and no function can obtain relevant data.

Default conversion
Once the application creates a device description table and immediately calls the GDI drawing or output function, the conversion from the default page space to the device space and from the device space to the customer area is used, (The application will not convert the world coordinate space to the page space before calling setworldtransform.

By default, the conversion from a page space to a device space is a one-to-one ing. That is, a point in the page space is mapped to a point in the device space. This type of conversion is not specified by a matrix. Instead, it is obtained by dividing the width of the window by the height of the window. By default, the size of the view is 1*1 pixel, the window size is 1*1 page.

The device space is always one-to-one to physical devices (customer zone, desktop and printer). A unit in the device space is always the same as that in the customer zone and desktop, corresponds to a unit on the printer. The only purpose of this conversion is to translate. No matter where the window is moved to the desktop, it always ensures that the output is correctly displayed in the window.

By default, the device space and the y-axis of the application window are unique. By default, the Y axis is facing down, and the Y axis is facing up.

Logical coordinates and device coordinates
The coordinate values used in almost all GDI functions are logical units. In Windows, you must convert the logical coordinate values to device units, that is, pixels. This type of conversion is determined by the ing method, the origin of the window and the view, and the range of the window and the view.
Windows always uses the device coordinates for all messages (such as wm_size, wm_mousemove, wm_lbuttondown, and wm_lbuttonup), all non-GDI functions, and some GDI functions (getdevicecaps.

The window is based on logical coordinates. The logical coordinates can be pixels, millimeters, inches, and other units. The port is based on device coordinates (pixels. Generally, the view and customer area are the same.
The default mming mode is mm_text. In this ing mode, the logical unit is the same as the device unit.

Conversion of window (logical) coordinates and the viewport (device) coordinates
Xviewport = (XWindow-xwinorg) * xviewext/xwinext + xvieworg;
Yviewport = (ywindow-ywinorg) * yviewext/ywinext + yvieworg;
The conversion between the viewport (device) coordinates and the window (logic) coordinates is opposite to that above;

In mm_text ing mode, convert the window (logical) coordinates and the window (device) coordinates:
Xviewport = XWindow-xwinorg + xvieworg;
Yviewport = ywindow-ywinorg + yvieworg;
The conversion between the viewport (device) coordinates and the window (logic) coordinates is opposite to that above;

Oninitialupdate () is the first function called after the window is created, also before ondraw.
To make the window scroll, you can simply change all the base classes involved in the View class to cscrollview.
Add the virtual function oninitialupdate () and set the scroll window.
Void cgraphyicview: oninitialupdate ()
{
Cscrollview: oninitialupdate ();
 
// Todo: add your specialized code here and/or call the base class
Setscrollsizes (mm_text, csize (800,600 ));
}
Void
Setscrollsizes (INT nmapmode, size sizetotal, const size & sizepage
= Sizedefault, const size & sizeline = sizedefault );
Call
Setscrollsizes when the view is about to be updated. Call it in your
Override of the onupdate member function to adjust scrolling
Characteristics when, for example, the document is initially displayed
Or when it changes size.

The CDC provides two member functions: setviewpoitorg and setmediaworg, which are used to change the source of the view and window.
If you set the origin of a port
(Xvieworg, yvieworg), the logical point () is mapped to the device point (xvieworg, yvieworg ).
(Xwinorg, ywinorg), the logic point (xwinorg, ywinorg) will be mapped to the device point (0, 0), that is, the upper left corner.
The device point (0, 0) is always the upper left corner of the customer zone, no matter what changes are made to the window and the source of the view.

Before calling the ondraw function, the onpaint function calls the onpreparedc function, and adjusts the display context attribute to set the origin of the view
(0,-150). According to the formula yviewport = ywindow-ywinorg + yvieworg, the Y coordinate of the device point appears above the original display area.
Solution:
Call onpreparedc to adjust the attributes of the display context before saving the coordinate point. Set the source of the view to (0,-150 ), then, call the device coordinate transformation logical coordinate function dptolp to convert the device coordinate (680,390) to the logical coordinate.
Ywindow = yviewport-yvieworg + ywinorg;
The Y coordinate is 540. When the window is re-painted, onpreparedc is called to adjust the attributes of the display context, set the origin of the view to (0,-150), and then the GDI function draws the image using the logical coordinate point (680,540, converted to (680,390)
Onpreparedc (& DC );
DC. dptolp (& m_ptorigin); // The coordinates and window (logic) of the view (device)
DC. dptolp (& Point );

When the scroll bar is at the top and the window is re-painted, onpreparedc adjusts the display context and sets the origin of the view to (0, 0) instead of (0,-150)
Onpreparedc adjusts the origin of the view based on the position of the scroll window at any time.

Cmetafiledc: The device metadata file used to save the image. The CDC: playmetafile is used to play the metadata file repeatedly.
Cmetafiledc m_dcmetafile;
Initialize to m_dcmetafile.create () in the constructor ();
Points
To a null-terminated character string. specifies the filename of
Metafile to create. If lpszfilename is null, a new in-memory Metafile
Is created.
When drawing, we call the drawing function of m_dcmetafile:
M_dcmetafile.rectangle (crect (m_ptorigin, point ));
Save the command used for drawing to m_dcmetafile.
Window repainting
Hmetafile;
Hmetafile = m_dcmetafile.close (); // Save the drawing command
PDC-> playmetafile (hmetafile); // use the window DC to play the Metafile
M_dcmetafile.create (); // create a Metafile
M_dcmetafile.playmetafile (hmetafile); // re-draw the previous image and add it to the new image.
 
Deletemetafile (hmetafile); // release the Metafile

For "open" and "save", add the corresponding command function.
Decompress copymetafile (hmetafile, "sp. hmf ");
And hmetafile = getmetafile ("sp. hmf ");
M_dcmetafile.playmetafile (hmetafile );
To save and open the image.
Hmetafile copymetafile (
Hmetafile hmfsrc, // handle to a Windows-format Metafile
Lpctstr lpszfile // pointer to a filename string
);
Henhmetafile getenhmetafile (
Lpctstr lpszmetafile // pointer to Metafile name
);
The copymetafile and getmetafile functions have been deprecated. Now the enhanced functions copyenhmetafile and getenhmetafile are used. The usage is the same, and the old function can still be used.

Save images with compatible DC
Construct compatible DC objects:
CDC m_dccompatible
Source code:
If (! M_dccompatible.m_hdc)
{
M_dccompatible.createcompatibledc (& DC );
Crect rect;
Getclientrect (& rect );
Cbitmap bitmap;
Bitmap. createcompatiblebitmap (& DC, rect. Width (), rect. Height ());
M_dccompatible.selectobject (& Bitmap); m_dccompatible.bitblt (0, 0, rect. Width (), rect. Height (), & DC, 0, 0, srccopy );
M_dccompatible.selectobject (Brush );
}
Createcompatiblebitmap
The returned bitmap object only contains the bitmap information header in the device description table, and does not contain the color table or pixel data block. Therefore, the device description table of the bitmap object cannot be used as the device description table of the normal object.
You must call bitblt after the SelectObject function to copy the color table and pixel data block of the original device description table to the compatible device description table.

If you want to display the image while saving the image, you can call
M_dccompatible.moveto (m_ptorigin );
M_dccompatible.lineto (point );
At the same time.
DC. moveTo (m_ptorigin );
DC. lineto (point );

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.