📄 ch01.htm
字号:
Multimedia program:</P>
<PRE><FONT COLOR="#0066FF">object Form1: TForm1
Left = 244
Top = 147
Width = 493
Height = 388
Caption = `Form1'
Menu = MainMenu1
object Image1: TImage
Left = 0
Top = 41
Width = 485
Height = 301
Align = alClient
Picture.Data = { Lots of numbers omitted here }
end
object Panel1: TPanel
Left = 0
Top = 0
Width = 485
Height = 41
Align = alTop
TabOrder = 0
object MediaPlayer1:
TMediaPlayer
Left = 192
Top = 5
Width = 253
Height = 30
TabOrder = 0
end
end
// Menu would appear here
object OpenDialog1: TOpenDialog
FileEditStyle = fsEdit
Filter = `Movies, Sound,
Midi|*.avi;*.wav;*.mid'
InitialDir = `c:\'
Left = 48
Top = 48
end
end</FONT></PRE>
</BLOCKQUOTE>
<PRE><FONT COLOR="#0066FF"></FONT></PRE>
<BLOCKQUOTE>
<P>You can convert your forms into this kind of text by right-clicking them
and selecting
View as Text from a popup menu. Conversely, you can translate text into visual forms
by right-clicking them and selecting View as Form from a popup menu. You can also
convert programs back and forth from text to binary files by
running a command-line
utility called <TT>Convert.exe</TT>. Finally, you can type the preceding code into
a text editor, copy it to the Clipboard, and then paste it onto a BCB form or panel.
After the paste operation, you will not see text, but
live visual components. <BR>
<BR>
At any rate, I have opted not to use the kind of textual description of a form shown
above, primarily because the form itself is available on disk, and secondarily, because
a picture of a form, like that shown in
Figure 1.2, provides more information than
a textual description. I do, however, provide both binary and textual copies of the
forms on the CD that accompanies this book.
<HR>
</BLOCKQUOTE>
<H4><A NAME="Heading20"></A><FONT COLOR="#000077">A
Brief Note on Creating Menus</FONT></H4>
<P>You can add a menu to this program by dropping down a <TT>TMenu</TT> component,
double- clicking it, and filing it out as follows:</P>
<PRE><FONT COLOR="#0066FF">TMenuItem *File1; // Popup menu
TMenuItem
*Load1; // menu item
TMenuItem *Play1; // menu item
TMenuItem *N1; // (separator made by entering a dash in the Caption field)
TMenuItem *Exit1; // menu item
TMenuItem *Options1; // Popup menu
TMenuItem *ChangeBackground1; //
menu item
</FONT></PRE>
<P>The text for each of these menu items is the same as the name of the menu item
itself, except that the <TT>1</TT> is removed from the end of the name.<BR>
<BR>
<A NAME="Heading21"></A><A HREF="01ebu02.jpg" tppabs="http://pbs.mcp.com/ebooks/0672310228/art/01/01ebu02.jpg">FIGURE
1.2. </A><I>The Menu
Designer as it looks during the construction of the menu for the Multimedia RAD program.</I>
<DL>
<DT></DT>
</DL>
<BLOCKQUOTE>
<P>
<HR>
<FONT COLOR="#000077"><B>NOTE:</B></FONT><B> </B>I would not normally cover this
kind
of material in this book, but it might be helpful to hear one description of
how to use the C++Builder visual tools in hyper-mode. If you grasp the subtleties
of this technique, you will find that you do not need to manually switch back and
forth
between a form and the Object Inspector. Instead, the environment will move
you back and forth automatically between the two tools. <BR>
<BR>
To get started working in hyper-mode, make sure the Menu Designer is closed, because
this process works
best if you start from scratch. Now bring up the Menu Designer
by double-clicking the <TT>TMenu</TT> object you dropped on the form. Immediately
after double-clicking the item, start typing into the Menu Designer dialog. Don't
bring up the Object
Inspector. Instead, type directly on the Menu Designer, and watch
as the Object Inspector comes up of its own accord. When you want to switch back
to the Menu Designer, just press Enter. <BR>
<BR>
For instance, focus the Menu Designer on the first
blank menu item and type the word
<TT>File</TT>. Press Enter. Type <TT>Open</TT>. Press Enter. Type <TT>Close</TT>.
Press Enter. To move over to the next column, press the right arrow key. Type <TT>Edit</TT>,
press Enter, and so on. <BR>
<BR>
You
can also select items on the Menu Designer and edit them inside the Object Inspector.
However, it is easier to use the hyper-mode method. For more details, see the online
help or an introductory book on BCB programming.
<HR>
</BLOCKQUOTE>
<P>You
should also go to the Object Inspector for the <TT>TImage</TT> component and
set its <TT>Picture</TT> property to the bitmap you want to have as the background
for the main form. The <TT>TImage</TT> component should have its <TT>Align</TT> property
set to <TT>alClient</TT>, and its <TT>Stretch</TT> property set to <TT>True</TT>.</P>
<P>You should set the <TT>Filter</TT> property for the <TT>TOpenDialog</TT> component
so it looks like the screen shot shown in Figure 1.3. In particular, the text
for
the property would look like this, if you were filling it out in code rather than
via the Object Inspector:</P>
<PRE><FONT COLOR="#0066FF">OpenDialog1->Filter = "Movies, Sound, Midi | *.avi;*.wav;*.mid";
</FONT></PRE>
<P><FONT
COLOR="#0066FF"><BR>
<A NAME="Heading23"></A></FONT><A HREF="01ebu03.jpg" tppabs="http://pbs.mcp.com/ebooks/0672310228/art/01/01ebu03.jpg">FIGURE 1.3.</A><FONT
COLOR="#000077"> </FONT><I>The Property editor for the <TT>Filter</TT> property of
the <TT>TOpenDialog</TT> component.</I></P>
<PRE><I></I></PRE>
<H4><A NAME="Heading24"></A><FONT COLOR="#000077">Loading a Multimedia File</FONT></H4>
<P>The following function is called when the user selects the Load menu item from
the File menu:</P>
<PRE><FONT COLOR="#0066FF">void __fastcall
TForm1::Load1Click(TObject *Sender)
{
if (OpenDialog1->Execute())
{
MediaPlayer1->FileName = OpenDialog1->FileName;
MediaPlayer1->Open();
}
}
</FONT></PRE>
<P>This code first opens a common dialog to allow the user to
select a filename.
If the user clicks the OK button in this dialog, the selected filename is assigned
to the multimedia component and the component is opened. The act of opening the component
"turns on the lights" on the multimedia control
itself. In other words,
after you open the component, it moves from a grayed-out, inactive state to a colorful,
active state.
<H4><A NAME="Heading25"></A><FONT COLOR="#000077">The VCL and Memory Allocation</FONT></H4>
<P>Notice that the objects you
are working with here are all created on the heap.
There is no such thing as a static instance of a VCL component, or indeed, of a VCL
object. All VCL objects are created on the heap--that is, you always create a pointer
to a VCL object and you don't
ever create a static instance of a VCL component. In
fact, you can't create a static instance of a VCL object. The compiler won't let
you. VCL objects exist on the heap by definition, as will be explained further in
the next chapter.
<DL>
<DT></DT>
</DL>
<BLOCKQUOTE>
<P>
<HR>
<FONT COLOR="#000077"><B>NOTE:</B></FONT><B> </B>My mixing of the words component
and object in the previous paragraph is intentional. All VCL components are nothing
more than VCL objects with a small amount of
overhead added to them so they can appear
on the Component Palette. All VCL components are also VCL objects, but not all VCL
objects are components. This subject will be explained in depth in the chapters on
creating your own components. <BR>
<BR>
You will also find that I use the words class and object interchangeably. Contrary
to popular belief, this is not an error. Needless to say, I understand that quite
often people use the word class to refer to a declaration, and they use the word
object to refer to an instance of a class. However, this rather fine distinction
becomes a bit precious in real life, so I tend to use the words interchangeably unless
I have a specific need to make a distinction between the two concepts. When that
is the case, I will make it abundantly clear that you need to make a distinction
between a class declaration and an object instance.
<HR>
</BLOCKQUOTE>
<P>Notice also that you are not actually responsible for allocating or deallocating
memory for
VCL components. If you want to, you can explicitly create a component
in code. For instance, here is how to dynamically create a <TT>TButton</TT> control:</P>
<PRE><FONT COLOR="#0066FF">MyButton = new TButton(this);
MyButton->Parent = this;
MyButton->Caption = "Dynamic Button";
MyButton->Width = 250;
MyButton->Show();
</FONT></PRE>
<P>This type of code is explored in depth later in this chapter, but if you want
to see it in action right away, you can run the
DynamicButton program found on the
CD-ROM that accompanies this book, in the <TT>Chap01</TT> directory. A screen shot
of that program appears in Figure 1.4.<BR>
<BR>
<A NAME="Heading27"></A><A HREF="01ebu04.jpg" tppabs="http://pbs.mcp.com/ebooks/0672310228/art/01/01ebu04.jpg">FIGURE 1.4.</A><FONT
COLOR="#000077">
</FONT><I>The DynamicButton program dynamically allocates a button at runtime.</I></P>
<P>It is also not usually your concern to deallocate the memory associated with a
component. BCB has no garbage collection facility. The
constructor for <TT>TButton</TT>
shown above assigns <TT>this</TT> as the owner of the control. That means that the
main form for the program is responsible for disposing <TT>MyButton</TT>, because
it has been designated as the owner of the button.
(The <TT>this</TT> pointer is
a bit of syntactical hand-waving that allows an object to refer to itself. In this
case, <TT>Form1</TT> owns <TT>TButton</TT>, and the identifier <TT>this</TT> is a
way of referring to <TT>Form1</TT>.) The code in
<TT>TForm</TT> that deallocates
<TT>MyButton</TT> is built into the VCL. You never have to think about it. I will,
however, discuss how it works in several parts of this book.</P>
<P>The scheme described here sounds a lot like garbage collection. In
fact, if you
drop a component on a form from the Component Palette and then run the program and
terminate it normally, you will never have to worry about either allocating or deallocating
memory for components. This is not a true garbage-collection
scheme because you have
the option of not passing in a parent to an object when you create it and you can
decide to deallocate an object at any time if you want. In other words, many of the
memory management chores are taken care of for you, but they
do not have to be handled
by the system if you would rather do them yourself. This freedom is what I love about
BCB, but it also brings responsibility with it.</P>
<P>A true garbage collection scheme would never allow you to make mistakes allocating
or deallocating memory. The VCL does not go that far. You can definitely make mistakes
with memory management if you are not careful. On the other hand, it should be clear
to you that BCB programmers are relieved of many onerous memory management
chores.
In fact, if you do things right, you rarely have to think about memory management.
Part of the job of this book will be to explain how to ensure that you never have
to worry about memory management. I will, however, also show you how to take
matters
into your own hands, if you wish.
<H4><A NAME="Heading28"></A><FONT COLOR="#000077">A First Glance at Exception Handling</FONT></H4>
<P>The simple act of opening the <TT>TMediaPlay</TT> component is not the same as
causing the component to
play a movie or song. If the users want to play a file that
has been loaded into the component, they can push the green button on the <TT>TMediaPlayer</TT>
control. Alternatively, they can select the Play menu item from the File menu:</P>
<PRE><FONT
COLOR="#0066FF">void __fastcall TForm1::Play1Click(TObject *Sender)
{
try
{
MediaPlayer1->Play();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -