WinAPI Toolbar Control: Increase Width of Drop Down Chevron - winapi

Ist is possible to extend the width of the dropdown button for a Toolbarctrl button with BTNS_DROPDOWN style?
Reason: for this particular button, there is a default action (basically "use the same device as before") executed immediately, which is likely over 95% of all clicks. The dropdown allows to select another device to work with.
Aiming for the chevron but clicking the default action instead by accident is a little dangerous however.
I want to avoid separate "use prev device" / "select other device" buttons, as this seems clumsy.
The actual control is an MFC CToolbar / CToolbarCtrl, I'm happy with a WinAPI or a MFC answer. (that's why the two tags) - but I assume there's little difference.

Related

WS_GROUP, any secret protocol between dialogbox-manager-WndProc and standard control?

I'm reading Charles Petzold Programming Windows 5th-ed, Chapter 11, "Tabs Stops and Groups" section. I have a big question now.
The book says, when some controls belong to the same group, you can use left/right arrow key to switch focus between them, and this feature is used most often with a group of radio boxes. But what about other type of controls?
I tried having 3 button controls grouped together(A,B,C, only A has WS_GROUP, B and C don't). Then, I can confirm left/right arrow can switch focus between A,B and C.
Observing it more carefully, I see difference between radio box and button [P1]:
For a radio box group, pressing left/right-arrow repeatedly will cycle focus among all radio boxes in that group.
For button group, pressing right-arrow repeatedly will have focus move and stop at button C, the same left-arrow has it stop at A, no cycle behavior.
The case for "edit" control [P2]: If I make 3 edit boxes in one group, pressing left/right-arrow will NEVER switch the focus, which is not the same behavior as a button group.
So, my question boils down to: Does windows internal dialog box mananger WndProc (just call it DefDlgProc) treats some type of controls specially(like "edit")? For example, if DefDlgProc finds that a WM_KEYDOWN message with VK_RIGHT is destined for a "edit" control, it will never take the focus-switch action but pass the message to "edit" control honestly.
Is that special treatment done in a hard-coded way or some generic, configurable way? I need to know it because, if I write my own custom editbox control, I need a way to have DefDlgProc treat arrow keys specially for my control, right?
Sample code: For the 3-edit experiment, I use .rc statement like this:
ABOUTBOX DIALOGEX 32, 32, 180, 100
STYLE DS_MODALFRAME | WS_POPUP
EXSTYLE WS_EX_STATICEDGE
FONT 8, "Tahoma"
BEGIN
EDITTEXT IDC_EDIT0,40,7,40,14, ES_AUTOHSCROLL| WS_GROUP ,WS_EX_CLIENTEDGE
EDITTEXT IDC_EDIT1,90,7,40,14, ES_AUTOHSCROLL ,WS_EX_CLIENTEDGE
EDITTEXT IDC_EDIT2,133,7,40,14,ES_AUTOHSCROLL
CONTROL "OOKK",IDOK,"EllipPush",WS_GROUP | WS_TABSTOP,7,63,166, 30
ICON "ABOUT3",IDC_STATIC,7,7,20,20
END
Doing my experiment on Windows 7.
Your question doesn't quite make sense. You wouldn't expect pressing the left or right cursor key in an edit control to shift the focus to another control, because the edit control itself consumes that keypress in order to move the cursor around.
Internally the dialog manager uses GetNextDlgGroupItem() to shift the focus to the next or previous control in the group. This doesn't distinguish between control types - it only looks at the WS_GROUP style. However, the dialog manager only calls this function if the control itself doesn't consume the key, and this is determined by the control's response to the WM_GETDLGCODE message.

X11: input focus for popups

For some fun and self-education, I'm tinkering with writing my own X11 toolkit. Here's something that's stumping me.
I have a traditional combo box display element, a typical combo box with a dropdown popup list, like all popular toolkits have.
For the dropdown popup list, I'm creating a new window, a child of the root window, appropriately positioned below the main combo-box display element.
The dropdown popup list is a window in its own full right, that implements keyboard-based navigation, to select the individual entries in the dropdown list.
So, I'm using SetInputFocus to set the input focus to the popup after it opens.
What I find is that when I do that, the window manager then redraws the frame of the main window to indicate that it no longer has input focus. Which is technically true, but I don't see the same results with the more mainstream toolkits, where, in the comparable situation, the main window's frame shows that it still has input focus.
For the pop-up window, in addition to setting override-redirect, I'm also doing everything I can think of, to tell the window manager what's going on: setting the window group leader ID in the popup window's WM_HINTS, setting WM_TRANSIENT_FOR, and setting _NET_WM_WINDOW_TYPE to _NET_WM_WINDOW_TYPE_COMBO; none of that seems to work (I verified that the properties are approriately set, via xprop).
It seems like I have to keep the input focus in the combo box window, and forward keypress and keyrelease events to the display elements in the dropdown popup, which feels clunky. Am I overlooking some property that would tell the window manager that the popup's input focus is linked to the main window's (besides the ones that I've mentioned), that would keep the main window's frame drawn to show that it has input focus, when the input focus is actually in the popup?
Most X11 override-redirect exclusive popup windows (menus, combo boxes, ...) grab the keyboard and/or pointer with either passive or active grab.
See XGrabKey, XGrabKeyboard, XGrabButton, XGrabPointer in the X11 programming manual.
Or maybe don't, because the manual is totally unclear about what the heck these functions are and how they can be used. Search the interwebs for usage examples, probably in other widget libraries. Unfortunately I don't know of a simple informative example offhand.
It is not necessary to call XSetInputFocus at all because all keyboard and/or pointer events are reported to the grabbing clients.

Standard placement order for common buttons

I know that in Microsoft Windows, OK/Cancel buttons normally appear in this respective order. On the other hand, in Linux distros, I often saw Cancel/OK instead.
What about (Yes/No), (Yes/No/Cancel), (Add/Edit/Remove) and other common buttons?
Is there any standard placement order for these?
From the Microsoft Windows User Experience Interaction Guidelines:
Right-align commit buttons in a single row across the bottom of the
dialog box, but above the footnote area. Do this even if there is a
single commit button (such as OK).
Present the commit buttons in the following order:
OK/[Do it]/Yes
[Don't do it]/No
Cancel
Apply (if present)
Help (if present)
From the Apple Human Interface Guidelines:
The buttons at the bottom right of a dialog all dismiss the dialog. A
button that initiates an action is furthest to the right. This action
button confirms the alert message text. The Cancel button is to the
left of this button.
If there’s a third button for dismissing the dialog, it should go to
the left of the Cancel button. If the third button could result in
data loss—Don’t Save, for example—position it at least 24 pixels away
from the “safe” buttons (Cancel and Save, for example).
A button that affects the contents of the dialog itself, such as
Reset, should have its left edge aligned with the main dialog text or
if there is a Help button, 12 pixels to the right of it.
From the Java Look and Feel Design Guidelines:
If a dialog box has a default button, make it the first command button
in the group. For example, in languages that read from left to right,
the default button is the leftmost button.
Some of the above conflict with one another. You may also find that the advice conflicts with the vendors own applications. However, I would follow the guidelines for your operating system of choice and stick with them. At least that way you have consistancy within your own output and hopefully the vast majority of other apps on your platform.
Microsoft recommends one, Apple another.
Survey here shows 50/50 split:
http://measuringuserexperience.com/SubmitCancel/index.htm
This page has also links to official UI guidelines, which answer your question for some OSes.

Windows CWnd::OnLButtonDown not called as expected on double click

I'm developing an interactive MFC application which displays a 3D object using my own algorithm, essentially using MFC as a framework, but using lots of pDC->Polygon(), pDC->Rectangle(), pDC->DrawText(), etc. calls.
The UI has numerous clickable areas which all work well. However, the onscreen controls for rotating, spinning, etc. the 3D image motivate users to double click, triple click, and beyond.
I'm 99% positive that CWnd::OnLButtonDown() is not called until Windows (or whatever) has decided the operation is not a double click, or when double clicked, but only once. That is a series of clicks results in a notification every second click. The user experience is stuttered rotation. The temporary workaround is to have users move the mouse slightly between clicks—It solves the problem, but is rather unfriendly.
The application does no double click event hooking. Maybe there's a way to go further to disable potential double click processing? Or maybe there is a lower-level way to capture the mouse button down?
I think you have it backwards - the first click gets through as a WM_LBUTTONDOWN, the second one gets turned into a double-click.
To prevent a window from generating WM_LBUTTONDBLCLK messages, remove the CS_DBLCLKS style from the window.
This is all explained in the WM_LBUTTONDBLCLK documentation.
Edit: I misspoke, CS_DBLCLKS is a class style, not a window style. I don't think you can remove it, you have to create a new window class that doesn't include it. It's provided by MFC - see this page http://msdn.microsoft.com/en-us/library/a77269ff(VS.80).aspx.
Just to add an answer, this method worked for me:
WORD dwStyle = GetClassLongPtr(handle, GCL_STYLE);
dwStyle &= ~CS_DBLCLKS;
SetClassLongPtr(handle, GCL_STYLE, dwStyle);
You can use these functions to edit a WNDCLASSEX style structure for an specific window removing the double click event and correcting the single click behavior.
GetClassLongPtr
SetClassLongPtr

Setting the width of a menu in the Windows API

I'm creating a custom control in wxWidgets that displays a menu as part of it, and currently working on the Windows side of things. wxWidgets doesn't have a way of setting the width of a menu. It just makes the window as wide as the longest string plus a few pixels on either side.
In the API, there is a way to get the actual Windows API menu handle. Does the Windows API have a method of setting the width of a menu other than just calculating it on its own based on the width of the string?
With the handle of the menu, you can cycle through the menu items and call SetMenuItemInfo, indicating that you want to owner-draw the menu items. When you do this, the window that the menu is attached to will receive the WM_MEASUREITEM message, which you would then respond to by setting the dimensions required for the menu. It is here you can set your width.
Of course, this means you have to subclass the windows message handler for the window that contains the menu.
First of all, try to obtain the HWND to the menu:
(1) WM_DRAWITEM (2)get the HDC (3)WindowFromDC(),
then you can arbitrarily adjust aspects of the menu.
NOTE: don't send WM_QUIT WM_CLOSE to the menu, or you'll effectively shut down your computer with no clue.

Resources