29 #include <shobjidl_core.h> 40 #pragma region Initialization 48 const char appname[] =
"Lindenmayer";
50 WNDCLASSEX wndClass = {0};
52 wndClass.cbSize =
sizeof(WNDCLASSEX);
53 wndClass.style = CS_HREDRAW | CS_VREDRAW;
55 wndClass.cbClsExtra = 0;
56 wndClass.cbWndExtra = 0;
57 wndClass.hInstance = hInst;
58 wndClass.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_ICON1));
59 wndClass.hCursor = LoadCursor(
nullptr, IDC_ARROW);
60 wndClass.hbrBackground = (HBRUSH)GetStockObject(COLOR_WINDOW+1);
61 wndClass.lpszMenuName =
nullptr;
62 wndClass.lpszClassName = appname;
63 wndClass.hIconSm = LoadIcon(hInst, MAKEINTRESOURCE(IDI_ICON2));
65 RegisterClassEx(&wndClass);
67 const DWORD dwStyle = WS_CAPTION | WS_MINIMIZEBOX | WS_THICKFRAME | WS_SYSMENU;
68 const DWORD dwStyleEx = WS_EX_APPWINDOW | WS_EX_DLGMODALFRAME;
74 r.left = 0; r.right = w;
75 r.top = 0; r.bottom = h + GetSystemMetrics(SM_CYMENU);
76 AdjustWindowRectEx(&r, dwStyle, FALSE, dwStyleEx);
78 const HWND hwnd = CreateWindowEx(dwStyleEx, appname, appname, dwStyle,
79 CW_USEDEFAULT, CW_USEDEFAULT, r.right - r.left, r.bottom - r.top,
80 nullptr,
nullptr, hInst,
nullptr);
82 ShowWindow(hwnd, nShow);
90 Gdiplus::GdiplusStartupInput gdiplusStartupInput;
91 ULONG_PTR gdiplusToken;
92 Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput,
nullptr);
96 #pragma endregion Initialization 101 #pragma region Rectangles 111 r.left = min(r.left,
int(std::floor(point.X)));
112 r.right = max(r.right,
int(std::ceil (point.X)));
114 r.top = min(r.top,
int(std::floor(point.Y)));
115 r.bottom = max(r.bottom,
int(std::ceil (point.Y)));
124 GetClientRect(hwnd, &r);
126 return Gdiplus::RectF((
float)r.left, (
float)r.top,
127 (
float)r.right - r.left, (
float)r.bottom - r.top);
141 GetClientRect(hwnd, &cr);
142 GetWindowRect(hwnd, &wr);
146 const int bw = (wr.right - wr.left) - (cr.right - cr.left);
147 const int bh = (wr.bottom - wr.top) - (cr.bottom - cr.top);
151 const int dw = max(n, pRect->right - pRect->left - bw) + bw;
152 const int dh = max(n, pRect->bottom - pRect->top - bh) + bh;
158 pRect->left = pRect->right - dw;
162 pRect->right = pRect->left + dw;
166 pRect->top = pRect->bottom - dh;
170 pRect->bottom = pRect->top + dh;
174 pRect->top = pRect->bottom - dh;
175 pRect->right = pRect->left + dw;
179 pRect->top = pRect->bottom - dh;
180 pRect->left = pRect->right - dw;
183 case WMSZ_BOTTOMRIGHT:
184 pRect->bottom = pRect->top + dh;
185 pRect->right = pRect->left + dw;
188 case WMSZ_BOTTOMLEFT:
189 pRect->bottom = pRect->top + dh;
190 pRect->left = pRect->right - dw;
195 #pragma endregion Rectangles 212 Gdiplus::ImageCodecInfo* pCodecInfo =
nullptr;
213 if(FAILED(Gdiplus::GetImageEncodersSize(&num, &n)))
return E_FAIL;
214 if(n == 0)
return E_FAIL;
216 pCodecInfo = (Gdiplus::ImageCodecInfo*)(malloc(n));
217 if(pCodecInfo ==
nullptr)
return E_FAIL;
218 if(FAILED(GetImageEncoders(num, n, pCodecInfo)))
return E_FAIL;
220 for(UINT j=0; j<num && hr!=S_OK; j++)
221 if(wcscmp(pCodecInfo[j].MimeType, format) == 0){
222 *pClsid = pCodecInfo[j].Clsid;
242 COMDLG_FILTERSPEC filetypes[] = {
243 {L
"PNG Files", L
"*.png"}
246 std::wstring wstrFileName;
247 CComPtr<IFileSaveDialog> pDlg;
249 std::wstring wstrName = L
"Image" + std::to_wstring(n++);
250 CComPtr<IShellItem> pItem;
251 LPWSTR pwsz =
nullptr;
255 if(FAILED(pDlg.CoCreateInstance(__uuidof(FileSaveDialog))))
return E_FAIL;
257 pDlg->SetFileTypes(_countof(filetypes), filetypes);
258 pDlg->SetTitle(L
"Save Image");
259 pDlg->SetFileName(wstrName.c_str());
260 pDlg->SetDefaultExtension(L
"png");
262 if(FAILED(pDlg->Show(hwnd)))
return E_FAIL;
263 if(FAILED(pDlg->GetResult(&pItem)))
return E_FAIL;
264 if(FAILED(pItem->GetDisplayName(SIGDN_FILESYSPATH, &pwsz)))
return E_FAIL;
269 if(FAILED(
GetEncoderClsid((WCHAR*)L
"image/png", &clsid)))
return E_FAIL;
270 pBitmap->Save(pwsz, &clsid,
nullptr);
277 #pragma endregion Save LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
Window procedure.
void InitWindow(HINSTANCE hInst, INT nShow, WNDPROC WndProc)
Initialize window.
void MinDragRect(HWND hwnd, WPARAM wParam, RECT *pRect, int n)
Enforce minimum drag rectangle.
HRESULT SaveBitmap(HWND hwnd, Gdiplus::Bitmap *pBitmap)
Save bitmap to file.
void AddPointToRect(RECT &r, Gdiplus::PointF point)
Add point to rectangle.
Interface for some helpful Windows-specific functions.
HRESULT GetEncoderClsid(const WCHAR *format, CLSID *pClsid)
ULONG_PTR InitGDIPlus()
Initialize GDI+.
Gdiplus::RectF GetClientRectF(HWND hwnd)
Get client rectangle as a RectF.