summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Melcher <fltk@matthiasm.com>2005-05-29 22:36:25 +0000
committerMatthias Melcher <fltk@matthiasm.com>2005-05-29 22:36:25 +0000
commit386cadbcf76d68c7ded89346915695602f7e15ec (patch)
tree32ec080a65143dc90a8a3d72055b22b5dcdf259b
parent0132f4f8fd7cd707213914c51361cd7832e67733 (diff)
Fluid interactive window resizing fixe (STR #873, 791)
Fixed fake_X_wm call on Win32 to return the correct window decoration sizes, even in XP's "Teletubbies" mode. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.1@4379 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
-rw-r--r--CHANGES1
-rw-r--r--src/Fl_win32.cxx89
2 files changed, 67 insertions, 23 deletions
diff --git a/CHANGES b/CHANGES
index b3253e03a..38dae6911 100644
--- a/CHANGES
+++ b/CHANGES
@@ -2,6 +2,7 @@ CHANGES IN FLTK 1.1.7
- Documentation fixes (STR #648, STR #692, STR #730, STR
#744, STR #745)
+ - Fluid interactive window resizing fixe (STR #873, 791)
- Fluid panel resize and alignment fixes (STR #891)
- Fl_Window::show(argc, argv) now sets the scheme before
showing the window; this should eliminate any
diff --git a/src/Fl_win32.cxx b/src/Fl_win32.cxx
index 6d182d831..6fbec0146 100644
--- a/src/Fl_win32.cxx
+++ b/src/Fl_win32.cxx
@@ -896,27 +896,70 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
int Fl_X::fake_X_wm(const Fl_Window* w,int &X,int &Y, int &bt,int &bx, int &by) {
int W, H, xoff, yoff, dx, dy;
int ret = bx = by = bt = 0;
- if (w->border() && !w->parent()) {
- if (w->size_range_set && (w->maxw != w->minw || w->maxh != w->minh)) {
- ret = 2;
- bx = GetSystemMetrics(SM_CXSIZEFRAME);
- by = GetSystemMetrics(SM_CYSIZEFRAME);
- } else {
- ret = 1;
- bx = GetSystemMetrics(SM_CXFIXEDFRAME);
- by = GetSystemMetrics(SM_CYFIXEDFRAME);
+
+ int fallback = 1;
+ if (!w->parent()) {
+ HWND hwnd = fl_xid(w);
+ if (hwnd) {
+ // 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.
+ HWND hwnd = fl_xid(w);
+ // request the style flags of this window, as WIN32 sees them
+ LONG style = GetWindowLong(hwnd, GWL_STYLE);
+ LONG exstyle = GetWindowLong(hwnd, GWL_EXSTYLE);
+ RECT r;
+ r.left = w->x();
+ r.top = w->y();
+ r.right = w->x()+w->w();
+ r.bottom = w->y()+w->h();
+ // get the decoration rectangle for the desired client rectangle
+ BOOL ok = AdjustWindowRectEx(&r, style, FALSE, exstyle);
+ if (ok) {
+ X = r.left;
+ Y = r.top;
+ W = r.right - r.left;
+ H = r.bottom - r.top;
+ bx = w->x() - r.left;
+ bt = GetSystemMetrics(SM_CYCAPTION);
+ by = w->y() - r.top - bt;
+ xoff = bx;
+ yoff = by + bt;
+ dx = W - w->w();
+ dy = H - w->h();
+ if (w->size_range_set && (w->maxw != w->minw || w->maxh != w->minh))
+ ret = 2;
+ else
+ ret = 1;
+ fallback = 0;
+ }
+ }
+ }
+ // This is the original (pre 1.1.7) routine to calculate window border sizes.
+ if (fallback) {
+ if (w->border() && !w->parent()) {
+ if (w->size_range_set && (w->maxw != w->minw || w->maxh != w->minh)) {
+ ret = 2;
+ bx = GetSystemMetrics(SM_CXSIZEFRAME);
+ by = GetSystemMetrics(SM_CYSIZEFRAME);
+ } else {
+ ret = 1;
+ bx = GetSystemMetrics(SM_CXFIXEDFRAME);
+ by = GetSystemMetrics(SM_CYFIXEDFRAME);
+ }
+ bt = GetSystemMetrics(SM_CYCAPTION);
}
- bt = GetSystemMetrics(SM_CYCAPTION);
+ //The coordinates of the whole window, including non-client area
+ xoff = bx;
+ yoff = by + bt;
+ dx = 2*bx;
+ dy = 2*by + bt;
+ X = w->x()-xoff;
+ Y = w->y()-yoff;
+ W = w->w()+dx;
+ H = w->h()+dy;
}
- //The coordinates of the whole window, including non-client area
- xoff = bx;
- yoff = by + bt;
- dx = 2*bx;
- dy = 2*by + bt;
- X = w->x()-xoff;
- Y = w->y()-yoff;
- W = w->w()+dx;
- H = w->h()+dy;
//Proceed to positioning the window fully inside the screen, if possible
//Make border's lower right corner visible
@@ -963,10 +1006,10 @@ void Fl_Window::resize(int X,int Y,int W,int H) {
if (!border()) flags |= SWP_NOACTIVATE;
if (resize_from_program && shown()) {
if (!resizable()) size_range(w(),h(),w(),h());
- int dummy, bt, bx, by;
+ int dummy_x, dummy_y, bt, bx, by;
//Ignore window managing when resizing, so that windows (and more
//specifically menus) can be moved offscreen.
- if (Fl_X::fake_X_wm(this, dummy, dummy, bt, bx, by)) {
+ if (Fl_X::fake_X_wm(this, dummy_x, dummy_y, bt, bx, by)) {
X -= bx;
Y -= by+bt;
W += 2*bx;
@@ -1137,9 +1180,9 @@ void Fl_Window::size_range_() {
void Fl_X::set_minmax(LPMINMAXINFO minmax)
{
- int td, wd, hd, dummy;
+ int td, wd, hd, dummy_x, dummy_y;
- fake_X_wm(w, dummy, dummy, td, wd, hd);
+ fake_X_wm(w, dummy_x, dummy_y, td, wd, hd);
wd *= 2;
hd *= 2;
hd += td;