It's been a while since I've done any work with MFC's and I just got handed a project where I need to add a simple console to show logging messages received by the application. I decided to use a RichEditView because I want to be able to format and color the received messages.
I have been banging my head all day trying to set ES_AUTOHSCROLL and ES_AUTOVSCROLL in my CRichEditView and I just can't get it to work...
I derived a class from CRichEditView called CConsoleView and in CConsolesView::PreCreateWindows I set the style to
- ES_READONLY | ES_MULTILINE | ES_WANTRETURN | ES_AUTOHSCROLL | ES_AUTOVSCROLL
but this didn't work as expected.
OK... nothing wrong with going back to basics so I've tried this in a simple MFC wizard and it worked and I was expecting this to work in my app as well.
From http://msdn.microsoft.com/en-us/library/windows/desktop/bb775464(v=vs.85).aspx I know that autoscroll can't be changed after the object creation so I guess my object is being created before I call get the call to PreCreateWindow...
Can I force the style in my CConsoleView constructor?
When/where is (generic question) the CRichEditView::Create() method being called? shouldn't it be called after PreCreateWindow?
Besides attaching a new object is there any way to get around this?
Any help would be appreciated!
Cheers
If you're using the control in a dialog template, just add the create flags to the resource file that's declaring the control in dialog. If you're dynamically creating the control, you'd be doing the Create... unless you're doing MDI (which doesn't seem to fit based on your description).
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 a simple MFC application in VS2010 and I am trying to move this app to VS2015 environment.
I am able to build the project successfully in VS2015. But the checkboxes in the application are appearing different than the VS2010.
I am using CCheckListBox class and create method of CCheckListBox to create the checkboxes. Window style and List Box style used as below while creating checkboxes: { WS_CHILD | WS_BORDER | LBS_NOTIFY | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | WS_VSCROLL | LBS_DISABLENOSCROLL | LBS_NOINTEGRALHEIGHT } Also I am using SetCheckStyle method with BS_AUTOCHECKBOX option.
MFC app built with VS2015:
MFC app built with VS2010:
What am I doing wrong here? The code is exactly same.
Is MFC supported in VS2015?
It might not be a "state of the art" fix but I patched this bug with the following line :
SetWindowTheme(m_boards.GetSafeHwnd(), L"Explorer", "L");
In my dialog's OnInitDialog() method where m_board is a member CheckListBox binded to my list box control in the DoDataExchange() method.
You might want to use another theme than Explorer though.
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 have a custom CWnd-derived MFC control, which works like this:
the control has its own OnPaint, and a black background
clicking anywhere on the control causes an edit control to appear at that location, borderless and with black-background, so it blends in
the user types in this box and hits enter, the box disappears and the control's custom paint functionality renders the same text in the same position on the background.
So our control owns a CCustomEdit, when you click on the background the control is either created or moved, and made visible:
CCustomEdit::Show(Rect &rc,CCustomControl *pParent)
{
if ( !::IsWindow( m_hWnd ) )
{
Create( ES_LEFT | ES_AUTOHSCROLL | WS_CHILD | ES_NOHIDESEL | ES_CENTER | ES_UPPERCASE, rc, pParent, 999 );
}
else
MoveWindow( &rc );
}
The main parts actually work OK (and we're stuck with the approach). But one thing that's not working is that CCustomEdit self-registers for EN_CHANGE events and so on. When CCustomEdit is created as a normal dialog control (CEdit on the dialog template, DDX-bound to a CCustomEdit variable) these work, but within CCustomControl they are not.
CCustomEdit::PreSubclassWindow() calls SetEventmask() and is being called. And CCustomEdit's ON_CHAR handler is also being called for key-presses in the edit box, however the handlers for edit-box messages like EN_CHANGE are not.
Are there any obvious things like changing the style flags? Otherwise, why is my custom control stopping these events reaching the contained edit control?
I'm not sure I understand the situation, but I have a number of control that work roughly in the same way as what I think is happening and they all work, it is possible.
EN_CHANGE for the edit control is send to your CWnd-derived control. Are you reflecting the messages? Have you tried if EN_CHANGE gets to the custom control? From what you are describing, you are expecting EN_CHANGE to end up in CCustomEdit's message dispatcher macro chain automatically, but it doesn't; you need the help of the containing window. Now MFC does most of that for you in a CDialog, but if you roll your own you need to do it manually, or use the message reflection macro's.
I found it... somehow, my SetEventMask() was being overriden. I don't know how or where but when I added an extra call later on to test, most event handlers started getting called.
I can only assume some part of the init code in MFC is responsible.