⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch07.htm

📁 好书《C++ Builder高级编程技术》
💻 HTM
📖 第 1 页 / 共 5 页
字号:
}



void __fastcall TForm1::FormMouseUp(TObject *Sender, TMouseButton Button,

                                    
TShiftState Shift, int X, int Y)

{

  if (FDrawing)

  {

    FDrawing = False;

    FShapeRect.Right = X;

    FShapeRect.Bottom = Y;

    PaintBox1->Canvas->Pen->Mode = pmCopy;

    MyCanvas->Pen->Mode = pmCopy;

    DrawShape();

  
}

}



void __fastcall TForm1::DrawShape()

{

  PaintBox1->Canvas->Brush->Color = FBrushColor;

  PaintBox1->Canvas->Brush->Style = bsSolid;

  PaintBox1->Canvas->Pen->Color = FPenColor;

  
PaintBox1->Canvas->Pen->Width = FPenThickness;



  MyCanvas->Brush->Color = FBrushColor;

  MyCanvas->Brush->Style = bsSolid;

  MyCanvas->Pen->Color = FPenColor;

  MyCanvas->Pen->Width = FPenThickness;



  switch 
(FCurrentShape)

  {

    case csLine:

      MyCanvas->MoveTo(FShapeRect.Left, FShapeRect.Top);

      MyCanvas->LineTo(FShapeRect.Right, FShapeRect.Bottom);

      PaintBox1->Canvas->MoveTo(FShapeRect.Left, FShapeRect.Top);

      
PaintBox1->Canvas->LineTo(FShapeRect.Right, FShapeRect.Bottom);

      break;



    case csRectangle:

      PaintBox1->Canvas->Rectangle(FShapeRect.Left, FShapeRect.Top,

                                   FShapeRect.Right, 
FShapeRect.Bottom);

      MyCanvas->Rectangle(FShapeRect.Left, FShapeRect.Top,

                          FShapeRect.Right, FShapeRect.Bottom);

      break;



    case csEllipse:

      PaintBox1->Canvas->Ellipse(FShapeRect.Left, 
FShapeRect.Top,

                                 FShapeRect.Right, FShapeRect.Bottom);

      MyCanvas->Ellipse(FShapeRect.Left, FShapeRect.Top,

                        FShapeRect.Right, FShapeRect.Bottom);

      break;



    default:

      ;



  
}

}



void __fastcall TForm1::FormMouseMove(TObject *Sender,

                                      TShiftState Shift, int X, int Y)

{

  if (FDrawing)

  {

    PaintBox1->Canvas->Pen->Mode = pmNotXor;

    MyCanvas->Pen->Mode = 
pmNotXor;

    if (FShapeRect.Right != -32000)

      DrawShape();

    FShapeRect.Right = X;

    FShapeRect.Bottom = Y;

    DrawShape();

  }

}



void __fastcall TForm1::SpeedButton1Click(TObject *Sender)

{

  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::New1Click(TObject *Sender)

{

  delete MyCanvas;

  delete MyMetafile;



  MyMetafile = new TMetafile;

  MyCanvas = new TMetafileCanvas(MyMetafile, 
0);

  InvalidateRect(Handle, NULL, True);  

}



void __fastcall TForm1::PaintBox1Paint(TObject *Sender)

{

  delete MyCanvas;

  if (MyMetafile)

    PaintBox1->Canvas->Draw(0,0,MyMetafile);

  MyCanvas = new TMetafileCanvas(MyMetafile, 
PaintBox1->Canvas->Handle);

  MyCanvas->Draw(0, 0, MyMetafile);

}



void __fastcall TForm1::FormDestroy(TObject *Sender)

{

  delete MyCanvas;

}



void __fastcall TForm1::Exit1Click(TObject *Sender)

{

  Close();

}



void __fastcall 
TForm1::Save1Click(TObject *Sender)

{

  if (SaveDialog1->Execute())

  {

    delete MyCanvas;

    MyMetafile->SaveToFile(SaveDialog1->FileName);

    MyCanvas = new TMetafileCanvas(MyMetafile, 0);

    MyCanvas->Draw(0, 0, MyMetafile);

  
}

}



void __fastcall TForm1::Open1Click(TObject *Sender)

{

  if (OpenDialog1->Execute())

  {

    FShapeRect = Rect(0, 0, 0, 0);

    delete MyCanvas;

    TFileStream *Stream = new TFileStream(OpenDialog1->FileName, fmOpenRead);

    
MyMetafile->LoadFromStream(Stream);

    MyCanvas = new TMetafileCanvas(MyMetafile, PaintBox1->Canvas->Handle);

    MyCanvas->Draw(0, 0, MyMetafile);

    PaintBox1->Canvas->Draw(0, 0, MyMetafile);

    Stream->Free();

  }

}


</FONT></PRE>
<P>This program works just like the BitmapShapes program shown previously, in that
it lets you draw colored shapes to the screen and then save them to file. A screenshot
of the program is shown in Figure 7.3.<BR>
<BR>
<A 
NAME="Heading21"></A><A HREF="07ebu03.jpg" tppabs="http://pbs.mcp.com/ebooks/0672310228/art/07/07ebu03.jpg">FIGURE 7.3.</A><FONT COLOR="#000077">
</FONT><I>The MetaShapes program in action.</I></P>
<P>When working with metafiles, you need to create both a <TT>TMetafile</TT> object
and a 
<TT>TMetafileCanvas</TT> object.</P>
<PRE><FONT COLOR="#0066FF">MyMetafile = new TMetafile;

MyCanvas = new TMetafileCanvas(MyMetafile, PaintBox1-&gt;Canvas-&gt;Handle);

</FONT></PRE>
<P>Notice that the <TT>TMetafileCanvas</TT> is explicitly 
associated with a particular
<TT>TMetafile</TT> object. Specifically, the <TT>TMetaFile</TT> object is passed
in as the first parameter of the <TT>TMetaFileCanvas</TT> object's constructor. These
two classes are designed to work in tandem, and both 
pieces must be present if you
want to create a metafile.</P>
<P>Here is a simple example of how to draw into a <TT>TMetafile</TT> canvas:</P>
<PRE><FONT COLOR="#0066FF">MyCanvas-&gt;Ellipse(FShapeRect.Left, FShapeRect.Top,

                  
FShapeRect.Right, FShapeRect.Bottom);

</FONT></PRE>
<P>This code looks exactly like any other call to the <TT>TCanvas::Ellipse</TT>,
only this time I am writing into a <TT>TMetafileCanvas</TT> rather than a form's
<TT>Canvas</TT>.

<DL>
	<DT></DT>

</DL>



<BLOCKQUOTE>
	<P>
<HR>
<FONT COLOR="#000077"><B>NOTE:</B></FONT><B> </B>The VCL preserves the <TT>Canvas</TT>
	metaphor in a wide variety of contexts, such as when you are working with metafiles
	or bitmaps. This enables you to learn one set 
of commands, and to then apply them
	to a wide variety of objects. As you will see later in the book, this type of functionality
	derives in part from a judicious and intelligent use of polymorphism. <BR>
	<BR>
	Basing a suite of objects on one model 
enables users to quickly get up to speed on
	new technologies. The underlying code for creating bitmaps is very different from
	the code for creating metafiles. But the <TT>TCanvas</TT> object enables you to treat
	each operation as if it were nearly 
identical. People who are interested in object
	design should contemplate the elegance of this implementation. 
<HR>


</BLOCKQUOTE>

<P>If you only want to display a metafile, you can work solely with the <TT>TMetafile</TT>
object. However, if you 
want to create metafiles, to draw images into a metafile,
you need a <TT>TMetafileCanvas</TT> object. You can draw directly into a <TT>TMetafileCanvas</TT>,
but when you want to display the image to the user, you need to delete the object
so that its 
contents will be transferred into a metafile that can be displayed for
the user:</P>
<PRE><FONT COLOR="#0066FF">delete MyCanvas;

PaintBox1-&gt;Canvas-&gt;Draw(0,0,MyMetafile);

</FONT></PRE>
<P>In this code I am using a <TT>PaintBox</TT> as the 
surface on which to display
the metafile. The code first deletes the <TT>TMetafileCanvas</TT>, thereby transferring
the painting from the <TT>TMetafileCanvas</TT> to the <TT>TMetafile</TT>. This implementation
is, I suppose, a bit awkward, but once 
you understand the principle involved, it
should not cause you any serious difficulty.</P>
<P>There is no particular connection between metafiles and the <TT>TPaintBox</TT>
object. In fact, I could just as easily have painted directly into a 
<TT>TForm</TT>.
The reason I chose <TT>TPaintBox</TT> is that it enables me to easily define a subsection
of a form that can be used as a surface on which to paint. In particular, part of
the form in the <TT>MetaShapes</TT> program is covered by a 
<TT>TPanel</TT> object.
To make sure that the user can see the entire canvas on which he will be painting,
I used a <TT>TPaintBox</TT>.</P>
<P>If you are interested in these matters, you might want to open up <TT>EXTCTRLS.HPP</TT>
and compare the 
declarations for <TT>TPaintBox</TT> and <TT>TImage</TT>. Both of
these controls are descendants of <TT>TGraphicControl</TT>, and both offer similar
functionality. The big difference between them is that <TT>TImage</TT> has an underlying
bitmap, while 
<TT>TPaintBox</TT> has a simpler, sparer architecture.</P>
<P>By now it has probably occurred to you that there is no simple means for displaying
a metafile to the user at the time it is being created. In particular, you can't
show it to the user 
without first deleting the <TT>TMetafileCanvas</TT>. To avoid
performing this action too often, I simply record the user's motions into both the
<TT>TMetafileCanvas</TT> and the <TT>Canvas</TT> for the main form:</P>
<PRE><FONT 
COLOR="#0066FF">PaintBox1-&gt;Canvas-&gt;Brush-&gt;Color = FBrushColor;

 ... // Code ommitted

MyCanvas-&gt;Brush-&gt;Color = FBrushColor;

 ...// Code ommitted

switch (FCurrentShape)

{

  case csLine:

    MyCanvas-&gt;MoveTo(FShapeRect.Left, 
FShapeRect.Top);

    MyCanvas-&gt;LineTo(FShapeRect.Right, FShapeRect.Bottom);

    PaintBox1-&gt;Canvas-&gt;MoveTo(FShapeRect.Left, FShapeRect.Top);

    PaintBox1-&gt;Canvas-&gt;LineTo(FShapeRect.Right, FShapeRect.Bottom);

    break;

   ... // 
etc

</FONT></PRE>
<P>This duplication of code, while bothersome, is not really terribly costly in terms
of what it is adding to the size of my executable. Needless to say, I use this technique
so that the user can see what he or she is painting.</P>

<P>If the user flips away from the program and covers it with another application,
I need to repaint the image when the user flips back to <TT>MetaShapes</TT>:</P>
<PRE><FONT COLOR="#0066FF">void __fastcall TForm1::PaintBox1Paint(TObject *Sender)

{

  
delete MyCanvas;

  PaintBox1-&gt;Canvas-&gt;Draw(0,0,MyMetafile);

  MyCanvas = new TMetafileCanvas(MyMetafile, PaintBox1-&gt;Canvas-&gt;Handle);

  MyCanvas-&gt;Draw(0, 0, MyMetafile);

}

</FONT></PR

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -