Back

1     //------------------------------------------------------------------------------
2     //    module: FAbout.cpp                                                      //
3     //                                                                            //
4     //    About-dialog with a few lines of text and an animated icon playing      //
5     //    pinball with the dialogs frame.                                         //
6     //                                                                            //
7     //    Copyright (c) 2000-2004 by Lars Haendel                                 //
8     //    home: http://www.newty.de                                               //
9     //                                                                            //
10    //    This program is free software and can be used under the terms of the    //
11    //    GNU licence. See header-file for further information and disclaimer.    //
12    //                                                                            //
13    //------------------------------------------------------------------------------
14
15
16    #include <vcl.h>
17    #pragma hdrstop
18
19    #include <math>                   // due to:  cos()/sin()
20    #include <stdio>                  //          sprintf()
21    #include <process>                //          _beginthread()
22
23
24    #pragma package(smart_init)
25    #pragma resource "*.dfm"
26
27
28    //----------------------------------------------------------------------------------------------------------------------
29    #include "FAbout.h"
30
31    #define SZ_PURPOSE   "A Source to HTML Converter"
32    #define SZ_AUTHOR    "Lars Haendel"
33    #define SZ_URL       "http:\/\/www.newty.de\/lsc/index.html"
34
35
36    TFAbout *FAbout;
37    //----------------------------------------------------------------------------------------------------------------------
38    // constructor
39    __fastcall TFAbout::TFAbout(TComponent* Owner, const AnsiString& szName, const AnsiString& szDir) : TForm(Owner)
40    {
41    // ToDo: move code to OnShow() ??
42
43       // compose and set dialog's caption
44       Caption = AnsiString("About the program ") + szName;
45
46       // ask for the size of an icon - usually 32x32
47       cxIcon = GetSystemMetrics(SM_CXICON);
48       cyIcon = GetSystemMetrics(SM_CYICON);
49
50
51       // create and load the two icons
52       icon1 = new TPicture;
53       icon2 = new TPicture;
54
55       icon1->LoadFromFile(szDir + "Smiley1.ico");
56       icon2->LoadFromFile(szDir + "Smiley2.ico");
57
58       // icon start position
59       randomize();
60       xIcon = random(Width);             // initialize icon position and ...
61       yIcon = random(Height);
62       directionPhi = 1;                  // ... moving direction
63
64
65       // set the icon to be shown in the image, set its size and show it
66       Image->Picture  = icon1;
67
68
69       // create panel
70       panel = new TPanel(this);
71       panel->Parent = this;
72       panel->HandleNeeded();                   // this creates the window
73       panel->BorderStyle = bsNone;
74       panel->BevelInner  = bvNone;
75       panel->BevelOuter  = bvNone;
76       panel->FullRepaint = false;
77
78
79
80       // set the panel position to be the same as the Image's one
81       panel->Left   = xIcon;
82       panel->Top    = yIcon;
83       panel->Width  = cxIcon;
84       panel->Height = cyIcon;
85
86
87       Image->Parent   = panel;    // make the panel to be the image's parent ...
88       Image->Left     = 0;        // ... and position it inside the panel
89       Image->Top      = 0;
90
91
92       // exchange the panel's WindowProc() function
93       OldWindowProc = panel->WindowProc;              // remember old one
94       panel->WindowProc = NewWindowProc;              // set new one
95
96
97       Timer->Enabled=true;                            // enable timer
98
99
100      // wrap handle in the wrapper (needed to pass it by pointer to a thread function
101      wrapper.hwnd = Handle;
102   }
103
104
105   //----------------------------------------------------------------------------------------------------------------------
106   // initialize purpose and author texts
107   void __fastcall TFAbout::FormShow(TObject *Sender)
108   {
109      LaPurpose  ->Caption = AnsiString("// ") + SZ_PURPOSE;
110      LaWrittenBy->Caption = AnsiString("// Written by ") + SZ_AUTHOR;
111   }
112
113
114
115   //----------------------------------------------------------------------------------------------------------------------
116   // disable timer and restore the panel's old WindowProc() function
117   void __fastcall TFAbout::OnClose(TObject *Sender, TCloseAction &Action)
118   {
119      panel->WindowProc = OldWindowProc;     // restore
120      Timer->Enabled = false;                // disable timer
121      Action = caFree;                       // emulates 'wfDeleteOnClose' behaviour
122   }
123
124
125   //----------------------------------------------------------------------------------------------------------------------
126   // eliminate the panel's WM_ERASEBKGND message and forward all other
127   void __fastcall TFAbout::NewWindowProc(TMessage& msg)
128   {
129      if(msg.Msg == WM_ERASEBKGND)
130         msg.Result=false;
131      else
132         OldWindowProc(msg);
133   }
134
135   //----------------------------------------------------------------------------------------------------------------------
136   // close dialog if user hits escape
137   void __fastcall TFAbout::FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift)
138   {
139      if(Key==VK_ESCAPE)
140         Close();
141   }
142
143
144   //----------------------------------------------------------------------------------------------------------------------
145   // evaluate timer event: move the panel with the icon and check for contact with the dialog's frame
146   void __fastcall TFAbout::OnTimer(TObject *Sender)
147   {
148      // eventually restore display to the standard-icon
149      if(nSmile == 0)
150         Image->Picture = icon1;
151      nSmile--;                  // decrease counter
152
153
154      // calculate new position
155      xIcon +=  2.5*cos(directionPhi);
156      yIcon += -2.5*sin(directionPhi);
157
158
159      // check calculated position against the dialog's border and "reflect" if the icon hits it
160      if(xIcon < 0)                                      // left border
161      {
162         xIcon             = 0;
163         directionPhi      = -directionPhi + M_PI;
164         nSmile            = 5;
165         Image->Picture    = icon2;
166      }
167
168
169      if(yIcon < 0)                                      // top border
170      {
171         yIcon             = 0;
172         directionPhi      = -directionPhi;
173         nSmile            = 5;
174         Image->Picture    = icon2;
175      }
176
177      if(xIcon > ClientWidth-cxIcon)                     // right border
178      {
179         xIcon             = ClientWidth-cxIcon;
180         directionPhi      = -directionPhi + M_PI;
181         nSmile            = 5;
182         Image->Picture    = icon2;
183      }
184
185      if(yIcon > ClientHeight-cyIcon)                    // bottom border
186      {
187         yIcon             = ClientHeight-cyIcon;
188         directionPhi      = -directionPhi;
189         nSmile            = 5;
190         Image->Picture    = icon2;
191      }
192
193      panel->Left = xIcon;   // move panel with the icon inside
194      panel->Top  = yIcon;
195   }
196
197
198      //-------------------------------------------------------------------------------------------------------------------
199      //   functions to open URL in browser
200      //
201
202   //----------------------------------------------------------------------------------------------------------------------
203   // function executes the shell command in an additional thread - see below
204   void OpenURL(void* _tmp)
205   {
206      TFAbout::THandleWrap* tmp = (TFAbout::THandleWrap*) _tmp;
207      ShellExecute(tmp->hwnd, "open", SZ_URL, 0, 0, SW_NORMAL);
208   }
209
210
211   //----------------------------------------------------------------------------------------------------------------------
212   // functions open homepage URL in browser or mail client. both call a thread function which executes
213   // the necessary shell command.  done this way cause some browsers need a long time to open ... ;-)
214   void __fastcall TFAbout::UrlClick(TObject *Sender)
215   {
216      _beginthread(OpenURL, 4096, (void*) &wrapper);
217      Image->Picture = icon2;
218   }

Top