C++ Visual Studio 2012应用程序窗口创建/调整大小与VS2008窗口创建不同?为什么?
@编辑:我发现这似乎是Windows8RC的一个问题,因为我尝试了Windows7和VS2012,包括经典和Aero视图,并且效果很好。感谢@Werner Henze和@Ven Boigt的反馈 编辑2:事实证明这是Windows中的一个bug,因为它是测试版,在更新的版本中得到了修复,所以我不必再担心这个问题了。无论如何,谢谢你的反馈 我过去常常执行以下操作来创建800*600客户区的窗口:C++ Visual Studio 2012应用程序窗口创建/调整大小与VS2008窗口创建不同?为什么?,c++,windows,winapi,visual-c++,visual-studio-2012,C++,Windows,Winapi,Visual C++,Visual Studio 2012,@编辑:我发现这似乎是Windows8RC的一个问题,因为我尝试了Windows7和VS2012,包括经典和Aero视图,并且效果很好。感谢@Werner Henze和@Ven Boigt的反馈 编辑2:事实证明这是Windows中的一个bug,因为它是测试版,在更新的版本中得到了修复,所以我不必再担心这个问题了。无论如何,谢谢你的反馈 我过去常常执行以下操作来创建800*600客户区的窗口: dwStyle = WS_OVERLAPPED | WS_THICKFRAME | WS_BORDER
dwStyle = WS_OVERLAPPED | WS_THICKFRAME | WS_BORDER | WS_DLGFRAME | WS_SYSMENU | WS_MINIMIZEBOX;
hWindowHandle = CreateWindow( L"CGFramework", wszWndCaption,
pWindowData->dwStyle, pWindowData->nPositionX, pWindowData->nPositionY,
800 + GetSystemMetrics( SM_CXSIZEFRAME )*2,
600 + GetSystemMetrics( SM_CYSIZEFRAME ) *2
+ GetSystemMetrics( SM_CYCAPTION ),
0, 0, hInstance, 0
);
然后,当使用GetClientRect查询客户机rect时,我以前得到800*600,但现在我将Visual Studio 2008项目升级到VS2012,现在GetClientRect()函数返回792*592
最重要的是,正在创建的窗口的实际大小是804*629,我认为没有理由,因为可调整大小的帧(来自WS_THICKFRAME)每侧明显大于2个像素
我原以为这是Windows8的Aero行为问题,但后来我意识到这只发生在我的VS2012版本上,而不是VS2008版本上。如果我在Aero或经典风格上运行它,这没有什么区别,这种行为只适用于VS2012版本。为什么?我是否可以在VS2012项目配置中更改某些内容来修复这种可怕的行为
我尝试更改项目配置的“DPI感知”设置,但这并没有任何区别。我还在同一个配置页面中删除了manifest的使用,仍然没有在结果窗口中看到任何更改
这是我的测试代码:
#include <Windows.h>
#include <cstdio>
LRESULT CALLBACK MainWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
switch( uMsg )
{
// WM_DESTROY is sent when the window is being destroyed.
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc( hWnd, uMsg, wParam, lParam );
}
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT nShowCmd )
{
WNDCLASS wc;
wc.style = NULL; // CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = MainWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(0, IDI_APPLICATION);
wc.hCursor = LoadCursor(0, IDC_ARROW);
wc.hbrBackground = CreateSolidBrush(GetSysColor(COLOR_3DFACE));
wc.lpszMenuName = 0;
wc.lpszClassName = L"CGFramework";
DWORD dwStyle = WS_OVERLAPPED | WS_THICKFRAME | WS_BORDER |
WS_DLGFRAME | WS_SYSMENU | WS_MINIMIZEBOX; // WS_DLGFRAME |
if( !RegisterClass(&wc) )
{
MessageBox(0, L"RegisterClass FAILED", 0, 0);
return E_FAIL;
}
RECT r;
//r.left = 100;
//r.top = 100;
//r.right = 800;
//r.bottom = 600;
////-----------------------------
r.left = 100;
r.top = 100;
r.right = 900;
r.bottom = 700;
////-----------------------------
//r.left = 100;
//r.top = 100;
//r.right = 800+GetSystemMetrics( SM_CXFRAME )*2;
//r.bottom = 600+GetSystemMetrics( SM_CYFRAME )*2+GetSystemMetrics( SM_CYCAPTION );
BOOL result = AdjustWindowRect( &r, dwStyle, FALSE );
HWND hWindowHandle = CreateWindow( L"CGFramework", L"testWindow", dwStyle,
r.left, r.top, r.right-r.left, r.bottom-r.top,
// r.left, r.top, r.right, r.bottom,
0, 0, hInstance, 0 );
if( 0 == hWindowHandle )
{
MessageBox(0, L"CreateWindow FAILED", 0, 0);
UnregisterClass( wc.lpszClassName, hInstance );
return 0;
}
char buffer[512]; // for outing test message
GetClientRect( hWindowHandle, &r );
sprintf( &buffer[0], "left=%i, top=%i, right=%i, bottom=%i", r.left, r.top, r.right, r.bottom );
MessageBoxA(0, buffer, 0, 0); // print rect values before ShowWindow
ShowWindow( hWindowHandle, SW_SHOW );
GetClientRect( hWindowHandle, &r );
sprintf( &buffer[0], "left=%i, top=%i, right=%i, bottom=%i", r.left, r.top, r.right, r.bottom );
MessageBoxA(0, buffer, 0, 0); // print rect values after ShowWindow
// main window loop
MSG msg;
ZeroMemory( &msg, sizeof( MSG ) );
while( msg.message != WM_QUIT )
{
while( PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
if( GetAsyncKeyState( VK_ESCAPE ) )
DestroyWindow( hWindowHandle );
}
UnregisterClass( wc.lpszClassName, hInstance );
return 0;
}
#包括
#包括
LRESULT回调MainWndProc(HWND HWND、UINT uMsg、WPARAM WPARAM、LPARAM LPARAM)
{
开关(uMsg)
{
//WM_DESTROY在销毁窗口时发送。
案例WM_销毁:
PostQuitMessage(0);
返回0;
违约:
返回DefWindowProc(hWnd、uMsg、wParam、lParam);
}
}
int-WINAPI WinMain(HINSTANCE-HINSTANCE、HINSTANCE-hPrevInstance、LPSTR-lpCmdLine、int-nShowCmd)
{
WNDCLASS wc;
wc.style=NULL;//CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc=MainWndProc;
wc.cbClsExtra=0;
wc.cbWndExtra=0;
wc.hInstance=hInstance;
wc.hIcon=加载图标(0,IDI_应用程序);
wc.hCursor=加载光标(0,IDC_箭头);
wc.hbrBackground=CreateSolidBrush(GetSysColor(COLOR_3DFACE));
wc.lpszMenuName=0;
wc.lpszClassName=L“CGFramework”;
DWORD dwStyle=WS|U重叠| WS|U厚框| WS|U边框|
WS_DLGFRAME | WS_SYSMENU | WS_MINIMIZEBOX;//WS_DLGFRAME |
如果(!注册表类(&wc))
{
MessageBox(0,L“RegisterClass失败”,0,0);
返回E_失败;
}
矩形r;
//r、 左=100;
//r、 top=100;
//r、 右=800;
//r、 底部=600;
////-----------------------------
r、 左=100;
r、 top=100;
r、 右=900;
r、 底部=700;
////-----------------------------
//r、 左=100;
//r、 top=100;
//r、 右=800+GetSystemMetrics(SM_CXFRAME)*2;
//r、 底部=600+GetSystemMetrics(SM\u CYFRAME)*2+GetSystemMetrics(SM\u CYCAPTION);
BOOL结果=AdjustWindowRect(&r,dwStyle,FALSE);
HWND hWindowHandle=CreateWindow(L“CGFramework”,L“testWindow”,dwStyle,
r、 左,右上,右右左,右下,右上,
//右左,右上,右右下,
0,0,0);
if(0==hWindowHandle)
{
MessageBox(0,L“CreateWindow失败”,0,0);
取消注册类(wc.lpszClassName,hInstance);
返回0;
}
字符缓冲区[512];//用于路由测试消息
GetClientRect(hWindowHandle和r);
sprintf(缓冲区[0],“左=%i,上=%i,右=%i,下=%i”,r.left,r.top,r.right,r.bottom);
MessageBoxA(0,缓冲区,0,0);//在ShowWindow之前打印rect值
展示窗口(hWindowHandle、SW_SHOW);
GetClientRect(hWindowHandle和r);
sprintf(缓冲区[0],“左=%i,上=%i,右=%i,下=%i”,r.left,r.top,r.right,r.bottom);
MessageBoxA(0,缓冲区,0,0);//在ShowWindow之后打印rect值
//主窗口循环
味精;
零内存(&msg,sizeof(msg));
while(msg.message!=WM_退出)
{
while(peek消息(&msg,0,0,PM_-REMOVE))
{
翻译信息(&msg);
发送消息(&msg);
}
if(GetAsyncKeyState(VK_ESCAPE))
销毁窗口(hWindowHandle);
}
取消注册类(wc.lpszClassName,hInstance);
返回0;
}
在回答之前,请仔细观察代码,因为你可能会回答我已经尝试过的问题(我发布这个问题是因为我已经浪费了我所有的选择)
我正在使用Windows 8 RC(MS Windows 6.2.8400)和VS2012 RC(11.0.50706.0 QRELRC 2012年7月)来获得这种奇怪的行为,没有一种答案能够解决这个问题。在做出任何假设之前,请务必阅读它们并测试我的代码,因为此代码已在许多方面进行了测试,但存在细微的差异,最终没有任何改进。CreateWindow函数是Windows API的一部分,它不是由Visual Studio提供的,Visual Studio版本不会影响它 最可能的解释是,VS2012中的默认项目设置添加了一个清单,将应用程序标记为Aero aware或DPI aware,并且该清单的存在会更改WinAPI函数的行为。您可以编辑或删除清单以获取旧行为 Windows检查PE标题中的“最低操作系统版本”字段也是可能的,但可能性较小。较新版本的链接器通常不支持将较旧版本写入此字段,但
编辑
dwStyle = WS_OVERLAPPED | WS_THICKFRAME | WS_BORDER | WS_DLGFRAME | WS_SYSMENU | WS_MINIMIZEBOX;
RECT r;
r.left = 100;
r.top = 100;
r.right = 900;
r.bottom = 700;
BOOL result = AdjustWindowRect( &r, dwStyle, FALSE );
hWindowHandle = CreateWindow( L"CGFramework", wszWndCaption, pWindowData->dwStyle,
pWindowData->nPositionX, pWindowData->nPositionY,
r.left, r.top, r.right-r.left, r.bottom-r.top,
0, 0, hInstance, 0 );
#include "stdafx.h"
#include <Windows.h>
#include <cstdio>
#include <cassert>
LRESULT CALLBACK MainWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
switch( uMsg )
{
// WM_DESTROY is sent when the window is being destroyed.
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc( hWnd, uMsg, wParam, lParam );
}
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT nShowCmd )
{
WNDCLASS wc;
wc.style = NULL; // CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = MainWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(0, IDI_APPLICATION);
wc.hCursor = LoadCursor(0, IDC_ARROW);
wc.hbrBackground = CreateSolidBrush(GetSysColor(COLOR_3DFACE));
wc.lpszMenuName = 0;
wc.lpszClassName = L"CGFramework";
DWORD dwStyle = WS_OVERLAPPED | WS_THICKFRAME | WS_BORDER |
WS_DLGFRAME | WS_SYSMENU | WS_MINIMIZEBOX;
if( !RegisterClass(&wc) )
{
MessageBox(0, L"RegisterClass FAILED", 0, 0);
return E_FAIL;
}
RECT r;
//r.left = 100;
//r.top = 100;
//r.right = 800;
//r.bottom = 600;
////-----------------------------
r.left = 100;
r.top = 100;
r.right = 900;
r.bottom = 700;
////-----------------------------
//r.left = 100;
//r.top = 100;
//r.right = 800+GetSystemMetrics( SM_CXSIZEFRAME )*2;
//r.bottom = 600+GetSystemMetrics( SM_CYSIZEFRAME )*2+GetSystemMetrics( SM_CYCAPTION );
BOOL result = AdjustWindowRect( &r, dwStyle, FALSE );
assert(result);
char buffer[512];
sprintf( &buffer[0], "adjust left=%i, top=%i, right=%i, bottom=%i", r.left, r.top, r.right, r.bottom );
MessageBoxA(0, buffer, 0, 0);
HWND hWindowHandle = CreateWindow( L"CGFramework", L"Window Test", dwStyle, r.left, r.top, r.right-r.left, r.bottom-r.top, 0, 0, hInstance, 0 );
if( 0 == hWindowHandle )
{
MessageBox(0, L"CreateWindow FAILED", 0, 0);
UnregisterClass( wc.lpszClassName, hInstance );
return 0;
}
assert(GetWindowRect(hWindowHandle, &r));
sprintf( &buffer[0], "wnd left=%i, top=%i, right=%i, bottom=%i", r.left, r.top, r.right, r.bottom );
MessageBoxA(0, buffer, 0, 0);
GetClientRect( hWindowHandle, &r );
sprintf( &buffer[0], "style=%08x/%08x, exstyle=%08x, left=%i, top=%i, right=%i, bottom=%i", GetWindowLong(hWindowHandle, GWL_STYLE), dwStyle, GetWindowLong(hWindowHandle, GWL_EXSTYLE), r.left, r.top, r.right, r.bottom );
MessageBoxA(0, buffer, 0, 0);
ShowWindow( hWindowHandle, SW_SHOW );
GetClientRect( hWindowHandle, &r );
sprintf( &buffer[0], "left=%i, top=%i, right=%i, bottom=%i", r.left, r.top, r.right, r.bottom );
MessageBoxA(0, buffer, 0, 0);
MSG msg;
ZeroMemory( &msg, sizeof( MSG ) );
while( msg.message != WM_QUIT )
{
while( PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
if( GetAsyncKeyState( VK_ESCAPE ) )
DestroyWindow( hWindowHandle );
}
UnregisterClass( wc.lpszClassName, hInstance );
return 0;
}