Буфер обмена
Использование интерфейса OLE
Значение, которое придается сегодня внедрению интерфейса OLE, трудно переоценить. Фирма Microsoft извещает о том, что на получение логотипа "Windows 95 Compatible" будут сертифицированы только те приложения, которые имеют средства работы с OLE.
Разъяснять суть механизмов OLE с точки зрения пользователя здесь не имеет смысла; кратко опишем их с точки зрения программиста.
- Подробности
- Родительская категория: Буфер обмена
- Категория: Общие вопросы
Следущие операции производятся с активным контролом на форме:
Code: |
procedure TForm1.Cut1Click(Sender: TObject); begin SendMessage (ActiveControl.Handle, WM_Cut, 0, 0); end;
procedure TForm1.Copy1Click(Sender: TObject); begin SendMessage (ActiveControl.Handle, WM_Copy, 0, 0); end;
procedure TForm1.Paste1Click(Sender: TObject); begin SendMessage (ActiveControl.Handle, WM_Paste, 0, 0); end; |
Если Вы разрабатываете приложение MDI, то необходимо отправлять сообщение в активное дочернее окно, т.е. использовать: ActiveMDIChild.ActiveControl.Handle
- Подробности
- Родительская категория: Буфер обмена
- Категория: Общие вопросы
Code: |
uses Clipbrd;
//Copy procedure TForm1.Button1Click(Sender: TObject); var S: string; GRect: TGridRect; C, R: Integer; begin GRect := StringGrid1.Selection; S := ''; for R := GRect.Top to GRect.Bottom do begin for C := GRect.Left to GRect.Right do begin if C = GRect.Right then S := S + (StringGrid1.Cells[C, R]) else S := S + StringGrid1.Cells[C, R] + #9; end; S := S + #13#10; end; ClipBoard.AsText := S; end;
// Paste procedure TForm1.Button2Click(Sender: TObject); var Grect: TGridRect; S, CS, F: string; L, R, C: Byte; begin GRect := StringGrid1.Selection; L := GRect.Left; R := GRect.Top; S := ClipBoard.AsText; R := R - 1; while Pos(#13, S) > 0 do begin R := R + 1; C := L - 1; CS := Copy(S, 1,Pos(#13, S)); while Pos(#9, CS) > 0 do begin C := C + 1; if (C <= StringGrid1.ColCount - 1) and (R <= StringGrid1.RowCount - 1) then StringGrid1.Cells[C, R] := Copy(CS, 1,Pos(#9, CS) - 1); F := Copy(CS, 1,Pos(#9, CS) - 1); Delete(CS, 1,Pos(#9, CS)); end; if (C <= StringGrid1.ColCount - 1) and (R <= StringGrid1.RowCount - 1) then StringGrid1.Cells[C + 1,R] := Copy(CS, 1,Pos(#13, CS) - 1); Delete(S, 1,Pos(#13, S)); if Copy(S, 1,1) = #10 then Delete(S, 1,1); end; end; |
- Подробности
- Родительская категория: Буфер обмена
- Категория: Общие вопросы
Этот пример использует картинку, кнопку и компонент shape на форме. Когда пользователь кликает по кнопке, то изображение формы сохраняется в в переменной FormImage и копируется в буфер обмена (Clipboard). Затем изображение формы копируется обратно в компонент картинки, тем самым создавая интересный эффект, особенно, если кнопку понажимать несколько раз.
- Подробности
- Родительская категория: Буфер обмена
- Категория: Общие вопросы
Code: |
unit MyEdit;
interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, stdctrls, clipbrd;
type TPreventNotifyEvent = procedure(Sender: TObject; Text: string; var Accept: Boolean) of object;
type TMyEdit = class(TCustomEdit) private FPreventCut: Boolean; FPreventCopy: Boolean; FPreventPaste: Boolean; FPreventClear: Boolean;
FOnCut: TPreventNotifyEvent; FOnCopy: TPreventNotifyEvent; FOnPaste: TPreventNotifyEvent; FOnClear: TPreventNotifyEvent;
procedure WMCut(var Message: TMessage); message WM_CUT; procedure WMCopy(var Message: TMessage); message WM_COPY; procedure WMPaste(var Message: TMessage); message WM_PASTE; procedure WMClear(var Message: TMessage); message WM_CLEAR; protected { Protected declarations } public { Public declarations } published property PreventCut: Boolean read FPreventCut write FPreventCut default False; property PreventCopy: Boolean read FPreventCopy write FPreventCopy default False; property PreventPaste: Boolean read FPreventPaste write FPreventPaste default False; property PreventClear: Boolean read FPreventClear write FPreventClear default False; property OnCut: TPreventNotifyEvent read FOnCut write FOnCut; property OnCopy: TPreventNotifyEvent read FOnCopy write FOnCopy; property OnPaste: TPreventNotifyEvent read FOnPaste write FOnPaste; property OnClear: TPreventNotifyEvent read FOnClear write FOnClear; end;
procedure Register;
implementation
procedure TMyEdit.WMCut(var Message: TMessage); var Accept: Boolean; Handle: THandle; HandlePtr: Pointer; CText: string; begin if FPreventCut then Exit; if SelLength = 0 then Exit; CText := Copy(Text, SelStart + 1, SelLength); try OpenClipBoard(Self.Handle); Accept := True; if Assigned(FOnCut) then FOnCut(Self, CText, Accept); if not Accept then Exit; Handle := GlobalAlloc(GMEM_MOVEABLE + GMEM_DDESHARE, Length(CText) + 1); if Handle = 0 then Exit; HandlePtr := GlobalLock(Handle); Move((PChar(CText))^, HandlePtr^, Length(CText)); SetClipboardData(CF_TEXT, Handle); GlobalUnlock(Handle); CText := Text; Delete(CText, SelStart + 1, SelLength); Text := CText; finally CloseClipBoard; end; end;
procedure TMyEdit.WMCopy(var Message: TMessage); var Accept: Boolean; Handle: THandle; HandlePtr: Pointer; CText: string; begin if FPreventCopy then Exit; if SelLength = 0 then Exit; CText := Copy(Text, SelStart + 1, SelLength); try OpenClipBoard(Self.Handle); Accept := True; if Assigned(FOnCopy) then FOnCopy(Self, CText, Accept); if not Accept then Exit; Handle := GlobalAlloc(GMEM_MOVEABLE + GMEM_DDESHARE, Length(CText) + 1); if Handle = 0 then Exit; HandlePtr := GlobalLock(Handle); Move((PChar(CText))^, HandlePtr^, Length(CText)); SetClipboardData(CF_TEXT, Handle); GlobalUnlock(Handle); finally CloseClipBoard; end; end;
procedure TMyEdit.WMPaste(var Message: TMessage); var Accept: Boolean; Handle: THandle; CText: string; LText: string; AText: string; begin if FPreventPaste then Exit; if IsClipboardFormatAvailable(CF_TEXT) then begin try OpenClipBoard(Self.Handle); Handle := GetClipboardData(CF_TEXT); if Handle = 0 then Exit; CText := StrPas(GlobalLock(Handle)); GlobalUnlock(Handle); Accept := True; if Assigned(FOnPaste) then FOnPaste(Self, CText, Accept); if not Accept then Exit; LText := ''; if SelStart > 0 then LText := Copy(Text, 1, SelStart); LText := LText + CText; AText := ''; if (SelStart + 1) < Length(Text) then AText := Copy(Text, SelStart + SelLength + 1, Length(Text) - SelStart + SelLength + 1); Text := LText + AText; finally CloseClipBoard; end; end; end;
procedure TMyEdit.WMClear(var Message: TMessage); var Accept: Boolean; CText: string; begin if FPreventClear then Exit; if SelStart = 0 then Exit; CText := Copy(Text, SelStart + 1, SelLength); Accept := True; if Assigned(FOnClear) then FOnClear(Self, CText, Accept); if not Accept then Exit; CText := Text; Delete(CText, SelStart + 1, SelLength); Text := CText; end;
procedure Register; begin RegisterComponents('Samples', [TMyEdit]); end;
end. |
- Подробности
- Родительская категория: Буфер обмена
- Категория: Общие вопросы
Code: |
unit ClipStrm;
interface uses Classes, Windows;
type TClipboardStream = class(TStream) private FMemory : pointer; FSize : longint; FPosition : longint; FFormat : word; public constructor Create(fmt : word); destructor Destroy; override;
function Read(var Buffer; Count : Longint) : Longint; override; function Write(const Buffer; Count : Longint) : Longint; override; function Seek(Offset : Longint; Origin : Word) : Longint; override; end;
implementation uses SysUtils;
constructor TClipboardStream.Create(fmt : word);
var tmp : pointer; FHandle : THandle; begin FFormat := fmt; OpenClipboard(0); FHandle := GetClipboardData(FFormat); FSize := GlobalSize(FHandle); FMemory := AllocMem(FSize); tmp := GlobalLock(FHandle); MoveMemory(FMemory, tmp, FSize); GlobalUnlock(FHandle); FPosition := 0; CloseClipboard; end;
destructor TClipboardStream.Destroy; begin FreeMem(FMemory); end;
function TClipboardStream.Read(var Buffer; Count : longint) : longint; begin if FPosition + Count > FSize then Result := FSize - FPosition else Result := Count; MoveMemory(@Buffer, PChar(FMemory) + FPosition, Result);
Inc(FPosition, Result); end;
function TClipboardStream.Write(const Buffer; Count : longint) : longint; var FHandle : HGlobal; tmp : pointer; begin ReallocMem(FMemory, FPosition + Count); MoveMemory(PChar(FMemory) + FPosition, @Buffer, Count); FPosition := FPosition + Count; FSize := FPosition; FHandle := GlobalAlloc(GMEM_MOVEABLE or GMEM_SHARE or GMEM_ZEROINIT, FSize); try tmp := GlobalLock(FHandle); try MoveMemory(tmp, FMemory, FSize); OpenClipboard(0); SetClipboardData(FFormat, FHandle); finally GlobalUnlock(FHandle);
end; CloseClipboard; except GlobalFree(FHandle); end; Result := Count; end;
function TClipboardStream.Seek(Offset : Longint; Origin : Word) : Longint; begin case Origin of 0 : FPosition := Offset; 1 : Inc(FPosition, Offset); 2 : FPosition := FSize + Offset; end; Result := FPosition; end;
end. |
Alexey Mahotkin Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра. (2:5020/433)
Взято из FAQ: Delphi and Windows API Tips'n'Tricks
Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра.
- Подробности
- Родительская категория: Буфер обмена
- Категория: Общие вопросы
Просмотр буфера обмена.
Пример на основе простого модуля-класса, осуществляющего просмотр буфера обмена.
- Подробности
- Родительская категория: Буфер обмена
- Категория: Общие вопросы
Приложение может быть уведомлено об изменениях в данных, хранящихся в
Буфер обмена Windows, зарегистрировавшись как средство просмотра буфера обмена.
- Подробности
- Родительская категория: Буфер обмена
- Категория: Общие вопросы
Если вы когда-нибудь пробовали вставлять html в буфер обмена, используя обычный CF_TEXT
формате, то вы, возможно, были разочарованы, обнаружив, что визуальный HTML-код
редакторы вставляют ваше предложение, как если бы это был только текст,
вместо того, чтобы распознавать его как html. Для этого нужен формат CF_HTML.
CF_HTML полностью текстовый формат и использует формат преобразования UTF-8.
Он включает в себя описание контекста, и в контексте фрагмента.
- Подробности
- Родительская категория: Буфер обмена
- Категория: Общие вопросы
Code: |
procedure CopyButtonClick(Sender: TObject); begin if ActiveControl is TMemo then TMemo(ActiveControl).CopyToClipboard; if ActiveControl is TDBMemo then TDBMemo(ActiveControl).CopyToClipboard; if ActiveControl is TEdit then TEdit(ActiveControl).CopyToClipboard; if ActiveControl is TDBedit then TDBedit(ActiveControl).CopyToClipboard; end;
procedure PasteButtonClick(Sender: TObject); begin if ActiveControl is TMemo then TMemo(ActiveControl).PasteFromClipboard; if ActiveControl is TDBMemo then TDBMemo(ActiveControl).PasteFromClipboard; if ActiveControl is TEdit then TEdit(ActiveControl).PasteFromClipboard; if ActiveControl is TDBedit then TDBedit(ActiveControl).PasteFromClipboard; end;
|
- Подробности
- Родительская категория: Буфер обмена
- Категория: Общие вопросы
Code: |
uses Clipbrd;
procedure ListBoxToClipboard(ListBox: TListBox; BufferSize: Integer; CopyAll: Boolean); var Buffer: PChar; Size: Integer; Ptr: PChar; I: Integer; Line: string[255]; Count: Integer; begin if not Assigned(ListBox) then Exit;
GetMem(Buffer, BufferSize); Ptr := Buffer; Count := 0; for I := 0 to ListBox.Items.Count - 1 do begin Line := ListBox.Items.strings[I]; if not CopyAll and ListBox.MultiSelect and (not ListBox.Selected[I]) then Continue; { Check buffer overflow } Count := Count + Length(Line) + 3; if Count = BufferSize then Break; { Append to buffer } Move(Line[1], Ptr^, Length(Line)); Ptr := Ptr + Length(Line); Ptr[0] := #13; Ptr[1] := #10; Ptr := Ptr + 2; end; Ptr[0] := #0; ClipBoard.SetTextBuf(Buffer); FreeMem(Buffer, BufferSize); end;
procedure ClipboardToListBox(ListBox: TListbox); begin if not Assigned(ListBox) then Exit;
if not Clipboard.HasFormat(CF_TEXT) then Exit;
Listbox.Items.Text := Clipboard.AsText; end;
//Copy all items from Listbox1 to the clipboard procedure TForm1.Button1Click(Sender: TObject); begin ListBoxToClipboard(ListBox1, 1024, True); end;
//Paste items in clipboard to Listbox2 procedure TForm1.Button2Click(Sender: TObject); begin ClipboardToListBox(Listbox2); end;
//Copy only selected items from Listbox1 to the clipboard procedure TForm1.Button3Click(Sender: TObject); begin ListBoxToClipboard(Listbox1, 1024, False); end; |
- Подробности
- Родительская категория: Буфер обмена
- Категория: Общие вопросы
Страница 3 из 4