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.
Related
On this page : https://learn.microsoft.com/en-us/windows/win32/gdi/wm-ncpaint it is explained how to draw in the nonclient area with GDI.
How can I draw in the nonclient area of my window with Direct2D without having to deal with GDI or GDI+ ?
First of all, WM_NCPAINT is old. Using it will disable the DWM theme-ing for the window, giving a windows classic/7 basic look. So don't do it.
But to use any rendering API do draw in the client area, remove the standard window frame from the window by returning 0 when wParam is true in your WM_NCCALCSIZE message.
case WM_NCCALCSIZE:
if (static_cast<bool>(wParam))
return 0;
return DefWindowProc(hwnd, msg, wParam, lParam);
If you want to keep the standard borders, recalculate the window bounds in WM_NCCALCSIZE.
Then to get a "client area" title bar, use DwmExtendFrameIntoClientArea and extend it from the TOP.
Make sure to handle WM_NCHITTEST so that dragging your window will work too.
Make sure to premultiply your ALPHA in direct2d.
Drawing a rectangle at (0,0) will draw a rectangle in the titlebar of your new custom window.
SEE: https://github.com/oberth/custom-chrome
I am currently using GDIGRAB to capture a window. The problem is, because of the border, the mouse cursor has an offset on its position.
The idea is to put a window as borderless so the offset won't appear anymore. Given the handle of the aimed process, how can I change a window from windowed to borderless ?
Don't tinker with another process' windows. Instead, get the border offset.
HWND window = ...;
RECT wndRect, clientRect;
GetWindowRect(window,&wndRect);
GetClientRect(window,&clientRect);
POINT borderOffset={clientRect.left,clientRect.top};
ClientToScreen(window,&borderOffset);
borderOffset.x-=wndRect.left;
borderOffset.y-=wndRect.top;
// borderOffset now contains the x and y offsets for the window
am trying to move a custom button whose base class is CWnd, am using MoveWindow() method but each time i move the window the previously drawn window is still visible. i tryed to call InvalidateWindow, InvalidateRect together with UpdateWindow on the parent window but all didn't work. i also tried RedrawWindow nothing happend. how can i properly update the parent window with the new position of the button?
here is my sample code
void CCalendarCtrl::Shift()
{
RECT rc;
m_Up.GetWindowRect(&rc);
rc.top -= 20;
rc.bottom -=20;
m_Up.MoveWindow(&rc,TRUE);
RedrawWindow();
}
Call Invalidate() after movewindow().
https://social.msdn.microsoft.com/Forums/en-US/d6da8041-747c-4b31-b493-343e4516b452/are-the-coordinates-returned-by-cwndgetwindowrect-mfc-and-cwndmovewindow-mfc?forum=vcmfcatl
GetWindowRect returns screen coordinates. MoveWindow works using Client coordinates. So you need to do ScreenToClient(&rc) between the two calls.
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);
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.