diff --git a/Fltk/FlGui.cpp b/Fltk/FlGui.cpp
index 1e9c5eefb4202605557c00a925124a8dc9dee4c3..9bfff256cc3cc02c2b8ef2c6a60f535d48690b42 100644
--- a/Fltk/FlGui.cpp
+++ b/Fltk/FlGui.cpp
@@ -49,6 +49,7 @@ typedef unsigned long intptr_t;
 #include "Generator.h"
 #include "gl2ps.h"
 #include "gmshPopplerWrapper.h"
+#include "PixelBuffer.h"
 #if defined(HAVE_3M)
 #include "3M.h"
 #endif
@@ -816,6 +817,63 @@ void FlGui::splitCurrentOpenglWindow(char how)
   }
 }
 
+void FlGui::copyCurrentOpenglWindowToClipboard()
+{
+#if defined(WIN32)
+  GLint width = FlGui::instance()->getCurrentOpenglWindow()->w();
+  GLint height = FlGui::instance()->getCurrentOpenglWindow()->h();
+
+  // lines have to be 32 bytes aligned, suppose 24 bits per pixel; just crop it
+  width -= width % 4;
+
+  // get pixels
+  PixelBuffer *buffer = new PixelBuffer(width, height, GL_RGB, GL_UNSIGNED_BYTE);
+  buffer->fill(0);
+  unsigned char *pixels = (unsigned char*)buffer->getPixels();
+
+  // swap R and B since Windows bitmap format is BGR
+  int nBytes = 3 * width * height;
+  for(int i = 0; i < nBytes; i += 3){
+    unsigned char tmp = pixels[i];
+    pixels[i] = pixels[i + 2];
+    pixels[i + 2] = tmp;
+  }
+
+  // fill header
+  BITMAPINFOHEADER header;
+  header.biWidth = width;
+  header.biHeight = height;
+  header.biSizeImage = nBytes;
+  header.biSize = 40;
+  header.biPlanes = 1;
+  header.biBitCount = 3 * 8;
+  header.biCompression = BI_RGB;
+  header.biXPelsPerMeter = 0;
+  header.biYPelsPerMeter = 0;
+  header.biClrUsed = 0;
+  header.biClrImportant = 0;
+
+  // generate handle
+  HANDLE handle = (HANDLE)::GlobalAlloc(GHND, sizeof(BITMAPINFOHEADER) + nBytes);
+  if(handle != NULL){
+    // lock handle
+    char *pData = (char *)::GlobalLock((HGLOBAL)handle);
+    // copy header and data
+    memcpy(pData, &header, sizeof(BITMAPINFOHEADER));
+    memcpy(pData + sizeof(BITMAPINFOHEADER), pixels, nBytes);
+    // unlock
+    ::GlobalUnlock((HGLOBAL)handle);
+    // push DIB in clipboard
+    OpenClipboard(NULL);
+    EmptyClipboard();
+    SetClipboardData(CF_DIB, handle);
+    CloseClipboard();
+  }
+
+  delete buffer;
+#endif
+}
+
 char FlGui::selectEntity(int type)
 {
   return getCurrentOpenglWindow()->selectEntity
diff --git a/Fltk/FlGui.h b/Fltk/FlGui.h
index 060a28f1448f26f00e3d3d1e5a18876fc121f95e..be140f06292cb066dbe057abec9b61828dc8edd4 100644
--- a/Fltk/FlGui.h
+++ b/Fltk/FlGui.h
@@ -107,6 +107,8 @@ class FlGui{
   openglWindow *getCurrentOpenglWindow();
   // split the current opengl window
   void splitCurrentOpenglWindow(char how);
+  // copy the current opengl window to the clipboard
+  void copyCurrentOpenglWindowToClipboard();
   // select an entity in the most recent graphic window
   char selectEntity(int type);
   // display status message
diff --git a/Fltk/graphicWindow.cpp b/Fltk/graphicWindow.cpp
index fee9d895d8efe25e09c381ad803871cd8670022d..6e4a20d2745ccfbf635ab13609b82ad2cd13f399 100644
--- a/Fltk/graphicWindow.cpp
+++ b/Fltk/graphicWindow.cpp
@@ -246,6 +246,9 @@ static void file_window_cb(Fl_Widget *w, void *data)
   else if(str == "split_u"){
     FlGui::instance()->splitCurrentOpenglWindow('u');
   }
+  else if(str == "copy"){
+    FlGui::instance()->copyCurrentOpenglWindowToClipboard();
+  }
   drawContext::global()->draw();
 }
 
@@ -1949,6 +1952,9 @@ static Fl_Menu_Item bar_table[] = {
     {0},
   {"&Window", 0, 0, 0, FL_SUBMENU},
     {"New Window", 0, (Fl_Callback *)file_window_cb, (void*)"new", FL_MENU_DIVIDER},
+#if defined(WIN32)
+    {"Copy to Clipboard",  FL_CTRL+'c', (Fl_Callback *)file_window_cb, (void*)"copy", FL_MENU_DIVIDER},
+#endif
     {"Split Horizontally", 0, (Fl_Callback *)file_window_cb, (void*)"split_h"},
     {"Split Vertically",   0, (Fl_Callback *)file_window_cb, (void*)"split_v"},
     {"Unsplit",            0, (Fl_Callback *)file_window_cb, (void*)"split_u", FL_MENU_DIVIDER},