获取详细的窗口区域大小 - CreateWindow的窗口大小不是窗口的正确尺寸(Get exac

2019-09-20 16:34发布

我尝试创建C ++中的窗口,绘制窗口大小不我设置的大小相匹配矩形注意到了一些很烦人。

例如,如果我设置了小480x240窗口,并尝试通过获取GetWindowRect(HWND,与矩形),并计算宽度和高度绘制从上到下,从左到右的矩形:

rectangle_width = (rect.right - rect.left) / amountRectangleX;
rectangle_height = (rect.bottom - rect.top) / amountRectangleY;

如果amountRectangleX = 2且Y = 2它绘制4个矩形,但因此它不会填满整个屏幕或它呈现在它的宽度和高度是“关”。 发生这种情况的唯一方法是,如果我设置窗口大小=小480x240我想,要成为“画”的区域(我在其他语言的很多,所以我知道它做到了这一点)。 因为如果边界包含在窗口的大小 - 这将是另一台计算机上用不同的窗口样式和这样的不同。 我不能只是人工“改变”这为我的电脑。

如果我设置窗口大小=小480x240,并采取截图我看到,窗口空间= 452x232这是令人困惑的。 这将是确定的,如果我设置窗口大小=小480x240,但是当我GetWindowRect()我得到452x232,而不是小480x240然后是无效的,因为我没有多少空间可以利用。 这可以解释为什么我的矩形呈现出窗口的空间,我不希望这样。 但我还是希望能够把我的大小=小480x240或其他任何东西,但仍然有边界。

为什么它的工作这种方式,是有这个问题的解决方案? 我不能说希望能够设置一个窗口的分辨率,无论你使用什么计算机只有一个,你设置的大小是绘图区,你可以在画画。

Answer 1:

我用这个方法,现在它的工作原理:

if ( IsWindow( hwnd ) )
{

DWORD dwStyle = GetWindowLongPtr( hwnd, GWL_STYLE ) ;
DWORD dwExStyle = GetWindowLongPtr( hwnd, GWL_EXSTYLE ) ;
HMENU menu = GetMenu( hwnd ) ;

RECT rc = { 0, 0, width, height } ;

AdjustWindowRectEx( &rc, dwStyle, menu ? TRUE : FALSE, dwExStyle );

SetWindowPos( hwnd, NULL, 0, 0, rc.right - rc.left, rc.bottom - rc.top, SWP_NOZORDER | SWP_NOMOVE ) ;

}


Answer 2:

就像@Deukalion,我无意中把所需的客户端区域的大小为::CreateWindow()调用,并在绘制网格,我发现自己的短像素。 我把我的研究应用程序的屏幕截图的像素大小相同的方法。 我能理解,窗口的边框和标题栏带走从客户区一些空间 - 但令人沮丧的是,Windows 10下,甚至没有总的应用程序窗口具有所要求的大小!

我怀疑::CreateWindow()在宽度和高度中减去像素的硬编码的计算量较小的客户区,然后建立围绕窗口边框和标题栏。 这硬编码数量与Windows 10的超薄鲜明的主题窗口不再正确这是荒谬的- 没什么好说的尺寸在屏幕上被要求在这::CreateWindow()

我跟着@PeterRuderman的建议使用::AdjustWindowRect()调用:

RECT rect;
rect.left = rect.top = 0;
rect.right = clientWidth;
rect.bottom = clientHeight;
::AdjustWindowRect(&rect, wflags, false);
HWND hWindow = ::CreateWindow(wcName, title, wflags, 0, 0,
  rect.right - rect.left, rect.bottom - rect.top, 0, 0, hInstance, 0);
  • 如上所述https://msdn.microsoft.com/en-us/library/windows/desktop/dd162897.aspx的RECT结构考虑了rightbottom场作为预期的矩形之外
  • 这本来是很好,如果::AdjustWindowRect()会离开给定的原点坐标(0,0)的完整,使rightbottom可以直接填充到::CreateWindow()调用。 但让我吃惊,在leftbottom场转为阴性。


Answer 3:

我仍然不认为您提供足够的信息来解决你的问题,但这里的,你想要做什么(基本)一个完整的程序。 你可以把它比作自己,看看你要去哪里错了。

#include <Windows.h>

LRESULT CALLBACK WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
    switch( uMsg ) {
    case WM_CLOSE:
        PostQuitMessage( 0 );
        break;

    case WM_PAINT:
        {
            RECT clientArea;
            GetClientRect( hwnd, &clientArea );

            PAINTSTRUCT ps;
            BeginPaint( hwnd, &ps );

            HBRUSH brush = (HBRUSH)GetStockObject( BLACK_BRUSH );

            RECT topLeft = clientArea;
            topLeft.right /= 2;
            topLeft.bottom /= 2;

            RECT bottomRight = clientArea;
            bottomRight.left = bottomRight.right / 2;
            bottomRight.top = bottomRight.bottom / 2;

            FillRect( ps.hdc, &topLeft, brush );
            FillRect( ps.hdc, &bottomRight, brush );

            EndPaint( hwnd, &ps );
        }

        return 0;
    }

    return DefWindowProc( hwnd, uMsg, wParam, lParam );
}

int CALLBACK WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
    // Error checking omitted for brevity.
    WNDCLASSEX wc = { 0 };

    wc.cbSize = sizeof( wc );
    wc.lpfnWndProc = WindowProc;
    wc.hInstance = hInstance;
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wc.lpszClassName = L"testclass";

    ATOM classAtom = RegisterClassEx( &wc );

    HWND window = CreateWindow( L"testclass", L"Test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 480, 240, NULL, NULL, hInstance, NULL );

    MSG msg;

    while( GetMessage( &msg, NULL, 0, 0 ) ) {
        TranslateMessage( &msg );
        DispatchMessage( &msg );
    }
}

编辑

在重新阅读你的问题,我认为你只是为了寻找AdjustWindowRect API。 在这种情况下,你的问题是这样的一个的副本: WinAPI的:有指定的客户端区域大小创建一个窗口 。 对于未来的参考,“你可以在绘制区域”被称为客户区。



文章来源: Get exact window region size - CreateWindow window size isn't correct size of window