# WINAPI Tooltip für Button erzeugen



## souljumperZ (18. Januar 2008)

Hi,

ich versuche grade verzweifelt für einen button in einem fenster einen tooltip zu erzeugen, aber es tut sich leider gar nichts. die msdn beispiele hab ich mittlerweile auch schon divererse male gelesen ohne zu sehen was ich falsch mache.

ich poste mal kurz meinen kompletten code:

sieht jemand was falsch ist, warum er mir den tooltip für den button nicht erzeugt?

ich mittlerweile schon so viel rumprobiert das ich nicht mehr weis wo mir der kopf steht 

was ich bei msdn gefunden hab war die seite, leider funktionieren diese beispiele bei mir auch nicht(und beziehen sich alle immer auf dialoge-den grund dafür ist mir nicht ersichtlich, muss ich was anders machen wenn ich fürs hauptwindow einen tooltip haben will?)


```
// tooltip.cpp : Definiert den Einstiegspunkt für die Anwendung.
//

#include "stdafx.h"
#include "tooltip.h"
#include "commctrl.h"

#define MAX_LOADSTRING 100
#pragma comment(lib, "comctl32.lib")

// Globale Variablen:
HINSTANCE hInst;								// Aktuelle Instanz
TCHAR szTitle[MAX_LOADSTRING];					// Titelleistentext
TCHAR szWindowClass[MAX_LOADSTRING];			// Klassenname des Hauptfensters

HWND g_Butt;
static HWND hWndToolTip;
void CreateToolTipForRect(HWND hwndParent);

// Vorwärtsdeklarationen der in diesem Codemodul enthaltenen Funktionen:
ATOM				MyRegisterClass(HINSTANCE hInstance);
BOOL				InitInstance(HINSTANCE, int);
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK	About(HWND, UINT, WPARAM, LPARAM);

int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);

 	// TODO: Hier Code einfügen.
	MSG msg;
	HACCEL hAccelTable;

	// Globale Zeichenfolgen initialisieren
	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
	LoadString(hInstance, IDC_TOOLTIP, szWindowClass, MAX_LOADSTRING);
	MyRegisterClass(hInstance);

	// Anwendungsinitialisierung ausführen:
	if (!InitInstance (hInstance, nCmdShow))
	{
		return FALSE;
	}

	hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_TOOLTIP));

	// Hauptmeldungsschleife:
	while (GetMessage(&msg, NULL, 0, 0))
	{
		if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}

	return (int) msg.wParam;
}



//
//  FUNKTION: MyRegisterClass()
//
//  ZWECK: Registriert die Fensterklasse.
//
//  KOMMENTARE:
//
//    Sie müssen die Funktion verwenden,  wenn Sie möchten, dass der Code
//    mit Win32-Systemen kompatibel ist, bevor die RegisterClassEx-Funktion
//    zu Windows 95 hinzugefügt wurde. Der Aufruf der Funktion ist wichtig,
//    damit die kleinen Symbole, die mit der Anwendung verknüpft sind,
//    richtig formatiert werden.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX);

	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_TOOLTIP));
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName	= MAKEINTRESOURCE(IDC_TOOLTIP);
	wcex.lpszClassName	= szWindowClass;
	wcex.hIconSm		= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

	return RegisterClassEx(&wcex);
}

//
//   FUNKTION: InitInstance(HINSTANCE, int)
//
//   ZWECK: Speichert das Instanzenhandle und erstellt das Hauptfenster.
//
//   KOMMENTARE:
//
//        In dieser Funktion wird das Instanzenhandle in einer globalen Variablen gespeichert, und das
//        Hauptprogrammfenster wird erstellt und angezeigt.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   HWND hWnd;

   InitCommonControls();

   hInst = hInstance; // Instanzenhandle in der globalen Variablen speichern

   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

   g_Butt = CreateWindow(TEXT("button"), TEXT("AAAAA"),	WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON |WS_TABSTOP,
									0, 0, 0, 0, hWnd, (HMENU) 3000,
									hInstance, NULL);

   MoveWindow(g_Butt, 200,200,23,40,true);


   if (!hWnd)
   {
      return FALSE;
   }

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   return TRUE;
}

//
//  FUNKTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  ZWECK:  Verarbeitet Meldungen vom Hauptfenster.
//
//  WM_COMMAND	- Verarbeiten des Anwendungsmenüs
//  WM_PAINT	- Zeichnen des Hauptfensters
//  WM_DESTROY	- Beenden-Meldung anzeigen und zurückgeben
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT uiMessage, WPARAM wParam, LPARAM lParam)
{


    switch(uiMessage)
    {
        case WM_CREATE:
            TOOLINFO tiToolInfo;
            RECT     rcClient;
            // ToolTip-Fenster erstellen:
            hWndToolTip = CreateWindowEx
                (
                  0L, TOOLTIPS_CLASS, NULL, WS_POPUP | TTS_NOPREFIX,
                  CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
                  CW_USEDEFAULT, hWnd, NULL, hInst, NULL
                );

			POINT ptCursor;
			GetCursorPos(&ptCursor); 

            // Client-Area des Hauptfensters ermitteln
            // in der der ToolTip angezeigt wird.
			GetClientRect(hWnd, &rcClient);
            // Informations-Struktur für ToolTip füllen:
            tiToolInfo.cbSize        = sizeof(TOOLINFO);
            tiToolInfo.uFlags        = TTF_CENTERTIP;
			tiToolInfo.hwnd            = g_Butt;
            tiToolInfo.hinst        = hInst;
            tiToolInfo.uId            = 3000;
            tiToolInfo.lpszText        = L"asdf";
            /*
            Hinweis:
            Immer wenn das Tooltip seinen Text 'benötigt',
            also angezeigt werden muss, wird eine Nachricht
            WM_NOTIFY (siehe Message-Handler) gesendet, in
            der der Text gesetzt wird.
            */
            tiToolInfo.rect.left    = rcClient.left;
            tiToolInfo.rect.top        = rcClient.top;
            tiToolInfo.rect.right    = rcClient.right;
            tiToolInfo.rect.bottom    = rcClient.bottom;
            // Tooltip an das Fenster zuweisen:
            SendMessage(hWndToolTip, TTM_ADDTOOL, 0,
                        reinterpret_cast<LPARAM>(&tiToolInfo));
			break;

		case WM_DESTROY:
            PostQuitMessage(0);
            break;

        default:
            return (DefWindowProc(hWnd, uiMessage, wParam, lParam));
    }

    return (0L);
}
// Meldungshandler für Infofeld.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	UNREFERENCED_PARAMETER(lParam);
	switch (message)
	{
	case WM_INITDIALOG:
		return (INT_PTR)TRUE;

	case WM_COMMAND:
		if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
		{
			EndDialog(hDlg, LOWORD(wParam));
			return (INT_PTR)TRUE;
		}
		break;
	}
	return (INT_PTR)FALSE;
}
```


----------



## BOND_WR (18. Januar 2008)

Hallo,

ich habe heute auch zufällig einen Tooltip für einen CButton erzeugt aber mein Code ist etwas kürzer. Der Code von dir sieht aus wie der Quellcode der CTooltip Class aber du willst doch nur die Klasse verwenden oder?

Du hast übrigens PHP Syntaxhighlight.


Hier der Code:

Im Header:

```
afx_msg BOOL PreTranslateMessage(MSG* pMsg);

CToolTipCtrl* m_pToolTip;
```

In der CPP:

Im Konstruktor:

```
m_pToolTip = new CToolTipCtrl();
m_pToolTip->Create(this);
```

Im Destruktor:

```
delete m_pToolTip;
```

Dort wo du es brauchst:

```
m_pToolTip->AddTool(&m_DeinCButton, _T("ToolTip Text"));
m_pToolTip->Activate(TRUE);
```


```
BOOL C_DeineClass::PreTranslateMessage(MSG* pMsg) 
{
  if(m_pToolTip != NULL)
    m_pToolTip->RelayEvent(pMsg);
  
  return PreTranslateMessage(pMsg);
}
```


Funktioniert prima.

Edit:

OH, okay ich hab grad WINAPI Tooltip gelesen, dann kann ich dir leider nicht helfen. Da kenn ich mich nicht aus.


----------



## souljumperZ (18. Januar 2008)

du benutzt die MFC oder? die verwende ich nicht, es muss doch auch ohne MFC hinbekommen zu sein


----------

