What is the correct way to select a button in WinAPI so that the button or item has input focus indicated by the dotted lines? If i just set focus it is not selected. An example: I select an item index in a combobox via CB_SETSEL, how to select the complete item (dotted line, blue background)?
Thank you very much!!
In a dialog, you should use the DM_SETDEFID message to make a push button the default. Simply calling SetFocus will give focus to a button (the "dotted lines") but won't make it the default button (the one that's actioned by pressing the Return key). For example,
SendMessage(hwndDlg, DM_SETDEFID, IDC_BUTTON, 0);
For other types of controls, SetFocus is all you need, e.g:
SetFocus(GetDlgItem(hwndDlg, IDC_COMBO));
The 'blue background' indicates the cell or list item is selected. The 'dotted line' indicates that the cell or list item has the focus. These are two different things that require two different method calls or messages. In the style you are using, you have to send the CB_SETCURSEL message also.
http://www.jasinskionline.com/windowsapi/ref/c/cb_setcursel.html
Related
I've got two little questions at Visual Studio MFC-GUI programming technique regarding the handling of a group of radio buttons in VS2015 CE.
I have a little dialog based application. This application draws some lines on my dialog with a specified pen.
Now I made a group of radio buttons to be able do use different colors for the pen. So I created a group box, placed the radio buttons into this group box, enabled the group property of the first radio button and checked the tab sequence so that all of the radio buttons are properly in sequence.
That's ok - testing the GUI I'm able to select just one of the radio button as planned, because I wouldn't be able to draw a line in to different colors at the same time. Now I added an handler for the BN_CLICKED Message of the first radio button object in the ClassWizard to add the selection of different colored pens.
Now comes the interesting part. This handler is executed only when i click the first radio button. The one with group property enabled. I thought it should be executed whenever I click any of the radio buttons in this group. The next thing I tried was to add an BN_CLICKED-Messagehandler to all of those radio buttons, but the ClassWizard does not shows the BN_CLICKED Message for the other radio buttons - only for the one with group proerty enabled.
After googling around I read a post that one would be able to add an BN_CLICKED-Messagehandler for an button by simply double clicking it in the Dialog. So I double clicked all of my radio buttons and added an invocation of the BN_CLICKED-Messagehandler of the first radio button. That's working as a workaround so that now my line is drawn in the different colors whenever I click on any of those radio buttons (black, blue, red , and so on).
I have two questions - is this behaviour intended? I suppose the reason why I'm only able to add a BN_CLICKED-Messagehandler in the ClassWizard for the first radio button is, that it would be invoked by any of the radio buttons in my group, wouldn't it?
Another question is, I would have preferred to write the handler once and be able to tell the class wizard to use this particular handler instead of creating a unique handler for each of the buttons. That's independent of this radio buttons. I tested this with a simple application which consists of an assembly of several buttons - which can have their own BN_CLICKED-Messagehandlers attached by the class wizard. When I didn't accept the automatically generated functionname from the wizard and enter the name of my own handlerfunction it simply states that it wouldn't be able to overwrite it. How can I select an existing handler for an object message in the class wizard or is that not possible and I have to do this manually in code for myself?
Hope there's an VS2015 MFC Guy out there be able to tell me ..
This is indeed by design. You could have wanted different behaviour for each button click - if you don;t simply associate all of the BN_CLICKED to the same message handler and delete the ones that were automatically generated.
You can also use ON_CONTROL_RANGE(BN_CLICKED, id1, id2, memberFxn ) - make sure your buttons are in the same range in your resource.h
Hope that helps!
My CListCtrl (Report View, single column) ignores item selection when there's another control behind the CListCtrl. It's as if the click passes through to the control BEHIND the CListCtrl.
Selection is fine if the list item isn't on top of another dialog-box item.
It's baffling because the CListCtrl's z order is ABOVE these other controls. Can anyone suggest something I could try to make the CListCtrl accept a click even when there's another overlapped control? Thanks!
User Spy++ to check the message flow. And to check if another control is above your control! Maybe there is something wrong with you´r z-order even if you think that the control is above. Also check if you overwrote WM_NCHITTEST
If I have a listview control in report mode, how could I stick a syslink control into one of the columns?
I want to have a link the user can click in one of the columns.
The listview control doesn't support this itself.
You could create a real Syslink control that's a child of the listview. You would need to sub-class the listview and reposition the Syslink control whenever the list scrolls (watch for WM_HSCROLL / WM_VSCROLL messages) or when items are added or removed, or when it's sorted. You can use LVM_GETSUBITEMRECT to find out where to position it.
Alternatively, you could handle it yourself by using NM_CUSTOMDRAW to display the "link" in a different color, and handle NM_CLICK to catch when the user clicks on the link. This would be the simplest method in my opinion. Note that if you want a hand cursor to be displayed over the link you would still need to sub-class the list and handle WM_SETCURSOR yourself.
I have a dialog box (CDialog) with owner-drawn CTabCtrl in it. Tabs content are child dialogs (one for each tab). There is an CEdit in each tab. When the user clicks a tab, I'm hiding all child dialogs using ShowWindow(SW_HIDE) and showing a selected one.
The problem is that when I have, for example, two tabs, click inside an edit box in the first tab and then switch to second, input focus stays on that (invisible) edit box in the first tab no matter what I do in my code (tried calling all methods that potentially can set focus, nothing changed).
Try this:
GetDlgItem(IDC_YOURCONTROL)->SetFocus();
Or the related variable linked with the control:
m_YOURCONTROLControl.SetFocus();
I have a windows gui built in Microsoft Visual C++ and when the user performs a certain set of actions the keyboard tabbing to move from widget to widget stops working.
Simply put, there are two list boxes with an add and a remove buttons. Selecting a row in listbox #1 and pressing the add button removes the object from list box #1 and moves it to list box #2. The problem I am seeing is that the keyboard tabbing functionality goes away since the tab focus was on the add button which become desensitized when the add callback is completed (since no row in list box #1 is selected currently).
I want to be able to re-set the tab focus to listbox #1 (but not the selection of a particular row). Any ways to do this? I believe I am running as a standard modal dialog.
If I understand correctly, you just want to set the focus back to one of the listboxes. Since this is in a dialog, instead of calling SetFocus, The Old New Thing recommends you send a message to the listbox's hWnd to do this:
void SetDialogFocus(HWND hdlg, HWND hwndControl)
{
SendMessage(hdlg, WM_NEXTDLGCTL, (WPARAM)hwndControl, TRUE);
}