Project source
Form source (Pascal)
Form source (DFM)
| Project source: memotest.dpr |
program memotest;
{Main program file for test application for UnitOOPS OLE Drag and Drop Components.}
uses
Forms,
fmcaretmemo in 'fmcaretmemo.pas' {Form1};
{$R *.RES}
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
Back to top
|
| Form source: fmCaretMemo.pas |
unit fmcaretmemo;
{ UnitOOPS OLE Drag and Drop Components - Example
Form for TMemo demonstration, showing caret feedback and status bar
processing.
Last modified: 08/12/98}
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
uoole, StdCtrls, ExtCtrls, ComCtrls;
type
TForm1 = class(TForm)
Panel1: TPanel;
Memo1: TMemo;
StatusBar1: TStatusBar;
UOTextTarget1: TUOTextTarget;
procedure UOTextTarget1Drop(Sender: TObject; Acceptor: TWinControl;
const dropText: String; X, Y: Integer);
procedure UOTextTarget1DragOver(Sender: TObject; effect: TDropEffect;
X, Y: Integer);
procedure UOTextTarget1DragLeave(Sender: TObject);
private
{ Private declarations }
function CharPosInMemo(aMemo: TMemo; X, Y: integer): integer;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
function TForm1.CharPosInMemo(aMemo: TMemo; X, Y: integer): integer;
// Get the current character position (0-based) in the TMemo aMemo
// corresponding to the client coordinates X, Y. Returns -1 if there
// is no corresponding character.
begin
result := LoWord(SendMessage(aMemo.Handle, EM_CHARFROMPOS, 0, MAKELPARAM(X, Y)));
end;
procedure TForm1.UOTextTarget1Drop(Sender: TObject; Acceptor: TWinControl;
const dropText: String; X, Y: Integer);
// Handle a drop of text
var
aCharPos: integer;
// Following needed for case a) only
// aString: string;
begin
// Get the current position
aCharPos := CharPosInMemo(Memo1, X, Y);
// If it makes sense, do an insert
if (aCharPos <> -1) then
begin
// Here are 3 different ways of doing it
// a) Total text replacement
// Advantage - simple
// Disadvantage - no undo, possible flicker.
//
// Get the current text
//aString := Memo1.Text;
// Insert the dropped text at the right position
// Note the +1 as strings are 1-based
//Insert(dropText, aString, aCharPos+1);
// Give the new string back to the memo
//Memo1.Text := aString;
// b) Using a VCL wrapper method, replace the selection
// (i.e., insert at the zero-length caret position)
// Advantage - fairly simple
// Disadvantage - no undo
//
//Memo1.SetSelTextBuf(PChar(dropText));
// c) Using a WinAPI message, replace the selection
// Advantage - undo is available
// Disadvantage - not quite as simple
// The "true" is the "can undo" flag
Memo1.Perform(EM_REPLACESEL, integer(true), integer(PChar(dropText)));
// Alternative to preceding line:
// SendMessage(Memo1.Handle, EM_REPLACESEL, integer(true), integer(PChar(dropText)));
// Following is common to all 3 methods.
// Finally, move the caret to immediately following
// the dropped text
Memo1.SelStart := aCharPos+length(dropText);
Memo1.SelLength := 0;
end
else
// Otherwise, just give the entire text to the memo
Memo1.Text := dropText;
// Clean up the status bar
StatusBar1.SimpleText := '';
end;
procedure TForm1.UOTextTarget1DragOver(Sender: TObject;
effect: TDropEffect; X, Y: Integer);
// Handle dragging over our drop target.
// We could, e.g., set up a custom caret here if we wanted
// to do something like Word's grayed caret to indicate position.
var
aCharPos: integer;
aString: string;
begin
// Make the status bar look like Word's on OLE drop
if (deCopy = effect) then
aString := 'Copy'
else
if (deMove = effect) then
aString := 'Move'
else
begin
// Not a move or copy - bale out altogether
StatusBar1.SimpleText := '';
exit;
end;
StatusBar1.SimpleText := Format('%s to where?', [aString]);
// Focus the memo so we can see the caret.
Memo1.SetFocus;
// Get the current position
aCharPos := CharPosInMemo(Memo1, X, Y);
// If it makes sense, then put the caret there.
if (aCharPos <> -1) then
begin
Memo1.selStart := aCharPos;
Memo1.selLength := 0;
end;
end;
procedure TForm1.UOTextTarget1DragLeave(Sender: TObject);
begin
StatusBar1.SimpleText := '';
Memo1.SetFocus;
end;
end.
Back to top
|
| Form source: fmCaretMemo.dfm |
object Form1: TForm1
Left = 217
Top = 206
Width = 446
Height = 253
Caption = 'Test of TUOTextTarget cursor feedback'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
PixelsPerInch = 96
TextHeight = 13
object Panel1: TPanel
Left = 0
Top = 0
Width = 438
Height = 207
Align = alClient
BevelOuter = bvNone
BorderWidth = 3
Caption = 'Panel1'
TabOrder = 0
object Memo1: TMemo
Left = 3
Top = 3
Width = 432
Height = 201
Align = alClient
Lines.Strings = (
'Drag text from some text drag source onto this TMemo, and watch ' +
'the caret track the '
'insertion point as you move the drag cursor around. Typical dra' +
'g sources you'#39'll already '
'have on your computer include: Windows Help, WordPad, Excel, Wo' +
'rd, etc.'
''
'When you drop the text, it is inserted at the current caret posi' +
'tion.'
''
'If you make the window smaller than the text vertically, you can' +
' have the TMemo scroll '
'while you'#39're dragging over it (to do the drop in a part of the t' +
'ext currently not visible) by '
'dragging close to the edge of the text. This happens automatica' +
'lly - you don'#39't have to '
'do anything in your own code.'
''
'Finally, the status bar mimics the behavior of MS-Word.'
''
'See the OnDragEnter, OnDragOver, OnDragLeave and OnDrop handlers' +
' for the '
'TUOTextTarget component included in this project for more detail' +
's. The whole '
'process '
'is accomplished in just a few lines of code.'
'')
ScrollBars = ssVertical
TabOrder = 0
end
end
object StatusBar1: TStatusBar
Left = 0
Top = 207
Width = 438
Height = 19
Panels = <>
SimplePanel = True
end
object UOTextTarget1: TUOTextTarget
AcceptorControl = Memo1
AcceptTextFormats = [dtfText]
OnDragOver = UOTextTarget1DragOver
OnDragLeave = UOTextTarget1DragLeave
OnDrop = UOTextTarget1Drop
Left = 80
Top = 32
end
end
Back to top
|