Tooltip (bzw. QuickInfo) bei disabelten Controls
-
Hi Leutz,
habe ein Dialog, im dem u.a. 8 Radio-Buttons enthalten sind.
Für jedes dieser Radio-Buttons habe ich ein Tool zum Tooltip hinzugefügt (über TTM_ADDTOOL).
Jedes Tool habe ich als mehrzeiligen (multiline) Text ausgelegt (über WM_NOTIFY mit TTN_GETDISPINFO).In der ganzen Applikation habe ich ein einziges Tooltip-Window definiert, d.h. auch die Tools z.B. für die Statusbar-Felder des Hauptfensters verwenden diesen gemeinsamen Tootlip.
Der Tooltip funtkioniert soweit wunderbar.ABER nur solange die Radio-Buttons nicht disabled (ausgegraut) sind!
Nach dem Googeln muß ich feststellen ich für diesen speziellen Fall selbst dafür sorgen muß, daß der Tooltip die Mausinformationen bekommt.
Und zwar über TTM_RELAYEVENT.
Bis jetzt habe ich es nicht geschafft, daß ein Tooltip über ein disabled Control erscheint.Hier meine Code Snippets (stark vereinfacht, sämtliche Fehlerabfragen der Übersicht halber entfernt):
Fensterprozedur für Hauptfenster mit hwnd_window_frame:
LRESULT CALLBACK Proc_Window_Frame( HWND hwnd_frame, //Handle-Nr. des Fensters. UINT message, //Message Identifier. WPARAM wParam, //Erster Message Parameter. LPARAM lParam ) //Zweiter Message Parameter. { switch ( message ) { case WM_CREATE: hwnd_window_tooltip = CreateWindowEx( WS_EX_TOPMOST, TOOLTIPS_CLASS, NULL, WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hwnd_frame, (HMENU)NULL, hinstance_app, NULL ); //Tooltip als Popupfenster generieren. //Der Stil TTS_NOPREFIX muß gesetzt sein, sonst wird bei //Vorkommen eines "&"-Zeichens im Tooltip-Text automatisch //auf 80 Zeichen begrenzt! SetWindowPos( hwnd_window_tooltip, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE ); SendMessage( hwnd_window_tooltip, TTM_SETDELAYTIME, (WPARAM)TTDT_AUTOMATIC, (LPARAM)MAKELONG( -1, 0 ) ); break; case WM_NOTIFY: switch ( ( (LPNMHDR)lParam )->code ) { case TTN_GETDISPINFO: //lpnmtdi = (LPNMTTDISPINFO)lParam; //Address of an NMTTDISPINFO structure. if( GetDlgCtrlID( (HWND)( (LPNMTTDISPINFO)lParam->hdr.idFrom ) ) == HWND des Controls) { (LPNMTTDISPINFO)lParam->lpszText = "Zeile1 \r\nZeile2 \r\nZeile3"; //Neuen Tooltip-Text übergeben. Die Variable muß static oder global //Typ oder dynamisch reserviert worden sein, da lokale Variablen //nach der Rückker der Nachricht ihre Gültigkeit verlieren. //The tooltip control allocates a buffer and copies the text into this new buffer. //Siehe KB180646: Howto display more than 80 characters in a ToolTip control. SendMessage( hwnd_window_tooltip, TTM_SETMAXTIPWIDTH, (WPARAM)0, (LPARAM)400 ); //We want to display multiline Tooltip. } break; } break; } }
Hier die Dialogprozedur (WM_INITDIALOG usw. bereits entfernt):
BOOL CALLBACK Proc_Dialog( HWND hwnd_dialog, //Handle-Nr. des Dialogs (ist eigentlich ein Fenster). UINT message, //Message Identifier. WPARAM wParam, //Erster Message Parameter. LPARAM lParam ) //Zweiter Message Parameter. { uint32 ui32_idx; HWND hwnd_return; HWND hwnd_disabledcontrol; POINT struct_point_cursor; TOOLINFO struct_toolinfo; switch ( message ) { case WM_INITDIALOG: //Tools für Tooltip anlegen. ui32_idx = 0; do { struct_toolinfo.cbSize = sizeof( TOOLINFO ); struct_toolinfo.uFlags = TTF_SUBCLASS | TTF_IDISHWND; //Bei TTF_IDISHWND wird an Member 'uId' der HWND des //Controls übergeben, Member 'rect' wird ignoriert. struct_toolinfo.hwnd = hwnd_window_frame; //Notifikationen werden an Proc_Window_Frame() gesendet. struct_toolinfo.hinst = NULL; struct_toolinfo.uId = (UINT_PTR)GetDlgItem( hwnd_dialog, IDC_RADIOBUTTON_1 + ui32_idx ); //HWND des jeweiligen Controls eintragen. struct_toolinfo.lpReserved = NULL; struct_toolinfo.lpszText = LPSTR_TEXTCALLBACK; SendMessage( hwnd_window_tooltip, TTM_ADDTOOL, (WPARAM)0, (LPARAM)(LPTOOLINFO)&struct_toolinfo ); //Tool für Tooltip registrieren. } while ( ++ui32_idx < 8 ); //Alle 8 Tools fertig? SendMessage( hwnd_window_tooltip, TTM_SETDELAYTIME, (WPARAM)TTDT_AUTOPOP, (LPARAM)MAKELONG( 15000, 0 ) ); //15s Anzeigedauer. break; case WM_MOUSEMOVE: //Der Mauszeiger wurde bewegt. struct_point_cursor.x = LOWORD(lParam); struct_point_cursor.y = HIWORD(lParam); hwnd_return = ChildWindowFromPoint( hwnd_dialog, struct_point_cursor ); if ( ( hwnd_return != NULL ) && ( hwnd_return != hwnd_dialog ) ) { hwnd_disabledcontrol = GetDlgItem( hwnd_dialog, IDC_RADIOBUTTON_1 ); //Dieser Radio-Button ist disabled. if ( hwnd_return == hwnd_disabledcontrol ) { //Neue Message wird so zusammengestellt, als ob sie vom Radio-Button käme. struct_message.hwnd = hwnd_disabledcontrol; struct_message.lParam = lParam; struct_message.message = WM_MOUSEMOVE; struct_message.pt.x = LOWORD( GetMessagePos() ); struct_message.pt.y = HIWORD( GetMessagePos() ); struct_message.time = GetMessageTime(); struct_message.wParam = wParam; SendMessage( hwnd_window_tooltip, TTM_RELAYEVENT, (WPARAM)0, (LPARAM)&struct_message ); //Message an Tooltip-Window senden. } } } }
Ich habe sicherlich irgendwas grundsätzliches übersehen, doch ich komme selber nicht drauf
Die Nachricht mit TTM_RELAYEVENT soll an hwnd_window_tooltip übermittelt werden, oder nicht? Habe ich vielleicht das Konzept falsch verstanden?
Deshalb bitte ich um Eure Mithilfe.Martin