diff options
| author | Manolo Gouy <Manolo> | 2016-01-10 19:08:16 +0000 |
|---|---|---|
| committer | Manolo Gouy <Manolo> | 2016-01-10 19:08:16 +0000 |
| commit | eeb65bef23b2d269ea38474c04a55ffca5c6e63e (patch) | |
| tree | e00061d0a9dfd7b28e031b1f976ae31c852fac39 /src/Fl_win32.cxx | |
| parent | acc50806538da470ba18a2f7b76ea65a64cb5f5c (diff) | |
1) Replicate in branch-1.3-porting all recent changes of branch-1.3
2) Advance branch-1.3-porting with new function Fl_X::capture_titlebar_and_borders()
that contains all the platform-specific code of all operations related to drawing
window borders and title bars. What is platform-specific and what is not
is therefore much clearer, to ease porting.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3-porting@11002 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src/Fl_win32.cxx')
| -rw-r--r-- | src/Fl_win32.cxx | 129 |
1 files changed, 69 insertions, 60 deletions
diff --git a/src/Fl_win32.cxx b/src/Fl_win32.cxx index 2ae1e6145..ea4a43fac 100644 --- a/src/Fl_win32.cxx +++ b/src/Fl_win32.cxx @@ -1546,7 +1546,7 @@ static int fake_X_wm_style(const Fl_Window* w,int &X,int &Y, int &bt,int &bx, in W = r.right - r.left; H = r.bottom - r.top; bx = w->x() - r.left; - by = r.bottom - w->y() - w->h(); // height of the bootm frame + by = r.bottom - w->y() - w->h(); // height of the bottom frame bt = w->y() - r.top - by; // height of top caption bar xoff = bx; yoff = by + bt; @@ -2697,81 +2697,90 @@ FL_EXPORT Window fl_xid_(const Fl_Window *w) { return temp ? temp->xid : 0; } +static RECT border_width_title_bar_height(Fl_Window *win, int &bx, int &by, int &bt) +{ + RECT r = {0,0,0,0}; + bx = by = bt = 0; + if (win->shown() && !win->parent() && win->border() && win->visible()) { + static HMODULE dwmapi_dll = LoadLibrary("dwmapi.dll"); + typedef HRESULT (WINAPI* DwmGetWindowAttribute_type)(HWND hwnd, DWORD dwAttribute, PVOID pvAttribute, DWORD cbAttribute); + static DwmGetWindowAttribute_type DwmGetWindowAttribute = dwmapi_dll ? + (DwmGetWindowAttribute_type)GetProcAddress(dwmapi_dll, "DwmGetWindowAttribute") : NULL; + int need_r = 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; + } + } + if (need_r) { + GetWindowRect(fl_xid(win), &r); + } + bx = (r.right - r.left - win->w())/2; + by = bx; + bt = r.bottom - r.top - win->h() - 2*by; + } + return r; +} + int Fl_Window::decorated_w() { - if (!shown() || parent() || !border() || !visible()) return w(); - int X, Y, bt, bx, by; - Fl_X::fake_X_wm(this, X, Y, bt, bx, by); + int bt, bx, by; + border_width_title_bar_height(this, bx, by, bt); return w() + 2 * bx; } int Fl_Window::decorated_h() { - if (!shown() || parent() || !border() || !visible()) return h(); - int X, Y, bt, bx, by; - Fl_X::fake_X_wm(this, X, Y, bt, bx, by); + int bt, bx, by; + border_width_title_bar_height(this, bx, by, bt); return h() + bt + 2 * by; } -void Fl_Paged_Device::print_window(Fl_Window *win, int x_offset, int y_offset) -{ - if (!win->shown() || win->parent() || !win->border() || !win->visible()) - print_widget(win, x_offset, y_offset); - else - draw_decorated_window(win, x_offset, y_offset, this); -} - -void Fl_Paged_Device::draw_decorated_window(Fl_Window *win, int x_offset, int y_offset, Fl_Surface_Device *toset) +/* Returns images of the captures of the window title-bar, and the left, bottom and right window borders. + On the WIN32 platform, this function exploits a feature of fl_read_image() which, when called + with NULL first argument and when fl_gc is set to the screen device context, captures the window decoration. + */ +void Fl_X::capture_titlebar_and_borders(Fl_RGB_Image*& top, Fl_RGB_Image*& left, Fl_RGB_Image*& bottom, Fl_RGB_Image*& right) { - static HMODULE dwmapi_dll = LoadLibrary("dwmapi.dll"); - typedef HRESULT (WINAPI* DwmGetWindowAttribute_type)(HWND hwnd, DWORD dwAttribute, PVOID pvAttribute, DWORD cbAttribute); - static DwmGetWindowAttribute_type DwmGetWindowAttribute = 0; - static const DWORD DWMWA_EXTENDED_FRAME_BOUNDS = 9; - int bt, bx, by; // compute the window border sizes - RECT r; - int need_r = 1; - if (dwmapi_dll) { - if (!DwmGetWindowAttribute) DwmGetWindowAttribute = (DwmGetWindowAttribute_type)GetProcAddress(dwmapi_dll, "DwmGetWindowAttribute"); - if (DwmGetWindowAttribute) { - if ( DwmGetWindowAttribute(fl_xid(win), DWMWA_EXTENDED_FRAME_BOUNDS, &r, sizeof(RECT)) == S_OK ) { - need_r = 0; - } - } - } - if (need_r) { - GetWindowRect(fl_xid(win), &r); - } - bx = (r.right - r.left - win->w())/2; - by = bx; - bt = r.bottom - r.top - win->h() - 2*by; - int ww = win->w() + 2 * bx; - int wh = win->h() + bt + 2 * by; - Fl_Display_Device::display_device()->set_current(); // make window current - win->show(); - Fl::check(); - win->make_current(); + top = left = bottom = right = NULL; + if (!w->shown() || w->parent() || !w->border() || !w->visible()) return; + int wsides, hbottom, bt; + RECT r = border_width_title_bar_height(w, wsides, hbottom, bt); + int htop = bt + hbottom; HDC save_gc = fl_gc; + Window save_win = fl_window; + Fl_Surface_Device *previous = Fl_Surface_Device::surface(); + Fl_Display_Device::display_device()->set_current(); + w->show(); + Fl::check(); + w->make_current(); fl_gc = GetDC(NULL); // get the screen device context + int ww = w->w() + 2 * wsides; // capture the 4 window sides from screen - Window save_win = fl_window; fl_window = NULL; // force use of read_win_rectangle() by fl_read_image() - uchar *top_image = fl_read_image(NULL, r.left, r.top, ww, bt + by); - uchar *left_image = bx ? fl_read_image(NULL, r.left, r.top, bx, wh) : NULL; - uchar *right_image = bx ? fl_read_image(NULL, r.right - bx, r.top, bx, wh) : NULL; - uchar *bottom_image = by ? fl_read_image(NULL, r.left, r.bottom-by, ww, by) : NULL; + uchar *rgb; + if (htop) { + rgb = fl_read_image(NULL, r.left, r.top, ww, htop); + top = new Fl_RGB_Image(rgb, ww, htop, 3); + top->alloc_array = 1; + } + if (wsides) { + rgb = fl_read_image(NULL, r.left, r.top + htop, wsides, w->h()); + left = new Fl_RGB_Image(rgb, wsides, w->h(), 3); + left->alloc_array = 1; + rgb = fl_read_image(NULL, r.right - wsides, r.top + htop, wsides, w->h()); + right = new Fl_RGB_Image(rgb, wsides, w->h(), 3); + right->alloc_array = 1; + rgb = fl_read_image(NULL, r.left, r.bottom-hbottom, ww, hbottom); + bottom = new Fl_RGB_Image(rgb, ww, hbottom, 3); + bottom->alloc_array = 1; + } + ReleaseDC(NULL, fl_gc); fl_window = save_win; - ReleaseDC(NULL, fl_gc); fl_gc = save_gc; - toset->set_current(); - // print the 4 window sides - fl_draw_image(top_image, x_offset, y_offset, ww, bt + by, 3); delete[] top_image; - if (left_image) { fl_draw_image(left_image, x_offset, y_offset, bx, wh, 3); delete left_image; } - if (right_image) { fl_draw_image(right_image, x_offset + win->w() + bx, y_offset, bx, wh, 3); delete right_image; } - if (bottom_image) { fl_draw_image(bottom_image, x_offset, y_offset + win->h() + bt + by, ww, by, 3); delete bottom_image; } - // print the window inner part - this->print_widget(win, x_offset + bx, y_offset + bt + by); - fl_gc = GetDC(fl_xid(win)); - ReleaseDC(fl_xid(win), fl_gc); -} + fl_gc = save_gc; + previous->Fl_Surface_Device::set_current(); +} #ifdef USE_PRINT_BUTTON // to test the Fl_Printer class creating a "Print front window" button in a separate window |
