Solved

Why tooltip doesn't show up?

Posted on 2003-11-12
6
1,532 Views
Last Modified: 2007-12-19
Hi! This is a Windows program. Not just a plain C++. Here is the list of all C++, header and resource files. I couldn't figure out why the tooptip of the toolbar refuses to show. It doesn't seem to send TTN_NEEDTEXT notification message to the parent window.

Here is the list of codes.

Please advise.

Jzzhang

Domm.cpp

#include <windows.h>
#include <commctrl.h>
#include "Domm.h"
#include "ToolStatusBar.h"

char g_szClassName[] = "DOM Manager";
HINSTANCE g_hinst;
HWND g_hwnd;
HWND g_hwndSB;
HWND g_hwndTB;

LRESULT CALLBACK WindowFunc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
      static int i = 0;
      int iCode;
      char szMsg[100];
      LPTOOLTIPTEXT lpttt;
      UINT idButton;

      switch (msg)
      {
            case WM_COMMAND:
                  switch (LOWORD(wParam))
                  {
                        case ID_FILE_OPEN:
                              InfoMsgBox(g_hwnd, "Open");
                              break;
                        case ID_DOCUMENT_NEW:
                              InfoMsgBox(g_hwnd, "New");
                              break;
                        case ID_DOCUMENT_REVISE:
                              InfoMsgBox(g_hwnd, "Revise");
                              break;
                        case ID_FILE_EXIT:
                              PostMessage(hwnd, WM_CLOSE, 0, 0);
                              break;
                  }
                  break;

            case WM_NOTIFY:
                  iCode = ((LPNMHDR) lParam)->code;
                  switch (iCode)
                  {
                        case TTN_NEEDTEXT:
                              lpttt = (LPTOOLTIPTEXT) lParam;
                              lpttt->hinst = g_hinst;
 
                              idButton = lpttt->hdr.idFrom;

                              wsprintf(szMsg, "%d code: %u", i++, iCode);
                              SendMessage(g_hwndSB, SB_SETTEXT, 0, (LPARAM) szMsg);

                              switch (idButton)
                              {
                                    case ID_FILE_OPEN:
                                          lpttt->lpszText = MAKEINTRESOURCE(IDS_FILE_OPEN);
                                          break;
                                    case ID_DOCUMENT_NEW:
                                          lpttt->lpszText = MAKEINTRESOURCE(IDS_DOCUMENT_NEW);
                                          break;
                                    case ID_DOCUMENT_REVISE:
                                          lpttt->lpszText = MAKEINTRESOURCE(IDS_DOCUMENT_REVISE);
                                          break;
                              }
                        break;
                        default:
                              break;
                  }
                  break;

            case WM_SIZE:
                  SendMessage(g_hwndTB, TB_AUTOSIZE, 0, 0);
                  SendMessage(g_hwndSB, WM_SIZE, 0, 0);
                  break;

            default:
                  return DefWindowProc(hwnd, msg, wParam, lParam);
      }
      return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
      MSG msg;
      WNDCLASSEX wc;

    INITCOMMONCONTROLSEX icex;
    icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
    icex.dwICC  = ICC_BAR_CLASSES | ICC_LISTVIEW_CLASSES | ICC_TREEVIEW_CLASSES;
    InitCommonControlsEx(&icex);

      g_hinst = hInstance;

      wc.cbSize = sizeof(WNDCLASSEX);
      wc.style = 0;
      wc.lpfnWndProc = WindowFunc;
      wc.cbClsExtra = 0;
      wc.cbWndExtra = 0;
      wc.hInstance = hInstance;
      wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_DOMM_ICON));
      wc.hCursor = LoadCursor(NULL, IDC_ARROW);
      wc.hbrBackground = (HBRUSH) GetStockObject(LTGRAY_BRUSH);
      wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU_MAIN);
      wc.lpszClassName = g_szClassName;
      wc.hIconSm = NULL;

      if (!RegisterClassEx(&wc)) return 0;

      g_hwnd = CreateWindowEx(0, g_szClassName, "DOM Manager", WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT, CW_USEDEFAULT, 800, 480, NULL, NULL, hInstance, NULL);

      if (!g_hwnd) return 0;

      g_hwndTB = CreateToolbar(g_hinst, g_hwnd);
      if (g_hwndTB == NULL)
            ErrMsgBox(g_hwnd, "Error creating toolbar");

      g_hwndSB = CreateStatusbar(g_hinst, g_hwnd);
      if (g_hwndSB == NULL)
            ErrMsgBox(g_hwnd, "Error creating statusbar");

      ShowWindow(g_hwnd, nCmdShow);
      UpdateWindow(g_hwnd);

      while (GetMessage(&msg, g_hwnd, 0, 0) > 0)
      {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
      }

      return msg.wParam;
}

ToolStatusBar.cpp

#include <windows.h>
#include <commctrl.h>
#include "Domm.h"

#define BITMAP_NUM       3
#define BUTTON_NUM       4

void InfoMsgBox(HWND hwndParent, char* pszMsg)
{
      MessageBox(hwndParent, pszMsg, "INFO", MB_ICONINFORMATION | MB_OK);
}

void ErrMsgBox(HWND hwndParent, char* pszMsg)
{
      MessageBox(hwndParent, pszMsg, "ERROR", MB_ICONEXCLAMATION | MB_OK);
}

HWND CreateToolbar(HINSTANCE hInst, HWND hwndParent)
{
      HWND hwndTB;
      TBADDBITMAP tbab;
      TBBUTTON tbb[BUTTON_NUM];
      int iFirstId;

      hwndTB = CreateWindowEx(0, TOOLBARCLASSNAME, NULL,
            WS_CHILD | WS_VISIBLE | TBSTYLE_FLAT | TBSTYLE_TOOLTIPS, 0, 0, 0, 0,
            hwndParent, (HMENU)IDC_TOOLBAR, hInst, NULL);
      if(hwndTB == NULL)
            return NULL;

      SendMessage(hwndTB, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);

      tbab.hInst = hInst;
      tbab.nID = IDR_DOMM_TOOLBAR;
      iFirstId = SendMessage(hwndTB, TB_ADDBITMAP, BITMAP_NUM, (LPARAM)&tbab);
      if (iFirstId == -1)
            return NULL;

      tbb[0].iBitmap = iFirstId++;
      tbb[0].idCommand = ID_FILE_OPEN;
      tbb[0].fsState = TBSTATE_ENABLED;
      tbb[0].fsStyle = TBSTYLE_BUTTON;
      tbb[0].dwData = 0;
      tbb[0].iString = 0;
 
      tbb[1].iBitmap = 0;
      tbb[1].idCommand = 0;
      tbb[1].fsState = TBSTATE_ENABLED;
      tbb[1].fsStyle = TBSTYLE_SEP;
      tbb[1].dwData = 0;
      tbb[1].iString = 0;

      tbb[2].iBitmap = iFirstId++;
      tbb[2].idCommand = ID_DOCUMENT_NEW;
      tbb[2].fsState = TBSTATE_ENABLED;
      tbb[2].fsStyle = TBSTYLE_BUTTON;
      tbb[2].dwData = 0;
      tbb[2].iString = 0;

      tbb[3].iBitmap = iFirstId;
      tbb[3].idCommand = ID_DOCUMENT_REVISE;
      tbb[3].fsState = TBSTATE_ENABLED;
      tbb[3].fsStyle = TBSTYLE_BUTTON;
      tbb[3].dwData = 0;
      tbb[3].iString = 0;

      SendMessage(hwndTB, TB_ADDBUTTONS, BUTTON_NUM, (LPARAM)&tbb);
      SendMessage(hwndTB, TB_AUTOSIZE, 0, 0);
      return hwndTB;
}

HWND CreateStatusbar(HINSTANCE hInst, HWND hwndParent)
{
      HWND hwndSB;
      int statwidths[] = {100, -1};

      hwndSB = CreateWindowEx(0, STATUSCLASSNAME, NULL,
                        WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP, 0, 0, 0, 0,
                        hwndParent, (HMENU)IDC_STATUSBAR, hInst, NULL);
      if(hwndSB == NULL)
            return NULL;

      SendMessage(hwndSB, SB_SETPARTS, sizeof(statwidths)/sizeof(int), (LPARAM)statwidths);
      SendMessage(hwndSB, SB_SETTEXT, 0, (LPARAM)"Ready");
      return hwndSB;
}

Domm.h

// Resource ids
#define IDI_DOMM_ICON       101
#define IDR_MENU_MAIN       102
#define IDR_DOMM_TOOLBAR    103
#define IDM_DOMM_TOOLBAR    104

#define IDC_TOOLBAR         500
#define IDC_STATUSBAR       501

#define ID_FILE_OPEN                    40001
#define ID_FILE_EXIT                    40002
#define ID_DOCUMENT_NEW                 40003
#define ID_DOCUMENT_REVISE              40004
#define ID_DOCUMENT_VIEW                40005

#define IDS_FILE_OPEN                   60001
#define IDS_DOCUMENT_NEW                60002
#define IDS_DOCUMENT_REVISE             60003

ToolStatusBar.h

// Interfaces of toolbar, statusbar and custom message boxs

void InfoMsgBox(HWND hwndParent, char* pszMsg);
void ErrMsgBox(HWND hwndParent, char* pszMsg);
HWND CreateToolbar(HINSTANCE hInst, HWND hwndParent);
HWND CreateStatusbar(HINSTANCE hInst, HWND hwndParent);

Domm.rc

#include "Domm.h"

/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.

IDI_DOMM_ICON               ICON    DISCARDABLE     "Domm.ico"

/////////////////////////////////////////////////////////////////////////////
//
// Menu
//

IDR_MENU_MAIN MENU DISCARDABLE
BEGIN
    POPUP "File"
    BEGIN
        MENUITEM "Open",                        ID_FILE_OPEN
        MENUITEM "Exit",                        ID_FILE_EXIT
    END
    POPUP "Document"
    BEGIN
        MENUITEM "New",                         ID_DOCUMENT_NEW
        MENUITEM "Revise",                      ID_DOCUMENT_REVISE
        MENUITEM "View",                        ID_DOCUMENT_VIEW
    END
END

/////////////////////////////////////////////////////////////////////////////
//
// Bitmap
//

IDR_DOMM_TOOLBAR            BITMAP  DISCARDABLE     "Domm.bmp"

/////////////////////////////////////////////////////////////////////////////
//
// String Table
//

STRINGTABLE DISCARDABLE
BEGIN
    IDS_FILE_OPEN           "Open Project"
    IDS_DOCUMENT_NEW        "New doc"
    IDS_DOCUMENT_REVISE     "Revise doc"
END
0
Comment
Question by:jzzhang
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
6 Comments
 
LVL 1

Expert Comment

by:LuCkY
ID: 9735254
I don't think it will ever receive the TTN_NEEDTEXT messages as the toolbar has its own tooltip handling mechanism if you use the TBSTYLE_TOOLTIPS flag. It will send a TBN_GETINFOTIP message instead of TTN_NEEDTEXT through a WM_NOTIFY message if I'm not mistaken. Try catching that message instead.
0
 
LVL 2

Author Comment

by:jzzhang
ID: 9736574
I think TTN_NEEDTEXT should work too. Since I made a similar program using TTN_NEEDTEXT, it works. Why this time it doesn't work?

Jzzhang
0
 
LVL 2

Author Comment

by:jzzhang
ID: 9737040
I tested TBN_GETINFOTIP message, it doesn't seem to get this notification message either.

Jzzhang
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 2

Author Comment

by:jzzhang
ID: 9749872
I found the reason is that I only process the messages from the main window.

     while (GetMessage(&msg, g_hwnd, 0, 0) > 0)

I need to change it to:

     while (GetMessage(&msg, NULL, 0, 0) > 0)

So I process messages from all windows.

Jzzhang
0
 
LVL 9

Expert Comment

by:tinchos
ID: 10249076
No comment has been added lately, so it's time to clean up this TA.
I will leave the following recommendation for this question in the Cleanup topic area:

PAQ with points refunded

Please leave any comments here within the next seven days.
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

Tinchos
EE Cleanup Volunteer
0
 

Accepted Solution

by:
modulo earned 0 total points
ID: 10308138
PAQed, with points refunded (250)

modulo
Community Support Moderator
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

734 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question