📄 ch07.htm
字号:
FCurrentShape = TCurrentShape(dynamic_cast<TSpeedButton *>(Sender)->Tag);
}
void __fastcall TForm1::Brush1Click(TObject *Sender)
{
ColorDialog1->Color = FBrushColor;
if
(ColorDialog1->Execute())
FBrushColor = ColorDialog1->Color;
}
void __fastcall TForm1::Pen1Click(TObject *Sender)
{
ColorDialog1->Color = FPenColor;
if (ColorDialog1->Execute())
FPenColor = ColorDialog1->Color;
}
void __fastcall TForm1::SpeedButton5Click(TObject *Sender)
{
FPenThickness = dynamic_cast<TSpeedButton *>(Sender)->Tag;
}
void __fastcall TForm1::Save1Click(TObject *Sender)
{
if (SaveDialog1->Execute())
{
Image1->Picture->SaveToFile(SaveDialog1->FileName);
}
}
void __fastcall TForm1::Open1Click(TObject *Sender)
{
if (OpenDialog1->Execute())
{
Image1->Picture->LoadFromFile(OpenDialog1->FileName);
}
}
void
__fastcall TForm1::Exit1Click(TObject *Sender)
{
Close();
}
</FONT></PRE>
<P>The key change from the DrawShapes program is that all of the <TT>Canvas</TT>
operations are performed on the <TT>Canvas</TT> of a <TT>TImage</TT> control rather
than
directly on the <TT>Canvas</TT> of a form:</P>
<PRE><FONT COLOR="#0066FF">Image1->Canvas->MoveTo(FShapeRect.Left, FShapeRect.Top);
Image1->Canvas->LineTo(FShapeRect.Right, FShapeRect.Bottom);
</FONT></PRE>
<P>A <TT>TImage</TT> control is
designed explicitly for the type of operations undertaken
by this program. In particular, it maintains an internal bitmap into which images
are automatically drawn.</P>
<P>When it comes time to save the picture you have created, you can do so with one
line of code:</P>
<PRE><FONT COLOR="#0066FF">void __fastcall TForm1::Save1Click(TObject *Sender)
{
if (SaveDialog1->Execute())
{
Image1->Picture->SaveToFile(SaveDialog1->FileName);
}
}
</FONT></PRE>
<P>Loading a file into
memory from disk is also a simple one-line operation:</P>
<PRE><FONT COLOR="#0066FF">void __fastcall TForm1::Open1Click(TObject *Sender)
{
if (OpenDialog1->Execute())
{
Image1->Picture->LoadFromFile(OpenDialog1->FileName);
}
}
</FONT></PRE>
<P>Both of the preceding calls assume that you have dropped a <TT>TOpenDialog</TT>
onto the main form of your application. The <TT>TOpenDialog</TT> object is extremely
easy to use, so you should have no trouble learning how to use it
from the online
help.
<DL>
<DT></DT>
</DL>
<BLOCKQUOTE>
<P>
<HR>
<FONT COLOR="#000077"><B>NOTE:</B></FONT><B> </B>When I opt not to explain an object
such as <TT>TOpenDialog</TT>, my intention is not to ignore the needs of this book's
readers,
but rather to avoid inserting boring, repetitious information into the book.
If you really crave a reference other than the online help for this kind of information,
you should check the bookstore for introductory texts that cover this kind of
material.
<HR>
</BLOCKQUOTE>
<P>If you want a bit more flexibility, and desire to have a separate <TT>TBitmap</TT>
object which you can use for your own purposes, it is easy to create one from the
image you created with this program. To proceed,
just create a <TT>TBitmap</TT> object,
and then use the <TT>Assign</TT> method to copy the picture from the <TT>TImage</TT>
control to your bitmap:</P>
<PRE><FONT COLOR="#0066FF">Graphics::TBitmap *Bitmap = new Graphics::TBitmap();
Bitmap->Assign(Image1->Picture->Graphic);
Bitmap->SaveToFile(SaveDialog1->FileName);
delete Bitmap;
</FONT></PRE>
<P>In this example I save the bitmap to file and then delete the object when I am
through with it. In the context of
the current program, this doesn't make a great
deal of sense. However, code like this demonstrates some of the functionality of
the <TT>TBitmap</TT> object. I qualify the reference to <TT>TBitmap</TT> with <TT>Graphics.Hpp</TT>,
because there are two
<TT>TBitmap</TT> declarations in the header files included
in most BCB programs.
<H3><A NAME="Heading17"></A><FONT COLOR="#000077">Working with Metafiles</FONT></H3>
<P>Bitmaps are very convenient and are often the best way to work with graphic
images.
However, BCB also lets you work with enhanced metafiles.</P>
<P>Metafiles are collections of shapes drawn into a device context. Internally, they
are little more than a list of GDI calls that can be played back on demand to create
a picture.
Metafiles have two big advantages over bitmaps:
<UL>
<LI>They are very small. The same image that might take hundreds of KB to save in
bitmaps can often be saved in a metafile of just 10 or 20 thousand bytes.
<P>
<LI>Because metafiles consist of
a series of shapes, you can, at least potentially,
iterate through the list of shapes in a picture and edit them one at a time. This
can give you a very powerful ability to precisely edit the contents of a picture.
</UL>
<P>The disadvantage of
metafiles is that they must consist only of a series of GDI
calls. As a result, you can't easily transform a photograph or a scanned image into
a metafile. Metafiles are best defined as a simple way of preserving text, or as
a simple means of storing
a series of fairly simple shapes such as a line drawing.
In the hands of a good artist, however, you can get metafiles to show some fairly
powerful images. (See Figure 7.2.)
<H6></H6>
<P><A NAME="Heading18"></A><A HREF="07ebu02.jpg" tppabs="http://pbs.mcp.com/ebooks/0672310228/art/07/07ebu02.jpg">FIGURE
7.2.</A><FONT COLOR="#000077">
</FONT><I>A grayscale version of a colorful metafile that ships with Microsoft Office
shows some of the power of this technology. </I><BR>
<BR>
There are two types of metafiles available to Windows users. One has the
extension
<TT>.WMF</TT>, and is primarily designed for use in the 16-bit world. The second
type of file has the extension <TT>.EMF</TT>, for Enhanced Metafile. These latter
types of files are designed for use in the 32-bit world. I find them much more
powerful
than their 16-bit cousins.</P>
<P>The code shown in the forthcoming MetaShapes program is designed to work only
with enhanced metafiles. BCB will save a file as a regular metafile if you give it
an extension of <TT>.WMF</TT>, and it will save
it as an enhanced metafile if you
give it an extension of <TT>.EMF</TT>. When using BCB, it is best to stick with enhanced
metafiles. If you have some <TT>.WMF</TT> files you want to use with BCB, you might
want to find a third-party tool that will
convert your <TT>.WMF</TT> into an <TT>.EMF</TT>.</P>
<P>The MetaShapes program is very similar to the DrawShapes and BitmapShapes programs.
It has the same capabilities as the BitmapShapes program in terms of its capability
to save and preserve
images, only it works with metafiles rather than bitmaps. Metafiles
are many times smaller than standard <TT>.BMP</TT> files.</P>
<P>There is no <TT>TImage</TT> control for metafiles, so you have to do a little
more work to make this system function
properly. In particular, you have to explicitly
open a metafile and then draw directly into it, as shown in Listing 7.4 and 7.5.<BR>
<BR>
<A NAME="Heading19"></A><FONT COLOR="#000077"><B>Listing 7.4. The header for the
MetaShapes
program.</B></FONT></P>
<PRE><FONT COLOR="#0066FF">///////////////////////////////////////
// Main.h
// MetaShapes Example
// Copyright (c) 1997 by Charlie Calvert
//
#ifndef MainH
#define MainH
#include <vcl\Classes.hpp>
#include
<vcl\Controls.hpp>
#include <vcl\StdCtrls.hpp>
#include <vcl\Forms.hpp>
#include <vcl\Menus.hpp>
#include <vcl\ExtCtrls.hpp>
#include <vcl\Buttons.hpp>
#include <vcl\Dialogs.hpp>
enum TCurrentShape
{csLine, csRectangle, csEllipse};
class TForm1 : public TForm
{
__published:
TMainMenu *MainMenu1;
TMenuItem *File1;
TMenuItem *Open1;
TMenuItem *Save1;
TMenuItem *N1;
TMenuItem *Exit1;
TMenuItem *Shapes1;
TMenuItem
*Rectangle2;
TMenuItem *Ellipse1;
TMenuItem *Colors1;
TMenuItem *Brush1;
TMenuItem *Pen1;
TPanel *Panel1;
TSpeedButton *SpeedButton1;
TSpeedButton *SpeedButton2;
TSpeedButton *SpeedButton3;
TSpeedButton *SpeedButton4;
TMenuItem *Lines1;
TColorDialog *ColorDialog1;
TSpeedButton *SpeedButton5;
TMenuItem *New1;
TPaintBox *PaintBox1;
TSaveDialog *SaveDialog1;
TOpenDialog *OpenDialog1;
void __fastcall FormMouseDown(TObject *Sender, TMouseButton
Button,
TShiftState Shift, int X, int Y);
void __fastcall FormMouseUp(TObject *Sender, TMouseButton Button,
TShiftState Shift, int X, int Y);
void __fastcall FormMouseMove(TObject
*Sender, TShiftState Shift, int X,
int Y);
void __fastcall SpeedButton1Click(TObject *Sender);
void __fastcall Brush1Click(TObject *Sender);
void __fastcall Pen1Click(TObject *Sender);
void __fastcall
SpeedButton5Click(TObject *Sender);
void __fastcall New1Click(TObject *Sender);
void __fastcall Exit1Click(TObject *Sender);
void __fastcall PaintBox1Paint(TObject *Sender);
void __fastcall FormDestroy(TObject *Sender);
void __fastcall
Save1Click(TObject *Sender);
void __fastcall Open1Click(TObject *Sender);
private:
TRect FShapeRect;
TColor FPenColor;
TColor FBrushColor;
bool FDrawing;
TCurrentShape FCurrentShape;
int FPenThickness;
TMetafile* MyMetafile;
TMetafileCanvas* MyCanvas;
void __fastcall DrawShape();
public:
virtual __fastcall TForm1(TComponent* Owner);
};
extern TForm1 *Form1;
#endif
</FONT></PRE>
<P><A NAME="Heading20"></A><FONT COLOR="#000077"><B>Listing 7.5. The
MetaShapes program
shows how to draw into a metafile and save it to disk.</B></FONT></P>
<PRE><FONT COLOR="#0066FF">///////////////////////////////////////
// Main.cpp
// MetaShapes Example
// Copyright (c) 1997 by Charlie Calvert
//
#include
<vcl\vcl.h>
#pragma hdrstop
#include "Main.h"
#pragma resource "*.dfm"
TForm1 *Form1;
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
FDrawing= False;
FCurrentShape = csRectangle;
FBrushColor
= clBlue;
FPenColor = clYellow;
FPenThickness = 1;
MyMetafile = new TMetafile;
MyCanvas = new TMetafileCanvas(MyMetafile, PaintBox1->Canvas->Handle);
}
void __fastcall TForm1::FormMouseDown(TObject *Sender, TMouseButton Button,
TShiftState Shift, int X, int Y)
{
FShapeRect.Left = X;
FShapeRect.Top = Y;
FShapeRect.Right = - 32000;
FDrawing = True;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -