Some wxBook docs.
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@8997 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -3,5 +3,116 @@
|
||||
\setheader{{\it CHAPTER \thechapter: DRAWING ON DEVICE CONTEXTS}}{}{}{}{}{{\it CHAPTER \thechapter: DRAWING ON DEVICE CONTEXTS}}%
|
||||
\setfooter{\thepage}{}{}{}{}{\thepage}%
|
||||
|
||||
Device contexts, a great abstraction...
|
||||
\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}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user