I'm currently experiencing a very strange problem with a CComboBox used within a CFormView.
After adding strings to the combobox (created with WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWN | CBS_SORT | CBS_AUTOHSCROLL), I'm selecting an entry via CComboBox::SetCurSel and resize the combobox via MoveWindow in the OnSize() handler of the CFormView derived class.
As soon as I include the call to MoveWindow, the whole text in the edit part of the combobox gets selected. If I remove the call to MoveWindow, the text doesn't get selected. This happens not only for one, but for all comboboxes used.
I'm somehow lost at this point. Any hint is much appreciated!
Selecting all the text is standard Windows behavior when a combo box gets focus. I guess the MoveWindow is resetting the focus on the control.
Try using CComboBox::SetEditSel to remove the selection after MoveWindow.
Related
So my dilemma comes from making a UI in C++ with the windows API. I need to have an EDITTEXT box which allows for scrolling but doesn't allow the user to edit the text that gets displayed in the box. So far, it looks like this.
EDITTEXT ID_STATUS,7,237,439,50, WS_VSCROLL | ES_MULTILINE
This allows for the text to be scrolled if it's long and breaks it into new lines. However, if i add the DISABLED option to this, it disables both the scrollbar and the text. What would be the best way to solve this situation? I've also tried adding
SendDlgItemMessage(ID_STATUS, EM_SETREADONLY, 0, 0);
before the UI gets previewed to see if this would disable text editing but it doesn't. Any help would be appreciated.
EM_SETREADONLY is correct but you failed to actually ask it to be read-only. Try
SendDlgItemMessage(ID_STATUS, EM_SETREADONLY, TRUE, 0);
wParam
Specifies whether to set or remove the ES_READONLY style. A value of TRUE sets the ES_READONLY style; a value of FALSE removes the ES_READONLY style.
You can also specify the ES_READONLY style when you create the control.
I realize that this is a trivial problem and I even looked at an MFC book(Programming Windows with MFC by Prosise). However, I couldn't really find a solution.
I am trying to create a Spin Button Control dynamically and here is a simplified code:
CEdit* m_editControl = new CEdit();
m_EditControl->Create(WS_VISIBLE | WS_CHILD , rectEdit, this, EditID);
CSpinButtonCtrl* m_spinControlCtrl = new CSpinButtonCtrl;
m_spinControlCtrl->Create(WS_VISIBLE | WS_CHILD, rectSpinButton, this, SpinID);
m_spinControlCtrl->SetBase(10);
m_spinControlCtrl->SetBuddy(m_editControl );
m_spinControlCtrl->SetRange(-55, 55);
My problem is that the spin button does not change the value of the CEdit. Am I missing something? How can I create a Spin Button Control dynamically?
Your spin control is missing the style UDS_SETBUDDYINT:
UDS_SETBUDDYINT Causes the up-down control to set the text of the
buddy window (using the WM_SETTEXT message) when the position changes.
The text consists of the position formatted as a decimal or
hexadecimal string.
I also suggest setting UDS_ARROWKEYS so the arrow keys can be used to increment or decrement the value when the focus is on the edit control.
For the edit control I would add WS_TABSTOP so the user can navigate using the TAB key and WS_EX_CLIENTEDGE so the edit control shows the regular themed border.
I also noticed that you use dynamic memory allocation for the controls, which is not necessary. Just create non-pointer member variables like CEdit m_EditControl; so you don't have to worry about deallocation.
Fixed code:
m_EditControl.CreateEx(WS_EX_CLIENTEDGE, L"Edit", L"0", WS_VISIBLE|WS_CHILD|WS_TABSTOP,
rectEdit, this, EditID);
m_spinControlCtrl.Create(WS_VISIBLE|WS_CHILD|UDS_SETBUDDYINT|UDS_ARROWKEYS,
rectSpinButton, this, SpinID);
m_spinControlCtrl.SetBase(10);
m_spinControlCtrl.SetBuddy(&m_EditControl);
m_spinControlCtrl.SetRange(-55, 55);
I also strongly suggest learning to use Spy++. This is how I actually arrived at this answer. Using the resource editor I just dropped an edit control and an up-down control onto a dialog and used Spy++ to observe the default window styles.
I have combo box created with style CBS_DROPDOWN | CBS_HASSTRINGS | WS_VISIBLE | WS_CHILD.i want to perform some action on command cbn_closeup.But my control is not getting this event.Even in spy++ there is no cbn_closeup sent to combo box.Please somebody help me.
Not your Control gets the WM_COMMAND notification. The parent gets it. So you Need an ON_CBN_CLOSEUP in the parent window code.
If you want that your window gets the notification you Need an ON_CONTROL_REFLECT handler. But this only works if the parent window is created by the MFC too, or at least subclassed.
I want to implement a notification window by subclassing QDialog. It should be on top of other windows, but I don't want it to steal focus from other windows for obvious reasons. I'm also concerned that it would interfere with full-screen applications like videos and games.
How do I go about implementing this? Are there any common programming and UX practices I might want to know about?
It appears quite an old topic. However, I did not see anyone posting a proper answer that just works, so I am posting my solution to the same problem I have been facing recently.
First of all, if you want your dialog not to steal focus from other dialogs or input fields, you should set the following property: Qt::WA_ShowWithoutActivating. Using this property, window (dialog is also a window) will be shown without being activated. Then, probably you will want to customize your dialog to your needs, and you will want this dialog to be shown on top. So, the following Window flags can be set in order to achieve such a result in a cross-platform manner: Qt::FramelessWindowHint | Qt::NoDropShadowWindowHint | Qt::X11BypassWindowManagerHint | Qt::Tool | Qt::WindowStaysOnTopHint | Qt::WindowTransparentForInput | Qt::WindowDoesNotAcceptFocus.
The code below is one of the examples to achieve a dialog that is modeless, and does not steal focus from anyone (assuming dialog is a variable pointing to the valid instance of QDialog):
dialog->setAttribute(Qt::WA_ShowWithoutActivating, true);
dialog->setWindowFlags(dialog.windowFlags() | Qt::FramelessWindowHint | Qt::NoDropShadowWindowHint | Qt::X11BypassWindowManagerHint | Qt::Tool | Qt::WindowStaysOnTopHint | Qt::WindowTransparentForInput | Qt::WindowDoesNotAcceptFocus);
Haven't tried it but it looks like
my_dialog->setWindowFlags(Qt::CustomizeWindowFlags | ... | Qt::WindowStaysOnTopHint);
should work, in conjunction with making it modeless.
First of all you need to create a non modal dialog:
A modeless dialog is a dialog that operates independently of other
windows in the same application. Find and replace dialogs in
word-processors are often modeless to allow the user to interact with
both the application's main window and with the dialog.
In order to achive that you need to call the show function and not the exec one.
I want to create custom tooltips where I can put any kind of controls. I have derived from CDialog and used the WS_POPUP | WS_BORDER styles. I also add the CS_DROPSHADOW style in the OnInitDialog to get the tooltip shadow.
Then I manage myself the WM_MOUSEHOVER and WM_MOUSELEAVE events to show/hide the tooltips.
I display the tooltip using SetWindowPos and SWP_NOACTIVATE to prevent the parent from becoming inactive and the new dialog from becoming active. But anyway, when I create the dialog using CDialog::Create method...the main window becomes inactive...what makes a very bad effect.
So my custion is how can I create a CDialog with the WS_POPUP style without my main window (or the parent window of the dialog) becomening inactive when the new dialog shows up???
Thanks for helping!
Edited: I do not use the WS_VISIBLE style to create the dialog...this this the resource:
IDD_LABEL_TOOLTIP_DLG DIALOGEX 0, 0, 100, 9
STYLE DS_SETFONT | WS_POPUP | WS_BORDER
FONT 8, "Tahoma", 0, 0, 0x0
BEGIN
LTEXT "##################",IDC_TOOLTIP_LBL_TEXT,0,0,99,9
END
The code that display the tooltip is something like that:
if(!pTooltipDlg)
{
pTooltipDlg = new MyCustomTooltipDlg();
pTooltipDlg->Create( MyCustomTooltipDlg::IDD, this);
}
pTooltipDlg->ShowWindow(SW_SHOWNOACTIVATE);
The first time (ie when the create is being call) the main windows lose the focus...the rest of them this ugly effect is not happening...so I am sure is because of the Create.
When you create your window, don't set the WS_VISIBLE flag on it. Then you can use ShowWindow with SW_SHOWNA or SW_SHOWNOACTIVATE to make the dialog visible.
Are you calling CDialog::Create() with WS_VISIBLE set? It might be that even just calling Create() is enough to take focus from the parent. It might also be worth overriding WM_SETFOCUS on your tooltip class and not calling the base class to make it impossible for the focus to change windows.
First off, consider using a CWnd rather than a CDialog. This gives you much finer control. And you are not really using any features of the CDialog anyway other than the dialog template; it is not too difficult to dynamically create your controls.
You may also want to consider, in the message handlers, handling OnShowWindow and ensure any show commands are changed to SW_SHOWNA as in Mark Ransom's comment.
Additionally, as a tooltip, it should probably have a NULL parent window.
Ok. I finally got it! I just had to return FALSE in the OnInitDialog method to avoid the dialog from being activated.
Thanks to all of you!