C++ Win32 API - Tooltip erstellen

Paxo

Cadet 1st Year
Registriert
Apr. 2014
Beiträge
9
Hallo,
da ich hier immerwieder gute Tipps bekomme, wenn ich mal nicht weiter weiss, versuch ich hier wieder mein Glück.

Problem:
Meine Software soll allgemein verschiedene Sprachversionen anbieten. Somit müssen sich auch die Tooltips der entsprechenden Sprache anpassen. Die Tooltips werden zwar angezeigt, wenn man die Maus, über zum Beispiel einem Button, bewegt. Allerdings "merkt" sich irgendetwas die vorherigen Sprachversionen des Tooltip-Textes.

Zum Bespiel:
- Als standard Sprache ist englisch eingestellt -> Tooltip wird mit englischem Text angezeigt.
- Sprache wird auf deutsch gestellt -> Tooltip zeigt den englischen Text an, danach wird der deutsche Text drüber geschrieben.
- Sprache wieder auf englisch gestellt -> Tooltip zeigt englischen, dann deutschen, dann wieder englischen Text an.

Es werden also immer alle vorherigen Texte mit angezeigt.
Das beschränkt sich immer auf die jewilige ID des Buttons -> Buttons üben untersich keinen Einfluß aus.

Code
folgender Code veranschaulich, wie ein Tooltip erstellt wird.
Code:
HWND CreateToolTip(int toolID, HWND hWnd, PTSTR pszText)
{
	// Get the window of the tool.
	HWND hwndTool = GetDlgItem(hWnd, toolID);

	//tooltip erstellen
	//hInst ist entspricht dem globalen instance handle.
	HWND hwndTip = CreateWindowEx(NULL, TOOLTIPS_CLASS, NULL,
		WS_POPUP | TTS_ALWAYSTIP,
		CW_USEDEFAULT, CW_USEDEFAULT,
		CW_USEDEFAULT, CW_USEDEFAULT,
		hWnd, NULL,
		hInst, NULL);

	if (!hwndTool || !hwndTip)
	{
		return (HWND)NULL;
	}

	// Associate the tooltip with the tool.
	TOOLINFO toolInfo = { 0 };
	toolInfo.cbSize = sizeof(toolInfo);
	toolInfo.hwnd = hWnd;
	toolInfo.uFlags = TTF_IDISHWND | TTF_SUBCLASS;
	toolInfo.uId = (UINT_PTR)hwndTool;
	toolInfo.lpszText = pszText;
	SendMessage(hwndTip, TTM_ADDTOOL, 0, (LPARAM)&toolInfo);

	return hwndTip;
}

Ein Tooltip wird folgendermaßen übergeben:
Code:
  CreateToolTip(ID_BUTTON, hWnd, tooltip_button_text[sprachversion]);
mit
Code:
char tooltip_button_text[2][30] = { "englisch", "deutsch" };

Ich habe mir die Microsoft-Dokumentation durchgelesen, finde allerdings nichts, was das Problem erklären könnte. Hänge da jetzt schon seit einiger Zeit dran und kann es einfach nicht erklären.
Ich hoffe das Ihr mir hierbei helfen könnt.

mfg Paxo
 
Gehe ich recht in der Annahme, dass du die Funktion CreateToolTip bei jedem Wechsel der Sprache erneut aufrufst? In diesem Fall wird vermutlich jedes Mal ein weiterer Tooltip erzeugt, daher die Überlagerung. Du musst wahrscheinlich vorher den alten mit TTM_DELTOOL entfernen, oder alternativ mit TTM_UPDATETIPTEXT den Text des bestehenden Tooltips ändern.
 
Hallo ph4nt0m,
danke für deine schnelle Antwort. Die Tooltips werden bei jedem Sprachwechsel neu erstellt.
Ich hatte es schon einmal mit TTM_UPDATETIPTEXT in verschiedenen Varianten versucht. Scheinbar versteh ich nicht so recht wie es funktioniert.
Ich wollte es innerhalb der Funktion lösen.

Codeschnippsel befinden sich in der CreateToolTip-Funktion.

ein Versuch war folgender:
Code:
// Associate the tooltip with the tool.
	TOOLINFO toolInfo = { 0 };
	toolInfo.cbSize = sizeof(toolInfo);
	toolInfo.hwnd = hWnd;
	toolInfo.uFlags = TTF_IDISHWND | TTF_SUBCLASS;
	toolInfo.uId = (UINT_PTR)hwndTool;
	toolInfo.lpszText = pszText;

	SendMessage(hwndTip, TTM_ADDTOOL, 0, (LPARAM)&toolInfo);
	SendMessage(hwndTip, TTM_UPDATETIPTEXT, 0, (LPARAM)&toolInfo);
	return hwndTip;
der hat keinerlei Änderung gebracht, da ja durch ADD_TOOL jedesmal eine neuer Tooltip erstellt wird.

anderer Versuch:
Code:
// Associate the tooltip with the tool.
	TOOLINFO toolInfo = { 0 };
	toolInfo.cbSize = sizeof(toolInfo);
	toolInfo.hwnd = hWnd;
	toolInfo.uFlags = TTF_IDISHWND | TTF_SUBCLASS;
	toolInfo.uId = (UINT_PTR)hwndTool;
	toolInfo.lpszText = pszText;

       //update wird der Funktion mitgegeben
       // -> gedanke war es, das beim programmstart eine 1 mitgegeben wird
       // -> Tooltip wird nur 1x erstellt, anschließend nur noch 0 mitgeben um den Text zu updaten
	if (update == 0) {
		SendMessage(hwndTip, TTM_UPDATETIPTEXT, 0, (LPARAM)&toolInfo);
	}
	else if (update == 1){
		SendMessage(hwndTip, TTM_ADDTOOL, 0, (LPARAM)&toolInfo);
		update = 0;
	}
	return hwndTip;
Ergebnis war es, dass der Text einfach nie geändert wurde.
 
Ich habe einen anderen Vorschlag, der funktionieren müsste und eventuell einfacher zu realisieren ist:

Rufe deine ursprüngliche CreateToolTip-Funktion nur einmal zu Programmbeginn auf und sichere das Fensterhandle des Tooltips (du gibst dieses ja bereits aus der Funktion zurück).

Immer, wenn danach die Sprache geändert wird, kannst du mit SetWindowText den Tooltip-Text ändern (als Parameter das gesicherte Handle des Tooltips und den neuen Text übergeben).
 
Hi,
das war eigentlich eine richtig gute Idee. Allerdings scheint die auch nicht zu funktionieren :/.

CreateToolTip(ID_BUTTON, hWnd, Text); wird nur einmal zum Programmbeginn erstellt und einem handle zugewiesen:
Code:
htooltip_button = CreateToolTip(ID_BUTTON, hWnd, text_array[sprache]);
wobei htooltip_button ein globaler handle ist:
Code:
HWND htooltip_button;

Das mit dem handle übergeben sollte so aufjedenfall funktionieren, da ich andere Probleme auch auf diese Weise gelöst habe.

Wenn die Sprache geändert wird, soll einfach mal ein "test" als neuer Text angezeigt werden. Allerdings ändert sich überhaupt nichts.
Code:
SetWindowText(htooltip_button, "test");
 
Zuletzt bearbeitet:
Es war auf jeden Fall einen Versuch wert. ;) Ich vermute, dass es aus folgendem Grund nicht funktioniert: Ein Tooltip kann theoretisch für beliebig viele Fenster (sprich "Tools", z.B. Steuerelemente) einen Hilfstext anzeigen, nicht nur für eins. Beim Ändern dieses Textes muss also angegeben werden, für welches Tool der neue Text festgelegt werden soll, und das kann mit SetWindowText nicht funktionieren.

Also bleibt wohl doch nur der offizielle Weg über die TTM_UPDATETIPTEXT Nachricht. Versuche mal, meinen letzten Vorschlag folgendermaßen abzuändern:

Statt

Code:
SetWindowText(htooltip_button, "test");


rufst du bei jeder Änderung der Sprache folgenden Code auf:

Code:
TOOLINFO toolInfo = { 0 };
toolInfo.cbSize   = sizeof(TOOLINFO);
toolInfo.hwnd     = GetParent(hwndTool);
toolInfo.uFlags   = TTF_IDISHWND | TTF_SUBCLASS;
toolInfo.uId      = (UINT_PTR) hwndTool;
toolInfo.lpszText = "test"; // neuer Text, wahrscheinlich ein Zeiger auf irgendeinen String

SendMessage(htooltip_button, TTM_UPDATETIPTEXT, 0, (LPARAM)&toolInfo);

Mit hwndTool ist hier das Toolfenster gemeint, für welches der Tooltiptext geändert werden soll. Dieses Handle müsstest du also auch "global" irgendwo geeignet festhalten (etwa so, wie du es bereits mit htooltip_button, dem Handle des eigentlichen Tooltips, machst).
 
Hi,
ich danke dir vielmals, ich habe heute ein Testprojekt erstellt und es scheint wunderbar zu funktionieren. Ich verwende jetzt 2 Funktionen, die CreateToolTip() aus meinem ersten Post - die wird nur einmal zum Programmbeginn aufgerufen und einem handle zugewiesen
Code:
htooltip = CreateToolTip(ID_BUTTON, hWnd, tooltip_button_text[sprache]);

Sobald die Sprache geändert wird, wird die 2te Funktion aufgerufen.
Code:
change_text(ID_BUTTON, hWnd, tooltip_button_text[sprache]);

In dieser Funktion wurde nun die Toolinfo-Struktur so verändert, wie du es im Post #6 gezeigt hast.
Code:
TOOLINFO toolInfo = { 0 };
toolInfo.cbSize = sizeof(TOOLINFO);
toolInfo.hwnd = GetParent(hwndTool);
toolInfo.uFlags = TTF_IDISHWND | TTF_SUBCLASS;
toolInfo.uId = (UINT_PTR)hwndTool;
toolInfo.lpszText = pszText;

//es sind mehrere Steuerelemente im Code vorhanden ->
//Fallunterscheidung für die verschiedenen Handle
if (toolID == ID_BUTTON){
	SendMessage(htooltip, TTM_UPDATETIPTEXT, 0, (LPARAM)&toolInfo);
}
else if (toolID == ID_BUTTON2){
	SendMessage(htooltip2, TTM_UPDATETIPTEXT, 0, (LPARAM)&toolInfo);
}

mfg Paxo
 
Zurück
Oben