待辦事項 #30015

キーボードレイアウトがUSのとき、日本語文字列をクリップボードにコピーしたとき文字化けが発生する

啟用日期: 2012-11-05 12:45 最後更新: 2012-12-07 17:46

回報者:
負責人:
(del#1144)
類型:
狀態:
關閉
元件:
里程碑:
(無)
優先權:
5 - 中
嚴重程度:
5 - 中
處理結果:
修正
檔案:
Vote
Score: 0
No votes
0.0% (0/0)
0.0% (0/0)

細節

キーボードレイアウトがUSに設定されているとき、 日本語を含む文字列をコピーすると、 ペースト時に文字化けが発生します。

下記の環境で確認しました。 Windows XP Professional SP3 (日本語版) Windows 7 Professional SP1 (日本語版)

以下のコンソール文字列の場合:

[sys-user@gateway ~]$ date
Mon Nov  5 12:34:11 JST 2012
[sys-user@gateway ~]$ LANG=ja_JP.UTF-8 date
2012年 11月  5日 月曜日 12:34:14 JST

結果:

[sys-user@gateway ~]$ date
Mon Nov  5 12:34:11 JST 2012
[sys-user@gateway ~]$ LANG=ja_JP.UTF-8 date
2012”N 11ŒŽ  5“ú ŒŽ—j“ú 12:34:14 JST

最新版 trunk を取得し、調査をしてみました。 また、PuTTYでは発生しないため(PuTTYである必要はないですが)PuTTYのコピー処理とも見比べてみました。

PuTTY では、以下のコピー処理となっていました。(抜粋)

  1. /*
  2. * File: window.c
  3. */
  4. void write_clip(void *frontend, wchar_t * data, int *attr, int len, int must_deselect) {
  5. HGLOBAL clipdata, clipdata2, clipdata3;
  6. int len2;
  7. void *lock, *lock2, *lock3;
  8. len2 = WideCharToMultiByte(CP_ACP, 0, data, len, 0, 0, NULL, NULL);
  9. clipdata = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE,
  10. len * sizeof(wchar_t));
  11. clipdata2 = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, len2);
  12. /*** snip ***/
  13. if (OpenClipboard(hwnd)) {
  14. EmptyClipboard();
  15. SetClipboardData(CF_UNICODETEXT, clipdata);
  16. SetClipboardData(CF_TEXT, clipdata2);
  17. if (clipdata3)
  18. SetClipboardData(RegisterClipboardFormat(CF_RTF), clipdata3);
  19. CloseClipboard();
  20. } else {
  21. GlobalFree(clipdata);
  22. GlobalFree(clipdata2);
  23. }
  24. if (!must_deselect)
  25. SendMessage(hwnd, WM_IGNORE_CLIP, FALSE, 0);
  26. }

TeraTerm の処理は、CF_TEXT への set のみとなっているため、CF_UNICODETEXT をセットするようにしたところ、 うまくいきました。(PuTTY とは逆に、MultiByteToWideCharしました)

自分が試したコードのパッチを下記に記載いたします。

  1. Index: trunk/teraterm/teraterm/clipboar.c
  2. ===================================================================
  3. --- trunk/teraterm/teraterm/clipboar.c (revision 5057)
  4. +++ trunk/teraterm/teraterm/clipboar.c (working copy)
  5. @@ -67,6 +67,10 @@
  6. void CBClose()
  7. {
  8. BOOL Empty;
  9. + HGLOBAL CBCopyWideHandle = NULL;
  10. + LPWSTR CBCopyWidePtr = NULL;
  11. + int WideCharLength;
  12. +
  13. if (CBCopyHandle==NULL) {
  14. return;
  15. }
  16. @@ -76,6 +80,14 @@
  17. Empty = (CBCopyPtr[0]==0);
  18. }
  19. + WideCharLength = MultiByteToWideChar(CP_ACP, 0, CBCopyPtr, -1, NULL, 0);
  20. + CBCopyWideHandle = GlobalAlloc(GMEM_MOVEABLE, sizeof(WCHAR) * WideCharLength);
  21. + if (CBCopyWideHandle) {
  22. + CBCopyWidePtr = (LPWSTR)GlobalLock(CBCopyWideHandle);
  23. + MultiByteToWideChar(CP_ACP, 0, CBCopyPtr, -1, CBCopyWidePtr, WideCharLength);
  24. + GlobalUnlock(CBCopyWideHandle);
  25. + }
  26. +
  27. GlobalUnlock(CBCopyHandle);
  28. CBCopyPtr = NULL;
  29. @@ -83,10 +95,17 @@
  30. EmptyClipboard();
  31. if (! Empty) {
  32. SetClipboardData(CF_TEXT, CBCopyHandle);
  33. + if (CBCopyWidePtr) {
  34. + SetClipboardData(CF_UNICODETEXT, CBCopyWideHandle);
  35. + }
  36. }
  37. CloseClipboard();
  38. }
  39. CBCopyHandle = NULL;
  40. +
  41. + if (CBCopyWideHandle) {
  42. + GlobalFree(CBCopyWideHandle);
  43. + }
  44. }
  45. void CBStartPaste(HWND HWin, BOOL AddCR, BOOL Bracketed,

なにぶんC言語とWindows開発に慣れていないもので、 上記のコードが適切でないかもしれません。

受け入れ可能な状態に修正していただき、取り込んでいただけると幸いです。

なお、修正版は下記の環境でコピー機能の正常動作を確認しました。 * ビルド環境: Visual Studio 2010 Professional SP1 * 実行環境:

    • Windows 7 Professional SP1 (日本語版)
    • Windows XP Professional SP3 (日本語版)

Ticket History (3/11 Histories)

2012-11-05 12:45 Updated by: comutt
  • New Ticket "キーボードロケールがUSのとき、日本語文字列をクリップボードにコピーしたとき文字化けが発生する" created
2012-11-06 12:07 Updated by: (del#1144)
  • Details Updated
  • Summary Updated
2012-11-13 23:16 Updated by: (del#1144)
評語

いろいろ調べてみました。

GlobalFree

クリップボードに渡したポインタをプログラムから GlobalFree してはいけません。

パッチを適用しても、CP_ACP で日本語が文字化けしないための条件がある

「Unicode対応でないプログラムの言語」が「日本語」になっている(マルチバイトを Shift_JIS と決めつける)必要があります。

SetClipboardData している箇所

ここ以外に 3 箇所あります。

SetClipboardData が文字化けするなら GetClipboardData も文字化けします

GetClipboardData を利用しているところが 4 箇所あります。

To:開発メンバ

この機能を取り込むとして、on/offの設定は必要でしょうか。MultiByte/WideChar変換を有効にしてUNICODEを優先にすることで、かえって文字化けするようになる環境はないでしょうか。

2012-11-14 11:07 Updated by: (del#24082)
評語

IMEから文字を取得するところは、Unicodeで受け取り、それをMBCSに変換しています。 特に on/off の設定はありません。

クリップボードに関しても同様の処置で問題ないと考えます。

2012-11-16 00:37 Updated by: doda
評語

同じく、Unicodeからの変換でいいと思います。 on/off設定も必要無いと思います。

2012-11-16 13:04 Updated by: (del#1144)
  • 負責人 Update from (無) to maya
  • 處理結果 Update from to Accepted
評語

了解です。対応してみます。

2012-11-22 12:35 Updated by: (del#1144)
  • 處理結果 Update from Accepted to 修正
評語

対応をコミットしました。この処理で問題ないでしょうか。

2012-11-25 05:00 Updated by: None
評語

maya さま

ご対応ありがとうございました! trunk をビルドして、コピー&ペーストに問題ありませんでした。

2012-11-25 05:03 Updated by: comutt
評語

None への返信

maya さま ご対応ありがとうございました! trunk をビルドして、コピー&ペーストに問題ありませんでした。

すみません、名無しで書いてしまいました。チケットを起票した者です。

2012-12-01 09:01 Updated by: None
2012-12-07 17:46 Updated by: (del#1144)
  • 里程碑 Update from Tera Term 4.76 (closed) to (無)
  • Ticket Close date is changed to 2012-12-07 17:46
  • 狀態 Update from 開啟 to 關閉

Attachment File List

No attachments

編輯

You are not logged in. I you are not logged in, your comment will be treated as an anonymous post. » 登入