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:
Robert Roebling
2000-12-22 15:56:48 +00:00
parent 9f3280c9c4
commit e80658dacc
2 changed files with 168 additions and 2 deletions

View File

@@ -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}

View File

@@ -3,5 +3,60 @@
\setheader{{\it CHAPTER \thechapter: IMAGES AND BITMAPS}}{}{}{}{}{{\it CHAPTER \thechapter: IMAGES AND BITMAPS}}%
\setfooter{\thepage}{}{}{}{}{\thepage}%
wxImage and wxBitmap unravelled.
\section{The basics of images and bitmaps}
Both wxImage and wxBitmap represent what would commonly be referred as
a photo with a given number of pixels - in contrast to a drawing consisting
of a collection of lines, curves, circles, squares etc.
The difference between a wxImage and a wxBitmap is that wxImage is a
platform and screen independent representation of an image - every
pixel is always represented by three bytes, one for red, one for green
and one for blue, thus yielding the classical RGB acronym. Due to the
simplicity of wxImage, you will do all kinds of image manipulation
with this class, this includes loading images in various formats
such as GIF, TIFF or JPEG (these and some more are supported by wxWindows
without further work), analyizing the image in terms of colour usage etc
and applying filters to the image for higher-level manipulation, such
as blurring, sharpening etc.
The problem with wxImage is that you cannot draw it, i.e. its destiny
is to live its shadow life in memory, without ever being seen by man.
If you ever want to draw an image to screen, you have to convert it
to a wxBitmap first, typically, this will look like this:
\begin{verbatim}
wxImage image( 200, 200 );
wxBitmap bitmap( image.ConvertToBitmap() );
wxClientDC dc( this )
dc.DrawBitmap( bitmap );
\end{verbatim}
Note, that such as image conversion is an extremely expensive operation
and you are very well advised to avoid having to call this routine
more than absolutely required. In practice, you should not do this
in a paint event handler, for instance.
There is one more thing you can do with a wxBitmap: you can draw into
it like you would do with a window. All you need to do is set up a
proper device context (DC) for it and ensure that you clean up the
DC correctly afterwards:
\begin{verbatim}
wxBitmap bitmap( 200, 200 );
wxMemoryDC dc;
dc.SelectObject( bitmap );
dc.SetPen( *wxBLACK_PEN );
dc.DrawLine( 0, 0, 199, 199 );
dc.SelectObject( wxNullBitmap );
\end{verbatim}
\section{wxImage built-in features}
You can save it, load it, get access to it, assign it a mask colour,
turn it around, mirror it.