クリップボード履歴ソフトを作っています。
テキストとして履歴を取る事は出来ています。
追加でやりたいことは、
クリップボード内のすべてのフォーマット
※例えば画像やWordでコピーした形式の内容
について、それが保持しているメモリの内容を
そのままメモリもしくはファイルに保存しておいて
後で復帰させようとするには
どのように実装すればよいのでしょうか?
クリップボードにある形式で内容が保存されているときに
それを読み出して、ファイルに保存する方法と
それをファイルから読み出して
クリップボードに書く方法、
ご存じでしたら教えてください。
よろしくお願いします。
※連続質問ですまんっす。貯めこんでた質問を
この際、聞いてしまおうかと。
RegisterClipboardFormat でシステムに登録された数の取得方法は知らないのでとりあえず 99 にしてある
Button1 でファイルに保存
Button2 でクリア
Button3 でファイルから読み込み
procedure TForm1.Button1Click(Sender: TObject);
var
I : Integer;
Data: THandle;
DataPointer : Pointer;
MemoryStream : TMemoryStream;
Buffer : array[0..255] of Char;
begin
MemoryStream := TMemoryStream.Create;
try
ClipBoard := TClipBoard.Create;
try
ClipBoard.Open;
try
for I:=0 to ClipBoard.FormatCount -1 do
begin
if ClipBoard.HasFormat(ClipBoard.Formats[I]) = True then
begin
Data := GetClipBoardData(I);
DataPointer := GlobalLock(Data);
try
MemoryStream.Clear;
MemoryStream.WriteBuffer(DataPointer^, GlobalSize(Data));
MemoryStream.SaveToFile(IntToStr(I)+'.DAT');
finally
GlobalUnlock(Data);
end;
end;
end;
finally
ClipBoard.Close;
end;
finally
ClipBoard.Free;
end;
finally
MemoryStream.Free;
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
ClipBoard := TClipBoard.Create;
ClipBoard.Open;
ClipBoard.Clear;
ClipBoard.Close;
ClipBoard.Free;
end;
procedure TForm1.SetBuffer(Format: Word; var Buffer; Size: Integer);
var
Data: THandle;
DataPtr: Pointer;
begin
Data := GlobalAlloc(GMEM_MOVEABLE+GMEM_DDESHARE, Size);
try
DataPtr := GlobalLock(Data);
try
Move(Buffer, DataPtr^, Size);
SetClipboardData(Format, Data);
finally
GlobalUnlock(Data);
end;
except
GlobalFree(Data);
raise;
end;
end;
procedure TForm1.Button3Click(Sender: TObject);
var
FileName : String;
I,C : Integer;
Data: THandle;
DataPointer : Pointer;
MemoryStream : TMemoryStream;
begin
MemoryStream := TMemoryStream.Create;
try
ClipBoard := TClipBoard.Create;
try
ClipBoard.Open;
try
for I:=0 to 99 do
begin
FileName := IntToStr(I) + '.DAT';
if FileExists(FileName) = True then
begin
MemoryStream.Clear;
MemoryStream.LoadFromFile(FileName);
SetBuffer(I, MemoryStream.Memory^, MemoryStream.Size);
end;
end;
finally
ClipBoard.Close;
end;
finally
ClipBoard.Free;
end;
finally
MemoryStream.Free;
end;
end;
訂正
if ClipBoard.HasFormat(ClipBoard.Formats[I]) = True then
begin
Data := GetClipBoardData(I);
DataPointer := GlobalLock(Data);
try
MemoryStream.Clear;
MemoryStream.WriteBuffer(DataPointer^, GlobalSize(Data));
MemoryStream.SaveToFile(IntToStr(I)+'.DAT');
↓↓↓
Format := ClipBoard.Formars[I];
if ClipBoard.HasFormat(Format)= True then
Data := GetClipBoardData(Format);
DataPointer := GlobalLock(Data);
try
MemoryStream.Clear;
MemoryStream.WriteBuffer(DataPointer^, GlobalSize(Data));
MemoryStream.SaveToFile(IntToStr(Format)+'.DAT');
上記のサンプルでは for I:=0 to 99 do にしていますが、
RegisterClipboardFormatされた番号は0xC000〜0xFFFFになるので
forでは無駄になります。
ファイルを 認識番号.DAT で保存しているので
FindFirst でファイルを探して
Format := StrToInt(ChangeFileExt(SearchRec.Name,''),0);
のようにファイル名の認識番号を数値に変換して
if Format <> 0 then
begin
SetBuffer(Format, MemoryStream.Memory^, MemoryStream.Size);
end;
やればいいかも知れません
あけましておめでとうございます。
今年もよろしくおねがいします。
動作を確認しました。
ユニット変数に
var
ClipBoard: TClipboard;
これを追加
Button1Clickに
var
Format : Word;
を追加ですね。
すごいですね。
お見事です。勉強になります。
ファイル名の部分はIndexファイルも同時につくる方が
読み出しが楽かもしれませんね。
考慮します。
お返事、ありがとうございました。
また、解決を押し忘れた...
Clipboard は Clipbrd .pas のシングルトンだから、変数宣言もインスタンスをつくる必要もないですよ。
でも EXCEL でコピーするとおかしくなるんだよね・・・
こんなもん作ってみたよ?
ただ起動中にExcelでコピーを行なうとExcel側でエラーになるんだよね・・・
ツイート | ![]() |