WINDEX
window2file.h
1 #pragma once
2 #include <sstream>
3 #include <windows.h>
4 #include <gdiplus.h>
5 #include "wex.h"
6 namespace wex
7 {
13  {
14  public:
15  window2file()
16  {
17  using namespace Gdiplus;
18 
19  GdiplusStartupInput gdiplusStartupInput;
20  GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
21 
22  UINT num = 0;
23  UINT size = 0;
24 
25  ImageCodecInfo *pImageCodecInfo = NULL;
26 
27  GetImageEncodersSize(&num, &size);
28  if (size == 0)
29  throw std::runtime_error("window2file");
30 
31  pImageCodecInfo = (ImageCodecInfo *)(malloc(size));
32  if (pImageCodecInfo == NULL)
33  throw std::runtime_error("window2file");
34 
35  GetImageEncoders(num, size, pImageCodecInfo);
36  for (UINT j = 0; j < num; ++j)
37  {
38  if (wcscmp(pImageCodecInfo[j].MimeType, L"image/png") == 0)
39  {
40  myPngclsid = pImageCodecInfo[j].Clsid;
41  free(pImageCodecInfo);
42  return;
43  }
44  }
45  ::free(pImageCodecInfo);
46  throw std::runtime_error("window2file cannot find encoder");
47  }
48  ~window2file()
49  {
50  Gdiplus::GdiplusShutdown(gdiplusToken);
51  }
52 
57  void save(gui &w, const std::string &filename)
58  {
59  save( w.handle(), filename );
60  }
61  void save(HWND hw, const std::string &filename)
62  {
63  HDC memdc;
64  HBITMAP membit;
65  HDC scrdc = ::GetDC(hw);
66  RECT rcClient;
67  GetClientRect(hw, &rcClient);
68  int Height = rcClient.bottom - rcClient.top;
69  int Width = rcClient.right - rcClient.left;
70  memdc = CreateCompatibleDC(scrdc);
71  membit = CreateCompatibleBitmap(scrdc, Width, Height);
72  SelectObject(memdc, membit);
73  BitBlt(memdc, 0, 0, Width, Height, scrdc, 0, 0, SRCCOPY);
74 
75  Gdiplus::Bitmap bitmap(membit, NULL);
76  std::wstringstream wss;
77  wss << filename.c_str();
78 
79  bitmap.Save(
80  wss.str().c_str(),
81  &myPngclsid,
82  NULL);
83 
84  DeleteObject(memdc);
85  DeleteObject(membit);
86  ReleaseDC(0, scrdc);
87  }
93  bool draw(gui &w, const std::string &filename)
94  {
95  // read image from file
96  std::wstringstream wss;
97  wss << filename.c_str();
98  auto bitmap = new Gdiplus::Bitmap(wss.str().c_str());
99  if( ! bitmap )
100  return false;
101  if( bitmap->GetLastStatus() != S_OK)
102  return false;
103  // image dimensions
104  float xh = bitmap->GetHeight();
105  float xw = bitmap->GetWidth();
106 
107 
108  // window dimensions
109  RECT r;
110  GetClientRect(w.handle(), &r);
111  int rw = r.right - r.left;
112  int rh = r.bottom - r.top;
113 
114  // check if shrinking needed
115  if (xh > rh || xw > rw)
116  {
117  // preserve aspect ratio by scaling both dimensions by the largest required by either
118  float sh = xh / rh;
119  float sw = xw / rw;
120  float s = sh;
121  if (sw > sh)
122  s = sw;
123  xh /= s;
124  xw /= s;
125  }
126  Gdiplus::PointF dst[] =
127  {
128  Gdiplus::PointF(0.0f, 0.0f), // top left
129  Gdiplus::PointF(xw, 0.0f), // top right
130  Gdiplus::PointF(0.0f, xh), // bottom left
131  };
132 
133  // draw
134  Gdiplus::Graphics graphics(GetDC(w.handle()));
135  graphics.SetCompositingMode(Gdiplus::CompositingModeSourceCopy);
136  auto ret = graphics.DrawImage(bitmap, dst, 3);
137 
138  delete bitmap;
139 
140  if( ret != Gdiplus::Status::Ok )
141  return false;
142 
143  return true;
144  }
145 
146  private:
147  CLSID myPngclsid;
148  ULONG_PTR gdiplusToken;
149  };
150 }
The base class for all windex gui elements.
Definition: wex.h:824
HWND handle()
get window handle
Definition: wex.h:1655
transfer image between window contents and image file in PNG format.
Definition: window2file.h:13
bool draw(gui &w, const std::string &filename)
Draw png file in window.
Definition: window2file.h:93
void save(gui &w, const std::string &filename)
Save window contents to image file.
Definition: window2file.h:57
Definition: wex.h:3549