ホーム >プログラム >Delphi 6 ローテクTips >Unicode対応のクリップボード関数

ウムラウトのようなUnicode文字の入った文字列をクリップボードにコピーしたりクリップボードから貼り付けたいと思いました。


ほぼAPIバイブルのサンプルコードをDelphiに翻訳しただけのものです。

function gfnsStrFromClipboard: WideString;
//クリップボードの文字列を取得して返す
var
  li_Format: array[0..1] of Integer;
  li_Text: Integer;
  lh_Clip, lh_Data: THandle;
  lp_Clip, lp_Data: Pointer;
begin
  Result := '';

  //この順番を変えることでShift_JISを優先して取得することも可能
  li_Format[0] := CF_UNICODETEXT;
  li_Format[1] := CF_TEXT;

  li_Text := GetPriorityClipboardFormat(li_Format, 2);
  if (li_Text > 0) then
  begin
    if (OpenClipboard(Application.Handle)) then
    begin
      lh_Clip := GetClipboardData(li_Text);
      if (lh_Clip <> 0) then
      begin
        lh_Data := 0;
        if (GlobalFlags(lh_Clip) <> GMEM_INVALID_HANDLE) then
        begin
          try
            if (li_Text = CF_UNICODETEXT) then
            begin
              //Unicode文字列を優先
              lh_Data := GlobalAlloc(GHND or GMEM_SHARE, GlobalSize(lh_Clip));
              lp_Clip := GlobalLock(lh_Clip);
              lp_Data := GlobalLock(lh_Data);
              lstrcpyW(lp_Data, lp_Clip);
              Result := WideString(PWideChar(lp_Data));
              GlobalUnlock(lh_Data);
              GlobalFree(lh_Data);
              GlobalUnlock(lh_Clip); //GlobalFreeはしてはいけない
            end
            else
            if (li_Text = CF_TEXT) then
            begin
              lh_Data := GlobalAlloc(GHND or GMEM_SHARE, GlobalSize(lh_Clip));
              lp_Clip := GlobalLock(lh_Clip);
              lp_Data := GlobalLock(lh_Data);
              lstrcpy(lp_Data, lp_Clip);
              Result := WideString(AnsiString(PAnsiChar(lp_Data)));
              GlobalUnlock(lh_Data);
              GlobalFree(lh_Data);
              GlobalUnlock(lh_Clip); //GlobalFreeはしてはいけない
            end;
          finally
            if (lh_Data <> 0) then
              GlobalUnlock(lh_Data);
            end;
            CloseClipboard;
          end;
        end;
      end;
    end;
  end;
end;

稀にUnicode対応でないアプリからのコピペで日本語が文字化けしてしまうことがあります。
私の環境(Windows 7 Home Premium 64bit SP1)だとDelphi 6のIDEからのコピペが文字化けしてしまいます。

procedure gpcStrToClipboard(const sWText: WideString);
//クリップボードへ文字列をセットする
//Unicode文字列としてセットすると同時に(Unicodeでない)プレーンテキストとしてもセットする
var
  li_WLen, li_Len: Integer;
  ls_Text: AnsiString;
  lh_Mem: THandle;
  lp_Data: Pointer;
begin
  li_WLen := (Length(sWText) +1) * 2;
  ls_Text := AnsiString(sWText);
  li_Len  := Length(ls_Text) + 1;
  if (sWText <> '') then
  begin
    if (OpenClipboard(Application.Handle)) then
    begin
      try
        EmptyClipboard;
        //CF_UNICODETEXT
        lh_Mem  := GlobalAlloc(GHND or GMEM_SHARE, li_WLen);
        lp_Data := GlobalLock(lh_Mem);
        lstrcpyW(lp_Data, PWideChar(sWText));
        GlobalUnlock(lh_Mem);
        SetClipboardData(CF_UNICODETEXT, lh_Mem);
        //CF_TEXT
        lh_Mem  := GlobalAlloc(GHND or GMEM_SHARE, li_Len);
        lp_Data := GlobalLock(lh_Mem);
        lstrcpy(lp_Data, PAnsiChar(ls_Text));
        GlobalUnlock(lh_Mem);
        SetClipboardData(CF_TEXT, lh_Mem);
      finally
        CloseClipboard;
      end;
    end;
  end;
end;