FlatForm.pas 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  1. unit FlatForm;
  2. interface
  3. uses
  4. Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  5. Dialogs, StdCtrls, XMLDoc, XMLIntf, ExtCtrls, StrUtils, pngimage;
  6. type
  7. TFlatMouseStatus = (fmsOther, fmsOnCloseBtn, fmsOnMinBtn, fmsOnMaxBtn);
  8. TFlatForm = class(TForm)
  9. private
  10. FBorderColor,
  11. FBorderColorOuter,
  12. FBorderColorInter: TColor;
  13. FClosePic,
  14. FMinPic: TPicture;
  15. FMinBtnRect,
  16. FMaxBtnRect,
  17. FCloseBtnRect,
  18. FLeftTopCorner,
  19. FLeftBottomCorner,
  20. FRightTopCorner,
  21. FRightBottomCorner,
  22. FCaptionRect: TRect;
  23. FCanResizeWindow: Boolean;
  24. FFlatMouseStatus: TFlatMouseStatus;
  25. procedure SetBorderColor(const Value: TColor);
  26. procedure ReSetRect;
  27. procedure DoMouseLeave;
  28. protected
  29. procedure DrawButton(ACanvas: TCanvas);
  30. procedure WMNCHitTest(var msg: TWMNCHITTEST); message WM_NCHITTEST;
  31. procedure WMNCLButtonDown(var Message: TWMNCLButtonDown); message WM_NCLBUTTONDOWN;
  32. procedure AdjustClientRect(var Rect: TRect); override;
  33. procedure WMNCMouseMove(var msg: TWMNCMousemove); message WM_NCMOUSEMOVE;
  34. procedure WMEraseBkgnd(var Msg: TWMEraseBkgnd); message WM_ERASEBKGND;
  35. procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
  36. procedure WndProc(var Message: TMessage); override;
  37. procedure DoCreate; override;
  38. procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
  39. procedure Resize; override;
  40. public
  41. constructor Create(AOwner: TComponent); override;
  42. destructor Destroy; override;
  43. procedure ChangeUIColor(AColor: TColor); virtual;
  44. property BorderColor: TColor read FBorderColor write SetBorderColor;
  45. property CanResizeWindow: Boolean read FCanResizeWindow write FCanResizeWindow;
  46. end;
  47. implementation
  48. uses
  49. LoggerImport;
  50. const
  51. WIN_BTN_SIZE: Integer = 30;
  52. BORDER_WIDTH: Integer = 3;
  53. CAPTION_HEIGHT: Integer = 35;
  54. MIN_PIC: string ='\Images\AppCentre\Min.png';
  55. CLOSE_PIC: string ='\Images\AppCentre\Close.png';
  56. { TFlatForm }
  57. procedure TFlatForm.AdjustClientRect(var Rect: TRect);
  58. begin
  59. inherited;
  60. Rect.Left := BORDER_WIDTH;
  61. Rect.Top := CAPTION_HEIGHT;
  62. Rect.Right := ClientWidth - BORDER_WIDTH;
  63. Rect.Bottom := ClientHeight - BORDER_WIDTH;
  64. end;
  65. procedure TFlatForm.ChangeUIColor(AColor: TColor);
  66. begin
  67. // Color := ConvertColorToColor(Color, AColor);
  68. // FBorderColor := ConvertColorToColor(FBorderColor, AColor);
  69. end;
  70. procedure TFlatForm.CMMouseLeave(var Message: TMessage);
  71. begin
  72. if (FFlatMouseStatus <> fmsOther) then
  73. begin
  74. FFlatMouseStatus := fmsOther;
  75. Invalidate;
  76. end;
  77. inherited;
  78. end;
  79. constructor TFlatForm.Create(AOwner: TComponent);
  80. begin
  81. inherited;
  82. // DoubleBuffered := True;
  83. FBorderColor := $00CECECE;
  84. FBorderColorOuter := $00CECECE;
  85. // FBorderColorInter := $00EEEEEE;
  86. CanResizeWindow := True;
  87. FClosePic := TPicture.Create;
  88. FMinPic := TPicture.Create;
  89. FClosePic.LoadFromFile(ExtractFileDir(ParamStr(0)) + CLOSE_PIC);
  90. FMinPic.LoadFromFile(ExtractFileDir(ParamStr(0)) + MIN_PIC);
  91. // with Padding do
  92. // begin
  93. // Left := 3;
  94. // Right := 3;
  95. // Top := 30;
  96. // Bottom := 3;
  97. // end;
  98. end;
  99. destructor TFlatForm.Destroy;
  100. begin
  101. FreeAndNil(FClosePic);
  102. FreeAndNil(FMinPic);
  103. inherited;
  104. end;
  105. procedure TFlatForm.DoCreate;
  106. var
  107. hr :thandle;
  108. begin
  109. hr:=createroundrectrgn(1,1,width,height,2,2);
  110. setwindowrgn(handle,hr,true);
  111. ReSetRect;
  112. inherited;
  113. end;
  114. procedure TFlatForm.DoMouseLeave;
  115. begin
  116. inherited;
  117. if (FFlatMouseStatus <> fmsOther) then
  118. begin
  119. FFlatMouseStatus := fmsOther;
  120. Invalidate;
  121. end;
  122. end;
  123. procedure TFlatForm.DrawButton(ACanvas: TCanvas);
  124. var
  125. tmp1,
  126. tmp2: TRect;
  127. begin
  128. tmp1 := FCloseBtnRect;
  129. tmp2 := FMinBtnRect;
  130. OffsetRect(tmp1, 2, -2);
  131. OffsetRect(tmp2, 2, -2);
  132. case FFlatMouseStatus of
  133. fmsOther: ;
  134. fmsOnCloseBtn:
  135. begin
  136. ACanvas.Pen.Color := $002740D4;
  137. ACanvas.Brush.Color := $002740D4;
  138. ACanvas.Rectangle(tmp1);
  139. end;
  140. fmsOnMinBtn:
  141. begin
  142. ACanvas.Pen.Color := $00DE953A;
  143. ACanvas.Brush.Color := $00DE953A;
  144. ACanvas.Rectangle(tmp2);
  145. end;
  146. fmsOnMaxBtn: ;
  147. end;
  148. ACanvas.Draw(
  149. tmp1.Left + (WIN_BTN_SIZE - FClosePic.Width) div 2,
  150. tmp1.Top + (WIN_BTN_SIZE - FClosePic.Height) div 2,
  151. FClosePic.Graphic);
  152. ACanvas.Draw(
  153. tmp2.Left + (WIN_BTN_SIZE - FMinPic.Width) div 2,
  154. tmp2.Top + (WIN_BTN_SIZE - FMinPic.Height) div 2,
  155. FMinPic.Graphic);
  156. end;
  157. procedure TFlatForm.ReSetRect;
  158. begin
  159. FCloseBtnRect.Left := Width - BORDER_WIDTH - WIN_BTN_SIZE;
  160. FCloseBtnRect.Top := BORDER_WIDTH;
  161. FCloseBtnRect.Right := FCloseBtnRect.Left + WIN_BTN_SIZE;
  162. FCloseBtnRect.Bottom := FCloseBtnRect.Top + WIN_BTN_SIZE;
  163. FMinBtnRect.Left := FCloseBtnRect.Left - WIN_BTN_SIZE;
  164. FMinBtnRect.Top := BORDER_WIDTH;
  165. FMinBtnRect.Right := FMinBtnRect.Left + WIN_BTN_SIZE;
  166. FMinBtnRect.Bottom := FMinBtnRect.Top + WIN_BTN_SIZE;
  167. // FMaxBtnRect,
  168. // ,
  169. FLeftTopCorner := Rect(0, 0, BORDER_WIDTH, BORDER_WIDTH);
  170. FLeftBottomCorner := Rect(0, Height - BORDER_WIDTH, BORDER_WIDTH, Height);
  171. FRightTopCorner := Rect(Width - BORDER_WIDTH, 0, Width, BORDER_WIDTH);
  172. FRightBottomCorner := Rect(Width - BORDER_WIDTH, Height - BORDER_WIDTH, Width, Height);
  173. FCaptionRect := Rect(BORDER_WIDTH, BORDER_WIDTH, FMinBtnRect.Left, CAPTION_HEIGHT);
  174. end;
  175. procedure TFlatForm.Resize;
  176. var
  177. hr :thandle;
  178. begin
  179. inherited;
  180. ReSetRect;
  181. hr:=createroundrectrgn(1,1,width,height,2,2);
  182. setwindowrgn(handle,hr,true);
  183. end;
  184. procedure TFlatForm.SetBorderColor(const Value: TColor);
  185. begin
  186. FBorderColor := Value;
  187. end;
  188. procedure TFlatForm.WMNCHitTest(var msg: TWMNCHITTEST);
  189. var
  190. P: TPoint;
  191. begin
  192. P := ScreenToClient(Mouse.CursorPos);
  193. if PtInRect(FMinBtnRect, P) then
  194. begin
  195. msg.Result := HTMINBUTTON;
  196. // Cursor := crDefault;
  197. end
  198. else if PtInRect(FCloseBtnRect, P) then
  199. begin
  200. msg.Result := HTCLOSE;
  201. // Cursor := crDefault;
  202. end
  203. // else if PtInRect(FMaxBtnRect, P) and FCanResizeWindow and not FRevokeMaxButton then
  204. // begin
  205. // msg.Result := HTMAXBUTTON;
  206. // Cursor := crDefault;
  207. // end
  208. else if PtInRect(FLeftTopCorner, P) and FCanResizeWindow then
  209. begin
  210. msg.Result := HTTOPLEFT;
  211. end
  212. else if PtInRect(FRightTopCorner, P) and FCanResizeWindow then
  213. begin
  214. msg.Result := HTTOPRIGHT;
  215. end
  216. else if PtInRect(FLeftBottomCorner, P) and FCanResizeWindow then
  217. begin
  218. msg.Result := HTBOTTOMLEFT;
  219. end
  220. else if PtInRect(FRightBottomCorner, P) and FCanResizeWindow then
  221. begin
  222. msg.Result := HTBOTTOMRIGHT;
  223. end
  224. else if (P.X < BORDER_WIDTH) and FCanResizeWindow then
  225. begin
  226. msg.Result := HTLEFT;
  227. end
  228. else if (P.X > Width - BORDER_WIDTH) and FCanResizeWindow then
  229. begin
  230. msg.Result := HTRIGHT;
  231. end
  232. else if (P.Y < BORDER_WIDTH) and FCanResizeWindow then
  233. begin
  234. msg.Result := HTTOP;
  235. end
  236. else if (P.Y > Height - BORDER_WIDTH) and FCanResizeWindow then
  237. begin
  238. msg.Result := HTBOTTOM;
  239. end
  240. else if PtInRect(FCaptionRect, P) then
  241. msg.Result := HTCAPTION
  242. else
  243. inherited;
  244. end;
  245. procedure TFlatForm.WMNCLButtonDown(var Message: TWMNCLButtonDown);
  246. begin
  247. inherited;
  248. if Message.HitTest = HTMINBUTTON then
  249. begin
  250. WindowState := wsMinimized;
  251. end
  252. else if (Message.HitTest = HTMAXBUTTON) then
  253. begin
  254. end
  255. else if Message.HitTest = HTCLOSE then
  256. begin
  257. Close;
  258. end;
  259. end;
  260. procedure TFlatForm.WMNCMouseMove(var msg: TWMNCMousemove);
  261. var
  262. P: TPoint;
  263. begin
  264. P := ScreenToClient(Mouse.CursorPos);
  265. if PtInRect(FMinBtnRect, P) then
  266. begin
  267. if (FFlatMouseStatus <> fmsOnMinBtn) then
  268. begin
  269. FFlatMouseStatus := fmsOnMinBtn;
  270. Invalidate;
  271. end;
  272. Exit;
  273. end;
  274. if PtInRect(FCloseBtnRect, P) then
  275. begin
  276. if (FFlatMouseStatus <> fmsOnCloseBtn) then
  277. begin
  278. FFlatMouseStatus := fmsOnCloseBtn;
  279. Invalidate;
  280. end;
  281. Exit;
  282. end;
  283. if (FFlatMouseStatus <> fmsOther) then
  284. begin
  285. FFlatMouseStatus := fmsOther;
  286. Invalidate;
  287. end;
  288. end;
  289. procedure TFlatForm.WMEraseBkgnd(var Msg: TWMEraseBkgnd);
  290. begin
  291. Msg.Result := 1; // ÒÑ´¦Àí
  292. end;
  293. procedure TFlatForm.WMPaint(var Message: TWMPaint);
  294. var
  295. H: Integer;
  296. Tmp: Integer;
  297. PS: TPaintStruct;
  298. MemDC, DC: HDC;
  299. MemBitmap, OldBitmap: HBITMAP;
  300. ACanvas: TCanvas;
  301. begin
  302. DC := BeginPaint(Handle, PS);
  303. MemBitmap := CreateCompatibleBitmap(DC, Width, Height);
  304. try
  305. MemDC := CreateCompatibleDC(DC);
  306. OldBitmap := SelectObject(MemDC, MemBitmap);
  307. try
  308. SetWindowOrgEx(MemDC, 0, 0, nil);
  309. try
  310. ACanvas:= TCanvas.Create;
  311. ACanvas.Handle := MemDC;
  312. ACanvas.Pen.Color := Color;
  313. ACanvas.Brush.Color := Color;
  314. ACanvas.FillRect(Rect((Width - ClientWidth) div 2, (Height - ClientHeight) div 2, ClientWidth, ClientHeight));
  315. Message.DC := MemDC;
  316. inherited;
  317. DrawButton(ACanvas);
  318. ACanvas.Brush.Style := bsClear;
  319. ACanvas.Pen.Width := 1;
  320. ACanvas.Pen.Color := FBorderColorOuter;
  321. ACanvas.RoundRect(1, 1, Width - 1, Height - 1, 2, 2);
  322. ACanvas.Pen.Color := BorderColor;
  323. ACanvas.Rectangle(2, 2, Width - 2, Height - 2);
  324. ACanvas.Pen.Color := $00CECECE;
  325. ACanvas.MoveTo(2, CAPTION_HEIGHT - 1);
  326. ACanvas.LineTo(Width -2, CAPTION_HEIGHT - 1);
  327. // ACanvas.Pen.Color := FBorderColorInter;
  328. // ACanvas.Rectangle(3, 3, Width - 3, Height - 3);
  329. Tmp := (CAPTION_HEIGHT - 16) div 2;
  330. if Assigned(Icon) then
  331. ACanvas.StretchDraw(Rect(Tmp, Tmp, Tmp + 16, Tmp + 16), Icon);
  332. Inc(Tmp, 16 + 5);
  333. H := ACanvas.TextHeight(Caption);
  334. ACanvas.TextOut(Tmp, (CAPTION_HEIGHT - H) div 2, Caption);
  335. finally
  336. Message.DC := 0;
  337. ACanvas.Free;
  338. end;
  339. BitBlt(DC, 0, 0,
  340. Width,
  341. Height,
  342. MemDC,
  343. 0, 0,
  344. SRCCOPY);
  345. finally
  346. SelectObject(MemDC, OldBitmap);
  347. end;
  348. finally
  349. EndPaint(Handle, PS);
  350. DeleteDC(MemDC);
  351. DeleteObject(MemBitmap);
  352. end;
  353. end;
  354. procedure TFlatForm.WndProc(var Message: TMessage);
  355. var
  356. P: TPoint;
  357. begin
  358. if message.msg = WM_LBUTTONUP then
  359. begin
  360. P := ScreenToClient(Mouse.CursorPos);
  361. if PtInRect(FMinBtnRect, P) then
  362. begin
  363. WindowState := wsMinimized;
  364. end
  365. else if PtInRect(FCloseBtnRect, P) then
  366. begin
  367. Close;
  368. end;
  369. end;
  370. inherited;
  371. if (message.msg = WM_SIZE) or
  372. (message.msg = WM_WININICHANGE) or
  373. (message.msg = WM_DISPLAYCHANGE) then
  374. begin
  375. Invalidate;
  376. end;
  377. // if message.msg = WM_ACTIVATE then
  378. // begin
  379. // case message.WParamLo of
  380. // WA_ACTIVE, WA_CLICKACTIVE:
  381. // begin
  382. // if (Integer(OSVersion) > Integer(WinMe)) or (not FSettedDragFullWindows) then
  383. // begin
  384. // if not FLastIsActived then
  385. // begin
  386. // SystemParametersInfo(SPI_SETDRAGFULLWINDOWS , 0, nil , 0);
  387. // FSettedDragFullWindows := True;
  388. // FLastIsActived := True;
  389. // end;
  390. // end;
  391. // end;
  392. // WA_INACTIVE:
  393. // begin
  394. // if Integer(OSVersion) > Integer(WinMe) then
  395. // begin
  396. // FLastIsActived := False;
  397. // if FDragFullWindows then
  398. // SystemParametersInfo(SPI_SETDRAGFULLWINDOWS , 1, nil , 0)
  399. // else
  400. // SystemParametersInfo(SPI_SETDRAGFULLWINDOWS , 0, nil , 0);
  401. // end;
  402. // end;
  403. // end;
  404. // end;
  405. end;
  406. end.