Windows: remove necessity to compile with -DFLTK_HIDPI_SUPPORT to make WIN32 FLTK apps DPI-aware.

At this point, Windows FLTK apps detect HighDPI displays and rescale their GUI accordingly. They also
all reply to ctrl/+/-/0/ keystrokes to enlarge/shrink/reset their windows. 

git-svn-id: file:///fltk/svn/fltk/branches/branch-1.4@12723 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
Manolo Gouy 2018-03-09 16:27:27 +00:00
parent 12f6285147
commit 7f78b1ef14
8 changed files with 6 additions and 98 deletions

View File

@ -55,9 +55,7 @@ extern FL_EXPORT struct Fl_XMap {
COLORREF rgb; // this should be the type the RGB() macro returns
HPEN pen; // pen, 0 if none created yet
int brush; // ref to solid brush, 0 if none created yet
#ifdef FLTK_HIDPI_SUPPORT
int pwidth; // the width of the pen, if present
#endif
} *fl_current_xmap;
inline COLORREF fl_RGB() {return fl_current_xmap->rgb;}
inline HPEN fl_pen() {return fl_current_xmap->pen;}

View File

@ -87,10 +87,8 @@ void fl_cleanup_dc_list(void);
# include <wchar.h>
#endif
#ifdef FLTK_HIDPI_SUPPORT
typedef HRESULT(WINAPI * SetProcessDpiAwareness_type)(int);
static SetProcessDpiAwareness_type fl_SetProcessDpiAwareness = NULL;
#endif
typedef HRESULT(WINAPI * SetProcessDpiAwareness_type)(int);
static SetProcessDpiAwareness_type fl_SetProcessDpiAwareness = NULL;
extern bool fl_clipboard_notify_empty(void);
extern void fl_trigger_clipboard_notify(int source);
@ -522,7 +520,6 @@ void Fl_WinAPI_Screen_Driver::open_display_platform() {
return;
beenHereDoneThat = 1;
#ifdef FLTK_HIDPI_SUPPORT
HMODULE hMod = LoadLibrary("Shcore.DLL");
if (hMod) {
fl_SetProcessDpiAwareness = (SetProcessDpiAwareness_type)GetProcAddress(hMod, "SetProcessDpiAwareness");
@ -533,14 +530,12 @@ void Fl_WinAPI_Screen_Driver::open_display_platform() {
else fl_SetProcessDpiAwareness = NULL;
}
}
#endif // FLTK_HIDPI_SUPPORT
OleInitialize(0L);
get_imm_module();
}
#ifdef FLTK_HIDPI_SUPPORT
void Fl_WinAPI_Screen_Driver::init_screen_scale_factors() {
typedef HRESULT(WINAPI * GetDpiForMonitor_type)(HMONITOR, int, UINT *, UINT *);
HMODULE hMod = LoadLibrary("Shcore.DLL");
@ -558,7 +553,6 @@ void Fl_WinAPI_Screen_Driver::init_screen_scale_factors() {
}
}
}
#endif // FLTK_HIDPI_SUPPORT
class Fl_Win32_At_Exit {
@ -852,16 +846,9 @@ void Fl_WinAPI_System_Driver::paste(Fl_Widget &receiver, int clipboard, const ch
int hdots = GetDeviceCaps(hdc, HORZRES);
ReleaseDC(NULL, hdc);
float factor = (100.f * hmm) / hdots;
#ifdef FLTK_HIDPI_SUPPORT
float scaling = Fl::screen_driver()->scale(receiver.top_window()->driver()->screen_num());
width = int(width / (scaling * factor)); // convert to screen pixel unit
height = int(height / (scaling * factor));
#else
float scaling = ((Fl_WinAPI_Screen_Driver *)Fl::screen_driver())->DWM_scaling_factor();
width = int(width * scaling / factor); // convert to screen pixel unit
height = int(height * scaling / factor);
scaling = 1;
#endif
RECT rect = {0, 0, width, height};
Fl_Image_Surface *surf = new Fl_Image_Surface(width, height, 1);
Fl_Surface_Device::push_current(surf);
@ -1180,7 +1167,6 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
if (window) {
switch (uMsg) {
#ifdef FLTK_HIDPI_SUPPORT
case WM_DPICHANGED: { // 0x02E0
if (fl_SetProcessDpiAwareness && !Fl_WinAPI_Window_Driver::data_for_resize_window_between_screens_.busy) {
RECT r;
@ -1193,7 +1179,6 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
}
return 0;
}
#endif // FLTK_HIDPI_SUPPORT
case WM_QUIT: // this should not happen?
Fl::fatal("WM_QUIT message");
@ -2703,18 +2688,13 @@ void Fl_WinAPI_Window_Driver::capture_titlebar_and_borders(Fl_Shared_Image *&top
ww /= scaling;
if (wsides <= 1)
ww = w() + 2 * wsides;
#ifdef FLTK_HIDPI_SUPPORT
float DWMscaling = scaling;
#else
float DWMscaling = ((Fl_WinAPI_Screen_Driver *)Fl::screen_driver())->DWM_scaling_factor();
#endif
// capture the 4 window sides from screen
Fl_WinAPI_Screen_Driver *dr = (Fl_WinAPI_Screen_Driver *)Fl::screen_driver();
if (htop) {
r_top = dr->read_win_rectangle_unscaled(r.left, r.top, r.right - r.left, htop);
top = Fl_Shared_Image::get(r_top);
if (DWMscaling != 1)
top->scale(ww, htop / DWMscaling, 0, 1);
if (scaling != 1)
top->scale(ww, htop / scaling, 0, 1);
}
if (wsides) {
r_left = dr->read_win_rectangle_unscaled(r.left, r.top + htop, wsides, h() * scaling);

View File

@ -60,12 +60,8 @@ Fl_GDI_Copy_Surface_Driver::Fl_GDI_Copy_Surface_Driver(int w, int h) : Fl_Copy_S
float factorw = (100.f * hmm) / hdots;
float factorh = (100.f * vmm) / vdots;
// Global display scaling factor: 1, 1.25, 1.5, 1.75, etc...
#ifdef FLTK_HIDPI_SUPPORT
float scaling = Fl_Graphics_Driver::default_driver().scale();
((Fl_GDI_Graphics_Driver*)driver())->scale(scaling);
#else
float scaling = 1/((Fl_WinAPI_Screen_Driver*)Fl::screen_driver())->DWM_scaling_factor();
#endif
RECT rect; rect.left = 0; rect.top = 0; rect.right = (LONG)((w*scaling) * factorw); rect.bottom = (LONG)((h*scaling) * factorh);
gc = CreateEnhMetaFile (NULL, NULL, &rect, NULL);
if (gc != NULL) {

View File

@ -86,9 +86,7 @@ static void set_xmap(Fl_XMap& xmap, COLORREF c, int lw) {
// xmap.pen = CreatePen(PS_SOLID, 1, xmap.rgb); // get a pen into xmap.pen
LOGBRUSH penbrush = {BS_SOLID, xmap.rgb, 0};
xmap.pen = ExtCreatePen(PS_GEOMETRIC | PS_ENDCAP_FLAT | PS_JOIN_ROUND, lw, &penbrush, 0, 0);
#ifdef FLTK_HIDPI_SUPPORT
xmap.pwidth = lw;
#endif
xmap.brush = -1;
}
@ -100,11 +98,7 @@ void Fl_GDI_Graphics_Driver::color(Fl_Color i) {
Fl_Graphics_Driver::color(i);
Fl_XMap &xmap = fl_xmap[i];
int tw = line_width_ ? line_width_ : int(scale_); if (!tw) tw = 1;
if (!xmap.pen
#ifdef FLTK_HIDPI_SUPPORT
|| xmap.pwidth != tw
#endif
) {
if (!xmap.pen || xmap.pwidth != tw) {
#if USE_COLORMAP
if (fl_palette) {
set_xmap(xmap, PALETTEINDEX(i), tw);
@ -126,11 +120,7 @@ void Fl_GDI_Graphics_Driver::color(uchar r, uchar g, uchar b) {
COLORREF c = RGB(r,g,b);
Fl_Graphics_Driver::color( fl_rgb_color(r, g, b) );
int tw = line_width_ ? line_width_ : int(scale_); if (!tw) tw = 1;
if (!xmap.pen || c != xmap.rgb
#ifdef FLTK_HIDPI_SUPPORT
|| tw != xmap.pwidth
#endif
) {
if (!xmap.pen || c != xmap.rgb || tw != xmap.pwidth) {
clear_xmap(xmap);
set_xmap(xmap, c, tw);
}

View File

@ -42,9 +42,7 @@ protected:
static BOOL CALLBACK screen_cb(HMONITOR mon, HDC, LPRECT r, LPARAM);
BOOL screen_cb(HMONITOR mon, HDC, LPRECT r);
int get_mouse_unscaled(int &mx, int &my);
#ifdef FLTK_HIDPI_SUPPORT
void init_screen_scale_factors();
#endif
public:
Fl_WinAPI_Screen_Driver() : Fl_Screen_Driver() {
@ -86,7 +84,6 @@ public:
virtual void disable_im();
virtual void open_display_platform();
virtual void offscreen_size(Fl_Offscreen off, int &width, int &height);
#if defined(FLTK_HIDPI_SUPPORT)
virtual APP_SCALING_CAPABILITY rescalable() {
return PER_SCREEN_APP_SCALING;
}
@ -96,9 +93,6 @@ public:
virtual void scale(int n, float f) {
scale_of_screen[n] = f;
}
#else
float DWM_scaling_factor();
#endif
virtual float desktop_scale_factor();
};

View File

@ -600,32 +600,6 @@ Fl_RGB_Image *Fl_WinAPI_Screen_Driver::read_win_rectangle_unscaled(int X, int Y,
return rgb;
}
#ifndef FLTK_HIDPI_SUPPORT
/* Returns the current desktop scaling factor for screen_num (1.75 for example)
*/
float Fl_WinAPI_Screen_Driver::DWM_scaling_factor() {
// Compute the global desktop 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.
// We don't cache this value because it can change while the app is running.
HDC hdc = GetDC(NULL);
int hr = GetDeviceCaps(hdc, HORZRES); // pixels visible to the app
#ifndef DESKTOPHORZRES
#define DESKTOPHORZRES 118
/* As of 27 august 2016, the DESKTOPHORZRES flag for GetDeviceCaps()
has disappeared from Microsoft online doc, but is quoted in numerous coding examples
e.g., https://social.msdn.microsoft.com/Forums/en-US/6acc3b21-23a4-4a00-90b4-968a43e1ccc8/capture-screen-with-high-dpi?forum=vbgeneral
It is necessary for the computation of the scaling factor at runtime as done here.
*/
#endif
int dhr = GetDeviceCaps(hdc, DESKTOPHORZRES); // true number of pixels on display
ReleaseDC(NULL, hdc);
float scaling = dhr/float(hr);
scaling = int(scaling * 100 + 0.5)/100.; // round to 2 digits after decimal point
return scaling;
}
#endif // ! FLTK_HIDPI_SUPPORT
void Fl_WinAPI_Screen_Driver::offscreen_size(Fl_Offscreen off, int &width, int &height)
{

View File

@ -103,16 +103,10 @@ RECT // frame of the decorated window in screen coordinates
GetWindowRect(fl_xid(win), &r);
}
int width, height;
#ifdef FLTK_HIDPI_SUPPORT
RECT rc;
GetClientRect(fl_xid(win), &rc);
width = rc.right;
height = rc.bottom;
#else
float scaling = ((Fl_WinAPI_Screen_Driver*)Fl::screen_driver())->DWM_scaling_factor();
width = int(win->w() * scaling);
height = int(win->h() * scaling);
#endif
bx = (r.right - r.left - width)/2;
if (bx < 1) bx = 1;
by = bx;
@ -137,14 +131,9 @@ int Fl_WinAPI_Window_Driver::decorated_h()
{
int bt, bx, by;
border_width_title_bar_height(bx, by, bt);
#ifdef FLTK_HIDPI_SUPPORT
float s = Fl::screen_driver()->scale(screen_num());
int mini_by = by/s; if (mini_by < 1) mini_by = 1;
return h() + (bt + by)/s + mini_by;
#else
float scaling = ((Fl_WinAPI_Screen_Driver*)Fl::screen_driver())->DWM_scaling_factor();
return h() + bt/scaling + 2 * by +1;
#endif
}

View File

@ -84,19 +84,6 @@ public:
if( !pDataObj ) return E_INVALIDARG;
// set e_modifiers here from grfKeyState, set e_x and e_root_x
// check if FLTK handles this drag and return if it can't (i.e. BMP drag without filename)
/* Tricky point here: Not DPIaware applications use different units for the 'POINTL pt' argument
of the DragEnter, DragOver, and Drop member functions.
DragEnter receives the mouse coordinates in unscaled screen units,
whereas DragOver and Drop receive the mouse coordinates in scaled units.
DPIaware applications transmit unscaled screen units to all 3 member functions.
These coordinates should be divided by the window's scale to get FLTK units.
*/
#ifndef FLTK_HIDPI_SUPPORT
POINT mp;
GetCursorPos(&mp); // bypass Windows bug that gives mouse coordinates in unscaled screen units
pt.x = mp.x; pt.y = mp.y;
#endif
POINT ppt;
Fl::e_x_root = ppt.x = pt.x;
Fl::e_y_root = ppt.y = pt.y;