1

I have been trying for a very long time (well a few days) to create a toggle button. A button having a up or down state.

Took over a day to realize it is not possible to create an owner drawn toggle button, a checkbox and pushlike does not work. When using owner drawn there is no difference between a checkbox or regular button (MSDN also notes you cant use owner drawn with any of those styles.)

From reading I found out you have to do it yourself, normally not a problem at all, but I cannot get any real "responsiveness." That is, if I click fast, nothing happens, sometimes I will click and it changes states, other times not and only updates when I click a different button.

I created a global variable for if the button should be shown in up or down state. In the commands I have it set that when the button, IDC_BTN_TOGGLE, it will set the opposite value on the bool.

Then the draw item part:

// button down
if ((pDIS->itemState & ODS_SELECTED) || showButtonDown) { 
    oldBrush = (HBRUSH)SelectObject(pDIS->hDC, theme.hBrush[BRUSH_BUTTON2]);
}
// button up
else {
    oldBrush = (HBRUSH)SelectObject(pDIS->hDC, theme.hBrush[BRUSH_BUTTON]);
}

All my buttons are owner drawn and run through this. showButtonDown is only true when it is drawing IDC_BTN_TOGGLE and the top bool is true as well.

The normal buttons function normally, when I click them, it instantly shows the down state, release, back to normal, the toggle button is barely responsive.

enter image description here

Community
  • 1
  • 1
Evan Carslake
  • 2,267
  • 15
  • 38
  • 56
  • Does testing for `ODS_CHECKED` instead of `ODS_SELECTED` help? – Jonathan Potter Sep 11 '13 at 20:25
  • Nope, it for sure doesn't work when I used owner drawn. When testing, ODS_CHECKED and ODS_SELECTED both trigger, even with a normal push button. – Evan Carslake Sep 11 '13 at 21:03
  • Since you're doing the drawing it's fundamentally you who have control over what the button looks like, so the question is what state/inputs do you need to respond to. I'd start by printing out the state values you are seeing in your `WM_DRAWITEM` handler and see if you can establish a pattern. – Jonathan Potter Sep 11 '13 at 21:04
  • MSDN says that if you owner draw, any button control will only behave as a button control. I added this to my draw item: TESTINT(pDIS->itemState); The result for each button is: 0, 0, 16. That is the owner drawn button, and owner drawn checkbox. I have no idea why 3 integers are returned per 1 button drawn... No matter the configuration, the result is the same. I have it setup so that when clicking the button, there is a bool set to true, then when drawing the buttons I check the bool for how to display it. It doesn't update the button, I have to click a different button to update the other – Evan Carslake Sep 11 '13 at 21:21
  • 3
    I'm finding it hard to be more helpful without seeing more of the code, but do you just need to force the button to redraw (`InvalidateRect()`) after toggling your flag? – Jonathan Potter Sep 11 '13 at 21:24
  • InvalidateRect(GetDlgItem(hwnd, IDC_BTN_HOTKEYS), NULL, TRUE); That was exactly what I was looking for. At first I was thinking that it would generate flicker so I never tried it. Thanks. – Evan Carslake Sep 11 '13 at 21:34
  • Have you tried using RedrawWindow after using SelectObject? – João Marcelo Brito Sep 17 '13 at 00:44

0 Answers0