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

📄 ch17.htm

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

</FONT></PRE>
<P>The main form of the program can print text, such as that shown in Figure 17.12,
where you can see one of Shakespeare's sonnets. To 
send this text to the printer,
you need to retrieve the printer object from the VCL. This object is declared in
the Printers unit, so you must include that unit in your form. You can the write
the following code:</P>
<PRE><FONT COLOR="#0066FF">void 
TForm1::SendToPrinter()

{

  TPrinter *APrinter = Printer();

  APrinter-&gt;BeginDoc();

  PrintText(APrinter-&gt;Canvas);

  APrinter-&gt;EndDoc();

}

</FONT></PRE>
<P>This code first calls the <TT>Printer</TT> method to retrieve an object of type

<TT>TPrinter</TT>. It then calls the <TT>BeginDoc</TT> method of the <TT>TPrinter</TT>
object to start a document. When the printing task is done, you should call <TT>EndDoc</TT>.</P>
<P>The following method handles the actual printing chores:</P>

<PRE><FONT COLOR="#0066FF">void TForm1::PrintText(TCanvas *Canvas)

{

  int i, x;

  AnsiString S(&quot;Test String&quot;);

  x = Canvas-&gt;TextHeight(S);

  for (i = 0; i &lt; Memo1-&gt;Lines-&gt;Count; i++)

  {

    S = 
Memo1-&gt;Lines-&gt;Strings[i];

    Canvas-&gt;TextOut(1, x * i, S);

  }

}

</FONT></PRE>
<P>As you can see, this code starts at the beginning of the list of strings and iterates
through them all, using the <TT>TPrinter</TT> <TT>Canvas</TT> object 
to print the
current information. You can change the font, colors, and other aspects of the canvas
in any way you like. Recall that in Chapter 7, &quot;Graphics,&quot; I described
how to use the <TT>Canvas</TT> object.
<H3><FONT 
COLOR="#000077">Printing Shapes to the Printer</FONT></H3>
<P>One of the great advantages of the code shown in the <TT>PrintText</TT> method
is that you can use it with any <TT>Canvas</TT> object. For instance, I could pass
in the <TT>Canvas</TT> of 
the main form and then print the output to the main form,
rather than to the printer.</P>
<P>The technique described in the last paragraph is what goes on in the form shown
in Figure 17.13. This form provides the user with two buttons, one for 
printing information
to a control on the current form and the other for printing information to a printer:</P>
<PRE><FONT COLOR="#0066FF">void __fastcall TPaintBoxForm::PrintPictureBtnClick(TObject *Sender)

{

  switch(dynamic_cast&lt;TButton 
*&gt;(Sender)-&gt;Tag)

  {

    case 0:

    {

      SendToPrinter();

      break;

    }

    case 1:

    {

      ShowData(PaintBox1-&gt;Canvas);

      break;

    }

  }

</FONT></PRE>
<PRE><FONT COLOR="#0066FF">}

</FONT></PRE>
<P>If you opt 
to send information to the printer, the following code is called:</P>
<PRE><FONT COLOR="#0066FF">void TPaintBoxForm::SendToPrinter()

{

  if (PrintDialog1-&gt;Execute())

  {

    TPrinter *APrinter = Printer();

    APrinter-&gt;BeginDoc();

    
ShowData(APrinter-&gt;Canvas);

    APrinter-&gt;EndDoc();

  }

}

</FONT></PRE>
<P>This code first pops up a <TT>TPrintDialog</TT> and lets the user set up the printer,
and switch into color printing mode, if necessary. A document is started, and 
the
<TT>ShowData</TT> method is called:</P>
<PRE><FONT COLOR="#0066FF">void __fastcall TPaintBoxForm::ShowData(TCanvas *Canvas)

{

  Canvas-&gt;Brush-&gt;Color = clBlue;

  Canvas-&gt;Pen-&gt;Color = clYellow;

  Canvas-&gt;Rectangle(0, 0, 
PaintBox1-&gt;Width, PaintBox1-&gt;Height);

  Canvas-&gt;Font-&gt;Color = clYellow;

  Canvas-&gt;TextOut(5, 5, &quot;Hi&quot;);

  Canvas-&gt;Brush-&gt;Color = clPurple;

  Canvas-&gt;Ellipse(25, 25, 150, 150);

}

</FONT></PRE>
<P>As you can see, 
this method draws some text and a series of shapes into a canvas.
If the canvas you pass to this program is for the main form or for a control placed
on the main form, the output will appear there. If the canvas you pass in belongs
to the printer, the 
output will be sent to the printer.


<BLOCKQUOTE>
	<P>
<HR>
<FONT COLOR="#000077"><B>NOTE:</B></FONT><B> </B>One problem that I do not address
	in this code involves selecting the proper size and proportions for the current printer.
	As a rule, you 
will find that text or shapes that look okay on the screen will be
	far too small when shown on a printer. For hints on how to remedy the situation,
	view the code in <TT>Forms.pas</TT> that shows how to implement the <TT>poProportional</TT>
	and 
<TT>poPrintToFit</TT> options discussed earlier in this chapter. This code is
	almost all straight Windows API code, and will look virtually identical in C++ and
	Object Pascal. 
<HR>


</BLOCKQUOTE>

<H4><A NAME="Print Bitmaps"></A><FONT 
COLOR="#000077">Print Bitmaps</FONT></H4>
<P>The final portion of the PrintGDI program that might be of interest to some users
involves printing bitmaps. This sounds like it must be a complicated subject, but
the VCL makes it easy.</P>
<P>The key to 
this process is using a <TT>TImage</TT> control on the form from which
you want to print a bitmap. The following code can be used to load an image into
that <TT>TImage</TT> control.</P>
<PRE><FONT COLOR="#0066FF">void __fastcall 
TPrintBitmapForm::Open1Click(TObject *Sender)

{

  if (OpenDialog1-&gt;Execute())

  {

    Image1-&gt;Picture-&gt;LoadFromFile(OpenDialog1-&gt;FileName);

  }

}

</FONT></PRE>
<P>To print the image, just write the following code:</P>
<PRE><FONT 
COLOR="#0066FF">void __fastcall TPrintBitmapForm::Print1Click(TObject *Sender)

{

  if (PrintDialog1-&gt;Execute())

  {

    TPrinter *APrinter = Printer();

    APrinter-&gt;BeginDoc();

    APrinter-&gt;Canvas-&gt;Draw(1, 1, 
Image1-&gt;Picture-&gt;Bitmap);

    APrinter-&gt;EndDoc();

  }

}

</FONT></PRE>
<P>This code pops up a <TT>TPrintDialog</TT>, grabs the printer, and begins a document.
You can draw a bitmap on the <TT>TPrinter</TT> canvas by calling <TT>Draw</TT> 
and
passing in the bitmap already loaded into the <TT>TImage</TT> component. The first
two parameters passed to draw specify where you want the printing to begin as expressed
in X, Y coordinates. The final step is to call <TT>EndDoc</TT>, which sends 
a form-feed
to the printer.</P>
<P>That is all I'm going to say about the <TT>TPrinter</TT> class. There are more
features of this object that you can explore via the online help or by opening up
<TT>Printers.hpp</TT>. However, the basic facts 
outlined here should give you most
of the information you need to get started with this object.</P>
<H3><A NAME="Printing Records in ReportSmith"></A><FONT COLOR="#000077">Printing
Records in ReportSmith</FONT></H3>
<P>ReportSmith is no longer an 
integrated part of the VCL family of products. However,
I will touch on this subject briefly, just to give you a few clues about how to proceed
with the tool if you need it. In particular, I will show how to create a report for
the Address2 program.

<H3 ALIGN="CENTER"></H3>


<BLOCKQUOTE>
	<P>
<HR>
<FONT COLOR="#000077"><B>NOTE:</B></FONT><B> </B>In the current shipping version
	of BCB, there aren't any <TT>TReportSmith</TT> or <TT>TReport</TT> components. However,
	I am sure that the people now 
making ReportSmith supply this component with the product.
	In the worst-case scenario, you can just use the Windows API command called <TT>WinExec</TT>
	to start ReportSmith and pass as a parameter the name of the report you want to run.
	There are 
also ways to pass macros to ReportSmith, and you can talk to the product
	using DDE. 
<HR>


</BLOCKQUOTE>

<P>To start creating a report, bring up ReportSmith using the Explorer and select
the type of report you want to make, which is probably a 
label-based report. Go to
the Tables page in the Report Query dialog, choose Add Table, and select <TT>ADDRESS.DB</TT>.
ReportSmith understands BDE aliases, so you can use those to help you select a table.</P>
<P>Next, go to the Report Variables page 
and create a new variable called <TT>Filter</TT>.
Set its type to <TT>String</TT>, its title to <TT>Filter List</TT>, and the prompt
to <TT>&quot;What filter do you want to use?&quot;</TT>. Set the entry to <TT>Type-in</TT>,
as shown in Figure 17.15. 
When you are done, choose Add.<BR>
<BR>
<A NAME="Heading31"></A><A HREF="17ebu15.jpg" tppabs="http://pbs.mcp.com/ebooks/0672310228/art/17/17ebu15.jpg">FIGURE 17.15.</A><FONT COLOR="#000077">
</FONT><I>Creating report variables in ReportSmith.</I>
<H3 ALIGN="CENTER"></H3>


<BLOCKQUOTE>
	<P>
<HR>
<FONT 
COLOR="#000077"><B>NOTE:</B></FONT><B> </B>You do not have to choose Type-in
	as the entry method. In fact, the Address2 program is ideally suited for using the
	Choose from a Table method. After you select this method, a work space will appear
	in 
the bottom-right corner of the Report Variables page that enables you to choose
	a table and field that contain a list of available entries. In this case, you can
	choose the CATS.DB table and the <TT>Category</TT> field. Now when the user wants
	to 
run the report, he or she will be prompted with a list of valid categories and
	can choose the appropriate one, without the likelihood of an error being introduced.
	The copy of the ReportSmith report that ships with the CD for this book uses this
	
method. 
<HR>


</BLOCKQUOTE>

<P>Turn to the Selections page, click on the yellow number 1 in the center of the
page, and choose Select SQL selection criteria from the drop-down list. Select the
<TT>Category</TT> field from the DataFields list box on 
the left and choose x=y from
the Comparison Operators in the middle list box. Go back to the left-hand list box
and change the combo box at the top so it reads Report Variables rather than Data
Fields. Choose Filter and then set this variable in 
quotes:</P>
<PRE><FONT COLOR="#0066FF">`ADDRESSxDB'.'CATEGORY' = `&lt;&lt;Filter&gt;&gt;'

</FONT></PRE>
<P>When you are done, the dialog should look like that in Figure 17.16. Now click
the OK button at the bottom of the dialog.<BR>
<BR>
<A 
NAME="Heading32"></A><A HREF="17ebu16.jpg" tppabs="http://pbs.mcp.com/ebooks/0672310228/art/17/17ebu16.jpg">FIGURE 17.16.</A><FONT COLOR="#000077">
</FONT><I>Creating SQL selection criteria in ReportSmith.</I></P>
<P>The final step in this process is to create derived fields in the Derived Fields
page of the 
Report Query dialog. The first derived field should combine the <TT>FName</TT>
and <TT>LName</TT> fields, so you might want to call this field <TT>FirstLast</TT>.
After typing in the name, select Add, and the Edit Derived Fields dialog box will

appear. Select <TT>FName</TT> from the left column:</P>
<PRE><FONT COLOR="#0066FF">`ADDRESSxDB'.'FName'

</FONT></PRE>
<P>Choose Addition from the middle column:</P>
<PRE><FONT COLOR="#0066FF">`ADDRESSxDB'.'FName' +

</FONT></PRE>
<P>Add a space by 
writing the string <TT>` `</TT>:</P>
<PRE><FONT COLOR="#0066FF">`ADDRESSxDB'.'FName' + ` `

</FONT></PRE>
<P>Choose Addition again from the middle column:</P>
<PRE><FONT COLOR="#0066FF">`ADDRESSxDB'.'FName' + ` ` +

</FONT></PRE>
<P>End by adding the 
<TT>LName</TT> field. The string you create should look like
this:</P>
<PRE><FONT COLOR="#0066FF">`ADDRESSxDB'.'FName' + ` ` + `ADDRESSxDB'.'LName'

</FONT></PRE>
<P>This statement combines the <TT>FName</TT> and <TT>LName</TT> fields so that they

produce a single string out of a first and last name:</P>
<PRE><FONT COLOR="#0066FF">Kurt Weill

</FONT></PRE>
<P>You should then create a second derived field called <TT>CityStateZip</TT>, which
combines the <TT>City</TT>, <TT>State</TT>, and 
<TT>Zip</TT> fields:</P>
<PRE><FONT COLOR="#0066FF">`ADDRESSxDB'.'CITY' + `, ` + `ADDRESSxDB'.'STATE' + ` `  +

  `ADDRESSxDB'.'ZIP'

</FONT></PRE>
<P>You have now created the logic behind a report, so choose Done from the bottom
of the Report Query 
dialog. ReportSmith will then pop up a dialog to fill in the
report variable you created. In other words, it's time for you to fill in the Filter
portion of the following statement:</P>
<PRE><FONT COLOR="#0066FF">`ADDRESSxDB'.'CATEGORY' = 
`&lt;&lt;Filter&gt;&gt;'

</FONT></PRE>
<P>You can type the word <TT>Family</TT>, <TT>Work</TT>, or whatever value you feel
will return a reasonably sized dataset.</P>
<P>The Insert Field dialog now appears, and you can enter the fields and derived

fields that you have created. The combo box at the top of the dialog enables you
to switch back and forth between data fields and derived fields; you should do so
when you think it's appropriate. For instance, the first field you select will probably

be the derived field called <TT>FirstLast</TT>, whereas the second will probably
be the data field called <TT>Address1</TT>. When you are done, the report you create
should look something like the image shown in Figure 17.17.<BR>
<BR>
<A 
NAME="Heading33"></A><A HREF="17ebu17.jpg" tppabs="http://pbs.mcp.com/ebooks/0672310228/art/17/17ebu17.jpg">FIGURE 17.17.</A><FONT COLOR="#000077">
</FONT><I>A &quot;live

⌨️ 快捷键说明

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