#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Button.H>
Fl_Window *win2 = NULL;
void cb(Fl_Widget *widget, void *data)
{
if (win2->shown())
win2->hide();
else
win2->show();
}
int main(int argc, char **argv)
{
Fl_Window *win = new Fl_Window(100, 100, 100, 100);
Fl_Button *button = new Fl_Button(5, 5, 50, 20, "test");
button->callback(reinterpret_cast<Fl_Callback *>(cb));
win->add(button);
win->show();
win2 = new Fl_Window(300, 100, 100, 100);
Fl_Group *group = new Fl_Group(0, 0, 100, 100);
win2->add_resizable(*group);
win2->show();
Fl::run();
}
if (w->size_range_set && (w->maxw != w->minw || w->maxh != w->minh)) {
ret = 2;
bx = GetSystemMetrics(SM_CXSIZEFRAME);
by = GetSystemMetrics(SM_CYSIZEFRAME);
} else {
...
if (w->size_range_set && (w->maxw != w->minw || w->maxh != w->minh)) {
ret = 2;
int padding = GetSystemMetrics(SM_CXPADDEDBORDER);
NONCLIENTMETRICS ncm;
ncm.cbSize = sizeof(NONCLIENTMETRICS);
SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
bx = GetSystemMetrics(SM_CXFIXEDFRAME) + (padding ? padding + ncm.iBorderWidth : 0);
by = GetSystemMetrics(SM_CYFIXEDFRAME) + (padding ? padding + ncm.iBorderWidth : 0);
} else {
...
int Fl_X::fake_X_wm(const Fl_Window* w,int &X,int &Y, int &bt,int &bx, int &by, DWORD style, DWORD exstyle) {
int W, H, xoff, yoff, dx, dy;
int ret = bx = by = bt = 0;
int fallback = 1;
if (!w->parent()) {
if (fl_xid(w) || style) {
// The block below calculates the window borders by requesting the
// required decorated window rectangle for a desired client rectangle.
// If any part of the function above fails, we will drop to a
// fallback to get the best guess which is always available.
if (!style) {
HWND hwnd = fl_xid(w);
// request the style flags of this window, as WIN32 sees them
style = GetWindowLong(hwnd, GWL_STYLE);
exstyle = GetWindowLong(hwnd, GWL_EXSTYLE);
}
...
...
styleEx |= WS_EX_WINDOWEDGE | WS_EX_CONTROLPARENT; // changes start after this line
int wintype = 0;
if (w->border() && !w->parent()) {
if (w->size_range_set && (w->maxw != w->minw || w->maxh != w->minh)) wintype = 2;
else wintype = 1;
}
switch (wintype) {
// No border (used for menus)
case 0:
style |= WS_POPUP;
styleEx |= WS_EX_TOOLWINDOW;
break;
// Thin border and title bar
case 1:
style |= WS_DLGFRAME | WS_CAPTION;
if (!w->modal())
style |= WS_SYSMENU | WS_MINIMIZEBOX;
break;
// Thick, resizable border and title bar, with maximize button
case 2:
style |= WS_THICKFRAME | WS_SYSMENU | WS_MAXIMIZEBOX | WS_CAPTION;
if (!w->modal())
style |= WS_MINIMIZEBOX;
break;
}
int xwm = xp , ywm = yp , bt, bx, by;
fake_X_wm(w, xwm, ywm, bt, bx, by, style, styleEx);
if (by+bt) { // changes stop at this line
...
static int fake_X_wm(const Fl_Window* w,int &X, int &Y,
int &bt,int &bx,int &by,DWORD style=0,DWORD styleEx=0);
Sorry if I mislead you, I just noticed that resizing explicitly didn't help, so I assumed that it didn't detect the resize.
I'm afraid I can't be of much help in the internals of FLTK but just let me know if I should test something!
> I'm building my application on a new Windows development machine with
> Windows 8.1 (instead of previous Windows 7) and VS2013 (instead of
> previous VS2008) but with the same fltk-1.3.0 source as before.
You need to upgrade to 1.3.3, or the recent weekly snapshots.
Or switch to using mingw, or an older version of VC.
Or, use a bin editor to set the executable type to something older than Win7...
Basically, newer versions of the VS tools, running the exe on Win7 and later, will do some rather odd things to the window border settings.
I think this is fixed (or worked around at any rate) for fltk-1.3.3, but 1.3.0 is pretty old now and it has no idea what Win7, Win8.x or VS2013 are...
> @Greentea: Thanks very much for your work on this topic and the patch.
> It would be very much appreciated by the devs if you could attach your
> patch to the STR Andreas will hopefully file soon.
Does the function:
Fl_X::fake_X_wm(...)
have a user-visible scope?
If so, we may have a problem, as the patch will change its ABI which may not be a Good Thing...
So if Fl_X::fake_X_wm() is visible, we'll need to find another way to pass the relevant window style parameters around...
Of course, if Fl_X::fake_X_wm() is hidden internally to fltk, we are probably good to go.
Yes, that's what I thought, too. Unfortunately the method accesses some
private members of Fl_Window, so this is not as easy as it seems to be.
I just tried it as a proof of concept and got compile errors
class FL_EXPORT Fl_Window : public Fl_Group {
friend int fake_X_wm_Win7_compat(const Fl_Window* w,int &X, int &Y,
int &bt,int &bx,int &by,ulong style,ulong styleEx);
...
};
I’m not keen on the friend option; would it not be OK to just make fake_X_wm_Win7_compat() a private method?
because a bunch of its member functions call fake_X_wm().
What's the status for this right now? In the meantime I'm using greentea's fix locally here, but it would be great if a working solution was in place soon, so we can base our software release in January on at least a specified revision.
++++
The current patch looks to be ABI breaking, so probably can't be deployed in its current form...
Though that does not stop you using it if you are static linking, of course.
Or you can make sure the subsystem version code is set to 5 or less, of course, on the generated exe.
What you'd ideally want is a released version of fltk with a non ABI breaking fix in place. I'm not confident that will be in place in the timescale you have outlined...
--
Ian
Sent, much to my surprise, from my Fairphone FP1