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 |