FindWindow1.pas 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. unit FindWindow1;
  2. interface
  3. uses
  4. Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  5. Dialogs, ComCtrls, CommCtrl, VirtualTrees, JvComponent, JvDockControlForm,
  6. JvExComCtrls, JvListView, JvDotNetControls, StdCtrls, Misc;
  7. type
  8. TfrmFindWindow1 = class(TForm)
  9. JvDockClient1: TJvDockClient;
  10. lvwResult: TJvDotNetListView;
  11. procedure lvwResultCustomDrawSubItem(Sender: TCustomListView; Item: TListItem; SubItem: Integer; State: TCustomDrawState; var DefaultDraw: Boolean);
  12. procedure lvwResultDblClick(Sender: TObject);
  13. private
  14. { Private declarations }
  15. public
  16. { Public declarations }
  17. procedure AddResult(FileName: String; Line: Integer; Snipset: String);
  18. function GetSubItemRect(const Item: TListItem; const SubItem: integer; Code: TDisplayCode = drBounds): TRect;
  19. end;
  20. var
  21. frmFindWindow1: TfrmFindWindow1;
  22. implementation
  23. uses Main, Types;
  24. {$R *.dfm}
  25. procedure TfrmFindWindow1.AddResult(FileName: String; Line: Integer; Snipset: String);
  26. var
  27. pListitem: TListItem;
  28. begin
  29. pListitem := lvwResult.Items.Add;
  30. pListitem.Caption := FileName;
  31. pListitem.SubItems.Add(IntToStr(Line));
  32. pListitem.SubItems.Add(Snipset);
  33. end;
  34. function TfrmFindWindow1.GetSubItemRect(const Item: TListItem; const SubItem: integer; Code: TDisplayCode = drBounds): TRect;
  35. var
  36. ARect: TRect;
  37. const
  38. Codes: array[TDisplayCode] of Longint = (LVIR_BOUNDS, LVIR_ICON, LVIR_LABEL, LVIR_SELECTBOUNDS);
  39. begin
  40. // Win32 macro defined in commctrl.pas (Retreive the boundary of a sub item in a given listview)
  41. ListView_GetSubItemRect(Item.ListView.Handle, Item.Index, SubItem, Codes[Code], @ARect);
  42. Result := ARect;
  43. end;
  44. procedure TfrmFindWindow1.lvwResultCustomDrawSubItem(Sender: TCustomListView; Item: TListItem; SubItem: Integer; State: TCustomDrawState; var DefaultDraw: Boolean);
  45. var
  46. pRect, pOutRect, pPrevOutRect: TRect;
  47. sSnipset, sOut: String;
  48. pTemp: array[0..5120] of Char;
  49. StrPos: Integer;
  50. IsFirst: Boolean;
  51. begin
  52. DefaultDraw := True;
  53. // Only for the third column (code snipset)
  54. if ((SubItem = 2) and (not Item.Selected)) then
  55. begin
  56. IsFirst := True;
  57. DefaultDraw := False;
  58. pRect := GetSubItemRect(Item, SubItem);
  59. lvwResult.Canvas.FillRect(pRect);
  60. pRect.Left := pRect.Left + 4;
  61. pRect.Right := pRect.Right - 10;
  62. StrPCopy(pTemp, Item.SubItems[SubItem - 1]);
  63. sSnipset := pTemp;
  64. pOutRect := Rect(0, 0, 0, 0);
  65. pPrevOutRect := Rect(0, 0, 0, 0);
  66. DrawText(lvwResult.Canvas.Handle, pTemp, Length(sSnipset), pRect, DT_END_ELLIPSIS or DT_SINGLELINE or DT_VCENTER or DT_LEFT or DT_MODIFYSTRING);
  67. sSnipset := pTemp;
  68. // Extract one by one the
  69. while sSnipset <> '' do
  70. begin
  71. StrPos := Pos(frmLuaEditMain.sSearchInFilesString, sSnipset);
  72. if StrPos = 0 then
  73. begin
  74. // Retreive the rest of the string
  75. sOut := sSnipset;
  76. sSnipset := '';
  77. // Reset font style and color
  78. lvwResult.Canvas.Font.Style := [];
  79. // Calculate text dimensions
  80. SelectObject(lvwResult.Canvas.Handle, lvwResult.Canvas.Font.Handle);
  81. DrawText(lvwResult.Canvas.Handle, PChar(sOut), Length(sOut), pOutRect, DT_VCENTER or DT_LEFT or DT_SINGLELINE or DT_CALCRECT);
  82. // Offset new calculated rect with previous one if required
  83. if not IsFirst then
  84. begin
  85. pOutRect.Right := pOutRect.Right + pPrevOutRect.Right;
  86. pOutRect.Left := pPrevOutRect.Right;
  87. pOutRect.Top := pRect.Top;
  88. pOutRect.Bottom := pRect.Bottom;
  89. end
  90. else
  91. begin
  92. pOutRect.Right := pOutRect.Right + pRect.Left;
  93. pOutRect.Left := pOutRect.Left + pRect.Left;
  94. pOutRect.Top := pRect.Top;
  95. pOutRect.Bottom := pRect.Bottom;
  96. end;
  97. // Output the non bold part of string
  98. SelectObject(lvwResult.Canvas.Handle, lvwResult.Canvas.Font.Handle);
  99. DrawText(lvwResult.Canvas.Handle, PChar(sOut), Length(sOut), pOutRect, DT_VCENTER or DT_LEFT or DT_SINGLELINE);
  100. pPrevOutRect := pOutRect;
  101. pOutRect := Rect(0, 0, 0, 0);
  102. IsFirst := False;
  103. end
  104. else
  105. begin
  106. if StrPos <> 1 then
  107. begin
  108. // Retreive non bold part of string
  109. sOut := Copy(sSnipset, 1, StrPos - 1);
  110. sSnipset := Copy(sSnipset, StrPos, Length(sSnipset) - StrPos + 1);
  111. // Reset font style and color
  112. lvwResult.Canvas.Font.Style := [];
  113. // Calculate text dimensions
  114. SelectObject(lvwResult.Canvas.Handle, lvwResult.Canvas.Font.Handle);
  115. DrawText(lvwResult.Canvas.Handle, PChar(sOut), Length(sOut), pOutRect, DT_VCENTER or DT_LEFT or DT_SINGLELINE or DT_CALCRECT);
  116. // Offset new calculated rect with previous one if required
  117. if not IsFirst then
  118. begin
  119. pOutRect.Right := pOutRect.Right + pPrevOutRect.Right;
  120. pOutRect.Left := pPrevOutRect.Right;
  121. pOutRect.Top := pRect.Top;
  122. pOutRect.Bottom := pRect.Bottom;
  123. end
  124. else
  125. begin
  126. pOutRect.Right := pOutRect.Right + pRect.Left;
  127. pOutRect.Left := pOutRect.Left + pRect.Left;
  128. pOutRect.Top := pRect.Top;
  129. pOutRect.Bottom := pRect.Bottom;
  130. end;
  131. // Output the non bold part of string
  132. SelectObject(lvwResult.Canvas.Handle, lvwResult.Canvas.Font.Handle);
  133. DrawText(lvwResult.Canvas.Handle, PChar(sOut), Length(sOut), pOutRect, DT_VCENTER or DT_LEFT or DT_SINGLELINE);
  134. IsFirst := False;
  135. pPrevOutRect := pOutRect;
  136. pOutRect := Rect(0, 0, 0, 0);
  137. end;
  138. // Retreive bold part of string
  139. sOut := frmLuaEditMain.sSearchInFilesString;
  140. sSnipset := Copy(sSnipset, Length(sOut) + 1, Length(sSnipset) - Length(sOut) + 1);
  141. // Reset font style and color
  142. lvwResult.Canvas.Font.Style := [fsBold];
  143. // Calculate text dimensions
  144. SelectObject(lvwResult.Canvas.Handle, lvwResult.Canvas.Font.Handle);
  145. DrawText(lvwResult.Canvas.Handle, PChar(sOut), Length(sOut), pOutRect, DT_VCENTER or DT_LEFT or DT_SINGLELINE or DT_CALCRECT);
  146. // Offset new calculated rect with previous one if required
  147. if not IsFirst then
  148. begin
  149. pOutRect.Right := pOutRect.Right + pPrevOutRect.Right;
  150. pOutRect.Left := pPrevOutRect.Right;
  151. pOutRect.Top := pRect.Top;
  152. pOutRect.Bottom := pRect.Bottom;
  153. end
  154. else
  155. begin
  156. pOutRect.Right := pOutRect.Right + pRect.Left;
  157. pOutRect.Left := pOutRect.Left + pRect.Left;
  158. pOutRect.Top := pRect.Top;
  159. pOutRect.Bottom := pRect.Bottom;
  160. end;
  161. // Output the non bold part of string
  162. SelectObject(lvwResult.Canvas.Handle, lvwResult.Canvas.Font.Handle);
  163. DrawText(lvwResult.Canvas.Handle, PChar(sOut), Length(sOut), pOutRect, DT_VCENTER or DT_LEFT or DT_SINGLELINE);
  164. pPrevOutRect := pOutRect;
  165. pOutRect := Rect(0, 0, 0, 0);
  166. IsFirst := False;
  167. end;
  168. end;
  169. end;
  170. end;
  171. procedure TfrmFindWindow1.lvwResultDblClick(Sender: TObject);
  172. begin
  173. // Bring the file in the editor and go directly to the line where it's defined
  174. if Assigned(lvwResult.Selected) then
  175. frmLuaEditMain.PopUpUnitToScreen(lvwResult.Selected.Caption, StrToInt(lvwResult.Selected.SubItems[0]), False, HIGHLIGHT_SELECT);
  176. end;
  177. end.