1

Win32ツールチップコントロールにUnicode形式の動的テキストを提供するのに問題があります。次のコードを使用してコントロールを設定します。

INITCOMMONCONTROLSEX icc;
icc.dwSize = sizeof(INITCOMMONCONTROLSEX);
icc.dwICC = ICC_WIN95_CLASSES;
InitCommonControlsEx(&icc);

HWND hwnd_tip = CreateWindowExW(0, TOOLTIPS_CLASSW, NULL, 
  WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP, 
  CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
  NULL, NULL, hinst, NULL
);
SetWindowPos(hwnd_tip, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);

TOOLINFOW ti;
memset(&ti, 0, sizeof(TOOLINFOW));
ti.cbSize = sizeof(TOOLINFOW);
ti.hwnd = hwnd_main;
ti.uId = (UINT) hwnd_control;
ti.uFlags = TTF_IDISHWND | TTF_SUBCLASS;
ti.lpszText = L"This tip is shown correctly, including unicode characters.";
SendMessageW(hwnd_tip, TTM_ADDTOOLW, 0, (LPARAM) &ti);

でツールチップテキストを提供する限り、これは正常に機能しますti.lpszText。ただし、テキストを動的にしたいので、代わりに次のようにWindowProc()でコールバックを設定ti.lpszTextLPSTR_TEXTCALLBACKWて処理します。

...
case WM_NOTIFY:
{
  NMHDR *nm = (NMHDR *) lParam;
  switch (nm->code)
  {
    case TTN_GETDISPINFOW:
    {
      static std::wstring tip_string = L"Some random unicode string.";
      NMTTDISPINFOW *nmtdi = (NMTTDISPINFOW *) lParam;              
      nmtdi->lpszText = (LPWSTR) tip_string.c_str();
    }
    break;
  }
}
break;
...

TTN_GETDISPINOW私はメッセージを受け取らないので、これは機能しません。(注:TTN_GETDISPINFO代わりに処理NMTTDISPINFOしてchar配列を提供するために使用すると機能しますが、Unicodeサポートはありません...)

ここでのセットアップやメッセージ処理で何か問題が発生していると思いますか?それを適切に行う方法について何か提案はありますか?

更新
また、私のプロジェクトはunicoeモードでコンパイルされていないことに注意してください(つまり、_UNICODEが定義されておらず、プロジェクトはマルチバイト文字セットを使用するように設定されています)。これは意図的なものであり、アプリケーション全体をユニコード対応に書き直す必要はありません(少なくともまだ)。_UNICODE定義は、さまざまな関数とデータ構造の* Wバージョンを選択するために使用されるため、上記のように、コードでこれらを明示的に使用することで同じ結果が得られることを期待していました。

4

3 に答える 3

3

ロバート・スコットのリンクをありがとう。私は今それを解決する方法を見つけました。

要するに、受信ウィンドウが Unicode ウィンドウであることを確認し、Unicode ウィンドウ プロシージャを登録するというトリックでした。

WindowProc()問題は、親ウィンドウがTTN_GETDISPINFOW通知メッセージを処理するための Unicode を持っていなかったことです。このウィンドウ(クラス)はRegisterClassEx()/CreateWindowEx() and not RegisterClassExW()/CreateWindowExW(), it did not have registered window procedure for unicode messages.

To get around the problem I changed ti.hwnd from hwnd_main to hwnd_control when sending TTM_ADDTOOLW, resulting in the control's window procedure receving the notifications instead of its parent. In order to intercept the unicode events now sent to the control's window procedure, I subclassed it using SetWindowLongW(hwnd_control, GWL_WNDPROC, (LONG) NewControlWndProc).

hwnd_control は、CreateWindowExW() で作成された標準の「LISTBOX」ウィンドウであり、Unicode に対応していることに注意してください。これは、すべてのビルトイン Windows クラスが、システムによって Unicode と ANSI バージョンの両方で自動的に登録されるためです。

于 2009-06-14T21:26:58.113 に答える
3

TTN_GETDISPINFO 通知コードを受け取り、TTN_GETDISPINFOW を受け取っていないという事実は、プロジェクトが「マルチバイト文字セットを使用する」ように設定されていることを示しています。

プロジェクトのプロパティ ページを確認してください: "Configuration Properties" -> "General" -> "Character Set"
このプロパティは "Use Unicode Character Set" に設定する必要があります。

于 2009-06-14T15:24:39.090 に答える
1

アプリケーション全体でユニコードを使用していますか? それ以外の場合は、この「マイクロソフトの記事」をお読みください。特に「Unicode 対応への 12 のステップ」セクション。

または、この男がしたように試してください

Robert Scott Unicode ツールチップ

于 2009-06-14T15:15:35.867 に答える