source: branches/delphi/LocalPlayer/BaseWin.pas

Last change on this file was 6, checked in by chronos, 7 years ago
  • Modified: Formated all project source files using Delphi formatter as original indentation and other formatting was really bad.
File size: 14.8 KB
Line 
1{$INCLUDE switches}
2unit BaseWin;
3
4interface
5
6uses
7 ScreenTools, Messg,
8
9 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms;
10
11type
12 TBufferedDrawDlg = class(TDrawDlg)
13 public
14 UserLeft, UserTop: integer;
15 constructor Create(AOwner: TComponent); override;
16 procedure FormClose(Sender: TObject; var Action: TCloseAction);
17 procedure FormPaint(Sender: TObject);
18 procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
19 procedure FormDeactivate(Sender: TObject);
20 procedure SmartUpdateContent(ImmUpdate: boolean = false);
21 procedure StayOnTop_Workaround;
22 protected
23 FWindowMode, ModalFrameIndent: integer;
24 HelpContext: string;
25 procedure ShowNewContent(NewMode: integer; forceclose: boolean = false);
26 procedure MarkUsedOffscreen(xMax, yMax: integer);
27 procedure OffscreenPaint; virtual;
28 procedure VPaint; virtual;
29 public
30 property WindowMode: integer read FWindowMode;
31 end;
32
33 TFramedDlg = class(TBufferedDrawDlg)
34 public
35 constructor Create(AOwner: TComponent); override;
36 procedure FormCreate(Sender: TObject);
37 procedure SmartInvalidate; override;
38 protected
39 CaptionLeft, CaptionRight, InnerWidth, InnerHeight: integer;
40 WideBottom, FullCaption, TexOverride, ModalIndication: boolean;
41 procedure InitWindowRegion;
42 procedure VPaint; override;
43 procedure FillOffscreen(Left, Top, Width, Height: integer);
44 end;
45
46const
47 // window modes
48 wmNone = 0;
49 wmModal = $1;
50 wmPersistent = $2;
51 wmSubmodal = $3;
52
53 yUnused = 161;
54 NarrowFrame = 11;
55 WideFrame = 36;
56 SideFrame = 9;
57
58var
59 UsedOffscreenWidth, UsedOffscreenHeight: integer;
60 Offscreen: TBitmap;
61 OffscreenUser: TForm;
62
63procedure CreateOffscreen;
64
65implementation
66
67uses
68 Term, Help, ButtonBase, Area;
69
70constructor TBufferedDrawDlg.Create;
71begin
72 OnClose := FormClose;
73 OnPaint := FormPaint;
74 OnKeyDown := FormKeyDown;
75 OnDeactivate := FormDeactivate;
76 inherited;
77 FWindowMode := wmNone;
78 HelpContext := 'CONCEPTS';
79 TitleHeight := WideFrame;
80 ModalFrameIndent := 45;
81 UserLeft := (Screen.Width - Width) div 2;
82 UserTop := (Screen.Height - Height) div 2;
83end;
84
85procedure TBufferedDrawDlg.FormClose(Sender: TObject; var Action: TCloseAction);
86begin
87 if FWindowMode = wmPersistent then
88 begin
89 UserLeft := Left;
90 UserTop := Top
91 end;
92 if OffscreenUser = self then
93 OffscreenUser := nil;
94end;
95
96procedure TBufferedDrawDlg.FormPaint(Sender: TObject);
97begin
98 if OffscreenUser <> self then
99 OffscreenPaint;
100 VPaint
101end;
102
103procedure TBufferedDrawDlg.FormKeyDown(Sender: TObject; var Key: Word;
104 Shift: TShiftState);
105begin
106 if Key = VK_ESCAPE then
107 begin
108 if fsModal in FormState then
109 ModalResult := mrCancel
110 end
111 else if Key = VK_RETURN then
112 begin
113 if fsModal in FormState then
114 ModalResult := mrOK
115 end
116 else if Key = VK_F1 then
117 HelpDlg.ShowNewContent(FWindowMode or wmPersistent, hkText,
118 HelpDlg.TextIndex(HelpContext))
119 else if FWindowMode = wmPersistent then
120 MainScreen.FormKeyDown(Sender, Key, Shift);
121end;
122
123procedure TBufferedDrawDlg.FormDeactivate(Sender: TObject);
124begin
125 if FWindowMode = wmSubmodal then
126 Close
127end;
128
129procedure TBufferedDrawDlg.OffscreenPaint;
130begin
131 if (OffscreenUser <> nil) and (OffscreenUser <> self) then
132 OffscreenUser.Update; // complete working with old owner to prevent rebound
133 OffscreenUser := self;
134end;
135
136procedure TBufferedDrawDlg.VPaint;
137begin
138 BitBlt(Canvas.Handle, 0, 0, ClientWidth, ClientHeight,
139 Offscreen.Canvas.Handle, 0, 0, SRCCOPY);
140end;
141
142procedure TBufferedDrawDlg.ShowNewContent(NewMode: integer;
143 forceclose: boolean);
144begin
145 if Visible then
146 begin
147 assert((NewMode = wmModal) or (FWindowMode <> wmModal));
148 // don't make modal window non-modal
149 if (NewMode = wmModal) and (forceclose or (FWindowMode <> wmModal)) then
150 begin // make modal
151 UserLeft := Left;
152 UserTop := Top;
153 Visible := false;
154 FWindowMode := NewMode;
155 ShowModal;
156 end
157 else if forceclose then
158 begin // make modal
159 Visible := false;
160 FWindowMode := NewMode;
161 Left := UserLeft;
162 Top := UserTop;
163 Show;
164 end
165 else
166 begin
167 FWindowMode := NewMode;
168 if @OnShow <> nil then
169 OnShow(nil);
170 Invalidate;
171 BringToFront
172 end
173 end
174 else
175 begin
176 FWindowMode := NewMode;
177 Left := UserLeft;
178 Top := UserTop;
179 if FWindowMode = wmModal then
180 ShowModal
181 else
182 Show
183 end
184end;
185
186procedure TBufferedDrawDlg.SmartUpdateContent(ImmUpdate: boolean);
187begin
188 if Visible then
189 begin
190 OffscreenPaint;
191 SmartInvalidate;
192 if ImmUpdate then
193 Update
194 end
195end;
196
197procedure TBufferedDrawDlg.MarkUsedOffscreen(xMax, yMax: integer);
198begin
199 if xMax > UsedOffscreenWidth then
200 UsedOffscreenWidth := xMax;
201 if yMax > UsedOffscreenHeight then
202 UsedOffscreenHeight := yMax;
203end;
204
205procedure TBufferedDrawDlg.StayOnTop_Workaround;
206// stayontop doesn't work when window is shown for the first time
207// after application lost focus, so show all stayontop-windows in first turn
208var
209 SaveOnShow, SaveOnPaint: TNotifyEvent;
210begin
211 Top := Screen.Height;
212 SaveOnShow := OnShow;
213 OnShow := nil;
214 SaveOnPaint := OnPaint;
215 OnPaint := nil;
216 FWindowMode := wmNone;
217 Show;
218 Hide;
219 OnShow := SaveOnShow;
220 OnPaint := SaveOnPaint;
221end;
222
223constructor TFramedDlg.Create;
224begin
225 OnCreate := FormCreate;
226 inherited;
227end;
228
229procedure TFramedDlg.FormCreate(Sender: TObject);
230begin
231 CaptionLeft := 0;
232 CaptionRight := $FFFF;
233 WideBottom := false;
234 FullCaption := true;
235 TexOverride := false;
236 ModalIndication := true;
237 Canvas.Brush.Style := bsClear;
238 InnerWidth := ClientWidth - 2 * SideFrame;
239 InnerHeight := ClientHeight - TitleHeight - NarrowFrame;
240end;
241
242procedure TFramedDlg.SmartInvalidate;
243var
244 i, BottomFrame: integer;
245 r0, r1: HRgn;
246begin
247 if WideBottom then
248 BottomFrame := WideFrame
249 else
250 BottomFrame := NarrowFrame;
251 r0 := CreateRectRgn(SideFrame, TitleHeight, ClientWidth - SideFrame,
252 ClientHeight - BottomFrame);
253 for i := 0 to ControlCount - 1 do
254 if not(Controls[i] is TArea) and Controls[i].Visible then
255 begin
256 with Controls[i].BoundsRect do
257 r1 := CreateRectRgn(Left, Top, Right, Bottom);
258 CombineRgn(r0, r0, r1, RGN_DIFF);
259 DeleteObject(r1);
260 end;
261 InvalidateRgn(Handle, r0, false);
262 DeleteObject(r0);
263end;
264
265procedure TFramedDlg.VPaint;
266
267 procedure CornerFrame(x0, y0, x1, y1: integer);
268 begin
269 Frame(Canvas, x0 + 1, y0 + 1, x1 - 2, y1 - 2, MainTexture.clBevelLight,
270 MainTexture.clBevelShade);
271 Frame(Canvas, x0 + 2, y0 + 2, x1 - 3, y1 - 3, MainTexture.clBevelLight,
272 MainTexture.clBevelShade);
273 Corner(Canvas, x0 + 1, y0 + 1, 0, MainTexture);
274 Corner(Canvas, x1 - 9, y0 + 1, 1, MainTexture);
275 Corner(Canvas, x0 + 1, y1 - 9, 2, MainTexture);
276 Corner(Canvas, x1 - 9, y1 - 9, 3, MainTexture);
277 end;
278
279var
280 i, l, FrameTop, FrameBottom, InnerBottom, Cut, xTexOffset,
281 yTexOffset: integer;
282 R: TRect;
283begin
284 if not TexOverride then
285 begin
286 if (FWindowMode = wmModal) and ModalIndication then
287 MainTexture := MainTexture
288 else
289 MainTexture := MainTexture;
290 MainTexture := MainTexture
291 end;
292 Canvas.Font.Assign(UniFont[ftCaption]);
293 l := BiColorTextWidth(Canvas, Caption);
294 Cut := (ClientWidth - l) div 2;
295 xTexOffset := (wMaintexture - ClientWidth) div 2;
296 yTexOffset := (hMaintexture - ClientHeight) div 2;
297 if WideBottom then
298 InnerBottom := ClientHeight - WideFrame
299 else
300 InnerBottom := ClientHeight - NarrowFrame;
301 if FullCaption then
302 begin
303 FrameTop := 0;
304 FrameBottom := ClientHeight
305 end
306 else
307 begin
308 FrameTop := TitleHeight - NarrowFrame;
309 if WideBottom then
310 FrameBottom := ClientHeight - (WideFrame - NarrowFrame)
311 else
312 FrameBottom := ClientHeight
313 end;
314 Fill(Canvas, 3, InnerBottom + 1, ClientWidth - 6, ClientHeight - InnerBottom -
315 4, xTexOffset, yTexOffset);
316 Fill(Canvas, 3, TitleHeight - 2, SideFrame - 3, InnerBottom - TitleHeight + 4,
317 xTexOffset, yTexOffset);
318 Fill(Canvas, ClientWidth - SideFrame, TitleHeight - 2, SideFrame - 3,
319 InnerBottom - TitleHeight + 4, xTexOffset, yTexOffset);
320 Frame(Canvas, 0, FrameTop, ClientWidth - 1, FrameBottom - 1, 0, 0);
321 Frame(Canvas, SideFrame - 1, TitleHeight - 1, ClientWidth - SideFrame,
322 InnerBottom, MainTexture.clBevelShade, MainTexture.clBevelLight);
323 // RFrame(Canvas,SideFrame-2,TitleHeight-2,ClientWidth-SideFrame+1,
324 // InnerBottom+1,MainTexture.clBevelShade,MainTexture.clBevelLight);
325 if FullCaption then
326 begin
327 if (FWindowMode <> wmModal) or not ModalIndication then
328 begin
329 Fill(Canvas, 3, 3 + FrameTop, ClientWidth - 6, TitleHeight - FrameTop - 4,
330 xTexOffset, yTexOffset);
331 CornerFrame(0, FrameTop, ClientWidth, FrameBottom);
332 end
333 else
334 with Canvas do
335 begin
336 Fill(Canvas, 3 + ModalFrameIndent, 3 + FrameTop,
337 ClientWidth - 6 - 2 * ModalFrameIndent, TitleHeight - FrameTop - 4,
338 xTexOffset, yTexOffset);
339 Fill(Canvas, ClientWidth - 3 - ModalFrameIndent, 3 + FrameTop,
340 ModalFrameIndent, TitleHeight - FrameTop - 4, xTexOffset, yTexOffset);
341 Fill(Canvas, 3, 3 + FrameTop, ModalFrameIndent, TitleHeight - FrameTop -
342 4, xTexOffset, yTexOffset);
343 CornerFrame(0, FrameTop, ClientWidth, FrameBottom);
344 Pen.Color := MainTexture.clBevelShade;
345 MoveTo(3 + ModalFrameIndent, 2);
346 LineTo(3 + ModalFrameIndent, TitleHeight);
347 Pen.Color := MainTexture.clBevelShade;
348 MoveTo(4 + ModalFrameIndent, TitleHeight - 1);
349 LineTo(ClientWidth - 4 - ModalFrameIndent, TitleHeight - 1);
350 LineTo(ClientWidth - 4 - ModalFrameIndent, 1);
351 Pen.Color := MainTexture.clBevelLight;
352 MoveTo(ClientWidth - 5 - ModalFrameIndent, 2);
353 LineTo(4 + ModalFrameIndent, 2);
354 LineTo(4 + ModalFrameIndent, TitleHeight);
355 MoveTo(ClientWidth - 4 - ModalFrameIndent, 1);
356 LineTo(3 + ModalFrameIndent, 1);
357 Pen.Color := MainTexture.clBevelLight;
358 MoveTo(ClientWidth - 3 - ModalFrameIndent, 3);
359 LineTo(ClientWidth - 3 - ModalFrameIndent, TitleHeight);
360 end
361 end
362 else
363 begin
364 Fill(Canvas, 3, 3 + FrameTop, ClientWidth - 6, TitleHeight - FrameTop - 4,
365 xTexOffset, yTexOffset);
366 CornerFrame(0, FrameTop, ClientWidth, FrameBottom);
367
368 Frame(Canvas, CaptionLeft, 0, ClientWidth - CaptionLeft - 1,
369 FrameTop, 0, 0);
370 Fill(Canvas, CaptionLeft + 3, 3, ClientWidth - 2 * (CaptionLeft) - 6,
371 TitleHeight - 4, xTexOffset, yTexOffset);
372
373 Frame(Canvas, CaptionLeft + 1, 0 + 1, ClientWidth - CaptionLeft - 2,
374 TitleHeight - 1, MainTexture.clBevelLight, MainTexture.clBevelShade);
375 Frame(Canvas, CaptionLeft + 2, 0 + 2, ClientWidth - CaptionLeft - 3,
376 TitleHeight - 1, MainTexture.clBevelLight, MainTexture.clBevelShade);
377 Corner(Canvas, CaptionLeft + 1, 0 + 1, 0, MainTexture);
378 Corner(Canvas, ClientWidth - CaptionLeft - 9, 0 + 1, 1, MainTexture);
379
380 with Canvas do
381 begin
382 Pen.Color := MainTexture.clBevelShade;
383 MoveTo(CaptionLeft + 1, FrameTop + 2);
384 LineTo(CaptionLeft + 1, TitleHeight);
385 Pen.Color := MainTexture.clBevelLight;
386 MoveTo(ClientWidth - CaptionLeft - 2, FrameTop + 2);
387 LineTo(ClientWidth - CaptionLeft - 2, TitleHeight);
388 end;
389 if WideBottom then
390 begin
391 Frame(Canvas, CaptionLeft, FrameBottom, ClientWidth - CaptionLeft - 1,
392 ClientHeight - 1, 0, 0);
393 Fill(Canvas, CaptionLeft + 3, ClientHeight - 3 - (WideFrame - 5),
394 ClientWidth - 2 * (CaptionLeft) - 6, WideFrame - 5, xTexOffset,
395 yTexOffset);
396 Frame(Canvas, CaptionLeft + 1, ClientHeight - WideFrame - 1 + 1,
397 ClientWidth - CaptionLeft - 2, ClientHeight - 2,
398 MainTexture.clBevelLight, MainTexture.clBevelShade);
399 Frame(Canvas, CaptionLeft + 2, ClientHeight - WideFrame - 1 + 1,
400 ClientWidth - CaptionLeft - 3, ClientHeight - 3,
401 MainTexture.clBevelLight, MainTexture.clBevelShade);
402 Corner(Canvas, CaptionLeft + 1, ClientHeight - 9, 2, MainTexture);
403 Corner(Canvas, ClientWidth - CaptionLeft - 9, ClientHeight - 9, 3,
404 MainTexture);
405
406 with Canvas do
407 begin
408 Pen.Color := MainTexture.clBevelShade;
409 MoveTo(CaptionLeft + 1, ClientHeight - WideFrame);
410 LineTo(CaptionLeft + 1, FrameBottom - 2);
411 Pen.Color := MainTexture.clBevelLight;
412 MoveTo(ClientWidth - CaptionLeft - 2, ClientHeight - WideFrame);
413 LineTo(ClientWidth - CaptionLeft - 2, FrameBottom - 2);
414 end;
415 end
416 end;
417 RisedTextOut(Canvas, Cut - 1, 7, Caption);
418
419 for i := 0 to ControlCount - 1 do
420 if Controls[i].Visible and (Controls[i] is TButtonBase) then
421 begin
422 R := Controls[i].BoundsRect;
423 if (R.Bottom <= TitleHeight) or (R.Top >= InnerBottom) then
424 BtnFrame(Canvas, R, MainTexture);
425 end;
426
427 BitBlt(Canvas.Handle, SideFrame, TitleHeight, ClientWidth - 2 * SideFrame,
428 InnerBottom - TitleHeight, Offscreen.Canvas.Handle, 0, 0, SRCCOPY);
429end;
430
431procedure TFramedDlg.InitWindowRegion;
432var
433 r0, r1: HRgn;
434begin
435 if FullCaption then
436 exit;
437 r0 := CreateRectRgn(0, 0, ClientWidth, ClientHeight);
438 r1 := CreateRectRgn(0, 0, CaptionLeft, TitleHeight - NarrowFrame);
439 CombineRgn(r0, r0, r1, RGN_DIFF);
440 // DeleteObject(r1);
441 r1 := CreateRectRgn(ClientWidth - CaptionLeft, 0, ClientWidth,
442 TitleHeight - NarrowFrame);
443 CombineRgn(r0, r0, r1, RGN_DIFF);
444 // DeleteObject(r1);
445 if WideBottom then
446 begin
447 r1 := CreateRectRgn(0, ClientHeight - (WideFrame - NarrowFrame),
448 CaptionLeft, ClientHeight);
449 CombineRgn(r0, r0, r1, RGN_DIFF);
450 // DeleteObject(r1);
451 r1 := CreateRectRgn(ClientWidth - CaptionLeft,
452 ClientHeight - (WideFrame - NarrowFrame), ClientWidth, ClientHeight);
453 CombineRgn(r0, r0, r1, RGN_DIFF);
454 // DeleteObject(r1);
455 end;
456 SetWindowRgn(Handle, r0, false);
457 // DeleteObject(r0); // causes crash with Windows 95
458end;
459
460procedure TFramedDlg.FillOffscreen(Left, Top, Width, Height: integer);
461begin
462 Fill(Offscreen.Canvas, Left, Top, Width, Height,
463 SideFrame + (wMaintexture - ClientWidth) div 2,
464 TitleHeight + (hMaintexture - ClientHeight) div 2);
465end;
466
467procedure CreateOffscreen;
468begin
469 if Offscreen <> nil then
470 exit;
471 Offscreen := TBitmap.Create;
472 Offscreen.PixelFormat := pf24bit;
473 Offscreen.Width := Screen.Width;
474 if Screen.Height - yUnused < 480 then
475 Offscreen.Height := 480
476 else
477 Offscreen.Height := Screen.Height - yUnused;
478 Offscreen.Canvas.Brush.Style := bsClear;
479end;
480
481initialization
482
483Offscreen := nil;
484OffscreenUser := nil;
485
486finalization
487
488Offscreen.Free;
489
490end.
Note: See TracBrowser for help on using the repository browser.