Win32 Default Height of Edit Control - winapi

I'm using CreateWindowEx to create an Edit control (a textbox), but saying CW_DEFAULT doesn't help with getting the default height of the textbox -- it just makes a window with a height of zero.
How do I get the system-default size of a textbox, so I can turn Edit control into a normal-looking textbox?

The recommended size is 14 dialog units. Here is the reference
You can use MapDialogRect to convert dialog units into pixels.

Related

Vertical size of owner draw combo box bigger than that of non owner draw combo box

I have a dialog containing two combo boxes, one owner draw and one non owner draw.
This is how they are defined in the .rc file:
COMBOBOX IDC_COMBO2,149,49,77,73,
CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_SORT | VS_VSCROLL
COMBOBOX IDC_COMBO3,237,49,48,30,
CBS_DROPDOWNLIST CBS_SORT | WS_VSCROLL
They have exactly the same height in the .rc file, but the owner draw one (the one on the left side) is slightly higher that the non owner drawn one:
.
First the given height in the resource is the height of the combo box in the dropped down state.
This behavior is by
design. The size of the combobox item height is I believe determined by
the font height of the font assigned to the control.
With an owner-draw combobox the system has no idea so it sends you a
WM_MEASUREITEM initialized with the default size of the combobox (probably
depending on the system font rather than the gui font).
So you need to handle WM_MEASUREITEM in the parent dialog...
Something like this might help (code not validated against a compiler):
void CMyDlg::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
CClientDC dc(this);
CFont* pFont = GetFont();
CFont* pFontPrev = NULL;
if (pFont != NULL)
pFontPrev = dc.SelectObject(pFont);
int iborder = ::GetSystemMetrics(SM_CYBORDER);
CSize sz = dc.GetTextExtent(_T("0"));
lpMeasureItemStruct->itemHeight = sz.cy + 2*iborder;
if (pFont != NULL)
dc.SelectObject(pFontPrev);
__super::OnMeasureItem(nIDCtl, lpMeasureItemStruct);
}
The combobox is the most horrible control to work with in Windows when dealing with size and layout. Because it also supports the "simple" style with separate edit and listbox controls always visible it does not use the standard window border/edge styles and instead draws its borders when required.
The height specified when you create the control is actually the size used in the dropped-down state. It forces its own size of the edit control at run-time based on its font. Because so many people got this wrong the themed ComCtl32 v6 implementation makes sure the dropdown size is sane even if you gave it a small size initially.
To match the system you need to try to calculate the required size in WM_MEASUREITEM but the exact layout of the default control is of course not documented. It is probably the height of the font + the system metric size of SM_C*EDGE and probably some padding.
If you only need a icon next to the text you can use the ComboBoxEx control instead.

How can I measure the width of the caption bar available for text?

I'm trying to adjust the caption of my main window to show as much of a file name as is possible to fit in the caption area. So, I'm looking to calculate the width of the area marked up here in the red rectangle:
Now, I would ideally like to have code that can use whatever system metrics are available and thereby avoid being caught out by all the various platform/theme/dpi variations that can exist.
How can this be done, if indeed it is even possible?
As andlabs said in the comments, the WM_GETTITLEBARINFOEX message can be used to obtain the required information.
This message can be sent to the window and the TITLEBARINFOEX struct is populated with the state and location of the titlebar and each of its buttons. From there it is a simple task to determine how much space is available for the caption.
First, call GetTitleBarInfo, passing a pointer to the TITLEBARINFO structure:
TITLEBARINFO tbi;
GetTitleBarInfo(hwnd, &tbi);
The width of the titlebar is tbi.rcTitlebar.right - tbi.rcTitlebar.left. But that includes the three buttons (Close, Minimize, and Maximize). The width of one button is GetSystemMetrics(SM_CXSIZE), so the width of the title bar minus the three buttons is
(tbi.rcTitlebar.right - tbi.rcTitlebar.left) - (3 * GetSystemMetrics(SM_CXSIZE))
Of course, the code works on all versions of Windows where the width of each of the 3 buttons is equal

How do I specify that a VB6 form is not resizable?

How do I prevent the user from resizing form dialogues in VB6? The dialogues are small and simple and resizing them serves no purpose, so I'd prefer to prevent it than write code to handle it.
You can set the BorderStyle of the form to either "Fixed Single" (vbFixedSingle) or "Fixed Dialog" (vbFixedDouble) at design-time. Either of these will prevent the user from resizing the form.
Fixed Single provides a Control-menu box, title bar, Maximize
button, and Minimize button. The form
will still be resizable using the
Maximize and Minimize buttons, but not
by dragging the edges of the window.
Fixed Dialog provides a Control-menu box and title bar, but
eliminates the Maximize and Minimize
buttons. It is therefore not resizable
at all. (Also note that a form that
contains a menu cannot be displayed as
a Fixed Dialog and is automatically
changed to the Fixed Single border
style.)
See also the relevant MSDN entry: http://msdn.microsoft.com/en-us/library/aa245047(VS.60).aspx
Select as BorderStyle "Fixed Single"
Change the BorderStyle. Toolbox, Fixed dialog or property window should do it I think.
You can set the BorderStyle of the form to "Fixed Single" and If you want to have a minimizable form , set MinButton property to "True".
form border options available in vb6 are
me.BorderStyle = 0 ' – None
me.Appearance = 0 '– Flat
me.BorderStyle = 1 '– Fixed Single
me. Appearance = 1 '– 3D
me.BorderStyle = 1 '– Fixed Single

TabCtrl_SetItemSize and user drawn tab controls

I have this Win32 user-drawn tab control that is created as:
CONTROL "Tab1",IDC_TAB_CONT,"SysTabControl32",TCS_BOTTOM |
TCS_OWNERDRAWFIXED | NOT WS_VISIBLE,0,14,185,88
I'd like for this control to have its tabs resize as never to have to see the "sliding arrows":
Now, pretty much everything about this control works as expected, except for that fact that it won't respond to TabCtrl_SetItemSize. Try as I may, the size I get for the tabs when I get to draw them (in the DRAWITEMSTRUCT passed to WM_DRAWITEM) is always the size that fits the longest caption in them and never the size I've set with TabCtrl_SetItemSize.
However, in the TabCtrl_SetItemSize documentation, it says that:
[TabCtrl_SetItemSize] sets the width and height of tabs in a
fixed-width or owner-drawn tab
control.
The only way I've managed to have a decent resizing is by setting a dummy string of the desired length in it by sending the control a TCM_SETITEM message, and writing the desired text in it at draw time. This is rather inconvenient and not a particularly nice hack.
Is there anybody who would know
Why TabCtrl_SetItemSize isn't working as expected? and/or
How to set the tab size properly?
Many thanks,
joce.
Setting TCS_OWNERDRAWFIXED style is not enough, you have also to add TCS_FIXEDWIDTH style.
The minimum size of a tab is at least icon width + 3 if icon is present.
If you have icons (imageList attached to tabControl), you might get those "sliding arrows" even with fixed width (if there is less space available than: number of tabs*(icon width+3)

Full-screen window sizing in screen (pixel) units with VS6 C++ GUI editor, MFC?

I am trying to create a full-screen control panel window with many controls: buttons, sliders, list boxes, etc.
I can create a dialog window and add controls to it, but everything is scaled in dialog units. I just want to create a window in the GUI editor that is scaled in pixels, not derived units like dialog units.
I can sort of lay out all the controls in the GUI editor and then resize the window programmatically to full-screen using SetWindowPos, but the dialog window in the GUI editor will not look the same as the final product. I want it to be WYSIWIG in the GUI editor.
This is the front end for a small dedicated instrument control computer running XP. The SDK is written in MFC. I have to add and change controls frequently. The screen is small, 7" # 800 x 600, so of course I am developing the program on a different computer. I don't want the program window to change when I change monitors -- I want it fixed at 800 x 600, and I want the controls to be fixed in size and layout as well.
There must be a way -- this is more basic than the default functionality.
Thanks.
Dialog Units are based on properties of the font used by the dialog. A horizontal dialog unit is equal to 1/4th the average width of the current font.
A vertical dialog unit is equal to 1/8th the average character height of the current font.
I'd recommend using method 2 (MapDialogRect() for a 4 x 8 dialog) to figure out how many DLUs 800x600 corresponds to on your output display then make a reference form equal to that size. You can later use that reference form while you're designing.
p.s.-I'm glad Visual Studio no longer emphasizes dialog units since they were always a pain to deal with.
Thanks. I was able to make a reference form by just resizing the form manually in the GUI editor over and over again until it exactly filled the screen... No kidding that dialog units are a pain. From your response, I guess in the current Visual Studio there is a better way to do this? (This is my first experience with Windows programming).

Resources