Unit1.pas 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. unit Unit1;
  2. {$WARNINGS OFF}
  3. interface
  4. uses
  5. Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  6. DragDropHelper, StdCtrls;
  7. type
  8. TForm1 = class(TForm)
  9. Memo1: TMemo;
  10. Memo2: TMemo;
  11. DragDropHelper1: TDragDropHelper;
  12. ListBox1: TListBox;
  13. procedure Memo1MouseDown(Sender: TObject; Button: TMouseButton;
  14. Shift: TShiftState; X, Y: Integer);
  15. procedure Memo1MouseUp(Sender: TObject; Button: TMouseButton;
  16. Shift: TShiftState; X, Y: Integer);
  17. procedure Memo1StartDrag(Sender: TObject; var DragObject: TDragObject);
  18. procedure DragDropHelper1GetDragImage(Sender: TObject;
  19. AControl: TControl; ABitmap: TBitmap);
  20. procedure Memo2DragOver(Sender, Source: TObject; X, Y: Integer;
  21. State: TDragState; var Accept: Boolean);
  22. procedure Memo1EndDrag(Sender, Target: TObject; X, Y: Integer);
  23. procedure DragDropHelper1GetDragCursor(Sender: TObject;
  24. Accepted: Boolean; X, Y: Integer; var ACursor: TCursor);
  25. private
  26. { Private declarations }
  27. FLastSelStart : Integer;
  28. FLastSelLength : Integer;
  29. ST : string;
  30. public
  31. { Public declarations }
  32. end;
  33. var
  34. Form1: TForm1;
  35. implementation
  36. {$R *.DFM}
  37. procedure TForm1.Memo1MouseDown(Sender: TObject; Button: TMouseButton;
  38. Shift: TShiftState; X, Y: Integer);
  39. var
  40. Ch : Integer;
  41. begin
  42. if FLastSelLength > 0 then
  43. begin
  44. Ch := LoWord(Memo1.Perform(EM_CHARFROMPOS,0, MakeLParam(X, Y)));
  45. if (Ch >= FLastSelStart) and (Ch <= FLastSelStart+FLastSelLength-1) then
  46. begin
  47. Memo1.SelStart := FLastSelStart;
  48. Memo1.SelLength := FLastSelLength;
  49. St := memo1.SelText;
  50. St := StringReplace(St, #13#10, '', [rfReplaceAll]);
  51. Memo1.BeginDrag(True);
  52. end;
  53. end;
  54. end;
  55. procedure TForm1.Memo1MouseUp(Sender: TObject; Button: TMouseButton;
  56. Shift: TShiftState; X, Y: Integer);
  57. begin
  58. FLastSelStart := Memo1.SelStart;
  59. FLastSelLength := Memo1.SelLength;
  60. end;
  61. procedure TForm1.Memo1StartDrag(Sender: TObject;
  62. var DragObject: TDragObject);
  63. begin
  64. DragObject := DragDropHelper1.GetDragObject(Memo1);
  65. end;
  66. procedure TForm1.DragDropHelper1GetDragImage(Sender: TObject;
  67. AControl: TControl; ABitmap: TBitmap);
  68. var
  69. W : integer;
  70. H : Integer;
  71. TextH : integer;
  72. R : TRect;
  73. Flags : integer;
  74. ch : char;
  75. begin
  76. //First step is to select the font you want to use draw the text during drag operation
  77. //We will draw selected text using the font of memo,
  78. //but you can use another font for it
  79. ABitmap.Canvas.Font.Assign(Memo1.Font);
  80. //Here you can change font style, size, color, etc...
  81. ABitmap.Canvas.Font.Color := clNavy;
  82. //Width of the bitmap can be equal memo1.Width or
  83. //can be smaller, if the memo is too big
  84. W := Memo1.Width;
  85. //Calculate text height according to the size of the font
  86. TextH := ABitmap.Canvas.TextHeight('Wg');
  87. H := TextH;
  88. //Calculate the real rectangle we need to draw selected text
  89. //on the bitmap
  90. Flags := DT_CALCRECT or DT_LEFT or DT_EXPANDTABS;
  91. R := Rect(0,0,W, H);
  92. //It will not draw text, but calculate rectange and returns R with correct size to fit selected text
  93. DrawText(Canvas.Handle, PChar(St), Length(St), R, Flags);
  94. //If the last symbol of text string is CR or LF then we have do decrease the
  95. //size of bitmap for one empty line of text
  96. ch := St[Length(st)];
  97. if (ch = #13) or (ch = #10) then
  98. R.Bottom := R.Bottom - TextH; //decrease for one line
  99. //You can leave calculated bitmap as is or make it smaller if it's too big.
  100. //In this case you will see only part of the text, but if you drag 10000 lines
  101. //of the text maybe it will be good idea do not draw huge image :)
  102. if R.Left > 500 then
  103. R.Left := 500; //or whatever you want
  104. if R.Bottom > 500 then
  105. R.Bottom := 500; //You can use your own limit
  106. //set size of the drag image
  107. ABitmap.Width := R.Right;
  108. ABitmap.Height := R.Bottom;
  109. //If you want, you can change bitmap background color
  110. ABitmap.Canvas.Brush.Color := clYellow; //for example Yellow, but you can leave it White or what you like
  111. ABitmap.Canvas.FillRect(ABitmap.Canvas.ClipRect);
  112. //Draw the text on the bitmap
  113. Flags := DT_LEFT or DT_EXPANDTABS;
  114. DrawText(ABitmap.Canvas.Handle, PChar(St), Length(St), R, Flags);
  115. end;
  116. procedure TForm1.Memo2DragOver(Sender, Source: TObject; X, Y: Integer;
  117. State: TDragState; var Accept: Boolean);
  118. begin
  119. Accept := true;
  120. end;
  121. procedure TForm1.Memo1EndDrag(Sender, Target: TObject; X, Y: Integer);
  122. begin
  123. TMemo(Target).Text := TMemo(Target).Text + st;
  124. end;
  125. procedure TForm1.DragDropHelper1GetDragCursor(Sender: TObject;
  126. Accepted: Boolean; X, Y: Integer; var ACursor: TCursor);
  127. begin
  128. Caption := Format('X:%d,Y:%d', [X, Y]);
  129. end;
  130. end.