How to get width and height from CreateWindowEx() window? C++ - c++

I have made a window with CreateWindowEx() function, now how do i get the width and height from that window i created? This sounds very basic thing to do, but i just couldnt find any answer ;_;
This is needed because the window height is created automatically depending on how the Windows wants to create it.
Language C or C++

Use GetWindowRect. Subtract the right from the left to get the width and the bottom from the top to get the height.
RECT rect;
if(GetWindowRect(hwnd, &rect))
{
int width = rect.right - rect.left;
int height = rect.bottom - rect.top;
}
As a side note, if you'd like the client area instead of the entire window. You can use GetClientRect. For other information about the window you can use GetWindowInfo.

I believe you're looking for GetWindowInfo
Example:
HWND window = ::CreateWindowEx(...);
WINDOWINFO info;
if ( ::GetWindowInfo(window, &info) ) {
...
}

Have you tried GetWindowRect() or GetWindowInfo() which returns a WINDOWINFO structure?

Given there's no indication why you need the size, and that the size can change if the window style is set to include resizable attributes [and the user resizes the window using minimize/maximize/restore or drags a window edge], your safest choice is to include a message handler for WM_SIZE and use the wparam and lparam parameter values to determine window dimensions. This way, you'll always know the current size. WM_SIZE is called in the sequence of messages post window creation.

Related

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;
}

Find the position of a control in C++

I need to find the x and y coordinates of a control, but I'm not sure where to begin. The only solutions that I've found on the internet use MFC, and I want to avoid using that. So, is there a way to find the coordinates of a control without using MFC?
Using FindWindow to find the control:
RECT cr;
HWND chWnd = FindWindow("SunAwtCanvas", NULL);
GetWindowRect(chWnd, &cr);
cw = cr.right;
ch = cr.bottom;
cx = cr.left;
cy = cr.top;
cout << chWnd << endl;
chWnd is 0 when it should have the hWnd of the control.
use GetWindowRect on the hwnd of the control (every control has its own hwnd): http://msdn.microsoft.com/en-gb/library/windows/desktop/ms633519(v=vs.85).aspx. this will give you the left, right, top and bottom allowing to know the bounds of the control, and also work out its height and width
Your code for getting HWND is bad.
Cite from MSDN: FindWindow
Retrieves a handle to the top-level window whose class name and window
name match the specified strings. This function does not search child
windows. This function does not perform a case-sensitive search.
Use FindWindowEx instead.

Move buttons on a Dialog Box while it resizes

I have created a Dialog Box in a c++ windows application (using ATL lib) and I have set on it three buttons. The button lie as usual at the bottom of the Dialog Box. I want by the resize of the Dialog Box, the button to retain their position at the bottom of it. In other words, they should keep a constant (low) distance from the bottom margin and the on side (right or left) of the Dialog Box. To bring this into effect, I try to move the buttons accordingly while the Dialog Box size is changed. I use the following code (as example only with the OK button), but the only result is the button to disappear during the resize. How should I modify the code in order for the button to retain its distance from the bottom and the right side of the Dialog Box?
LRESULT RenameFolderDlg::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
RECT r;
GetWindowRect(&r);
CWindow okB(GetDlgItem(IDOK));
RECT okR;
okB.GetWindowRect(&okR);
okB.MoveWindow( r.right - 80 , r.bottom - 40, okR.right - okR.left, okR.bottom - okR.top, 1);
return 0;
}
I use winapi. In that I use GetWindowRect to fetch cordinates of control and then use MapWindowPoints to map those rectangular coordinates on to screen. Then use SetWindowPos to position windows according to mapped rectangular coordinates.
On Google, I found MapWindowPoints for ATL. I think what you are legging in your code is mapwindowpoints. Try using that.
Hope it work....
Instead of
GetWindowRect(&r);
you shall use
GetClientRect(&r);
because the coordinates returned by GetWindowRect are relative to the upper-left corner of the screen, while MoveWindow called for a child control expects they are relative to the upper-left corner of the parent window's client area.

Translate coords to re-position dialog box?

I am hooking CreateDialogIndirectParam. I want to do some manipulations over the dialog box, but but the width, height, and x and y positions are in dialog box units. Can someone explain how to convert them to screen coordinates?
Thanks in advance.
Try the MapDialogRect() function. I think it does what you think.
Remember that the mapping depends on the font used by the dialog, so the HWND must be that particular dialog.
Also from GetDialogBaseUnits():
pixelX = MulDiv(templateunitX, baseunitX, 4);
pixelY = MulDiv(templateunitY, baseunitY, 8);
Being baseunitX the value tmAveCharWidth and baseUnitY the value tmHeight returned by function GetTextMetrics(). You just need a HDC with the dialog font selected.

Troubles with ::MoveWindow - leaving blank space

I am quite desperate to resolve this very annoying issue :(
I am trying to display a child window on parent window. Some time the window need to be resized. But for some reason, when I using MoveWindow function it leaves blank space on the top of the parent window. I would like to present a picture here but I can not post a picture.
Here is the code example:
HWND hwnd // Comes from external function. Was defined as WS_CHILD previously
HWND hwndParent = ::GetParent(hwnd);
RECT parentRect = {0,0,0,0};
RECT childRect = {0,0,0,0};
::GetClientRect(hwndParent, &parentRect); // Suppose it returns {0,0,600,300}
BOOL ok = ::MoveWindow(hwnd, 0, 0, 600, 300, true);
::GetClientRect(hwnd, &childRect); // Will return {0,0,584,297}
WHY ?????
What am I doing wrong? Did I forgot some flags with window initialization?!
Rather than use GetClientRect, use GetWindowRect and MapWindowPoints(NULL,hwndParent,&parentRect,2) to adjust it to the parent window coordinates. GetWindowRect will include the non-client area that MoveWindow requires.
Edit: If you want a window that doesn't have a non-client area so the window rect and the client rect are the same size, you need to trim the window styles that you apply to the window. Avoid the WS_BORDER, WS_CAPTION, WS_DLGFRAME, WS_OVERLAPPED, WS_SIZEBOX, and WS_THICKFRAME styles.
MoveWindow updates window position, while GetClientRect gets a client-area part of the window, which does not have to be the same. If your window has non-client area, then everything is fine and works as expected.
If you are still under impression that child window does not fully cover parent's client area, then the spacing belongs to the child control/window, and you need to look for ways to remove it there (control flags, parameters etc).
MoveWindow operates on window coordinates -- including non-client area (borders, title bar, etc).
GetClientRect gets the area of the client portion of the window, ignoring borders, title bar, etc.
This is where the mismatch is. If you want to MoveWindow to a desired client size, you need to just AdjustWindowRect to try and predict what to pass into MoveWindow. Note that it's not always possible, and not always accurate. For example minimum / maximum sizes of windows, menus (which can wrap to multiple lines), etc.
The problem was WS_POPUP flag to the parent window.
Very strange. As far as I know it was not suppose to have such an effect.
Thanks for everyone!