How to recreate style used by resource editor when creating MFC controls dynamically? - c++

I need to create some controls in a MFC dialog dynamically. The creation works fine so far, but the controls created dynamically are looking different from controls created with the resource editor. Some controls even behave different. I think, that I'm missing some initializations the generated code does.
Currently I only create CStatic and CEdit controls. Both don't use the standard windows font when I create them dynamically (the font looks more like the default font used prior to Windows 95, if I remember correctly).
Also, the CEdit control behaves different from when I create it with the resource editor. The dynamically created control seems to limit the text length to the visible size. I can set a longer text with SetWindowText() and read the full text back in with GetWindowText(), but the user can't enter a text longer than the size displayed. The CEdit control created by the resource editor behaves different: If the user enters a text longer than what can be displayed, the entered text ist "scrolled" inside the control (no scrollbars, as its only a single line control).
I tried fixing that problem by calling SetLimitText() on the control, but that didn't change the behavior.
The controls are saved to arrays defined in the dialog-class:
CStatic** m_pLabels;
CEdit** m_pEdits;
The creation of the controls happens in the OnInitDialog() method of the dialog-class:
for (int i = 0; i < max; i++)
{
m_pLabels[i] = new CStatic();
m_pLabels[i]->Create("key", WS_CHILD | WS_VISIBLE | SS_RIGHT,
CRect(10, 10 + i * 30, 130, 35 + i * 30), this);
m_pEdits[i] = new CEdit();
m_pEdits[i]->CreateEx(WS_EX_CLIENTEDGE, "EDIT", "",
WS_CHILD | WS_TABSTOP | WS_VISIBLE | WS_BORDER,
CRect(133, 10 + i * 30, 350, 35 + i * 30), this, i + 100);
m_pEdits[i]->SetLimitText(499);
m_pEdits[i]->SetWindowText("value to be edited");
}
Thanks for your help!

Dynamically created controls always get the stock font initially: the usual approach is to just set the control's font to the parent dialog's font: something like
pEdits[i]->SetFont(GetFont());

I think the best way to do is to put a control through dialog editor on a dialog, set it's visual styles to the ones of your choice and then open the .rc file in a text editor and copy the styles of that control from there. This way you will be able to create controls that are far more closer to the ones you add through dialog editor.
e.g., after putting a simple button on a dialog having OK/Cancel buttons and a text control, my dialog looks like this in the .rc file:
IDD_MFCAPP_DIALOG DIALOGEX 0, 0, 320, 200
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
CAPTION "MFCApp"
FONT 8, "MS Shell Dlg", 0, 0, 0x1
BEGIN
DEFPUSHBUTTON "OK",IDOK,263,7,50,16
PUSHBUTTON "Cancel",IDCANCEL,263,25,50,16
CTEXT "TODO: Place dialog controls here.",IDC_STATIC,10,96,300,8
PUSHBUTTON "Button1",IDC_BUTTON1,43,17,50,14
END
Now, since I have all the information about how the dialog was created at the back-end, I can simply replicate this behviour through code.
P.S. Off course, you would do this in a separate test project.

You need to add the ES_AUTOHSCROLL style to the editbox. This style is responsible for scrolling the text leftwards when you enter more text than the box can display.
Opening .rc files in text editor and looking up the styles of controls can help you find out such points.

Related

Explorer-type custom dialog is maximized on the first open in the application

I have customized an explorer type browse dialog and added some controls. Upon opening the dialog, even though I have specified the width and height on the template resource, it is showing in maximized state.
I have tried to override this behavior by using the SetWindowPos, MoveWindow and ShowWindow API but none of them seems to resize the dialog.
Here are the specific codes, called during dialog initialization:
HWND hTrueDlg = GetParent(hwndDlg);
::SetWindowPos(hTrueDlg, HWND_TOP, iXPx, iYPx, iWinWidthPx, iWinHeightPx, SWP_SHOWWINDOW);
::ShowWindow(hTrueDlg, SW_RESTORE);
This is the resource file:
WPOPENDLGCUSTOM DIALOG 0, 0, 600, 40
STYLE DS_3DLOOK | DS_CONTROL | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CAPTION
// I have also tried this
STYLE (DS_3DLOOK | DS_CONTROL | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CAPTION) & ~WS_MAXIMIZE
When I double click the title bar, it is "Restored" and for the next time I open the dialog, it is displaying the correct size. The problem is only on the first open. When a user don't know this work around, it might cause some problems.
The explorer-style dialog box read size value from one registry hive first opening and record and read size value to one registry hive that could be Computer\HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\CIDSizeMRU later.

How do I implement this code into a dialog type resource file?

// Epvolume.rc -- Resource script
#include "resource.h"
#include "windows.h"
#include "commctrl.h"
//
// Dialog box
//
VOLUMECONTROL DIALOGEX 0, 0, 160, 60
STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU | DS_SETFONT
CAPTION "Audio Endpoint Volume"
FONT 8, "Arial Rounded MT Bold", 400, 0, 0x0
BEGIN
LTEXT "Min",IDC_STATIC_MINVOL,10,10,20,12
RTEXT "Max",IDC_STATIC_MAXVOL,130,10,20,12
CONTROL "",IDC_SLIDER_VOLUME,"msctls_trackbar32",
TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,10,20,140,12
CONTROL "Mute",IDC_CHECK_MUTE,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,20,40,70,12
END
I don't know a thing about resource files, I tried to make it a dialog resource type but I don't quite know how to enter this code into that dialog file because I don't really know how to work it. Just to clear things up, when I make a new dialog file it gives me a blank dialog, which I don't know how to edit, maybe I'm doing something wrong? I don't know where to put the code
You need to open the resource file as text rather than with the designer. In solution explorer select the resource script file and hit ctrl+alt+0. You can then cut-and-paste text as usual.
Most of the time when simply laying out a new dialog it is easier to use the designer but editting it as text is much easier when you have existing resources you want to bring into a project.
Note that you will also need to edit resources.h to add the various control symbol names (for example IDC_SLIDER_VOLUME) as well as modifying _APS_NEXT_CONTROL_VALUE to be the next unused value.

Visual C++ open Dialog Box when button clicked

So I am new to programming in C++ and new to using Visual Studio 2010. Basically I have a FLIR thermal camera; and I need to edit a GUI provided in an eBUS SDK that suits my needs.
What I want to do is open a new dialog box when I click the settings button. I am just not sure what code to use in the button handler to make the dialog box open. I have put different code in the button handler to test it and the settings button works fine.
This is the button handler that the code needs to go into.
void PvSimpleUISampleDlg::OnBnClickedSettings()
{
}
This is the dialog box in the resource file that I want to connect the button to. It is called IDD_SETTINGS. The actual button is called IDB_SETTINGS, not sure if that's relevant.
IDD_SETTINGS DIALOGEX 0, 0, 506, 300
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Settings"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "OK",IDOK,449,279,50,14
END
I am not sure what other code to add, but I am completely new so any help/advice you can give no matter how small would be greatly appreciated.
If you are using the MFC framework (the CDialog class), then you can create a new CDialog object using the settings-dialog resource you've created.
The CDialog::DoModal() function is what you want, if you want a simple popup box that grabs your attention until it is dismissed with OK or Cancel.
In your source file:
void PvSimpleUISampleDlg::OnBnClickedSettings()
{
CDialog mySettings( IDD_SETTINGS );
INT_PTR returnCode = -1;
returnCode = mySettings.DoModal();
switch( returnCode ) {
case IDOK :
//gather your input fields here
break;
case IDCANCEL :
//do something
break;
case -1:
default:
//error creating box
}
}
Here is a link for using the CDialog class as a starting point for extracting information from the box once OK is clicked:
https://msdn.microsoft.com/en-us/library/619z63f5.aspx

C++ Win32 Multiline static label

I'm having a problem with multiple lines on a label.
I've tried using ES_MULTILINE, but whenever I use that I get a grey/black rectangle on the location of the label, without the text of the label.
CreateWindowW(L"STATIC", selectedPatternProblem, WS_CHILD | WS_VISIBLE | SS_LEFT | ES_MULTILINE | WM_CTLCOLORSTATIC,500, 190, 380, 90,*hwnd, (HMENU) 1, NULL, NULL);
And when I add WM_CTLCOLORSTATIC, the rectangle is gone, but so is my text.
The 'selectedPatternProblem' is too big to display on just one line, so my question is:
How can I display my label on multiple lines?
Edit: After deleting ES_MULTILINE and WM_CTLCOLORSTATIC, I found out my word was too long. But now I wonder how can I display one long word on multiple lines?
You're using an edit control style (ES_MULTILINE) with a static control, which is not designed to support it. That style probably maps to SS_BLACKRECT or SS_GRAYRECT, which would explain the behavior you're observing.
You should not have to add any style to your current control to achieve what you want, because you're already specifying SS_LEFT, and the documentation says:
SS_LEFT
A simple rectangle and left-aligns the text in the rectangle. The text
is formatted before it is displayed. Words that extend past the end of
a line are automatically wrapped to the beginning of the next
left-aligned line. Words that are longer than the width of the control
are truncated.
Since you're specifying neither SS_LEFTNOWORDWRAP nor one of the SS_*ELLIPSIS styles, the text should wrap between word boundaries.
Note you're also using the WM_CTLCOLORSTATIC message as a style, which will definitely not work as you expect. You should remove that value from your control's styles.
ES_MULTILINE is suitable for Edit controls not labels
MSDN:
Designates a multiline edit control. The default is single-line edit
control.
When the multiline edit control is in a dialog box, the default
response to pressing the ENTER key is to activate the default button.
I used an edit control as an alternative to multi line edit control. I had set the following properties in resource file
EDITTEXT IDC_COMMENT,58,53,75,41,ES_MULTILINE | ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER

Changing a dialog's style at creation to override what's in the .RC template

I have a little dialog I created using Resource Editor in VS2005. It's going to be used as a child dialog of another dialog, in 2 different ways... either as a child which sits on top of the dialog like a custom control, or as a popup which can move beyond the boundaries of the parent window. If I modify a single style in the RC file, both of these work as expected - simply substitute WS_POPUP for WS_CHILD to toggle:
IDD_WIDGET DIALOGEX 0, 0, 221, 78
STYLE DS_SETFONT | DS_3DLOOK | DS_FIXEDSYS | DS_CONTROL | WS_POPUP | WS_BORDER
EXSTYLE WS_EX_TOOLWINDOW | WS_EX_STATICEDGE
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
PUSHBUTTON "Pre&view",IDC_ACTION_PREVIEW,64,59,50,15
PUSHBUTTON "M&ore",IDC_ACTION_MORE,115,59,50,15
PUSHBUTTON "S&elect",IDC_ACTION_SELECT,168,59,50,15
END
The problem is, I want to be able to choose the behavior when creating the child dialog at run-time as a sort of widget type framework, e.g overriding the RC file style
I tried:
BOOL CMyDlg::OnInitDialog()
{
CDialog::OnInitDialog();
m_Widget.Create(IDD_WIDGET,this);
DWORD oldstyle = m_Widget.GetStyle();
m_Widget.ModifyStyle(WS_POPUP,WS_CHILD);
DWORD newstyle = m_Widget.GetStyle();
}
But it makes no difference that I can see, other than that the result of GetStyle changes from 0x8400044C to 0x4400044C... the widget child-dialog starts invisible but when I show it, it retains the WS_POPUP behavior.
What's wrong, and how can it be fixed?
As Ben suggests, I wonder if this is not a style that can be changed after the window is created, but the problem then is how to intercept the dialog-template structure and modify the style before it's used to create the window?
I found this article for you: link text
Looks like InitDialog is too late to change the style. There's an example of how to do it in this link.