Fix computation of Fl_Window::decorated_w() and decorated_h() when apps are resized through display setting.

Under Windows 10:
when the user sets the value of "Change the size of text, apps and other items" in display settings
to above 100 %, the computation of Fl_Window::decorated_w() and decorated_h() has to
take the scaling factor into account.
This factor is also necessary to draw correctly window title bars.

git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3-porting@11893 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
Manolo Gouy 2016-08-25 12:42:50 +00:00
parent a7ce881c7d
commit 5dbfe413ae
3 changed files with 40 additions and 9 deletions

View File

@ -2391,7 +2391,8 @@ void Fl_WinAPI_Window_Driver::capture_titlebar_and_borders(Fl_Shared_Image*& top
top = left = bottom = right = NULL;
if (!shown() || parent() || !border() || !visible()) return;
int wsides, hbottom, bt;
RECT r = border_width_title_bar_height(wsides, hbottom, bt);
float scaling;
RECT r = border_width_title_bar_height(wsides, hbottom, bt, &scaling);
int htop = bt + hbottom;
Fl_Surface_Device *previous = Fl_Surface_Device::surface();
Window save_win = fl_window;
@ -2403,8 +2404,9 @@ void Fl_WinAPI_Window_Driver::capture_titlebar_and_borders(Fl_Shared_Image*& top
int ww = w() + 2 * wsides;
// capture the 4 window sides from screen
if (htop) {
r_top = Fl::screen_driver()->read_win_rectangle(NULL, r.left, r.top, ww, htop, 0);
r_top = Fl::screen_driver()->read_win_rectangle(NULL, r.left, r.top, r.right - r.left + 1, htop, 0);
top = Fl_Shared_Image::get(r_top);
if (scaling >= 1.1) top->scale(ww, htop/scaling, 0);
}
if (wsides) {
r_left = Fl::screen_driver()->read_win_rectangle(NULL, r.left, r.top + htop, wsides, h(), 0);

View File

@ -62,7 +62,7 @@ class FL_EXPORT Fl_WinAPI_Window_Driver : public Fl_Window_Driver
HICON small_icon;
};
private:
RECT border_width_title_bar_height(int &bx, int &by, int &bt);
RECT border_width_title_bar_height(int &bx, int &by, int &bt, float *pscaling = NULL);
void shape_bitmap_(Fl_Image* b);
void shape_alpha_(Fl_Image* img, int offset);
public:

View File

@ -60,7 +60,13 @@ Fl_WinAPI_Window_Driver::~Fl_WinAPI_Window_Driver()
// --- private
RECT Fl_WinAPI_Window_Driver::border_width_title_bar_height(int &bx, int &by, int &bt)
RECT // frame of the decorated window in screen coordinates
Fl_WinAPI_Window_Driver::border_width_title_bar_height(
int &bx, // left and right border width
int &by, // bottom border height (=bx)
int &bt, // height of window title bar
float *pscaling // display scaling factor
)
{
Fl_Window *win = pWindow;
RECT r = {0,0,0,0};
@ -71,20 +77,42 @@ RECT Fl_WinAPI_Window_Driver::border_width_title_bar_height(int &bx, int &by, in
static DwmGetWindowAttribute_type DwmGetWindowAttribute = dwmapi_dll ?
(DwmGetWindowAttribute_type)GetProcAddress(dwmapi_dll, "DwmGetWindowAttribute") : NULL;
int need_r = 1;
float scaling = 1;
if (DwmGetWindowAttribute) {
const DWORD DWMWA_EXTENDED_FRAME_BOUNDS = 9;
if ( DwmGetWindowAttribute(fl_xid(win), DWMWA_EXTENDED_FRAME_BOUNDS, &r, sizeof(RECT)) == S_OK ) {
need_r = 0;
// Compute the global display scaling factor: 1, 1.25, 1.5, 1.75, etc...
// This factor can be set in Windows 10 by
// "Change the size of text, apps and other items" in display settings.
HDC hdc = GetDC(NULL);
int hs = GetDeviceCaps(hdc, HORZSIZE);
int hr = GetDeviceCaps(hdc, HORZRES);
int px = GetDeviceCaps(hdc, LOGPIXELSX);
//int dhr = GetDeviceCaps(hdc, DESKTOPHORZRES);
//int vs = GetDeviceCaps(hdc, VERTSIZE);
//int vr = GetDeviceCaps(hdc, VERTRES);
//int py = GetDeviceCaps(hdc, LOGPIXELSY);
//int dvr = GetDeviceCaps(hdc, DESKTOPVERTRES);
ReleaseDC(NULL, hdc);
scaling = (hs * px) / (hr * 25.4); scaling = int(scaling * 100 + 0.5)/100.;
}
}
if (need_r) {
GetWindowRect(fl_xid(win), &r);
}
bx = (r.right - r.left - win->w())/2;
if (pscaling) *pscaling = scaling;
bx = (r.right - r.left - int(win->w() * scaling))/2;
if (bx < 1) bx = 1;
by = bx;
bt = r.bottom - r.top - win->h() - 2*by;
bt = r.bottom - r.top - int(win->h() * scaling) - 2 * by;
//fprintf(LOG,
// "HORZSIZE=%d %d, HORZRES=%d %d, LOGPIXELSX=%d %d, DESKTOPHORZRES=%d %d scaling=%f bx=%d bt=%d\n",
// hs,vs,hr,vr,px,py,dhr,dvr,scaling, bx,bt);fflush(LOG);
}
return RECT(r);
return r;
}
@ -100,8 +128,9 @@ int Fl_WinAPI_Window_Driver::decorated_w()
int Fl_WinAPI_Window_Driver::decorated_h()
{
int bt, bx, by;
border_width_title_bar_height(bx, by, bt);
return h() + bt + 2 * by;
float scaling;
border_width_title_bar_height(bx, by, bt, &scaling);
return h() + bt/scaling + 2 * by;
}