09-06-2011 06:57 AM
I've been using a Picture Command Button with its label that overlaps the button, because I need also some text to clarify its function.
The well known problem is that the button doesn't change state when the user clicks over the label (i.e. the label is not "transparent" to mouse events).
In this thread I found a partial workaround by Luis, that works, but the user doesn't see the button in "pressed" state: the EVENT_COMMIT callback is executed, but the user hasn't any visual feedback from the button.
Is there a way to force the button in the "pressed" state when the user clicks over the callback?
Solved! Go to Solution.
09-07-2011 06:37 PM
Vix,
We could not come up with an ideal solution for this scenario. Unfortunately, there is not a way to configure the "pressed" state of the control. We can however post a message to the UI that will trigger the EVENT_COMMIT case. Include Windows.h and then use the following code in the control callback:
case EVENT_COMMIT: //EVENT_COMMIT functionality break; case EVENT_LEFT_CLICK: //get label size and position GetCtrlAttribute (panelHandle, PANEL_PICTUREBUTTON, ATTR_LABEL_TOP, &top); GetCtrlAttribute (panelHandle, PANEL_PICTUREBUTTON, ATTR_LABEL_LEFT, &left); GetCtrlAttribute (panelHandle, PANEL_PICTUREBUTTON, ATTR_LABEL_WIDTH, &width); GetCtrlAttribute (panelHandle, PANEL_PICTUREBUTTON, ATTR_LABEL_HEIGHT, &height); //check if left click occurred over label if (eventData1 >= top && eventData1 < top + height && eventData2 >= left && eventData2 < left + width) { SetActiveCtrl (panelHandle, PANEL_PICTUREBUTTON); //get window handle GetPanelAttribute (panelHandle, ATTR_SYSTEM_WINDOW_HANDLE, (intptr_t*)&hwnd); //hide label so that event will not occur over label SetCtrlAttribute(panelHandle, PANEL_PICTUREBUTTON, ATTR_LABEL_VISIBLE, 0); //generate commit event SendMessage(hwnd, WM_LBUTTONDOWN, 0, 0); //unhide label SetCtrlAttribute(panelHandle, PANEL_PICTUREBUTTON, ATTR_LABEL_VISIBLE, 1); } break;
The downside to this approach is that the label will be hidden so long as the mouse is down. I could not come up with a way to prevent this, which is why this solution is not ideal. However, it is the closest to the behavior you want that we could come up with.
Alternatively, another approach that may be a possibility is if you have access to the images that are on the buttons. If so, then you could actually embed the label text in the image. If that is a possibility, then that would avoid the need for all of these event workarounds.
09-08-2011 10:29 AM
The workaround you proposed sounds nice, but unfortunately the downside (label hidden as long as the mouse is down) is a problem fro me, so I can't use it.
Embed the labels into the images is not a solution for me, so I really hope there is another way...
I think that this need will be more common, because this is the behavior of the buttons in the MS Office 2010 ribbon bar (mostly of them have both an image and a label).
09-08-2011 06:11 PM
Vix,
I agree that those solutions are not exactly ideal. Let me take a look a bit deeper at some other solutions and maybe we can come up with something better. However, it is likely that this is simply a hard limitation of the control and there may not be a way to do this.
09-09-2011 01:32 AM
I hope that you can help me finding a better workaround, but in any case I think that a native "picture and text button" would be an useful improvement, so I posted a new product suggestion here.
Feel free to give kudos if you think it's a good idea
09-15-2011 04:58 PM
Vix,
Found a workaround. What we hadn't realized before is that the second click that we are generating is being caught as a EVENT_LEFT_DOUBLE_CLICK. With this knowledge, it is then very easy to implement this because we can now unhide the label in the EVENT_LEFT_DOUBLE_CLICK case. Check out the code below.
case EVENT_LEFT_CLICK: //get label size and position GetCtrlAttribute (panelHandle, PANEL_PICTUREBUTTON, ATTR_LABEL_TOP, &top); GetCtrlAttribute (panelHandle, PANEL_PICTUREBUTTON, ATTR_LABEL_LEFT, &left); GetCtrlAttribute (panelHandle, PANEL_PICTUREBUTTON, ATTR_LABEL_WIDTH, &width); GetCtrlAttribute (panelHandle, PANEL_PICTUREBUTTON, ATTR_LABEL_HEIGHT, &height); //check if left click occurred over label if (eventData1 >= top && eventData1 < top + height && eventData2 >= left && eventData2 < left + width) { SetActiveCtrl (panelHandle, PANEL_PICTUREBUTTON); //get window handle GetPanelAttribute (panelHandle, ATTR_SYSTEM_WINDOW_HANDLE, (intptr_t*)&hwnd); //hide label so that event will not occur over label SetCtrlAttribute(panelHandle, PANEL_PICTUREBUTTON, ATTR_LABEL_VISIBLE, 0); //generate commit event isFakeDouble = 1; SendMessage(hwnd, WM_LBUTTONDOWN, 0, 0); isFakeDouble = 0; } break; case EVENT_LEFT_DOUBLE_CLICK: if(isFakeDouble) SetCtrlAttribute(panelHandle, PANEL_PICTUREBUTTON, ATTR_LABEL_VISIBLE, 1); break;