Visual Studio 2012应用程序窗口创建/调整大小与VS2008窗口创建不同?为什么? [英] Visual Studio 2012 app window creation/resizing differ from VS2008 window creation? Why?

查看:1892
本文介绍了Visual Studio 2012应用程序窗口创建/调整大小与VS2008窗口创建不同?为什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

@EDIT:我发现它似乎是一个问题的Windows 8 RC,因为我试图与Windows 7和VS 2012,经典和Aero视图,它工作正常。感谢@Werner Henze和@Ven Boigt的反馈

@ I found out that it seems to be an issue of the Windows 8 RC, because I tried with Windows 7 and VS 2012, both classic and Aero view and it works fine. Thanks to @Werner Henze and @Ven Boigt for their feedback

编辑2:这是Windows中的一个错误,因为它是测试版,并且在较新的修订版本中修复了我不必担心这个了。非常感谢您的反馈。

EDIT 2: Turns out this was a bug in Windows due to being beta and it was fixed in newer revisions so I don't have to worry about this anymore. Thanks for the feedback anyway.

我用来创建一个800 * 600客户区的窗口:

I used to do the following to create a window of an 800*600 client area:

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。

Then when querying the client rect with GetClientRect, I used to get 800*600, but now I upgraded my Visual Studio 2008 project to VS2012, and now the GetClientRect() function is returning 792*592 instead.

最重要的是,正在创建的窗口的实际大小是804 * 629,我看不到原因,因为可调整大小的框架(来自WS_THICKFRAME)

On top of that, the actual size of the window being created is 804*629, for which I see no reason as the resizeable frame (from WS_THICKFRAME) is obviously larger than 2 pixels on each side.

我认为这是Windows 8的Aero行为的一个问题,但后来我意识到这只发生在我的VS2012构建,而不是与我的VS2008构建。它没有什么区别,如果我在Aero或经典风格上运行它的行为将只适用于VS2012构建。为什么?有没有什么我可以改变我的VS2012项目配置来修复这个可怕的行为?

I thought it was an issue of the Aero behaviour of Windows 8, but then I realized this is only happening with my VS2012 builds and not with my VS2008 builds. It makes no difference if I run it on Aero or the classic style, the behaviour will only apply to VS2012 builds. Why? Is there something I can change on my VS2012 project configuration to fix this horrible behaviour?

我尝试改变项目配置的DPI意识设置,但这不是任何差异。我也删除了在同一配置页面使用清单,仍然看不到任何更改的结果窗口。

I tried changing "DPI Awareness" setting of the project config, but this is not making any difference. I also removed the use of manifest in the same config page, still don't see any change in the resulting window.

这是我的测试代码:

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

请务必仔细看看代码,然后再回答,

Please watch carefullly the code before answering as you may end up answering something I already tried (I'm posting this question because I already wasted all my choices).

我使用的是Windows 8 RC(MS Windows 6.2.8400)和VS2012 RC(我已经浪费了所有的选择) 11.0.50706.0 QRELRC 2012年7月)得到这个奇怪的行为,没有一个种类的答案能够解决这个问题。在做出任何假设之前,请务必阅读它们并测试我的代码,因为此代码已经通过许多方式进行了测试,并且最终没有提高。

I'm using Windows 8 RC (MS windows 6.2.8400) and VS2012 RC (11.0.50706.0 QRELRC July 2012) to get this weird behaviour and none of the kind answers were able to address this issue. Be sure of reading them and testing my code before making any assumptions, as this code has been tested in many ways with subtle differences which in the end provided no improvement.

推荐答案

像其他人说的AdjustWindowRect或AdjustWindowRectEx是要走的路。如果设置了WS_VSCROLL或WS_HSCROLL,则需要进行特殊处理。在我的util库中,我还有对WS_EX_STATICEDGE的特殊处理,但不要问我在哪里得到这个信息(至少它不是在MSDN文档中的AdjustWindowRect [Ex])。

As others stated AdjustWindowRect or AdjustWindowRectEx is the way to go. You need to do special handling if WS_VSCROLL or WS_HSCROLL is set. In my util library I also have special handling for WS_EX_STATICEDGE, but don't ask me where I got this information from (at least it's not in the MSDN documentation for AdjustWindowRect[Ex]).

你最近的测试中的错误是你调用CreateWindow的方式错误,它需要一个宽度和高度,不正确和底部。这应该按照需要工作:

The bug in your latest test was that you are calling CreateWindow the wrong way, it takes a width and heigth, not right and bottom. This should work as required:

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 );

仅供参考,以下是完整的示例:

And just for information, here is the complete sample:

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

这篇关于Visual Studio 2012应用程序窗口创建/调整大小与VS2008窗口创建不同?为什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆