What of these should I use in InvalidateRect to refresh my window? And why?
The window rect includes the non-client area, i.e. the window borders, caption bar etc. The client rect does not.
GetWindowRect returns a rect in screen coordinates whereas GetClientRect returns a rect in client coordinates.
InvalidateRect receives a rect in client coordinates. If you want to invalidate your entire client area, then pass NULL to InvalidateRect. You could pass in the rect returned by GetClientRect, but it is far simpler and clearer to pass NULL.
A very simple explanation is that GetWindowRect() gives you the rectangle that includes the borders of the window. GetClientRect() gives you the rectangle that excludes the borders - the area that is allocated to the window specific drawing.
Please note that GetWindowRect() returns a rectangle in screen coordinates - coordinates that are relative to the screen/monitor. GetClientRect() returns a rectangle that is relative to itself.
GetClientRect gets the coordinates of the window's client area. Specifically this is the area inside the window chrome and excludes the header etc. One of the comments on the MSDN page sums it up quite well:
I would say that this function return size of the area that I can render to.
GetWindowsRect gets the coordinates of the whole window. This includes the header, status bar etc. However according to a comment on the MSDN page
Apps under Vista that are not linked with WINVER=6 will receive a misleading set of values here, that do not account for the extra padding of "glass" pixels Vista Aero applies to the window.
So unless this have been fixed for Windows 7 double check the result you get and make sure you have the correct value of WINVER.
From MSDN:
GetWindowRect
Retrieves the dimensions of the bounding rectangle of the specified window. The dimensions are given in screen coordinates that are relative to the upper-left corner of the screen.
GetClientRect
Retrieves the coordinates of a window's client area. The client coordinates specify the upper-left and lower-right corners of the client area. Because client coordinates are relative to the upper-left corner of a window's client area, the coordinates of the upper-left corner are (0,0).
More: client rect does not include title bar, borders, scroll bars, status bar...
Related
Let's say you have a resizable window with child scrollbar controls, and the scrollbars come and go depending on whether the window contents are large enough to require scrolling.
When both scrollbars are present, a small rectangle is effectively created in the bottom right corner of the window, at their intersection. Is there a clean strategy for clipping that rectangle when drawing on the window, so that you don't paint on it?
I guess my current approach is to obtain the rectangles for each scrollbar, and if those rectangles are not null, then use the rectangles' locations to determine the rectangle that we want to clip. And then call ExcludeClipRect for that rectangle. I guess a similar approach could be used, except with GetSystemMetrics(SM_CXVSCROLL) and GetSystemMetrics(SM_CYVSCROLL) to get the rectangle dimensions.
But is there a more accepted way of doing this, perhaps using some helpful clipping API functions? Thank you for any input.
How will i get a application x y position relative to the client screen?
I tried but all unsucessful so can anyone help.
RECT pta;
GetWindowRect(hWnd,&pta);
POINT Rpt = { pta.left, pta.top };
ScreenToClient(hWnd, &Rpt);
But this doesn't work.
I want to set my cursor position to middle in the window of my app
If I understand right, you want to call the SetCursorPos() windows API call to center the mouse cursor to your window. That function takes screen coordinates.
GetWindowRect() returns the window top and left coordinates already in the screen coordinates, so no transform is necessary.
To get to your window's center coordinates, you just need to add half of your window's width and height to the top-left point's coordinates. Then you can call SetCursorPos().
I have a control derived from COleControl. When loading this control , it calls OnSize, Within OnSize I am getting ClientRect area by calling GetClientRect and moving the control to the area got from GetClientRect.
First time when initializing the GetClientRect returns sizes in right and bottom. But next time when referesh happens, GetClientRect returns the area with bottom as 0. So I couldn't able to view the control.
Is there any way to get proper Client rect area in referesh also?
Or Any idea how this client rect size determined?
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.
Currently I'm repositioning dialog controls when the dialog is resized like this:
// Get the list control rect.
CRect listRect;
list->GetWindowRect(&listRect);
ScreenToClient(listRect);
// Get the dialog Rect.
CRect dialogRect;
GetWindowRect(&dialogRect);
ScreenToClient(dialogRect);
list->MoveWindow(listRect.left, listRect.top,
dialogRect.right - (2 * listRect.left), dialogRect.bottom - 100);
This works great in Windows XP, but when I tried in Windows Vista the positioning was off. I think this must be down to larger dialog borders and captions in Windows Vista dialogs, and the fact that GetWindowRect has the following entry in the documentation:
The dimensions are given in screen coordinates relative to the upper-left corner of the display screen. The dimensions of the caption, border, and scroll bars, if present, are included.
So my question is, how do I reposition dialog controls when resizing a dialog so that they are consistent between operating systems? Thanks
You should use GetClientRect instead of GetWindowRect followed by ScreenToClient -- the former returns the extents of the client part of the window (i.e. without borders), whereas the latter retrieves the extents of the whole window including non-client parts (albeit in client coordinates).
// Get the list control rect.
CRect listRect;
list->GetWindowRect(&listRect);
dlg->ScreenToClient(&listRect);
// Get the dialog Rect.
CRect dialogRect;
dlg->GetClientRect(&dialogRect);
list->MoveWindow(listRect.left, listRect.top, dialogRect.right - (2 * listRect.left), dialogRect.bottom - 100);