AdjustWindowRect() off by 7 pixels? - c++

int width=640, height=480;
RECT rect{0,0,width,height};
const DWORD style = WS_VISIBLE|WS_OVERLAPPEDWINDOW;
AdjustWindowRect(&rect,style,false);
auto hwnd = CreateWindowA("listbox","test",style,CW_USEDEFAULT,CW_USEDEFAULT,rect.right-rect.left,rect.bottom-rect.top,nullptr,nullptr,nullptr,nullptr);
The client rectangle is 640x473. What did I do wrong?

when you use List Box control the result height is depend from LBS_NOINTEGRALHEIGHT style:
Specifies that the size of the list box is exactly the size specified
by the application when it created the list box. Normally, the system
sizes a list box so that the list box does not display partial items.
so without this style, default List Box window procedure resize window, for not display partial items

Related

How to set minimum size for m_wndClientArea in CMDIFramewndEx?

This is visualstudio screen.
When resizing visualstudio screen to minimum, the tabbeddocument view, left and right dialogpane are displayed with some minimum size.
After resizing IF I resize the screen to maximum by dragging it becomes like this.
Whereas in my application which is a MDI tabbed group application created using MFC feature pack.
When resizng to minimum the tabbed docuemnt and rightside pane is resized tozero width.For right pane I set the minimum size as 100 using SetMinSize().
After resizing IF I resize the screen to maximum by dragging it , the right pane is not getting displayed.
I guess, to achieve this we need to set minimum size for CMDIFramewndEx's m_wndClientArea or CDockingManager's m_rectClientAreaBounds.
How to achieve this?
If you have any other solution please suggest me.
Thanks
In order to constraint the minimum size for an window, you have to handle WM_GETMINMAXINFO message:
in header:
afx_msg void OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI);
and in cpp:
ON_WM_GETMINMAXINFO()
void CChildFrame::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI)
{
// TODO: Add your message handler code here and/or call default
lpMMI->ptMinTrackSize.x = 100;
lpMMI->ptMinTrackSize.y = 200;
CMDIChildWnd::OnGetMinMaxInfo(lpMMI);
}

Dynamically adjust the width of combobox so the entire string can be shown

I am using a combobox control to show names stored in a database ( I need to preserve space, that is why I use it instead of a listview, for example ).
My problem is that sometimes text is longer than the combobox so part of it can not be seen.
Is there a way to resize combobox' listbox so it can entirely show text, or at least to enable some kind of horizontal scrolling so the user can scroll to see the entire text?
Looking through combobox documentation, I haven't found any style that can solve my problem. Trying to add WS_HSCROLL as a style in my CreateWindowEx call didn't help either.
Thank you.
You are looking for the CB_SETHORIZONTALEXTENT message.
An application sends the CB_SETHORIZONTALEXTENT message to set the width, in pixels, by which a list box can be scrolled horizontally (the scrollable width). If the width of the list box is smaller than this value, the horizontal scroll bar horizontally scrolls items in the list box. If the width of the list box is equal to or greater than this value, the horizontal scroll bar is hidden or, if the combo box has the CBS_DISABLENOSCROLL style, disabled.
Parameters
wParam
Specifies the scrollable width of the list box, in pixels
lParam
This parameter is not used.

How does one resize the form(dialog) in a MFC SDI CFormView application?

I've tried
MoveWindow(50,50,150,200,TRUE) in CMyFormView::OnInitialUpdate();
Also, I have tried following code in
CWinApp::InitInstance();
RECT desktop;
const HWND hDesktop = ::GetDesktopWindow();
::GetWindowRect(hDesktop,&desktop);
MoveWindow(hDesktop,0,0,900,400,TRUE);
I am having no luck resizing the form(dialog).
I would appreciate any suggestions.
In an SDI program the dialog is sized by the mainframe window to fill the client area. Resize the frame window and the dialog will follow. Put this in the formview's OnInitialUpdate
AfxGetMainWnd()->MoveWindow(....);
KEY THINGS:
MINIMUM SIZE - YOU SET - The dialog template - or form view - you make IS the absolute minimum size CFormview will use
MAXIMUM SIZE - AUTOMATICALLY SIZED - The dialog template has no maximum. CFormview dynamically stretches it out to fit the CMainFrame window.
STARTING THE APPLICATION TO THE TEMPLATE SIZE
Naturally you might want the CMainFrame window to be as compact as possible, this is achieved using 3 mandatory lines of code in your CFormView::OnInitialUpdate()
void CSimpleSDIView::OnInitialUpdate()
{
CFormView::OnInitialUpdate();
GetParentFrame()->RecalcLayout();
ResizeParentToFit(); // FORCES CMainframe to be as small as the dialog template
}
FORCE CMainFrame to LIMIT MINIMUM SIZE - If necessary. Using WM_GETMINMAXINFO Here's the code:
void CMainFrame::OnGetMinMaxInfo(MINMAXINFO* lpMMI)
{
lpMMI->ptMinTrackSize.x = 500; // absolute minimum width for CMainFrame
lpMMI->ptMinTrackSize.y = 500; // absolute minimum height for CMainFrame
CFrameWnd::OnGetMinMaxInfo(lpMMI);
}
SET TO IDEAL SIZE This can achieved in CFormView ::OnInitialUpdate by using the following code (Step 3 is still required):
AfxGetMainWnd()->MoveWindow(0, 0, 1024, 600, 1);
TWEAK CONTROL POSITIONS With the advent of the ribbon in MFC things are looking good, but using steps 1 - 5 doesn't work without extra tweaking. Basically, the ribbon sends the main window an extra resize as it would seem, so even if you sent a minimum template size, things get a little out of proportion due to the extra resizing -- mainly because a group within a ribbon can be collapsed into a single icon. ** BEFORE DOING STEP 5** you might want to add the following code:
if(::GetSystemMetrics(SM_CXSCREEN) > 1024)
{
RECT r;
CWnd *someControl = GetDlgItem(IDC_SOMECONTROL);
someControl->GetWindowRect(&r);
ScreenToClient(&r);
r.right += 300;//r.right += 30;
r.bottom += 150;
someControl->MoveWindow(&r)
}
EXPLANATION:
The short answer, you don't! Basically, I had the same issue, made a dialog box template for use in a CFormView derived class. When I wanted to stretch the CMainFrame window out like any normal window, I wanted the content of the formview to resize accordingly. That worked fine with some code, but the problem came when I made the window very small. When I did that, I would get these ugly scrollbars. My thought was the scrollbars were there because they are trying to respect the original dialog template size. That thought is correct! For example, you make your dialog box 500 x 500 and you resize small less than that, you will get scrollbars - since CFormview respects that the application MUST BE AT A MINIMUM 500x500. The minimum size is governed by the template you make and you can not dynamically make it smaller.
Usually, child window's size, position is changed in child's init code.
If you change this in parent window code, you always have to check whether the child window handle value is valid.
I input this code WM_CREATE handler of CAboutDlg.
int CAboutDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CDialogEx::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
RECT desktop;
const HWND hDesktop = ::GetDesktopWindow();
::GetWindowRect(hDesktop,&desktop);
MoveWindow(&desktop,TRUE);
return 0;
}

How to set the default size in pixels of dialog in MFC

I want to set the default size in pixels of dialog, say it is 640 pixel width and 384 pixel height. what I mean by the default is that when the first time the CXXXDlg::OnSize(UINT nType, int cx, int cy) is called, the value of cx is 640 and the value of cy is 384. scene the default size of the dialog is in dialog units, and I can use the MapDialogRect() to convert the dialog units to the pixels, How can I do the reverse? the MoveWindow() and the SetWindowPos() can set eh size of the dialog but not the default size. I also have tried the GetDialogBaseUnits() like this:
DWORD dw = GetDialogBaseUnits();
WORD m_duXx4 = LOWORD(dw);
WORD m_duYx8 = HIWORD(dw);
int dialogUnitX = MulDiv(640, 4, m_duXx4);
int dialogUnitY = MulDiv(384, 8, m_duYx8);
it turned out that the dialogUnitX is 320 and the dialogUnitY is 192, but when I set the dialog unit to 320 * 192, what I got in CXXXDlg::OnSize(UINT nType, int cx, int cy) is not 640 * 384 but 560 * 336. Any ideas?
A window consists of a Client Area and a Nonclient Area.
The client area is the part of a window where the application displays output, such as text or graphics.
The title bar, menu bar, window menu, minimize and maximize buttons, sizing border, and scroll bars are referred to collectively as the window's nonclient area.
The Window Rect designates the area that encompasses the entire window. It includes the client area as well as the nonclient area. It can be retrieved by calling GetWindowRect (or its MFC-equivalent). It is also used as the input to functions like MoveWindow or SetWindowPos.
The Client Rect is the area of a window that is not occupied by the nonclient area. It can be queried by calling GetClientRect. The client rect dimensions are passed to the WM_SIZE message handler.
If an application requires a specific size for its client area it can calculate the respective window rect by calling AdjustWindowRect or AdjustWindowRectEx.
The window rect is usually expressed in Screen Coordinates while the client rect uses Client Coordinates. Both coordinate systems represent device pixels. The origin is in the top left corner of the primary display for screen coordinates and the top left corner of the client area for client coordinates. To translate between the coordinate systems an application uses ClientToScreen or ScreenToClient.
Dialog templates specify dimensions and positions in Dialog Template Units. Dialog template units are directly related to a dialog's font. To convert between dialog template units and device pixels an application calls MapDialogRect. There is no API call to calculate the reverse. An application has to perform the calculations manually:
width = MulDiv(width, 4, baseunitX);
height = MulDiv(height, 8, baseunitY);
If an application wants to confine the window size dynamically it can handle the WM_GETMINMAXINFO message and populate a MINMAXINFO structure with the desired dimensions. This message is sent to a window when the size or position of the window is about to change.

How to increase a cells height and width in ListControl

How can we increase the the height and width of a cell in List
It is created using Listcontrol MFC
Write a custom list control (owner
drawn).
handle message MEASUREITEM_REFLECT
set the cell height and width in the
method:
MeasureItem( LPMEASUREITEMSTRUCT
lpMeasureItemStruct )
To set the cell width take a look at the ListView_SetColumnWidth Win32 function.
One way to set the height is to attach an image list to the list control. The list control will then set the row height based on the height of the icons in the image list.
An easy way to set the cell height of a list control is by supplying an image list of the required height:
In the header:
CImageList m_imageList;
In the implementation:
m_imageList.Create(68, 68, ILC_COLOR4, 10, 10); // 68 = cell height in pixels
m_list.SetImageList(&m_imageList, LVSIL_SMALL);
Setting the cell width is achieved by simply calling SetColumnWidth (as pointed out by jussij)