クリップボードのあらゆる形式の内容をファイルに保存するのは

解決


Fusa  URL  2007-12-30 22:25:48  No: 29138

クリップボード履歴ソフトを作っています。
テキストとして履歴を取る事は出来ています。

追加でやりたいことは、

クリップボード内のすべてのフォーマット
※例えば画像やWordでコピーした形式の内容
について、それが保持しているメモリの内容を
そのままメモリもしくはファイルに保存しておいて
後で復帰させようとするには
どのように実装すればよいのでしょうか?

クリップボードにある形式で内容が保存されているときに
それを読み出して、ファイルに保存する方法と
それをファイルから読み出して
クリップボードに書く方法、
ご存じでしたら教えてください。

よろしくお願いします。

※連続質問ですまんっす。貯めこんでた質問を
  この際、聞いてしまおうかと。


KHE00221  URL  2007-12-31 00:09:08  No: 29139

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;


KHE00221  2008-01-01 08:02:25  No: 29140

訂正

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');


KHE00221  2008-01-01 08:59:33  No: 29141

上記のサンプルでは 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;

やればいいかも知れません


Fusa  URL  2008-01-01 11:35:00  No: 29142

あけましておめでとうございます。
今年もよろしくおねがいします。

動作を確認しました。

ユニット変数に
var
  ClipBoard: TClipboard;
これを追加

Button1Clickに
var
    Format : Word;
を追加ですね。

すごいですね。
お見事です。勉強になります。

ファイル名の部分はIndexファイルも同時につくる方が
読み出しが楽かもしれませんね。
考慮します。

お返事、ありがとうございました。


Fusa  2008-01-01 12:08:18  No: 29143

また、解決を押し忘れた...


うんと  2008-01-01 14:50:20  No: 29144

Clipboard は Clipbrd .pas のシングルトンだから、変数宣言もインスタンスをつくる必要もないですよ。


KHE00221  2008-01-01 19:06:02  No: 29145

でも EXCEL でコピーするとおかしくなるんだよね・・・


KHE00221  URL  2008-01-01 21:51:02  No: 29146

こんなもん作ってみたよ?

http://khe00221.image.coocan.jp/index.php?FrontPage%2FApplication%2FClipBoardHistory%28%A5%BD%A1%BC%A5%B9%C9%D5%A4%AD%29

ただ起動中にExcelでコピーを行なうとExcel側でエラーになるんだよね・・・


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加