I'm trying to understand the listbox notification LBN_SELCANCEL. MSDN says "Notifies the application that the user has canceled the selection in a list box." OK, but how exactly does a user "cancel the notification"? I've got LBS_NOTIFY set, and I've tried selecting another item, clicking outside the listbox, clicking another window, and none of these trigger LBN_SELCANCEL.
Anyone know what specifically triggers this notification?
I believe LBN_SELCANCEL only applies to ComboBox controls because they also use lists.
It should be called when you open the drop down hover over an element then press ESC.
Related
I want to log the messages of this menu using Spy++.
Usually, if I want to log the messages of a window, I would use Spy++ and drag the "Find Window" tool over it. But in this case, if I drag the tool over this menu, the menu disappears because I clicked outside it.
Is there any workaround to this?
A little more information:
What I want to achieve is finding out what messages are sent when I click the menu's items (they are buttons).
That particular menu in the first picture is created only when I click the button, and it has a different HWND every time I click it.
If I can't accomplish this in Spy++, can I do this using some other application similar to Spy++?
Actually I figured it out myself.
You can just log messages of the parent window with the logging options set to also log messages of child windows.
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
I've stumbled into a problem with drag and drop.
I've got a REPORT style of my list view.
First thing to think of is catching the LVN_BEGINDRAG message, but I was unable to catch it in the parent window procedure. I went to MSDN and figured out that REPORT style doesn't support this notification because other styles had some mentioning of d'n'd in their description and report style didn't have one.
So I went the other path - handling NM_CLICK notification, but actually it's not perfect for the situation. The problem is that if i want to drag the already selected item, and click on it and hold the button, then no notification comes until I stop pressing the button.
I've also tried subclassing listview to catch LVM_LBUTTONDOWN to get 100% drag enter before any other calculations happen inside of a window proc, but it doesnt' do the job also; or maybe I've done some bad work subclassing the list view. Anyways. I need advice how to do it properly.
My target drag and drop zone is a treeview control actually.
Thanks
Calling SendInput to simulate pressing down left click appears to be executed after code written below said call to SendInput is executed.
I made a listbox and I want right click to select items from the list box so I decided to make the message WM_CONTEXTMENU call SendInput to simulate a left click immediately before opening a context menu, but I believe the context menu is popping up before the left click occurs, resulting in the left click clicking the edge of the context menu (which does nothing).
Adding MessageBox(0,0,0,0); right in between the call to SendInput and the creation of the popup menu results in the left click successfully occurring and selecting an item, this is the behaviour I expected and desire. Strangely calling Sleep(1000) after the call to SendInput delays the program but doesn't cause the SendInput to behave as expected.
EDIT: Yes I know one solution to my problem is to select it using LB_SETSEL, but I'm partially doing this for learning purposes and if I run into a similar problem using SendInput I want to know how to solve it, so please help me resolve this specific bug.
SendInput() merely injects keystrokes into the keyboard's input buffer and then exits immediately, letting your app do other things while Windows handles the keystrokes in the background as if the user had typed them manually. That is not the solution to your problem.
In your WM_CONTEXTMENU handler, simply send a LB_SETCURSEL message (for a single-select ListBox) or a LB_SETSEL message (for a multi-select ListBox) directly to the ListBox's HWND to select the desired list item(s) before then displaying your popup menu.
I currently have some toolbar buttons with a small arrow on the side (TBSTYLE_EX_DRAWDDARROWS) that, when clicked, result in a popup context menu being displayed under the button. This is done by constructing a custom popup menu and calling TrackPopupMenu.
The client now wants to be able to select multiple options from the menu before it closes, so that multiple options can be be modified without the need to re-open the menu and wait for an intermediate redraw between each change.
For example:
User clicks dropdown button
Dropdown menu appears (modal, waits indefinitely for user action)
User clicks some item (e.g., toggle a checkmark)
Timer (e.g., 500ms) starts
If timer expires, the menu is closed and all selected actions are executed.
User clicks another item before the timer expires, go back to 4.
The best I can come up with is to redisplay the menu by calling TrackPopupMenu multiple times. This makes the menu "flicker" when you select an item, and will probably require me to start a thread in order to do the timeouts, which I would rather avoid.
Rather than a menu, put up a dialog box with the options on it. A dialog can easily do all that is required.
A menu that doesn't close when you click it will just seem wrong. A dialog that closes by itself will seem wrong too, but it's probably the least of two evils.
Edit: If there's anything I've learned with Microsoft, it's don't try to fight the default behavior. You're asking for trouble if you do.
If you're building your menu dynamically I can see how automatic sizing can be handy, but it's not hard to do in a dialog either - make the dialog really big and before it becomes visible, enumerate the children and take a union of all their rectangles, then resize to that. Checking the boundaries to make sure they're on-screen is just a few if statements with OffsetRect. Checkboxes are trivial; icons less so, but still not bad.
One additional enhancement that would be easy to add is to dismiss the dialog immediately on a double-click.
Following #Mark Ransom's answer, you should put up a dialog box. But you can make the dialog modeless and make it close itself when you click outside of it (i.e., the dialog loses focus). That way it could behave more like a menu.
Notice that normal menus never go away by themselves, you always have to click somewhere outside the menu (or one of its options) to make it disappear.