Skip to content

Commit e8ad426

Browse files
committed
Moved drawing into its own class, sample_draw, to isolate it from platform-specific code. Some miscellany clean up to avoid a crash and to encapsulate the Win32RenderWindow's surface. Changed the initial window size to 800x600 from 320x240. Also fixed a minor design issue with the About dialog in the RC resource file.
1 parent 8bf9bc8 commit e8ad426

File tree

8 files changed

+264
-239
lines changed

8 files changed

+264
-239
lines changed
20 Bytes
Binary file not shown.

win32/N3888_RefImpl/N3888_RefImpl.vcxproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ cmd /c copy "$(ProjectDir)DLLs\$(PlatformTarget)\$(Configuration)\zlib1.dll" "$(
179179
<ClInclude Include="drawing.h" />
180180
<ClInclude Include="entrypoint-win32.h" />
181181
<ClInclude Include="Resource.h" />
182+
<ClInclude Include="sample_draw.h" />
182183
<ClInclude Include="targetver.h" />
183184
<ClInclude Include="throw_helpers.h" />
184185
<ClInclude Include="Win32RenderWindow.h" />
@@ -202,6 +203,7 @@ cmd /c copy "$(ProjectDir)DLLs\$(PlatformTarget)\$(Configuration)\zlib1.dll" "$(
202203
<ClCompile Include="radial_pattern.cpp" />
203204
<ClCompile Include="raster_source_pattern.cpp" />
204205
<ClCompile Include="region.cpp" />
206+
<ClCompile Include="sample_draw.cpp" />
205207
<ClCompile Include="scaled_font.cpp" />
206208
<ClCompile Include="solid_color_pattern.cpp" />
207209
<ClCompile Include="standalone_functions.cpp" />

win32/N3888_RefImpl/N3888_RefImpl.vcxproj.filters

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@
4848
<ClInclude Include="Win32RenderWindow.h">
4949
<Filter>Header Files</Filter>
5050
</ClInclude>
51+
<ClInclude Include="sample_draw.h">
52+
<Filter>Header Files</Filter>
53+
</ClInclude>
5154
</ItemGroup>
5255
<ItemGroup>
5356
<ClCompile Include="entrypoint-win32.cpp">
@@ -119,6 +122,9 @@
119122
<ClCompile Include="Win32RenderWindow.cpp">
120123
<Filter>Source Files</Filter>
121124
</ClCompile>
125+
<ClCompile Include="sample_draw.cpp">
126+
<Filter>Source Files</Filter>
127+
</ClCompile>
122128
</ItemGroup>
123129
<ItemGroup>
124130
<ResourceCompile Include="N3888_RefImpl.rc">

win32/N3888_RefImpl/Win32RenderWindow.cpp

Lines changed: 93 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ using namespace std::experimental::drawing;
1919
using namespace Microsoft::WRL;
2020

2121
Win32RenderWindow::Win32RenderWindow(unsigned int width, unsigned int height, const std::wstring& caption) :
22-
handle( 0 )
22+
handle(0)
2323
{
2424
// Record the desired client window size
2525
RECT rc;
@@ -51,18 +51,20 @@ Win32RenderWindow::Win32RenderWindow(unsigned int width, unsigned int height, co
5151
NULL, // instance of this application
5252
NULL); // extra creation parms
5353

54-
if ( handle != 0 ) {
55-
// Set in the "extra" bytes the pointer to the 'this' pointer
56-
// so it can handle messages for itself.
57-
SetWindowLongPtr( handle, 0, (LONG_PTR)this);
58-
59-
// Initially display the window
60-
ShowWindow(handle, SW_SHOWNORMAL);
61-
UpdateWindow(handle);
54+
if (handle == nullptr) {
55+
throw_get_last_error<logic_error>("Failed call to CreateWindowEx.");
6256
}
6357

6458
// Create the initial surface for drawing to.
65-
g_psurface = unique_ptr<surface>(new surface(move(make_surface(format::argb32, lwidth, lheight))));
59+
g_psurface = shared_ptr<surface>(new surface(move(make_surface(format::argb32, lwidth, lheight))));
60+
61+
// Set in the "extra" bytes the pointer to the 'this' pointer
62+
// so it can handle messages for itself.
63+
SetWindowLongPtr(handle, 0, (LONG_PTR)this);
64+
65+
// Initially display the window
66+
ShowWindow(handle, SW_SHOWNORMAL);
67+
UpdateWindow(handle);
6668
}
6769

6870
Win32RenderWindow::~Win32RenderWindow()
@@ -125,96 +127,96 @@ LRESULT Win32RenderWindow::WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM
125127
{
126128
switch (msg)
127129
{
128-
case WM_CREATE:
129-
{
130-
// Automatically return 0 to allow the window to proceed in the
131-
// creation process.
132-
return(0);
133-
} break;
134-
135-
case WM_CLOSE:
136-
{
137-
// This message is sent when a window or an application should
138-
// terminate.
139-
} break;
130+
case WM_CREATE:
131+
{
132+
// Automatically return 0 to allow the window to proceed in the
133+
// creation process.
134+
return(0);
135+
} break;
140136

141-
case WM_DESTROY:
142-
{
143-
// This message is sent when a window has been destroyed.
144-
PostQuitMessage(0);
145-
return(0);
146-
} break;
137+
case WM_CLOSE:
138+
{
139+
// This message is sent when a window or an application should
140+
// terminate.
141+
} break;
147142

148-
case WM_SIZE:
149-
{
150-
auto width = lparam & 0xFFFF;
151-
auto height = (lparam & 0xFFFF0000) >> 16;
143+
case WM_DESTROY:
144+
{
145+
// This message is sent when a window has been destroyed.
146+
PostQuitMessage(0);
147+
return(0);
148+
} break;
152149

153-
g_psurface = unique_ptr<surface>(new surface(move(make_surface(format::argb32, width, height))));
150+
case WM_SIZE:
151+
{
152+
auto width = lparam & 0xFFFF;
153+
auto height = (lparam & 0xFFFF0000) >> 16;
154154

155-
} break;
155+
g_psurface = unique_ptr<surface>(new surface(move(make_surface(format::argb32, width, height))));
156156

157-
case WM_COMMAND:
158-
{
159-
int wmId, wmEvent;
157+
} break;
160158

161-
wmId = LOWORD(wparam);
162-
wmEvent = HIWORD(wparam);
163-
// Parse the menu selections:
164-
switch (wmId)
165-
{
166-
case IDM_ABOUT:
167-
{
168-
auto aboutResult = DialogBox(0, MAKEINTRESOURCE(IDD_ABOUTBOX), handle, About);
169-
if (aboutResult <= 0) {
170-
throw_get_last_error<logic_error>("Failed call to DialogBox.");
171-
}
172-
} break;
159+
case WM_COMMAND:
160+
{
161+
int wmId, wmEvent;
173162

174-
case ID_EDIT_SCREENCAPTURE:
175-
ShowSaveAsPNGDialog();
176-
break;
163+
wmId = LOWORD(wparam);
164+
wmEvent = HIWORD(wparam);
165+
// Parse the menu selections:
166+
switch (wmId)
167+
{
168+
case IDM_ABOUT:
169+
{
170+
auto aboutResult = DialogBox(0, MAKEINTRESOURCE(IDD_ABOUTBOX), handle, About);
171+
if (aboutResult <= 0) {
172+
throw_get_last_error<logic_error>("Failed call to DialogBox.");
173+
}
174+
} break;
177175

178-
case IDM_EXIT:
179-
DestroyWindow(handle);
180-
break;
176+
case ID_EDIT_SCREENCAPTURE:
177+
ShowSaveAsPNGDialog();
178+
break;
181179

182-
default:
183-
return DefWindowProc(handle, msg, wparam, lparam);
184-
} break;
185-
} break;
180+
case IDM_EXIT:
181+
DestroyWindow(handle);
182+
break;
186183

187-
case WM_ENTERSIZEMOVE:
188-
{
189-
//g_doNotPaint = true; // Don't paint while resizing to avoid flicker.
184+
default:
190185
return DefWindowProc(handle, msg, wparam, lparam);
191186
} break;
187+
} break;
192188

193-
case WM_EXITSIZEMOVE:
194-
{
195-
//g_doNotPaint = false;
196-
return DefWindowProc(handle, msg, wparam, lparam);
197-
} break;
189+
case WM_ENTERSIZEMOVE:
190+
{
191+
//g_doNotPaint = true; // Don't paint while resizing to avoid flicker.
192+
return DefWindowProc(handle, msg, wparam, lparam);
193+
} break;
198194

199-
case WM_PAINT:
200-
{
201-
//if (!g_doNotPaint) {
202-
// OnPaint(handle, msg, wparam, lparam);
203-
//}
204-
PAINTSTRUCT ps;
205-
HDC hdc;
206-
207-
// Flush to ensure that it is drawn to the window.
208-
hdc = BeginPaint(handle, &ps);
209-
g_psurface->flush();
210-
211-
auto surface = make_surface(cairo_win32_surface_create(hdc));
212-
auto ctxt = context(surface);
213-
ctxt.set_source_surface(*g_psurface, 0.0, 0.0);
214-
ctxt.paint();
215-
surface.flush();
216-
EndPaint(handle, &ps);
217-
} break;
195+
case WM_EXITSIZEMOVE:
196+
{
197+
//g_doNotPaint = false;
198+
return DefWindowProc(handle, msg, wparam, lparam);
199+
} break;
200+
201+
case WM_PAINT:
202+
{
203+
//if (!g_doNotPaint) {
204+
// OnPaint(handle, msg, wparam, lparam);
205+
//}
206+
PAINTSTRUCT ps;
207+
HDC hdc;
208+
209+
// Flush to ensure that it is drawn to the window.
210+
hdc = BeginPaint(handle, &ps);
211+
g_psurface->flush();
212+
213+
auto surface = make_surface(cairo_win32_surface_create(hdc));
214+
auto ctxt = context(surface);
215+
ctxt.set_source_surface(*g_psurface, 0.0, 0.0);
216+
ctxt.paint();
217+
surface.flush();
218+
EndPaint(handle, &ps);
219+
} break;
218220
}
219221

220222
return(DefWindowProc(hwnd, msg, wparam, lparam));
@@ -227,7 +229,7 @@ void Win32RenderWindow::ShowSaveAsPNGDialog() {
227229
throw_if_failed_hresult<logic_error>(
228230
CoCreateInstance(CLSID_FileSaveDialog, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&fsd)), "Failed call to CoCreateInstance for IFileSaveDialog.");
229231

230-
FILEOPENDIALOGOPTIONS fodOptions{};
232+
FILEOPENDIALOGOPTIONS fodOptions{ };
231233
throw_if_failed_hresult<logic_error>(
232234
fsd->GetOptions(&fodOptions), "Failed call to IFileDialog::GetOptions.");
233235
throw_if_failed_hresult<logic_error>(
@@ -312,3 +314,7 @@ void Win32RenderWindow::ShowSaveAsPNGDialog() {
312314
}
313315

314316
}
317+
318+
const shared_ptr<surface>& Win32RenderWindow::GetSurface() {
319+
return g_psurface;
320+
}

win32/N3888_RefImpl/Win32RenderWindow.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,12 @@ class Win32RenderWindow
2020
LRESULT WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
2121
void ShowSaveAsPNGDialog();
2222

23-
std::unique_ptr<std::experimental::drawing::surface> g_psurface;
23+
const ::std::shared_ptr<::std::experimental::drawing::surface>& GetSurface();
2424

2525
private:
2626
HWND handle;
27+
28+
::std::shared_ptr<::std::experimental::drawing::surface> g_psurface;
2729
};
2830

2931
#endif // _WIN32RENDERWINDOW_

0 commit comments

Comments
 (0)