Display control buttons on your taskbar preview window


Today's "Little Program" displays a button on the taskbar preview window. For now, the button increments a number, because incrementing numbers is so retro.

Welcome, visitor number  0 0 3 1 4

Start with the program from last week and make these changes:

int g_iCounter;

void
PaintContent(HWND hwnd, PAINTSTRUCT *pps)
{
  RECT rc;
  GetClientRect(hwnd, &rc);
  LOGFONTW lf = { 0 };
  lf.lfHeight = rc.bottom - rc.top;
  wcscpy_s(lf.lfFaceName, L"Verdana");
  HFONT hf = CreateFontIndirectW(&lf);
  HFONT hfPrev = SelectFont(pps->hdc, hf);
  wchar_t wszCount[80];
  swprintf_s(wszCount, L"%d", g_iCounter);
  DrawTextW(pps->hdc, wszCount, -1, &rc,
            DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  SelectFont(pps->hdc, hfPrev);
  DeleteObject(hf);
}

That's an awful lot of typing just to print a big number on the screen.

#define IDC_INCREMENT 100

void CreateThumbBarButtons(HWND hwnd)
{
  THUMBBUTTON rgtb[1];
  rgtb[0].iId = IDC_INCREMENT;
  rgtb[0].hIcon = g_hicoAlert;
  rgtb[0].dwFlags = THBF_ENABLED;
  rgtb[0].dwMask = THB_ICON | THB_TOOLTIP | THB_FLAGS;
  wcscpy_s(rgtb[0].szTip, L"Increment the value");
  ITaskbarList3Ptr sptb3;
  sptb3.CreateInstance(CLSID_TaskbarList);
  sptb3->ThumbBarAddButtons(hwnd, 1, rgtb);
}

We define only one thumbbar button, and out of laziness, I just reuse that alert icon.

void OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{
  switch (id) {
  case IDC_INCREMENT:
    ++g_iCounter;
    InvalidateRect(hwnd, nullptr, TRUE);
    break;
  }
}

When the button is pressed, we increment the counter and invalidate our window so we redraw with the new counter.

    // HANDLE_MSG(hwnd, WM_CHAR, OnChar);
    HANDLE_MSG(hwnd, WM_COMMAND, OnCommand);

    default:
      if (uiMsg != 0 && uiMsg == g_wmTaskbarButtonCreated) {
        CreateThumbBarButtons(hwnd);
      }
      break;

Okay, run the program, and then hover over the taskbar button so that the preview window appears. Hey, look, there's an alert icon button under the thumbnail.

Click it.

Boom, the number increments.

That's why I chose a huge font to draw the number: So it's big enough that you can see the number in the thumbnail.

Comments (15)
  1. This line looks a little suspicious:

    lf.lfHeight = rc.bottom – rc.top;

  2. Ah, here we go

    msdn.microsoft.com/…/aa911419.aspx

       < 0: The font mapper transforms this value into device units [pixels] and matches its absolute value against the character height of the available fonts.

    I believe you want to match the character height against the device units of the window, so rc.top – rc.bottom (though negative) is going to give a better fit.

  3. No, I'm wrong. You want to match the cell height, not the character height (which is smaller) so your code is correct.

  4. Jonathan says:

    Nice counter. BTW, Google Reader was visitor #00314.

  5. John Doe says:

    @Jonathan, nope, that's the counter's initial contents literally: 00314. Take a look at the actual transferred original page.

  6. anyfoo says:

    I like how you used that fantasy font and a totally mismatched formatting for the numbers, to reinforce that retro feeling!

  7. John Doe says:

    IE8 and below also display 00314, they don't support Date.now().

  8. Ben says:

    The CreateThumbBarButtons function needs this line to make the button's tooltip and icon appear consistently (as it is, it's filled with random bits that might or might not have the right flags set):

    rgtb[0].dwMask = THB_ICON | THB_TOOLTIP | THB_FLAGS;

    [Thanks! Fixed. -Raymond]
  9. Azarien says:

    @Ben: aah, thanks. I was wondering why I don't see the icon.

  10. Neil says:

    @John Doe: Whereas Gecko didn't copy the non-standard innerText property, so Firefox users see 00314 too…

    [Fixed. -Raymond]
  11. Neil says:

    Thanks for fixing the innerText, although (given that Date.now() limits you to IE9 anyway) you could probably have used textContent rather than innerHTML in this case.

    [I'll remember that for next time, if there is a next time. -Raymond]
  12. Medinoc says:

    I don't understand. My progam never seems to receive the TaskbarButtonCreated message (nor any other Register'd message)… And I'm on Windows 7.

    [Methinks the fault, dear Brutus, is not in the stars. -Raymond]
  13. Medinoc says:

    Well, I think people deserve to know the end of the story: Problems (message not received, button not sending the command) occur when running the application as an administrator. Or doing so accidentally, by launching it from a Visual Studio launched as Administrator.

    I guess the taskbar runs within the shell, which doesn't run as administrator, therefore UAC blocks its messages to the application.

  14. Joshua says:

    [Methinks the fault, dear Brutus, is not in the stars. -Raymond]

    Methinks the Raymond is well-read.

  15. To complete the quote:

    The fault, dear Brutus, is not in our stars/But in ourselves

Comments are closed.

Skip to main content