Visual Studio 2012应用程序窗口创建/调整大小与VS2008窗口创建有所不同吗?为什么?

问题描述 投票:3回答:3

@@:我发现这似乎是Windows 8 RC的问题,因为我尝试使用Windows 7和VS 2012(经典视图和Aero视图),并且运行良好。感谢@Werner Henze和@Ven Boigt的反馈

编辑2:原来这是Windows中的一个错误,因为它是Beta版,并且已在较新的版本中修复,因此我不必再为此担心。仍然感谢您的反馈。

我曾经做过以下工作,以创建一个800 * 600客户区域的窗口:

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查询客户端时,我曾经得到800 * 600,但是现在我将Visual Studio 2008项目升级到VS2012,现在GetClientRect()函数返回了792 * 592。

最重要的是,正在创建的窗口的实际大小为804 * 629,由于可调整大小的帧(来自WS_THICKFRAME)明显大于每侧2个像素,因此我没有理由。

我以为这是Windows 8的Aero行为的问题,但是后来我意识到这仅在我的VS2012版本而不是VS2008版本中发生。如果我以Aero或经典样式运行它,则没有区别,该行为仅适用于VS2012构建。为什么?我可以在VS2012项目配置上进行一些更改来修复此可怕行为吗?

我尝试更改项目配置的“ DPI Awareness”设置,但这没有任何区别。我还删除了在同一配置页面中使用清单的方法,但仍然看不到结果窗口中的任何更改。

这是我的测试代码:

#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;
}

请在回答之前仔细查看代码,因为您可能最终会回答我已经尝试过的内容(我发布此问题是因为我已经浪费了所有选择)。

我正在使用Windows 8 RC(MS Windows 6.2.8400)和VS2012 RC(11.0.50706.0 QRELRC 2012年7月)来获得这种奇怪的行为,没有一个好的答案能够解决此问题。在做任何假设之前,请务必阅读它们并测试我的代码,因为此代码已经通过多种方式进行了测试,但存在细微的差异,最终并没有任何改善。

@@:我发现这似乎是Windows 8 RC的问题,因为我尝试使用Windows 7和VS 2012(经典视图和Aero视图),并且运行良好。感谢@Werner Henze和@Ven Boigt ...

c++ windows winapi visual-c++ visual-studio-2012
3个回答
6
投票

正如其他人所述,AdjustWindowRectAdjustWindowRectEx是必经之路。如果设置为WS_VSCROLLWS_HSCROLL,则需要进行特殊处理。在我的实用程序库中,我还对WS_EX_STATICEDGE进行了特殊处理,但不要问我从何处获得此信息(至少在AdjustWindowRect[Ex]的MSDN文档中没有)。


6
投票

CreateWindow函数是Windows API的一部分,Visual Studio不提供,并且Visual Studio版本不影响它。


3
投票

尝试使用AdjustWindowRectEx,并确保样式和扩展样式与精确

© www.soinside.com 2019 - 2024. All rights reserved.