我尝试创建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或其他任何东西,但仍然有边界。
为什么它的工作这种方式,是有这个问题的解决方案? 我不能说希望能够设置一个窗口的分辨率,无论你使用什么计算机只有一个,你设置的大小是绘图区,你可以在画画。
我用这个方法,现在它的工作原理:
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 ) ;
}
就像@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结构考虑了
right
和bottom
场作为预期的矩形之外 。 - 这本来是很好,如果
::AdjustWindowRect()
会离开给定的原点坐标(0,0)的完整,使right
和bottom
可以直接填充到::CreateWindow()
调用。 但让我吃惊,在left
和bottom
场转为阴性。
我仍然不认为您提供足够的信息来解决你的问题,但这里的,你想要做什么(基本)一个完整的程序。 你可以把它比作自己,看看你要去哪里错了。
#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