git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@8997 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
		
			
				
	
	
		
			119 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			TeX
		
	
	
	
	
	
			
		
		
	
	
			119 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			TeX
		
	
	
	
	
	
| \chapter{Drawing on device contexts}\label{chapdrawing}
 | |
| \pagenumbering{arabic}%
 | |
| \setheader{{\it CHAPTER \thechapter: DRAWING ON DEVICE CONTEXTS}}{}{}{}{}{{\it CHAPTER \thechapter: DRAWING ON DEVICE CONTEXTS}}%
 | |
| \setfooter{\thepage}{}{}{}{}{\thepage}%
 | |
| 
 | |
| \section{The concept of device contexts}
 | |
| 
 | |
| Device contexts, commonly referred as DCs, represent more or less anything
 | |
| you can draw into, i.e. a window, a bitmap, the screen, a printer, a Postscript
 | |
| file, most recently even an SVG file. There is one abstract base class (wxDC)
 | |
| which defines the interface for all other classes so that drawing code for
 | |
| one device context can be used for all others as well - with certain limitation
 | |
| as the hardware specifies (e.g. you cannot read a pixel from a printer).
 | |
| 
 | |
| \section{Drawing into windows}
 | |
| 
 | |
| Let's start with the most simple case: you want to draw a line in a window.
 | |
| Or rather not the window, but its client area, the usually white or grey
 | |
| large area that is surrounded by the window's decorations such as its border
 | |
| which you normally would not want to draw over.
 | |
| 
 | |
| In addition to defining classes that represent devices, wxWindows has a few
 | |
| of classes that define colours and so-called pens and brushes. A pen is used
 | |
| for drawing lines (which can be a curve or a rectangle) whereas brushes are
 | |
| used to paint areas, such as a filled rectangle or a filled circle. Indeed,
 | |
| you can use both at the same time for drawing a rectangle which is both filled
 | |
| and has a border. If you want to draw a red rectangle with a black border,
 | |
| you will do this:
 | |
| 
 | |
| \begin{verbatim}
 | |
| void MyWindow::DrawSomething()
 | |
| {
 | |
|     wxClientDC dc(this);
 | |
|     
 | |
|     dc.SetPen( *wxBLACK_PEN );
 | |
|     dc.SetBrush( *wxRED_BRUSH );
 | |
|     
 | |
|     dc.DrawRectangle( 0, 0, 100, 100 );
 | |
| }
 | |
| \end{verbatim}
 | |
| 
 | |
| If you want to draw a rectangle without any border, you can use the special
 | |
| oen wxTRANSPARENT_PEN, if the rectangle is not supposed to be filled with
 | |
| any colour, you use the special brush wxTRANSPARENT_BRUSH. When using both
 | |
| these special classes, you could draw an invisible rectangle like this:
 | |
| 
 | |
| \begin{verbatim}
 | |
| void MyWindow::DrawNothing()
 | |
| {
 | |
|     wxClientDC dc(this);
 | |
|     
 | |
|     dc.SetPen( *wxTRANSPARENT_PEN );
 | |
|     dc.SetBrush( *wxTRANSPARENT_BRUSH );
 | |
|     
 | |
|     dc.DrawRectangle( 0, 0, 100, 100 );
 | |
| }
 | |
| \end{verbatim}
 | |
| 
 | |
| Now what happens when you window gets obscured by another window and 
 | |
| then returns to the surface again? The rectangle will not appear again
 | |
| because a window does not remember what has been drawn into it. Instead,
 | |
| your program has to remember what to draw and where and it will receive
 | |
| a so called wxPaintEvent indicating that some region has been unobscured
 | |
| and needs repainting. In order to catch such an event so that you can
 | |
| react appropriately to it, you will have to set up an event handler
 | |
| like this:
 | |
| 
 | |
| \begin{verbatim}
 | |
| BEGIN_EVENT_TABLE(MyWindow, wxWindow)
 | |
|     EVT_PAINT  (MyWindow::OnPaint)
 | |
| END_EVENT_TABLE()
 | |
| 
 | |
| void MyWindow::OnPaint( wxPaintEvent &event )
 | |
| {
 | |
|     wxPaintDC dc(this);
 | |
|     
 | |
|     dc.SetPen( *wxBLACK_PEN );
 | |
|     dc.SetBrush( *wxRED_BRUSH );
 | |
|     
 | |
|     dc.DrawRectangle( 0, 0, 100, 100 );
 | |
| }
 | |
| \end{verbatim}
 | |
| 
 | |
| Note that this time, you have to use a wxPaintDC as these are used
 | |
| in connection with wxPaintEvents. Note also, that every such handler
 | |
| has to use a wxPaintDC even of you (for the moment) don't draw anything.
 | |
| If there is no such wxPaintDC, your program will not work under Windows.
 | |
| 
 | |
| One difference between a wxPaintDC and a wxClientDC is that the wxPaintDC
 | |
| always sets a clipping region to the region of the window that was
 | |
| unobscured with the effect that all drawing commands will be clipped to
 | |
| that region. This leads to a reduction of flicker as only those
 | |
| areas of the window get redrawn, which actually need to get redrawn.
 | |
| 
 | |
| \section{Querying the update region}
 | |
| 
 | |
| Call me lazy:
 | |
| 
 | |
| \begin{verbatim}
 | |
| BEGIN_EVENT_TABLE(MyWindow, wxWindow)
 | |
|     EVT_PAINT  (MyWindow::OnPaint)
 | |
| END_EVENT_TABLE()
 | |
| 
 | |
| void MyWindow::OnPaint( wxPaintEvent &event )
 | |
| {
 | |
|     wxPaintDC dc(this);
 | |
|     
 | |
|     if (IsExposed( 0, 0, 100, 100))
 | |
|     {
 | |
|         dc.SetPen( *wxBLACK_PEN );
 | |
|         dc.SetBrush( *wxRED_BRUSH );
 | |
|         
 | |
|         dc.DrawRectangle( 0, 0, 100, 100 );
 | |
|     }
 | |
| }
 | |
| \end{verbatim}
 | |
| 
 | |
| 
 |