summaryrefslogtreecommitdiff
path: root/src/Fl_win32.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'src/Fl_win32.cxx')
-rw-r--r--src/Fl_win32.cxx129
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