クリップボードの操作

Windowsのクリップボードを使うと、文字列やビットマップなどのデータを簡単にコピーできます。クリップボードとのやり取りは、メモリオブジェクトで行いますが、コピー・貼り付け操作は単にメモリオブジェクトにデータを書き込んでクリップボードに渡したり、メモリオブジェクトを取得するだけなので意外に簡単にできるようです。
今回は、APIでプログラムとクリップボード間で文字列(テキストデータ)をやり取りしてみました。

クリップボードへのコピー

クリップボードとデータをやり取りする時には、データを入れるメモリオブジェクトとデータの型を設定する必要があります。メモリオブジェクトは、データを入れるバッファとして使い、データの型はクリップボードに入れる、またはクリップボードから取得するデータ形式を指定するものです。今回は、テキストデータなので、データ形式にはテキストを示すCF_TEXTを指定します。

まず、クリップボードにデータをコピーする時には、データを入れるメモリオブジェクトを作成します。ただし、クリップボードにはメモリのポインタではなく移動可能なメモリオブジェクトのハンドルを渡すので注意してください。具体的には、GlobalAlloc()で移動可能なメモリオブジェクトを作成したら、そのハンドルをGlobalLock()に渡してロックします。これで、メモリオブジェクトのポインタを取得できるので、後はここにデータを書き込んでからアンロックし再び移動可能なメモリオブジェクトに戻します。そして、そのハンドルをクリップボードに渡せばコピー完了です。

クリップボードにデータを渡す時には、クリップボードをオープンしてクリップボードをクリアします。この時、すでに他のプログラム(というよりウインドウ)がクリップボードを使っていたりするとクリップボードのオープンに失敗するので、確実にコピーしたい時にはOpenClipboard()が返す結果を確認してください。クリップボードをオープンしたら、SetClipBoard()でデータが入っているメモリオブジェクトのハンドルを渡すとクリップボードにデータを入れる事が出来ます。
クリップボードは、なるべく早くクローズする必要があるので、データを入れたらすぐにCloseClipboard()を呼び出しましょう。

クリップボードに文字列"Test"をコピーする例

  HGLOBAL hMem;
  LPTSTR lpMem;

  /* メモリオブジェクト確保 */
  hMem=GlobalAlloc(GHND,5);
  /* メモリオブジェクトをロックしてアドレスを取得 */
  lpMem=GlobalLock(hMem);

  /* メモリオブジェクトに文字列を書き込む */
  lstrcpy(lpMem,"Test");

  /* メモリオブジェクトをアンロック */
  GlobalUnlock(hMem);

  /* クリップボードをオープン */
  OpenClipboard(hwnd);
  /* クリップボードをクリア */
  EmptyClipboard();

  /* クリップボードにメモリオブジェクトの文字列をコピー */
  SetClipboardData(CF_TEXT,hMem);

  /* クリップボードをクローズ */
  CloseClipboard();

なお、SetClipboardData()でクリップボードに渡したメモリオブジェクトはそれ以降使用できなくなるので、必要なら別にバッファを確保してそこに保存しておきます。

クリップボードからの貼り付け

クリップボードからテキストデータを取得する時は、クリップボードをオープンしてGetClipboardData()を呼び出しクリップボードのデータが入ったメモリオブジェクトを取得します。ただし、もしメモリオブジェクトのハンドルがNULLならテキストデータは入っていないので、すぐにクリップボードをクローズして処理を中止しましょう(クリップボードにデキストデータがあるかどうかは、IsClipboardFormatAvailable()でも調べられます)。
クリップボードからテキストが入ったメモリオブジェクトを取得したら、それをロックしてポインタを取得します。後は、その文字列をどこかに描くなり保存するなりして使い終わったらメモリオブジェクトのアンロック、クリップボードの解放、という手続きで処理を終えてください。

クリップボードから文字列を取得する例

  OpenClipboard(hwnd);

  /* クリップボードから文字列のメモリオブジェクト取得 */
  hMem=GetClipboardData(CF_TEXT);

  if (hMem==NULL) { /* テキストがなければ中止 */

      CloseClipboard();

      中断処理

  }

  /* メモリオブジェクトをロック */
  lpMem=GlobalLock(hMem);

               ・
               ・
  lpMem(テキストデータ)を使った処理
               ・
               ・

  /* メモリオブジェクトをアンロック */
  GlobalUnlock(hMem);
  CloseClipboard();

プログラム

プログラムソース表示

プログラムを実行すると、入力欄と「コピー」「貼り付け」ボタンの入ったウインドウが表示されます。入力欄とクリップボード間で文字列のコピー・貼り付けができるので、同時にエディタなどを起動して文字列をやり取りしてみましょう。例えば、エディタでコピーした文字列を入力欄に貼り付けたり、その逆を試してみてください。


プログラミング資料庫 > Windowsプログラミング研究室