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

📄 ch28.htm

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

}




//--------------------------------------------------------------------------



</FONT></PRE>
<P>Run the project once with <TT>Exclusive</TT> set to <TT>False</TT>. Click the
Run button once to switch on DirectX. In this mode, you should see the color 
of the
main form change, but nothing else very special will happen.</P>
<P>Go back into design mode, and check once to make sure that you have not placed
any components on the main form other than the menu and the <TT>THermes</TT>. The
rest of the 
form must be free of visual controls so that you can detect keystrokes
directly on the surface of the form.</P>
<P>Set <TT>Exclusive</TT> to <TT>True</TT> and run the program again. Click the Run
menu item, and the whole screen should go blank as you 
switch into <TT>Exclusive</TT>
mode. To get out of the mode, simply press any key.</P>
<P>If you want, you can change the code for the <TT>OnKeyDown</TT> event:</P>
<PRE><FONT COLOR="#0066FF">

void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD 
&amp;Key,

  TShiftState Shift)

{

  if ((Shift.Contains(ssAlt)) &amp;&amp; (Key == `X'))

    Close();

}

</FONT></PRE>
<P>With this code in place, you will be able to press Alt+Tab to move away from the
main window of the program and switch out of 
<TT>Exclusive</TT> mode. You can then
press Alt+Tab to move back to the program and press Alt+X to exit. When you're pressing
these keys, the actual picture drawn on your screen when in <TT>Exclusive</TT> mode
is undefined because <TT>THermes</TT> 
does not control the output in <TT>Exclusive</TT>
mode; it controls only the act of entering and exiting <TT>Exclusive</TT> mode.</P>
<P>DirectX allows you to run applications in a windowed mode. That is, you don't
have to slip into <TT>Exclusive</TT> 
mode to run DirectX applications. However, windowed
mode is not very good in terms of performance. In fact, you'll find little advantage
to a windowed mode DirectX application over a GDI-based standard Windows program.</P>
<P>I give you access to 
windowed mode primarily because it is valuable when you're
debugging an application. In short, you should run your DirectX applications in windowed
mode while you're debugging them so that you can step through the debugger while
viewing your 
application's output. After you set up your application correctly, switch
into Exclusive mode and test it.</P>
<P>If an exception happens when you're in <TT>Exclusive</TT> mode, that is a bad
thing. In particular, your program will appear to lock up, 
and you may be forced
to reboot. Following the steps outlined in the preceding paragraphs helps you eliminate
the possibility that this will happen. However, you cannot be sure that an exception
will not be raised in your application. As a result, you 
might want to override the
exception handler for your application in this case:</P>
<PRE><FONT COLOR="#0066FF">

__fastcall TForm1::TForm1(TComponent* Owner)

  : TForm(Owner)

{

  Application-&gt;OnException = MyExceptions;

}



void __fastcall 
TForm1::MyExceptions(TObject *Sender,

  Exception *E)

{

  Hermes1-&gt;EndExclusive();

  ShowMessage(E-&gt;Message);

}

</FONT></PRE>
<P>The constructor for the main form designates a custom routine called <TT>MyExceptions</TT>
to handle all the 
exceptions that occur in this application. Whenever an unhandled
exception occurs, it will be passed to this routine. When I get the exception, I
call <TT>Hermes1-&gt;EndExclusive</TT>, which pops the application out of <TT>Exclusive</TT>
mode, 
therefore making it possible to open the dialog box that shows the error message.


<BLOCKQUOTE>

	<DL>
	<DD>
<HR>
<FONT COLOR="#000077"><B>NOTE: </B></FONT>This system will not do you any good, of
	course, unless you turn off the Break On Exception 
option, which you can find by
	choosing Options | Environment | Preferences. If you are in Exclusive mode, and the
	IDE tries to take you to the line of code in your application where an exception
	occurred, your system will appear to lock up. 
<HR>

	
</DL>


</BLOCKQUOTE>

<P>As a rule, I will not show you the underlying Object Pascal code that makes this
component work. However, in this one case, I will show you what goes on:</P>
<PRE><FONT COLOR="#0066FF">procedure THermes.EndExclusive;

begin

  
if (FDirectDraw &lt;&gt; nil) then begin

    FDirectDraw.FlipToGDISurface;

    if FExclusive then

      FDirectDraw.SetCooperativeLevel(FHandle, DDSCL_Normal);

  end;



end;

</FONT></PRE>
<P>This code first flips away from DirectX to GDI mode 
and then cuts out of Exclusive
mode by setting the cooperative level to normal. When I take the application into
Exclusive mode, I make the same call but with different parameters:</P>
<PRE><FONT COLOR="#0066FF">

DDTest(DirectDrawCreate(nil, 
FDirectDraw, nil), `InitObjects1');

if not FExclusive then

  Flags := DDSCL_NORMAL

else

  Flags := DDSCL_EXCLUSIVE or DDSCL_FULLSCREEN;

DDTest(FDirectDraw.SetCooperativeLevel(FHandle, Flags),'SetCooperativeLevel');

if FExclusive then begin

  hr 
:= FDirectDraw.SetDisplayMode(640, 480, 8);

  if(hr &lt;&gt; DD_OK) then

    raise EDDError.CreateFmt(`THermes.InitObjects: %d %s',

      [hr, GetOleError(hr)]);

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

end;

</FONT></PRE>
<P>Notice that my 
<TT>EndExclusive</TT> method makes no attempt to set the display
mode back to the dimensions and bit depth selected by the user in his or her system
configuration. Instead, I just leave it to the user to close the application, which
will return the 
screen to its normal resolution. My goal in using <TT>EndExclusive</TT>
is just to keep the system from hanging.
<H2><FONT COLOR="#000077">TScene: Drawing a Background</FONT></H2>
<P>After you know how to get into and out of <TT>Exclusive</TT> mode, 
the next step
is to learn how to draw a picture to the screen. Most games consist of many pictures,
but I start out showing you how to use a simple object that just displays a single
bitmap. For most people, this object is not really very useful, in 
that there is
no point in using DirectX if you want to show only one picture. However, <TT>TScene</TT>
serves as a base class for other objects that handle more complex tasks. I will therefore
spend a few moments showing you how to use it so that you 
will understand the class
on which the other objects are built.</P>
<P>You can find the declaration for the class and some code that uses it in Listings
28.4 through 28.6. Again, I show only the class declarations for the Pascal code
and give the 
complete listings for the C++ code.
<H4><FONT COLOR="#000077">Listing 28.4. The class declaration for the key parts of
the TScene and TDraw objects.</FONT></H4>
<PRE><FONT COLOR="#0066FF">

class TDraw;

class TDraw : public Classes::TComponent

{

  
typedef Classes::TComponent inherited;

  friend THermesTiler;

  friend THermesChart;

  friend TScene;

  friend TSpriteScene;



private:

  AnsiString FDLLName;

  THermes* FHermes;

  HANDLE FLib;

  IDirectDrawPalette* FPalette;

  int 
FTransparentColor;

  bool __fastcall CreateDDSurface(IDirectDrawSurface* &amp;DDS,

    System::AnsiString BitmapName, bool UsePalette);

  IDirectDrawSurface* __fastcall CreateSurface(HANDLE Bitmap);

  HANDLE __fastcall GetDib(HANDLE Instance,  
System::AnsiString S);

  IDirectDrawPalette* __fastcall LoadPalette(HANDLE Instance,

    const System::AnsiString BitmapName);



public:

  __fastcall virtual TDraw(Classes::TComponent* AOwner);

  __fastcall virtual ~TDraw(void);

      void 
__fastcall WriteXY(int X, int Y,  System::AnsiString S);

  __property int TransparentColor =

    {read=FTransparentColor, write=FTransparentColor, nodefault};



__published:

  __property AnsiString DLLName =

    {read=FDLLName, write=FDLLName};


};



class TScene : public TDraw

{

  typedef TDraw inherited;

  friend THermes;

private:

  System::AnsiString FBackgroundBitmap;

  Graphics::TColor FBackColor;

  RECT FBackRect;

  tagPOINT FBackOrigin;

  bool FBlankScene;

  bool 
FShowBitmap;

  IDirectDrawSurface* FWorkSurface;

  Classes::TNotifyEvent FOnSetupSurfaces;

  Classes::TNotifyEvent FOnDrawScene;



public:

  __fastcall virtual TScene(Classes::TComponent* AOwner);

  virtual void __fastcall DestroyObjects(void);

  
virtual void __fastcall DrawScene(void);

  virtual long __fastcall RestoreSurfaces(void);

  virtual void __fastcall SetupSurfaces(System::TObject* Sender);



__published:

  __property System::AnsiString BackgroundBitmap =

    
{read=FBackgroundBitmap, write=FBackgroundBitmap, nodefault};

  __property bool BlankScene = {read=FBlankScene, write=FBlankScene, nodefault};

  __property long OriginX ={read=FBackOrigin.x, write=FBackOrigin.x, nodefault};

  __property long 
OriginY ={read=FBackOrigin.y, write=FBackOrigin.y, nodefault};

  __property bool ShowBitmap = {read=FShowBitmap, write=FShowBitmap, default=1};

  __property Classes::TNotifyEvent OnDrawScene =

    {read=FOnDrawScene, write=FOnDrawScene};

  
__property Classes::TNotifyEvent OnSetupSurfaces =

    {read=FOnSetupSurfaces, write=FOnSetupSurfaces};

  __property Graphics::TColor BackColor =

    {read=FBackColor, write=FBackColor, nodefault};

  __property TransparentColor ;

public:

  
__fastcall virtual ~TScene(void) { }

</FONT></PRE>
<P><FONT COLOR="#0066FF"><TT>};</TT></FONT>
<H4><FONT COLOR="#000077">Listing 28.5. The header for the unit from the SceneTest1
project that tests the TScene object.</FONT></H4>
<PRE><FONT 
COLOR="#0066FF">

///////////////////////////////////////

// Main.h

// Test the TScene object

// Copyright (c) 1997 by Charlie Calvert

//

#ifndef MainH

#define MainH

#include &lt;vcl\Classes.hpp&gt;

#include &lt;vcl\Controls.hpp&gt;

#include 
&lt;vcl\StdCtrls.hpp&gt;

#include &lt;vcl\Forms.hpp&gt;

#include &lt;vcl\Menus.hpp&gt;

#include &quot;Mercury2.h&quot;



class TForm1 : public TForm

{

__published:

  TScene *Scene1;

  THermes *Hermes1;

  TMainMenu *MainMenu1;

  TMenuItem 
*Run1;

  void __fastcall Run1Click(TObject *Sender);

  void __fastcall FormKeyDown(TObject *Sender, WORD &amp;Key, TShiftState Shift);

private:

⌨️ 快捷键说明

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