CnDockSupportProc.pas 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. {******************************************************************************}
  2. { CnPack For Delphi/C++Builder }
  3. { 中国人自己的开放源码第三方开发包 }
  4. { (C)Copyright 2001-2018 CnPack 开发组 }
  5. { ------------------------------------ }
  6. { }
  7. { 本开发包是开源的自由软件,您可以遵照 CnPack 的发布协议来修 }
  8. { 改和重新发布这一程序。 }
  9. { }
  10. { 发布这一开发包的目的是希望它有用,但没有任何担保。甚至没有 }
  11. { 适合特定目的而隐含的担保。更详细的情况请参阅 CnPack 发布协议。 }
  12. { }
  13. { 您应该已经和开发包一起收到一份 CnPack 发布协议的副本。如果 }
  14. { 还没有,可访问我们的网站: }
  15. { }
  16. { 网站地址:http://www.cnpack.org }
  17. { 电子邮件:master@cnpack.org }
  18. { }
  19. {******************************************************************************}
  20. {*******************************************************}
  21. { }
  22. { 一些通用的函数 }
  23. { CnDockSupportProc 单元 }
  24. { }
  25. { 版权 (C) 2002,2003 鲁小班 }
  26. { }
  27. {*******************************************************}
  28. unit CnDockSupportProc;
  29. {* |<PRE>
  30. ================================================================================
  31. * 软件名称:不可视工具组件包停靠单元
  32. * 单元名称:一些通用的函数单元
  33. * 单元作者:CnPack开发组 周益波(鲁小班)
  34. * 备 注:本单元由原作者授权CnPack开发组移植,已保留原作者版权信息
  35. * 开发平台:
  36. * 兼容测试:PWin9X/2000/XP + Delphi 5/6/7
  37. * 本 地 化:该单元中的字符串均符合本地化处理方式
  38. * 单元标识:$Id$
  39. * 修改记录:2008.11.18 V1.1
  40. * wqyfavor 修正 D2009 下的不兼容问题
  41. * 2007.07.13 V1.0
  42. * 移植单元
  43. ================================================================================
  44. |</PRE>}
  45. interface
  46. {$I CnPack.inc}
  47. uses Classes, Windows, SysUtils, Graphics, Forms, Controls, Messages;
  48. type
  49. TListScanKind = (lskForward, lskBackward);
  50. { ---------------------------------------------------------------------------- }
  51. function Cn_StreamDataToString(Stream: TStream): string;
  52. procedure Cn_StringToStreamData(Stream: TStream; Data: string);
  53. { ---------------------------------------------------------------------------- }
  54. function Cn_FindDockFormWithName(FormName: string;
  55. FromDockManager: Boolean = False;
  56. FromList: Boolean = True;
  57. ScanKind: TListScanKind = lskForward): TCustomForm;
  58. function Cn_FindDockServerFormWithName(FormName: string;
  59. FromDockManager: Boolean = False;
  60. FromList: Boolean = True;
  61. ScanKind: TListScanKind = lskForward): TCustomForm;
  62. function Cn_FindDockClientFormWithName(FormName: string;
  63. FromDockManager: Boolean = False;
  64. FromList: Boolean = True;
  65. ScanKind: TListScanKind = lskForward): TCustomForm;
  66. function Cn_FindDockServerFromDockManager(FormName: string;
  67. FromList: Boolean = True;
  68. ScanKind: TListScanKind = lskForward): TCustomForm;
  69. function Cn_FindDockClientFromDockManager(FormName: string;
  70. FromList: Boolean = True;
  71. ScanKind: TListScanKind = lskForward): TCustomForm;
  72. function Cn_FindDockFormFromScreen(FormName: string;
  73. ScanKind: TListScanKind = lskForward): TCustomForm;
  74. { ---------------------------------------------------------------------------- }
  75. function Cn_GetMinOffset(TBDockSize, ControlSize: Integer; Scale: Real): Integer;
  76. { ---------------------------------------------------------------------------- }
  77. function Cn_GetNoNClientMetrics: TNONCLIENTMETRICS;
  78. { 获得系统的标题栏的高度 }
  79. function Cn_GetSysCaptionHeight: Integer;
  80. { 获得系统的窗体的边框 }
  81. function Cn_GetSysBorderWidth: Integer;
  82. function Cn_GetSysCaptionHeightAndBorderWidth: Integer;
  83. { ---------------------------------------------------------------------------- }
  84. { 获得活动的标题栏的开始颜色 }
  85. function Cn_GetActiveTitleBeginColor: TColor;
  86. { 获得活动的标题栏的结束颜色 }
  87. function Cn_GetActiveTitleEndColor: TColor;
  88. { 获得非活动的标题栏的开始颜色 }
  89. function Cn_GetInactiveTitleBeginColor: TColor;
  90. { 获得非活动的标题栏的结束颜色 }
  91. function Cn_GetInactiveTitleEndColor: TColor;
  92. { 获得标题栏的字体颜色,Active指示是否是获得焦点 }
  93. function Cn_GetTitleFontColor(Active: Boolean): TColor;
  94. { 获得活动的标题栏的字体颜色 }
  95. function Cn_GetActiveTitleFontColor: TColor;
  96. { 获得非活动的标题栏的字体颜色 }
  97. function Cn_GetInactiveTitleFontColor: TColor;
  98. { 获得标题栏的字体 }
  99. function Cn_GetTitleFont: TFont;
  100. { 锁住窗体 }
  101. procedure Cn_LockWindow(Control: TWinControl);
  102. { 解锁窗体 }
  103. procedure Cn_UnLockWindow;
  104. { ---------------------------------------------------------------------------- }
  105. { 输入一些值创建一个TWMNCHitMessage结构并且返回 }
  106. function Cn_CreateNCMessage(Control: TControl; Msg: Cardinal; HTFlag: Integer; Pos: TPoint): TWMNCHitMessage;
  107. { 交换参数Orient的值 }
  108. function Cn_ExchangeOrient(Orient: TDockOrientation): TDockOrientation;
  109. { 根据输入的Control的Align属性得到它的方向 }
  110. function Cn_GetControlOrient(AControl: TControl): TDockOrientation;
  111. { 根据输入的Control的Align属性得到它的宽度或者高度 }
  112. function Cn_GetControlSize(AControl: TControl): Integer;
  113. implementation
  114. uses
  115. Math, CnDockFormControl, CnDockGlobal;
  116. var
  117. Cn_TitleFont: TFont;
  118. function Cn_StreamDataToString(Stream: TStream): string;
  119. var
  120. B: Byte;
  121. begin
  122. Result := '';
  123. Stream.Position := 0;
  124. while Stream.Position < Stream.Size do
  125. begin
  126. Stream.Read(B, SizeOf(B));
  127. Result := Result + IntToHex(B, 2);
  128. end;
  129. end;
  130. procedure Cn_StringToStreamData(Stream: TStream; Data: string);
  131. var
  132. i: Integer;
  133. B: Byte;
  134. begin
  135. i := 1;
  136. while i < Length(Data) do
  137. begin
  138. B := StrToInt('$' + Copy(Data, i, 2));
  139. Stream.Write(B, SizeOf(B));
  140. Inc(i, 2);
  141. end;
  142. end;
  143. function Cn_FindDockFormWithName(FormName: string;
  144. FromDockManager: Boolean;
  145. FromList: Boolean;
  146. ScanKind: TListScanKind): TCustomForm;
  147. begin
  148. Result := Cn_FindDockClientFormWithName(FormName, FromDockManager, FromList, ScanKind);
  149. if Result = nil then
  150. Result := Cn_FindDockServerFormWithName(FormName, FromDockManager, FromList, ScanKind);
  151. end;
  152. function Cn_FindDockServerFormWithName(FormName: string;
  153. FromDockManager: Boolean;
  154. FromList: Boolean;
  155. ScanKind: TListScanKind): TCustomForm;
  156. begin
  157. if FromDockManager then
  158. Result := Cn_FindDockServerFromDockManager(FormName, FromList, ScanKind)
  159. else Result := Cn_FindDockFormFromScreen(FormName, ScanKind);
  160. end;
  161. function Cn_FindDockClientFormWithName(FormName: string;
  162. FromDockManager: Boolean;
  163. FromList: Boolean;
  164. ScanKind: TListScanKind): TCustomForm;
  165. begin
  166. if FromDockManager then
  167. Result := Cn_FindDockClientFromDockManager(FormName, FromList, ScanKind)
  168. else Result := Cn_FindDockFormFromScreen(FormName, ScanKind);
  169. end;
  170. function Cn_FindDockServerFromDockManager(FormName: string;
  171. FromList: Boolean;
  172. ScanKind: TListScanKind): TCustomForm;
  173. var
  174. i: Integer;
  175. begin
  176. case ScanKind of
  177. lskForward:
  178. begin
  179. for i := 0 to CnGlobalDockPresident.DockServersList.Count - 1 do
  180. if FormName = TCustomForm(CnGlobalDockPresident.DockServersList[i]).Name then
  181. begin
  182. Result := TCustomForm(CnGlobalDockPresident.DockServersList[i]);
  183. Exit;
  184. end;
  185. end;
  186. lskBackward:
  187. begin
  188. for i := CnGlobalDockPresident.DockServersList.Count - 1 downto 0 do
  189. if FormName = TCustomForm(CnGlobalDockPresident.DockServersList[i]).Name then
  190. begin
  191. Result := TCustomForm(CnGlobalDockPresident.DockServersList[i]);
  192. Exit;
  193. end;
  194. end;
  195. end;
  196. Result := nil;
  197. end;
  198. function Cn_FindDockClientFromDockManager(FormName: string;
  199. FromList: Boolean;
  200. ScanKind: TListScanKind): TCustomForm;
  201. var
  202. i: Integer;
  203. begin
  204. case ScanKind of
  205. lskForward:
  206. begin
  207. for i := 0 to CnGlobalDockPresident.DockClientsList.Count - 1 do
  208. if FormName = TCustomForm(CnGlobalDockPresident.DockClientsList[i]).Name then
  209. begin
  210. Result := TCustomForm(CnGlobalDockPresident.DockClientsList[i]);
  211. Exit;
  212. end;
  213. end;
  214. lskBackward:
  215. begin
  216. for i := CnGlobalDockPresident.DockClientsList.Count - 1 downto 0 do
  217. if FormName = TCustomForm(CnGlobalDockPresident.DockClientsList[i]).Name then
  218. begin
  219. Result := TCustomForm(CnGlobalDockPresident.DockClientsList[i]);
  220. Exit;
  221. end;
  222. end;
  223. end;
  224. Result := nil;
  225. end;
  226. function Cn_FindDockFormFromScreen(FormName: string;
  227. ScanKind: TListScanKind): TCustomForm;
  228. var
  229. i: Integer;
  230. begin
  231. case ScanKind of
  232. lskForward:
  233. begin
  234. for i := 0 to Screen.CustomFormCount - 1 do
  235. if FormName = Screen.CustomForms[i].Name then
  236. begin
  237. Result := Screen.CustomForms[i];
  238. Exit;
  239. end;
  240. end;
  241. lskBackward:
  242. begin
  243. for i := Screen.CustomFormCount - 1 downto 0 do
  244. if FormName = Screen.CustomForms[i].Name then
  245. begin
  246. Result := Screen.CustomForms[i];
  247. Exit;
  248. end;
  249. end;
  250. end;
  251. Result := nil;
  252. end;
  253. function Cn_GetMinOffset(TBDockSize, ControlSize: Integer; Scale: Real): Integer;
  254. begin
  255. if (Scale < 0) or (Scale > 1) then
  256. Scale := 1;
  257. Result := Min(TBDockSize, Round(ControlSize * Scale));
  258. end;
  259. function Cn_GetNoNClientMetrics: TNONCLIENTMETRICS;
  260. begin
  261. Result.cbSize := Sizeof(TNONCLIENTMETRICS);
  262. SystemParametersInfo(SPI_GETNONCLIENTMETRICS, Result.cbSize,
  263. @Result, 0);
  264. end;
  265. function Cn_GetSysCaptionHeight: Integer;
  266. begin
  267. Result := Cn_GetNoNClientMetrics.iCaptionHeight
  268. end;
  269. function Cn_GetSysBorderWidth: Integer;
  270. begin
  271. Result := Cn_GetNoNClientMetrics.iBorderWidth;
  272. end;
  273. function Cn_GetSysCaptionHeightAndBorderWidth: Integer;
  274. var NoNCM: TNONCLIENTMETRICS;
  275. begin
  276. NoNCM := Cn_GetNoNClientMetrics;
  277. Result := NoNCM.iBorderWidth + NoNCM.iCaptionHeight;
  278. end;
  279. function Cn_GetActiveTitleBeginColor: TColor;
  280. begin
  281. Result := GetSysColor(COLOR_ACTIVECAPTION);
  282. end;
  283. function Cn_GetActiveTitleEndColor: TColor;
  284. begin
  285. Result := GetSysColor(COLOR_GRADIENTACTIVECAPTION);
  286. end;
  287. function Cn_GetInactiveTitleBeginColor: TColor;
  288. begin
  289. Result := GetSysColor(COLOR_INACTIVECAPTION);
  290. end;
  291. function Cn_GetInactiveTitleEndColor: TColor;
  292. begin
  293. Result := GetSysColor(COLOR_GRADIENTINACTIVECAPTION);
  294. end;
  295. function Cn_GetTitleFontColor(Active: Boolean): TColor;
  296. begin
  297. if Active then
  298. Result := Cn_GetActiveTitleFontColor
  299. else Result := Cn_GetInactiveTitleFontColor;
  300. end;
  301. function Cn_GetActiveTitleFontColor: TColor;
  302. begin
  303. Result := GetSysColor(COLOR_CAPTIONTEXT);
  304. end;
  305. function Cn_GetInactiveTitleFontColor: TColor;
  306. begin
  307. Result := GetSysColor(COLOR_INACTIVECAPTIONTEXT);
  308. end;
  309. { 获得标题栏的字体 }
  310. function Cn_GetTitleFont: TFont;
  311. var
  312. NoNCM: TNONCLIENTMETRICS;
  313. begin
  314. Result := Cn_TitleFont;
  315. NoNCM := Cn_GetNoNClientMetrics;
  316. Result.Handle := CreateFontIndirect(NoNCM.lfCaptionFont);
  317. end;
  318. procedure Cn_LockWindow(Control: TWinControl);
  319. var
  320. Handle: HWND;
  321. begin
  322. if Control = nil then
  323. Handle := GetDesktopWindow
  324. else
  325. Handle := Control.Handle;
  326. LockWindowUpdate(Handle);
  327. end;
  328. procedure Cn_UnLockWindow;
  329. begin
  330. LockWindowUpdate(0);
  331. end;
  332. function Cn_CreateNCMessage(Control: TControl; Msg: Cardinal;
  333. HTFlag: Integer; Pos: TPoint): TWMNCHitMessage;
  334. begin
  335. { 下面的五条语句给TWMNCHitMessage赋值 }
  336. Result.Msg := Msg;
  337. Result.HitTest := HTFlag;
  338. Pos := Control.ClientToScreen(Pos);
  339. Result.XCursor := Pos.X;
  340. Result.YCursor := Pos.Y;
  341. end;
  342. function Cn_ExchangeOrient(Orient: TDockOrientation): TDockOrientation;
  343. begin
  344. case Orient of
  345. doHorizontal: Result := doVertical;
  346. doVertical: Result := doHorizontal;
  347. else
  348. Result := doNoOrient;
  349. end;
  350. end;
  351. function Cn_GetControlOrient(AControl: TControl): TDockOrientation;
  352. begin
  353. Assert(AControl <> nil);
  354. Result := doNoOrient;
  355. case AControl.Align of
  356. alClient, alNone: Result := doNoOrient;
  357. alLeft, alRight: Result := doVertical;
  358. alTop, alBottom: Result := doHorizontal;
  359. end;
  360. end;
  361. function Cn_GetControlSize(AControl: TControl): Integer;
  362. begin
  363. case Cn_GetControlOrient(AControl) of
  364. doVertical: Result := AControl.Width;
  365. doHorizontal: Result := AControl.Height;
  366. else
  367. raise Exception.Create(gs_CannotGetValueWithNoOrient);
  368. end;
  369. end;
  370. initialization
  371. Cn_TitleFont := TFont.Create;
  372. finalization
  373. Cn_TitleFont.Free;
  374. end.