Skip to content

Commit 9833892

Browse files
committed
Defined _WIN32_WINNT in the project properties to be 0x0600 (i.e. Vista). (Note: DLLs may still have code that requires 7+ functionality.) Cleaned up throw_helpers and made it so that Windows-specific helpers are only included if _WIN32_WINNT is defined. Added a timer class to get proper elapsed time values. Fixed up the sample draw code so that it works with the (now correct) elapsed time value passed to it.
1 parent e8ad426 commit 9833892

File tree

5 files changed

+120
-13
lines changed

5 files changed

+120
-13
lines changed

win32/N3888_RefImpl/N3888_RefImpl.vcxproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@
8383
<PrecompiledHeader>NotUsing</PrecompiledHeader>
8484
<WarningLevel>Level4</WarningLevel>
8585
<Optimization>Disabled</Optimization>
86-
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
86+
<PreprocessorDefinitions>WIN32;_WIN32_WINNT=0x0600;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
8787
<SDLCheck>true</SDLCheck>
8888
<AdditionalIncludeDirectories>$(ProjectDir)include\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
8989
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
@@ -105,7 +105,7 @@ cmd /c copy "$(ProjectDir)DLLs\$(PlatformTarget)\$(Configuration)\zlib1.pdb" "$(
105105
<PrecompiledHeader>NotUsing</PrecompiledHeader>
106106
<WarningLevel>Level4</WarningLevel>
107107
<Optimization>Disabled</Optimization>
108-
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
108+
<PreprocessorDefinitions>WIN32;_WIN32_WINNT=0x0600;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
109109
<SDLCheck>true</SDLCheck>
110110
<AdditionalIncludeDirectories>$(ProjectDir)include\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
111111
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
@@ -129,7 +129,7 @@ cmd /c copy "$(ProjectDir)DLLs\$(PlatformTarget)\$(Configuration)\zlib1.pdb" "$(
129129
<Optimization>MaxSpeed</Optimization>
130130
<FunctionLevelLinking>true</FunctionLevelLinking>
131131
<IntrinsicFunctions>true</IntrinsicFunctions>
132-
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
132+
<PreprocessorDefinitions>WIN32;_WIN32_WINNT=0x0600;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
133133
<SDLCheck>true</SDLCheck>
134134
<AdditionalOptions> /Qvec-report:2</AdditionalOptions>
135135
<AdditionalIncludeDirectories>$(ProjectDir)include\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@@ -154,7 +154,7 @@ cmd /c copy "$(ProjectDir)DLLs\$(PlatformTarget)\$(Configuration)\zlib1.dll" "$(
154154
<Optimization>MaxSpeed</Optimization>
155155
<FunctionLevelLinking>true</FunctionLevelLinking>
156156
<IntrinsicFunctions>true</IntrinsicFunctions>
157-
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
157+
<PreprocessorDefinitions>WIN32;_WIN32_WINNT=0x0600;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
158158
<SDLCheck>true</SDLCheck>
159159
<AdditionalOptions> /Qvec-report:2</AdditionalOptions>
160160
<AdditionalIncludeDirectories>$(ProjectDir)include\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>

win32/N3888_RefImpl/entrypoint-win32.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,18 @@ int WINAPI wWinMain(
5959

6060
Win32RenderWindow window(800, 600, L"N3888_RefImpl Main Window");
6161

62+
not_proposed::timer timer;
63+
6264
// Main message loop:
6365
while (msg.message != WM_QUIT)
6466
{
6567
if (!PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) {
6668
// Draw to the off-screen buffer.
69+
timer.update();
6770
sample_draw sampleDraw;
6871
auto& renderTarget = *window.GetSurface();
6972
auto rtCtxt = context(renderTarget);
70-
sampleDraw(rtCtxt, static_cast<double>(GetTickCount64()));
73+
sampleDraw(rtCtxt, timer.get_elapsed_time());
7174

7275
// Flush to ensure that it is drawn to the window.
7376
window.GetSurface()->flush();

win32/N3888_RefImpl/entrypoint-win32.h

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,86 @@
1111
#include <KnownFolders.h>
1212
#include <shellapi.h>
1313

14+
#include <stdexcept>
15+
#include "throw_helpers.h"
16+
1417
// Forward declarations of functions included in this code module:
1518
ATOM MyRegisterClass(HINSTANCE hInstance);
1619
BOOL InitInstance(HINSTANCE, int, HWND&);
1720
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
1821
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
1922

23+
namespace not_proposed {
24+
class timer {
25+
bool m_supportsHPC;
26+
LARGE_INTEGER m_frequencyHPC;
27+
LARGE_INTEGER m_startCountHPC;
28+
LARGE_INTEGER m_lastCountHPC;
29+
ULONGLONG m_startTickCount64;
30+
ULONGLONG m_lastTickCount64;
31+
double m_elapsedTime;
32+
double m_totalTime;
33+
34+
public:
35+
timer()
36+
: m_supportsHPC()
37+
, m_frequencyHPC()
38+
, m_startCountHPC()
39+
, m_lastCountHPC()
40+
, m_startTickCount64()
41+
, m_lastTickCount64()
42+
, m_elapsedTime()
43+
, m_totalTime() {
44+
reset();
45+
}
46+
47+
void reset() {
48+
// Though it's highly unlikely, it's not impossible that the computer doesn't support a high-resolution
49+
// performance counter, which is required for this API.
50+
m_supportsHPC = ::QueryPerformanceFrequency(&m_frequencyHPC) != 0;
51+
52+
if (m_supportsHPC) {
53+
// If this returns zero there's a runtime error of some sort per the API.
54+
if (::QueryPerformanceCounter(&m_startCountHPC) == 0) {
55+
throw_get_last_error<::std::runtime_error>("Failed call to QueryPerformanceCounter.");
56+
}
57+
m_lastCountHPC = m_startCountHPC;
58+
}
59+
else {
60+
// Fall back to the inaccurate timer.
61+
m_lastTickCount64 = m_startTickCount64 = ::GetTickCount64();
62+
}
63+
}
64+
65+
// Returns elapsed time since last call to Update or Reset.
66+
void update() {
67+
if (m_supportsHPC) {
68+
LARGE_INTEGER currentCountHPC;
69+
if (QueryPerformanceCounter(&currentCountHPC) == 0) {
70+
throw_get_last_error<::std::runtime_error>("Failed call to QueryPerformanceCounter.");
71+
}
72+
const double millisecondsPerSecond = 1000.0;
73+
m_elapsedTime = (static_cast<double>(currentCountHPC.QuadPart - m_lastCountHPC.QuadPart) / static_cast<double>(m_frequencyHPC.QuadPart)) * millisecondsPerSecond;
74+
m_totalTime += m_elapsedTime;
75+
m_lastCountHPC = currentCountHPC;
76+
}
77+
else {
78+
auto currentTickCount = ::GetTickCount64();
79+
if (currentTickCount < m_lastTickCount64) {
80+
currentTickCount = m_lastTickCount64;
81+
}
82+
m_elapsedTime = static_cast<double>(currentTickCount - m_lastTickCount64);
83+
m_totalTime += m_elapsedTime;
84+
m_lastTickCount64 = currentTickCount;
85+
}
86+
}
87+
88+
double get_elapsed_time() {
89+
return m_elapsedTime;
90+
}
91+
92+
double get_total_time() {
93+
return m_totalTime;
94+
}
95+
};
96+
}

win32/N3888_RefImpl/sample_draw.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ void sample_draw::operator()(::std::experimental::drawing::context& ctxt, double
2929
//context.set_source(pattern);
3030
//context.paint();
3131

32+
static double timer = 0.0;
33+
timer += elapsedTimeInMilliseconds;
34+
3235
ctxt.save();
3336
auto scp = solid_color_pattern(0.0, 0.0, 1.0);
3437
ctxt.set_source(scp);
@@ -116,7 +119,7 @@ void sample_draw::operator()(::std::experimental::drawing::context& ctxt, double
116119
matrix m;
117120
m.init_translate(300.0, 400.0);
118121
const double two_pi = 3.1415926535897932 * 2.0;
119-
m.rotate(two_pi * (fmod(elapsedTimeInMilliseconds, 4000.0) / 4000.0));
122+
m.rotate(two_pi * (fmod(timer, 4000.0) / 4000.0));
120123
ctxt.set_matrix(m);
121124
ctxt.new_path();
122125
ctxt.move_to(-100.0, 0.0);

win32/N3888_RefImpl/throw_helpers.h

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
#pragma once
2+
#ifndef THROW_HELPERS_H
3+
#define THROW_HELPERS_H
24

35
#include <sstream>
46
#include <string>
@@ -20,9 +22,10 @@ inline void throw_if_null(void* ptr, const char* msg) {
2022
}
2123
}
2224

23-
template <class exception_type>
24-
inline void throw_get_last_error(const char* backupMessage) {
25-
auto errorCode = GetLastError();
25+
#if defined(_WIN32_WINNT)
26+
27+
// Returns the system error message as a string or, if there is no message, the result of calling ::std::to_string on errorCode.
28+
inline ::std::string get_last_error_string(DWORD errorCode = GetLastError(), bool* foundSystemMessage = nullptr) {
2629
const auto strCount = 0xFFFF;
2730
::std::unique_ptr<char[]> str(new char[strCount]);
2831
ZeroMemory(str.get(), strCount * sizeof(char));
@@ -39,12 +42,33 @@ inline void throw_get_last_error(const char* backupMessage) {
3942
);
4043

4144
if (char_count == 0) {
42-
std::stringstream error_str;
43-
error_str << backupMessage << " Error code: " << errorCode;
44-
throw exception_type(error_str.str());
45+
if (foundSystemMessage != nullptr) {
46+
*foundSystemMessage = false;
47+
}
48+
return ::std::to_string(errorCode);
4549
}
4650
else {
47-
throw exception_type(std::string(str.get()));
51+
if (foundSystemMessage != nullptr) {
52+
*foundSystemMessage = true;
53+
}
54+
return ::std::string(str.get());
4855
}
4956
}
5057

58+
template <class exception_type>
59+
inline void throw_get_last_error(const char* backupMessage, DWORD errorCode = GetLastError()) {
60+
bool foundMessage;
61+
auto error_message = get_last_error_string(errorCode, &foundMessage);
62+
if (foundMessage) {
63+
throw exception_type(error_message);
64+
}
65+
else {
66+
::std::stringstream error_str;
67+
error_str << backupMessage << " Error code: " << error_message;
68+
throw exception_type(error_str.str());
69+
}
70+
}
71+
72+
#endif
73+
74+
#endif

0 commit comments

Comments
 (0)