C++ Builder XE4 > Windows 7, 8.1, 10의 윈도우 크기 정보 보기

구현 환경
C++ Builder XE4

관련


  • winAppDev > Link > Windows 10 > invisible border > 1px: visible, 8px: invisible

  • 창 크기 알아보기



    Windows 10 특유의 "invisible border".

    Windows 7, 8.1, 10에서 똑같이 윈도우 배치하기 위해서는, invisible border를 포함하지 않는 visible 윈도우 크기 정보를 알 필요가 있다.

    WPF and WIndows 10. Invisible border around windows?

    answered May 18 '16 at 23:59
    mikew

    You can get the offests by using a combination of the normal GetWindowRect function and the use of the DwmGetWindowAttribute function, together with the DWMWA_EXTENDED_FRAME_BOUNDS parameter.

    위의 함수를 사용하여 창 정보를 살펴보십시오.

    code



    Unit1.cpp
    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #pragma hdrstop
    
    #include "Unit1.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
        TRect arect_inv;
        RECT arect_nrm;
    
        HWND hwnd1 = this->Handle;
        HWND hwnd2 = this->Handle;
    
        GetWindowRect(hwnd1, &arect_nrm);
        DwmGetWindowAttribute(hwnd2, DWMWA_EXTENDED_FRAME_BOUNDS, &arect_inv, sizeof(TRect));
    
        String msg;
        msg = String().sprintf(L"GetWindowRect: top:%d, bottom:%d, left:%d, right:%d",
            arect_nrm.top, arect_nrm.bottom, arect_nrm.left, arect_nrm.right);
        msg += L"\r\n";
        msg += String().sprintf(L"DwmGetWindowAttribute: top:%d, bottom:%d, left:%d, right:%d",
            arect_inv.top, arect_inv.bottom, arect_inv.left, arect_inv.right);
    
        ShowMessage(msg);
    }
    //---------------------------------------------------------------------------
    

    실행 결과



    Windows 7





    Windows 8.1





    Windows 10





    지식


  • Windows 7에서 DwmGetWindowAttribute()가 0을 반환합니다
  • Windows 8.1과 10에서는 DwmGetWindowAttribute() 로부터 visible의 윈도우 사이즈를 얻을 수 있을 것 같다

    code > OS에 관계없이 visible 윈도우 크기를 얻는다.



    Unit1.c
    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #pragma hdrstop
    
    #include "Unit1.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
        TRect arect;
    
        GetVisibleWindowSize(this, &arect);
    
        int width = arect.bottom - arect.top;
        int height = arect.right - arect.left;
        String msg = String().sprintf(L"left:%d top:%d W:%d H:%d",
            arect.left, arect.top, width, height);
    
        ShowMessage(msg);
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::GetVisibleWindowSize(TForm *formPtr, TRect *rectPtr)
    {
        TRect arect_inv;
        RECT arect_nrm;
    
        if (formPtr == NULL || rectPtr == NULL) {
            return; // error
        }
    
        GetWindowRect(formPtr->Handle, &arect_nrm); // (1)
        DwmGetWindowAttribute(formPtr->Handle, DWMWA_EXTENDED_FRAME_BOUNDS, &arect_inv, sizeof(TRect)); // (2)
    
        // for Windows 7
        if (arect_inv.left == 0 && arect_inv.top == 0 && arect_inv.Bottom == 0 && arect_inv.right == 0) {
            // DwmGetWindowAttribute()が0を返すためGetWindowRect()の結果を使う
            rectPtr->left = arect_nrm.left;
            rectPtr->top = arect_nrm.top;
            rectPtr->right = arect_nrm.right;
            rectPtr->bottom = arect_nrm.bottom;
            return;
        }
    
        // for Windows 8.1, Windows 10
        //   Windows 8.1では(1)と(2)は同じ定義
        //   Windows 10ではinvisible borderにより(1)と(2)の結果が異なる
        //   invisible borderのサイズを含まない(2)の方を返す
        rectPtr->left = arect_inv.left;
        rectPtr->top = arect_inv.top;
        rectPtr->right = arect_inv.right;
        rectPtr->bottom = arect_inv.bottom;
    }
    
  • 좋은 웹페이지 즐겨찾기