I'm trying to use GetFocus() on a ComboBox control in a dialog box, but for some reason it isn't working.
Even if I set focus with the SetFocus() function it doesn't work, but it looks like it has keyboard focus.
SetFocus(hKeysComboBox);
if (GetFocus() == hKeysComboBox) // This is false
Maybe because it's in a dialog box? I don't know, this seems so simple.
Is this an editable combo? Those actually contain a child Edit control, and when you focus the combo, the combo in turn focuses the child edit control (so that it can receive manage the keyboard input). You can use Spy++ to see this parent/child structure.
So to check if the combo has focus, you could check if the parent of GetFocus is the Combo.
if (VC++)
{
use `tag order` property;
}
else
{
use WM_NEXTDLGCTL with SendMessage;
}
See How to set focus in a dialog box for details.
Related
I'm working on my first simple MFC project, but I'm struggling with one problem: want to set the focus of all CEdit boxes in one of the dialogs. My idea is when open the dialog, the focus to be on the first edit box and then to swap between them with 'tab'.
I saw the method SetFocus(), but I couldn't apply it correctly. Also I couldn't find a solution for implementing the order of the focus with a specific key.
Thanks in advance to everybody who takes time to help me!
You can set the focus to a given control when your dialog box is first shown by calling SetFocus in your OnInitDialog() function. However, if you do so, your OnInitDialog() must return FALSE:
BOOL MyDialog::OnInitDialog() {
CDialog::OnInitDialog(); // Call base class member
GetDlgItem(IDC_MYEDIT)->SetFocus();
//..
return FALSE; // Otherwise, the framework will reset the focus to its default
}
From the M/S documentation:
Return Value
Specifies whether the application has set the input focus to one of
the controls in the dialog box. If OnInitDialog returns nonzero,
Windows sets the input focus to the default location, the first
control in the dialog box. The application can return 0 only if it has
explicitly set the input focus to one of the controls in the dialog
box.
Fig1:
Fig2:
As in Fig1, after I clicked radio button, the radio button seems not get correctly painted, seems 50% transparent.
As in Fig2, after I move my mouse to hover the radio button again, it got correctly painted.
I have no idea about what is going on behind.
What are the possible reasons?
By the way, after I pressed a shortcut key PrtSc to get a screenshot(a freeware: Greeshot), this problem disappeared.
One hint I just found is: the dialog holding the radios were in modeless mode. The problem disappeared after I showed it as a modal dialog.
Actually, to achieve below goals, I am implementing the message pump for this dialog. Perhaps I am doing something wrong in the message pump logic. Continue to check the pump.
My Goal: user can interact with other windows while showing this dialog, one exception is: user should not be able to interact with the parent dialog of this dialog in question, so that database transaction may be issued prematurally.
I used to have a similar problem within wxWidgets. Turns out it's a long lasting bug that really never had been fixed. I now use a workaround with a simple wrapper function that 'enables' the element (places focus on it) and then 'unfocuses' it. Not sure in your current setup.
As a result, it seems I did something wrong in the message pump for the dialog in question.
I am implementing the message pump for this dialog.
To avoid user interact with the parent dialog of the dialog in question, I was ignoring message for the parent dialog and to children of parent dialog.
After I changed the above logic to below, the problem got solved.
EnableWindow(hParent, FALSE);
EnableWindow(hParent, TRUE);
So, I think I was doing something wrong in ignoring message, not sure exactly where.
I am developing an application using the MFC library and I am currently trying to prevent the user accidentally changing one of the combo box controls when they are scrolling the mouse wheel.
I am looking for a solution without deriving a new class from the CComboBox class and preventing the mouse scrolling there.
My understanding of the system is that Windows passes the WM_MOUSEWHEEL message to the Combo box control which handles it (scrolling the combo box) and then this is propagated up the chain of parent controls (so them to my CFormView etc.), which means I cannot prevent the scrolling by capturing the event in my form view.
Does anyone have a solution to this problem? Thanks in advance!
You can always derive a control from CComboBox and trap the WM_MOUSEWHEEL message in the control itself. Then simply use your new derived combo box in your form view.
If you don't want to create a derived class (perhaps it's too big a change for your project), you can subclass the combo box and trap the WM_MOUSEWHEEL there.
Override the PreTranslateMessage handler in the main window class and look for WM_MOUSEWHEEL messages. Compare the pMsg->hwnd handle in PreTranslateMessage handler with the combobox handle, if found, filter the messages away.
If I click anywhere on the dialog window, like in the "background", or on a Static Text, the function OnLButtonDown() is fired. But if I click a ListBox/EditBox/Combo/Calendar/Checkbox etc is not fired.
I thought that because these have control variables atached to it, and the Static Text don't. But adding a new Listbox to my Dialog and testing, I see that it doesn't fire either, so now I am confused...
I added OnLButtonDown() with the Class Wizard, it appears in:
BEGIN_MESSAGE_MAP(CMFCTesting2Dlg, CDialogEx)
ON_WM_SYSCOMMAND()
// other handlers, etc
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
END_MESSAGE_MAP()
My function:
void CMFCTesting2Dlg::OnLButtonDown(UINT nFlags, CPoint point)
{
AfxMessageBox(CString("BUTTON DOWN"));
CDialogEx::OnLButtonDown(nFlags, point);
}
I tried calling CDialogEx:: ... before AfxMessageBox... but same result.
The CListBox item, has the Notify option set to True, as I seen some advices in other posts.
I suspect that the WM notification message is captured somehow by the ListBox, and not sent "forward" to my CMFCTesting2Dlg, but I understood that this should happen with the Notify option set to True, on the ListBox, no? (well, obviously, not...)
Sorry, I am new to dealing with WM in MFC.
BTW, I use Visual Studio 2010 Ultimate, and this is a Visual C++ - MFC- MFC Application - Dialog Based project.
How can I capture this mouse down event if clicked on a listbox / combo / etc?
On the LONG STORY, I am actually trying to accomplish this issue:
I have two listboxes (lets say), and I want to scroll them synchronously, when user scrolls one of them, others must scroll the same (or update in the next moment). And I thought of using on mouse down to track the position of every Listbox (with the GetTopIndex), and on mouse up, to GetTopIndex again and compare with the previous ones. If a change was made, then a listbox was scrolled and then update all listboxes with SetTopIndex. The unfriendly solution for the user, but simpler for me, would be clicking a button that does this verification / update, but its not elegant at all, and it can only set them at the same level, but can't determine which one was scrolled last time. This automatically scrolling of the listboxes should be made just for displaying, it is not important the selections in the listboxes. I tried using the Message Type in the Add Event Handler for the Listbox, but none that are displayed work for my problem, KillFocus and SetFocus, are not fired if the scroll-bar is dragged, only if an item in the listbox is clicked... and I didn't succeed on the others message type either, from the Add Event Handler.
Once a window handles a message, it stops being sent to the other windows beneath it. A static window doesn't handle a mouse down, so it goes to the dialog. The other controls all handle it in some fashion (setting focus at least) so it never gets to the dialog.
You can override the OnLButtonDown handler in each of the controls to do something else once they've finished their default handling in the base class. You might also get to see the message in the PreTranslateMessage method of the dialog.
As far as getting the List Controls to sync scrolling goes, your best bet would be to intercept WM_VSCROLL by subclassing CListCtrl or perhaps by PreTranslateMessage, and then calling SetScrollInfo on the other list. If the number of items in the lists are the same, it should be fairly simple.
I am having a button in main dialog,if I click that,pop up dialog box will be opened.Now,I should stop creation of so many pop up dialog boxes when I click that button.So,I need to check whether the child window is opened already.Help me,how to get the handle of child window?
I'm not sure if this is something that you would want in your program but surely give it a try. May be once your work is done with the first pop up dialog box, add another button, name is "Close" in your popup box that would allow it close it and in the Event Handler for it, just type OnOK().
void CMyDlg::OnClose()
{
CDialog::OnOK();
}
..
Hope this helps.