Solution46
CTimer.cpp
[詳解]
1 //=============================================================================
2 /// @file
3 /// タイマクラス実装ファイル
4 ///
5 /// タイマクラス実装ファイルです。
6 ///
7 /// $Id: CTimer.cpp 245 2019-03-20 15:03:41Z admin $
8 /// $Date: 2019-03-21 00:03:41 +0900 (2019/03/21 (木)) $
9 /// $Author: admin $
10 ///
11 /// @attention なし
12 
13 #pragma managed( push, off )
14 
15 //=============================================================================
16 // インクルードファイル
17 #include <CTimer.h>
18 
19 //=============================================================================
20 // 共通ライブラリ名前空間
21 namespace LibCommon {
22  //=========================================================================
23  // タイマクラス
24  //=========================================================================
25  // 構築子と解体子
26  //-------------------------------------------------------------------------
27  // コンストラクタ
28  CTimer::CTimer() noexcept
29  // 基底クラスコンストラクタ
30  : CSync()
31  // メンバ変数初期化
32  , m_bInfinite( false )
33  , m_bSet( false )
34  {}
35 
36  //-------------------------------------------------------------------------
37  // コンストラクタ
38  CTimer::CTimer( DWORD dwTime ) noexcept
39  // 移譲コンストラクタ
40  : CTimer()
41  {
42  // 作成する
43  Create();
44 
45  // タイマを設定する
46  Set( dwTime );
47  }
48 
49  //-------------------------------------------------------------------------
50  // デストラクタ
51  CTimer::~CTimer() noexcept {
52  // クローズする
53  Close();
54  }
55 
56  //=========================================================================
57  // 公開関数
58  //-------------------------------------------------------------------------
59  // クローズ関数
60  void CTimer::Close() noexcept {
61  // 基底クラスの関数を実行する
62  CSync::Close();
63 
64  // メンバ変数をクリアする
65  m_bInfinite = false;
66  m_bSet = false;
67  }
68 
69  //-------------------------------------------------------------------------
70  // ウェイト関数
71  bool CTimer::Wait( DWORD dwTime ) noexcept {
72  // 処理ブロック
73  bool result = false;
74  do {
75  // 無限待機フラグを調べる
76  if ( m_bInfinite ) {
77  // 失敗!
78  break;
79  }
80  // タイマセットフラグを調べる
81  else if ( !m_bSet ) {
82  // 失敗!
83  break;
84  }
85 
86  // 同期オブジェクトをウェイトする
87  result = CSync::Wait( dwTime );
88  } while ( false );
89 
90  // 実行結果を返す
91  return result;
92  }
93 
94  //-------------------------------------------------------------------------
95  // リリース関数
96  bool CTimer::Release() noexcept {
97  // タイマを解除する
98  return Cancel();
99  }
100 
101  //-------------------------------------------------------------------------
102  // 作成関数
103  bool CTimer::Create( wchar_t const* pszObjectName ) noexcept {
104  // 処理ブロック
105  bool result = false;
106  do {
107  // タイマハンドルを調べる
108  if ( nullptr != m_hObject ) {
109  // クローズする
110  Close();
111  }
112 
113  // オブジェクト名を調べる
114  wchar_t szBuffer[ MAX_PATH ];
115  if ( nullptr != pszObjectName ) {
116  // オブジェクト名に拡張子を追加する
117  ::wcscpy_s( szBuffer, pszObjectName );
118  ::wcscat_s( szBuffer, OBJECT_NAME_EXT );
119  pszObjectName = szBuffer;
120  }
121 
122  // タイマを作成する
123  m_hObject = ::CreateWaitableTimerW( nullptr, false, pszObjectName );
124  if ( nullptr == m_hObject ) {
125  // 失敗!
126  break;
127  }
128  // エラーコードを調べる
129  else if ( ERROR_ALREADY_EXISTS != ::GetLastError() ) {
130  // 新規作成フラグをセットする
131  m_bIsCreate = true;
132  }
133 
134  // 成功!
135  result = true;
136  } while ( false );
137 
138  // 実行結果を返す
139  return result;
140  }
141 
142  //-------------------------------------------------------------------------
143  // オープン関数
144  bool CTimer::Open( wchar_t const* pszObjectName ) noexcept {
145  // 処理ブロック
146  bool result = false;
147  do {
148  // オブジェクト名を調べる
149  if ( nullptr == pszObjectName ) {
150  // 失敗!
151  break;
152  }
153  // タイマハンドルを調べる
154  else if ( nullptr != m_hObject ) {
155  // クローズする
156  Close();
157  }
158 
159  // オブジェクト名に拡張子を追加する
160  wchar_t szBuffer[ MAX_PATH ];
161  ::wcscpy_s( szBuffer, pszObjectName );
162  ::wcscat_s( szBuffer, OBJECT_NAME_EXT );
163  pszObjectName = szBuffer;
164 
165  // タイマをオープンする
166  m_hObject = ::OpenWaitableTimerW( TIMER_ALL_ACCESS, false, pszObjectName );
167  if ( nullptr == m_hObject ) {
168  // 失敗!
169  break;
170  }
171 
172  // 成功!
173  result = true;
174  } while ( false );
175 
176  // 実行結果を返す
177  return result;
178  }
179 
180  //-------------------------------------------------------------------------
181  // タイマ設定関数
182  bool CTimer::Set( DWORD dwTime ) noexcept {
183  // 処理ブロック
184  bool result = false;
185  do {
186  // タイマハンドルを調べる
187  if ( nullptr == m_hObject ) {
188  // 失敗!
189  break;
190  }
191  // タイマセットフラグを調べる
192  else if ( m_bSet ) {
193  // タイマをキャンセルする
194  Cancel();
195  }
196 
197  // 待機時間を調べる
198  if ( INFINITE == dwTime ) {
199  // 無限待機フラグをセットする
200  m_bInfinite = true;
201 
202  // 成功!
203  result = true;
204  break;
205  }
206 
207  // 100ナノタイマを設定する
208  LONGLONG llWait = ( -10LL * 1000 * dwTime );
209  result = SetNano100( llWait );
210  } while ( false );
211 
212  // 実行結果を返す
213  return result;
214  }
215 
216  //-------------------------------------------------------------------------
217  // 100なのタイマ設定関数
218  bool CTimer::SetNano100( LONGLONG llWait, LONG nPeriod, PTIMERAPCROUTINE pfnCallBack, LPVOID lpParam, bool bResume ) noexcept {
219  // 処理ブロック
220  bool result = false;
221  do {
222  // 無限待機フラグをクリアする
223  m_bInfinite = false;
224 
225  // タイマをアクティブにする
226  LARGE_INTEGER sDueTime;
227  sDueTime.QuadPart = llWait;
228  if ( 0 == ::SetWaitableTimer( m_hObject, &sDueTime, nPeriod, pfnCallBack, lpParam, bResume ) ) {
229  // 失敗!
230  break;
231  }
232  // 再開フラグを調べる
233  else if ( bResume ) {
234  // ラストエラーを調べる
235  if ( ERROR_NOT_SUPPORTED == ::GetLastError() ) {
236  // タイマをキャンセルする
237  ::CancelWaitableTimer( m_hObject );
238 
239  // 失敗!
240  break;
241  }
242  }
243 
244  // タイマセットフラグをセットする
245  m_bSet = true;
246 
247  // 成功!
248  result = true;
249  } while ( false );
250 
251  // 実行結果を返す
252  return result;
253  }
254 
255  //-------------------------------------------------------------------------
256  // タイマ解除関数
257  bool CTimer::Cancel() noexcept {
258  // 処理ブロック
259  bool result = false;
260  do {
261  // 無限待機フラグを調べる
262  if ( m_bInfinite ) {
263  // 無限待機フラグをクリアする
264  m_bInfinite = false;
265  }
266  // タイマセットフラグを調べる
267  else if ( m_bSet ) {
268  // タイマをキャンセルする
269  if ( 0 == ::CancelWaitableTimer( m_hObject ) ) {
270  // 失敗!
271  break;
272  }
273 
274  // タイマセットフラグをクリアする
275  m_bSet = false;
276  }
277 
278  // 成功!
279  result = true;
280  } while ( false );
281 
282  // 実行結果を返す
283  return result;
284  }
285 
286  //=====================================================================
287  // 静的限定公開文字列定数
288  wchar_t const* const CTimer::OBJECT_NAME_EXT = L".CTimer";
289 }
290 
291 #pragma managed( pop )
virtual void Close() noexcept
クローズ関数
Definition: CSync.cpp:45
CTimer() noexcept
コンストラクタ
Definition: CTimer.cpp:28
bool m_bSet
タイマセットフラグ
Definition: CTimer.h:201
static wchar_t const *const OBJECT_NAME_EXT
オブジェクト名拡張子
Definition: CTimer.h:195
virtual bool Wait(DWORD dwTime=INFINITE) noexcept override
ウェイト関数
Definition: CTimer.cpp:71
同期クラス
Definition: CSync.h:30
virtual bool SetNano100(LONGLONG llWait, LONG nPeriod=0, PTIMERAPCROUTINE pfnCallBack=nullptr, LPVOID lpParam=nullptr, bool bResume=false) noexcept
100ナノタイマ設定関数
Definition: CTimer.cpp:218
bool m_bIsCreate
新規作成フラグ
Definition: CSync.h:153
virtual bool Wait(DWORD dwTime=INFINITE) noexcept
ウェイト関数
Definition: CSync.cpp:59
共通ライブラリ名前空間
Definition: CArray.h:23
virtual bool Open(wchar_t const *pszObjectName) noexcept
オープン関数
Definition: CTimer.cpp:144
virtual ~CTimer() noexcept
デストラクタ
Definition: CTimer.cpp:51
HANDLE m_hObject
オブジェクトハンドル
Definition: CSync.h:152
virtual bool Set(DWORD dwTime) noexcept
タイマ設定関数
Definition: CTimer.cpp:182
タイマクラスヘッダファイル
virtual void Close() noexcept override
クローズ関数
Definition: CTimer.cpp:60
virtual bool Cancel() noexcept
タイマ解除関数
Definition: CTimer.cpp:257
virtual bool Create(wchar_t const *pszObjectName=nullptr) noexcept
作成関数
Definition: CTimer.cpp:103
virtual bool Release() noexcept override
リリース関数
Definition: CTimer.cpp:96
bool m_bInfinite
無限待機フラグ
Definition: CTimer.h:200