2008 Cubs Predictions: Take 4

Baseball No Comments »

Chicago Cubs Logo

Latest Cubs prediction: 110-54 (0.362 team OBP, 3.66 team ERA, underlying equation). (Previous predictions: 112-50, 113-49, 90-62)

We’ll have to see how Soriano’s broken finger affects the Cubs’ team OBP and thus the prediction.

Balloon Tooltips

Win32 2 Comments »

In the Windows XP login screen, the password text box will warn you with a balloon tooltip if you accidentally turn Caps Lock on:

Windows XP Caps Lock Warning Message

The balloon tooltip appears to be a Windows tooltip common control with the TTS_BALLOON style.

To replicate this functionality, I decided to write a function called ShowMsgBalloon() which, given a control and the various balloon tooltip parameters, creates and shows the balloon tooltip below the control.

The key insight to making ShowMsgBallon() work as intended was to use the TTF_TRACK option to create a tracking tooltip. This will immediately show the tooltip without requiring the user to position the mouse over the control. The main downside to using TTF_TRACK is that the tooltip will not move with the control if the window is moved; you need to manually move the tooltip using TTM_TRACKPOSITION as required. One could probably make this automatic by subclassing the tooltip’s parent control and handling WM_WINDOWPOSCHANGED messages.

Here is the source code to ShowMsgBalloon(). When you are done with the balloon, call DestroyWindow() on the returned HWND. Note: you may want your application to use comctl32.dll version 6 as it will lead to a nicer visual style, including a close button.

  1. #include <windows.h>
  2. #include <commctrl.h>
  3.  
  4. // Options to ShowMsgBallon() (see dwOpts parameter).  These are the
  5. // standard icon types for balloon tooltips.
  6. #define SMB_ICON_INFO    (1 << 0)
  7. #define SMB_ICON_WARNING (1 << 1)
  8. #define SMB_ICON_ERROR   (1 << 2)
  9.  
  10. // Given the options passed to ShowMsgBalloon(), determine what
  11. // parameter to send to TTM_SETTITLE for the balloon tooltip’s icon.
  12. static DWORD
  13. GetTitleIcon(DWORD dwOpts)
  14. {
  15.     if (dwOpts &amp; SMB_ICON_INFO)
  16.         return TTI_INFO;
  17.     else if (dwOpts &amp; SMB_ICON_WARNING)
  18.         return TTI_WARNING;
  19.     else if (dwOpts &amp; SMB_ICON_ERROR)
  20.         return TTI_ERROR;
  21.     else
  22.         return 0;
  23. }
  24.  
  25. // Create and show a balloon tooltip immediately below the control
  26. // hwndCtrl with the given title, message, and options.
  27. HWND
  28. ShowMsgBalloon(HWND hwndCtrl, LPCTSTR szTitle, LPCTSTR szMsg,
  29.                DWORD dwOpts)
  30. {
  31.     HWND hwndRet = NULL;
  32.     HWND hwndTT = NULL;
  33.     TOOLINFO ti = { 0 };
  34.     RECT rc;
  35.  
  36.     // Even though TTS_CLOSE is always specified, a close button will
  37.     // only be shown if your application has a manifest that requires
  38.     // comctl32.dll version 6.
  39.     hwndTT = CreateWindow
  40.         (
  41.         TOOLTIPS_CLASS,
  42.         TEXT(""),
  43.         WS_POPUP | TTS_NOPREFIX | TTS_BALLOON | TTS_CLOSE,
  44.         CW_USEDEFAULT, CW_USEDEFAULT,
  45.         CW_USEDEFAULT, CW_USEDEFAULT,
  46.         hwndCtrl,
  47.         NULL,
  48.         NULL,
  49.         NULL
  50.         );
  51.     if (hwndTT == NULL)
  52.         goto Cleanup;
  53.  
  54.     // By using TTTOOLINFO_V1_SIZE rather than sizeof(TOOLINFO),
  55.     // we don’t require users to be using comctl32 version 6.
  56.     ti.cbSize = TTTOOLINFO_V1_SIZE;
  57.     ti.uFlags = TTF_TRACK;
  58.     ti.hwnd = hwndCtrl;
  59.     ti.lpszText = const_cast<lptstr>(szMsg);
  60.     if (!SendMessage(hwndTT, TTM_ADDTOOL, 0, (LPARAM) &amp;ti))
  61.         goto Cleanup;
  62.     if (!SendMessage(hwndTT, TTM_SETTITLE, GetTitleIcon(dwOpts),
  63.                      (LPARAM) szTitle))
  64.         goto Cleanup;
  65.  
  66.     // Position the tooltip below the control
  67.     if (!GetWindowRect(hwndCtrl, &amp;rc))
  68.         goto Cleanup;
  69.     SendMessage(hwndTT, TTM_TRACKPOSITION, 0,
  70.                 MAKELONG(rc.left + 10, rc.bottom));
  71.  
  72.     // Show the tooltip
  73.     if (!SendMessage(hwndTT, TTM_TRACKACTIVATE, TRUE, (LPARAM) &amp;ti))
  74.         goto Cleanup;
  75.  
  76.     hwndRet = hwndTT;
  77.     hwndTT = NULL;
  78.  
  79. Cleanup:
  80.     if (hwndTT != NULL)
  81.         ::DestroyWindow(hwndTT);
  82.  
  83.     return hwndRet;
  84. }

Update 2008-11-01 3:08PM: If you are targeting comctl32.dll version 6 or later, I recommend using the EM_SHOWBALLOONTIP message.  Comctl32.dll version 6 or later also automatically shows the caps lock warning balloon for edit boxes with the ES_PASSWORD window style.

WP Theme & Icons by N.Design Studio
Entries RSS Comments RSS Log in