Solution46
CWndContainer.cpp
[詳解]
1 //=============================================================================
2 /// @file
3 /// コンテナウィンドウクラス実装ファイル
4 ///
5 /// コンテナウィンドウクラス実装ファイルです。
6 ///
7 /// $Id: CWndContainer.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 <CWndContainer.h>
18 #include <CommandIdDef.h>
19 #include <LibWindowUtility.h>
20 #include <algorithm>
21 
22 //=============================================================================
23 // インクルード実装ファイル
24 #include <CArray.hpp>
25 
26 //=============================================================================
27 // ウィンドウライブラリ名前空間
28 namespace LibWindow {
29  //=========================================================================
30  // コンテナウィンドウクラス
31  //=========================================================================
32  // 構築子と解体子
33  //-------------------------------------------------------------------------
34  // コンストラクタ
35  CWndContainer::CWndContainer( CWndElement* ( *pfnCreateElement )(), wchar_t const* pszElementName ) noexcept
36  // 基底クラスコンストラクタ
37  : CWndPane()
38  // メンバ変数初期化
39  , m_cElementList()
40  , m_pfnCreateElement( pfnCreateElement )
41  , m_pszElementName( pszElementName )
42  , m_bFocusElement( false )
43  {}
44 
45  //-------------------------------------------------------------------------
46  // ムーブコンストラクタ
48  // 基底クラスコンストラクタ
49  : CWndPane( std::move( rcInstance ) )
50  // メンバ変数初期化
51  , m_cElementList( std::move( rcInstance.m_cElementList ) )
52  , m_pfnCreateElement( rcInstance.m_pfnCreateElement )
53  , m_pszElementName( rcInstance.m_pszElementName )
54  , m_bFocusElement( rcInstance.m_bFocusElement )
55  {}
56 
57  //=========================================================================
58  // 公開関数
59  //-------------------------------------------------------------------------
60  // ウィンドウ作成関数
61  bool CWndContainer::Create( HWND hParent, HMENU hMenu ) noexcept {
62  // 処理ブロック
63  bool result = false;
64  do {
65  // 基底クラスの関数を実行する
66  if ( !CWndPane::Create( hParent, hMenu ) ) {
67  // 失敗!
68  break;
69  }
70  // エレメントウィンドウリストを作成する
71  else if ( !m_cElementList.CreateListWindow( m_hWnd ) ) {
72  // 失敗!
73  break;
74  }
75 
76  // 成功!
77  result = true;
78  } while ( false );
79 
80  // 実行結果を返す
81  return result;
82  }
83 
84  //-------------------------------------------------------------------------
85  // WM_SETFOCUSメッセージ処理関数
86  LRESULT CWndContainer::WmSetFocus() noexcept {
87  // 処理ブロック
88  LRESULT result = 0;
89  do {
90  // エレメントウィンドウフォーカス有効状態を調べる
91  if ( m_bFocusElement ) {
92  // 表示状態カレントエレメントウィンドウを取得する
94  if ( nullptr != pcElement ) {
95  // フォーカスウィンドウを設定する
96  ::SetFocus( pcElement->GetHandle() );
97 
98  // 終了!
99  break;
100  }
101  }
102 
103  // 基底クラスの関数を実行する
104  result = CWndPane::WmSetFocus();
105  } while ( false );
106 
107  // 実行結果を返す
108  return result;
109  }
110 
111  //-------------------------------------------------------------------------
112  // WM_NOTIFY_CHILD_SET_FOCUSメッセージ処理関数
114  // 処理ブロック
115  LRESULT result = 0;
116  do {
117  // エレメントウィンドウフォーカス有効フラグをクリアする
118  m_bFocusElement = false;
119 
120  // 子ウィンドウハンドルを取得する
121  HWND hChild = reinterpret_cast< HWND >( m_lParam );
122 
123  // エレメントウィンドウを取得する
124  CWndElement* pcElement = m_cElementList.GetElementWindow( hChild );
125  if ( nullptr != pcElement ) {
126  // カレントエレメントウィンドウを設定する
127  if ( m_cElementList.SetCurrentElement( pcElement ) ) {
128  // エレメントウィンドウフォーカス有効フラグをセットする
129  m_bFocusElement = true;
130  }
131  }
132 
133  // 基底クラスの関数を実行する
135  } while ( false );
136 
137  // 実行結果を返す
138  return result;
139  }
140 
141  //-------------------------------------------------------------------------
142  // ウィンドウ構成情報初期化関数
143  bool CWndContainer::InitConfig( CJsonConfig& rcConfig ) noexcept {
144  // 処理ブロック
145  bool result = false;
146  do {
147  // 基底クラスの関数を実行する
148  if ( !CWndPane::InitConfig( rcConfig ) ) {
149  // 失敗!
150  break;
151  }
152  // エレメントウィンドウリスト構成情報を初期化する
154  // 失敗!
155  break;
156  }
157 
158  // エレメントウィンドウフォーカス有効フラグを取得する
159  rcConfig.Get( m_bFocusElement, KEY_FOCUS_ELEMENT );
160 
161  // 成功!
162  result = true;
163  } while ( false );
164 
165  // 実行結果を返す
166  return result;
167  }
168 
169  //-------------------------------------------------------------------------
170  // ウィンドウ構成情報復元関数
171  bool CWndContainer::ResumeConfig( CJsonConfig& rcConfig ) noexcept {
172  // 処理ブロック
173  bool result = false;
174  do {
175  // 基底クラスの関数を実行する
176  if ( !CWndPane::ResumeConfig( rcConfig ) ) {
177  // 失敗!
178  break;
179  }
180  // エレメントウィンドウリスト構成情報を復元する
181  else if ( !m_cElementList.ResumeElementListConfig( rcConfig, m_pszElementName ) ) {
182  // 失敗!
183  break;
184  }
185 
186  // 成功!
187  result = true;
188  } while ( false );
189 
190  // 実行結果を返す
191  return result;
192  }
193 
194  //-------------------------------------------------------------------------
195  // ウィンドウ構成情報保存関数
196  bool CWndContainer::SaveConfig( CJsonConfig& rcConfig ) noexcept {
197  // 処理ブロック
198  bool result = false;
199  do {
200  // 基底クラスの関数を実行する
201  if ( !CWndPane::SaveConfig( rcConfig ) ) {
202  // 失敗!
203  break;
204  }
205  // エレメントウィンドウリスト構成情報を保存する
206  else if ( !m_cElementList.SaveElementListConfig( rcConfig, m_pszElementName ) ) {
207  // 失敗!
208  break;
209  }
210 
211  // エレメントウィンドウフォーカス有効状態を調べる
212  if ( m_bFocusElement ) {
213  // エレメントウィンドウフォーカス有効状態を保存する
214  if ( !rcConfig.Set( true, KEY_FOCUS_ELEMENT ) ) {
215  // 失敗!
216  break;
217  }
218  }
219 
220  // 成功!
221  result = true;
222  } while ( false );
223 
224  // 実行結果を返す
225  return result;
226  }
227 
228  //-------------------------------------------------------------------------
229  // 子ペインウィンドウ情報取得関数
230  bool CWndContainer::GetChildPaneInfo( SChildPaneInfo& rsChildInfo ) noexcept {
231  // 処理ブロック
232  bool result = false;
233  do {
234  // 基底クラスの関数を実行する
235  if ( !CWndPane::GetChildPaneInfo( rsChildInfo ) ) {
236  // 失敗!
237  break;
238  }
239  // 子エレメントウィンドウリスト情報を取得する
240  else if ( !m_cElementList.GetChildElementListInfo( this, rsChildInfo ) ) {
241  // 失敗!
242  break;
243  }
244 
245  // 成功!
246  result = true;
247  } while ( false );
248 
249  // 実行結果を返す
250  return result;
251  }
252 
253  //-------------------------------------------------------------------------
254  // ペインウィンドウオーダー番号取得関数
255  int CWndContainer::GetOrderIndex( CWndPane* pcPane, int* pnOrder ) noexcept {
256  // 処理ブロック
257  int result = -1;
258  do {
259  // 基底クラスの関数を実行する
260  int nOrder = CWndPane::GetOrderIndex( pcPane, pnOrder );
261  if ( 0 > nOrder ) {
262  // エレメントウィンドウリストオーダー番号を取得する
263  nOrder = m_cElementList.GetElementListOrderIndex( pcPane, pnOrder );
264  if ( 0 > nOrder ) {
265  // 失敗!
266  break;
267  }
268  }
269 
270  // 成功!
271  result = nOrder;
272  } while ( false );
273 
274  // 実行結果を返す
275  return result;
276  }
277 
278  //-------------------------------------------------------------------------
279  // オーダー番号ペインウィンドウ取得関数
280  CWndPane* CWndContainer::GetOrderPane( int* pnOrder ) noexcept {
281  // 処理ブロック
282  CWndPane* result = nullptr;
283  do {
284  // 基底クラスの関数を実行する
285  CWndPane* pcPane = CWndPane::GetOrderPane( pnOrder );
286  if ( nullptr == pcPane ) {
287  // エレメントウィンドウリストオーダー番号ペインウィンドウを取得する
288  pcPane = m_cElementList.GetElementListOrderPane( pnOrder );
289  if ( nullptr == pcPane ) {
290  // 失敗!
291  break;
292  }
293  }
294 
295  // 成功!
296  result = pcPane;
297  } while ( false );
298 
299  // 実行結果を返す
300  return result;
301  }
302 
303  //-------------------------------------------------------------------------
304  // 子ウィンドウ削除関数
305  bool CWndContainer::DeleteChildWindow( CWndPane* pcChild ) noexcept {
306  // 処理ブロック
307  bool result = false;
308  do {
309  // 子ペインウィンドウポインタを調べる
310  if ( nullptr == pcChild ) {
311  // 失敗!
312  break;
313  }
314 
315  // フォーカスウィンドウ保存ハンドルを調べる
316  bool bFocus = ( IsOwnOrChild( m_hWnd, s_hFocus ) );
317 
318  // エレメントウィンドウリストから削除する
319  if ( m_cElementList.RemoveElementWindow( pcChild ) ) {
320  // 子ウィンドウインスタンスを削除する
321  delete pcChild;
322 
323  // WM_SIZEメッセージを送信する
324  ::SendMessageW( m_hWnd, WM_SIZE, 0, 0 );
325  ::UpdateWindow( m_hWnd );
326 
327  // フォーカス状態を調べる
328  if ( bFocus ) {
329  // フォーカスウィンドウをクリアする
330  ::SetFocus( nullptr );
331 
332  // フォーカスウィンドウを設定する
333  ::SetFocus( m_hWnd );
334  }
335 
336  // 成功!
337  result = true;
338  break;
339  }
340 
341  // 基底クラスの関数を実行する
342  result = CWndPane::DeleteChildWindow( pcChild );
343  } while ( false );
344 
345  // 実行結果を返す
346  return result;
347  }
348 
349  //-------------------------------------------------------------------------
350  // 全子ウィンドウ表示関数
351  bool CWndContainer::ShowChildAll( bool bShow ) noexcept {
352  // 処理ブロック
353  bool result = false;
354  do {
355  // 基底クラスの関数を実行する
356  if ( !CWndPane::ShowChildAll( bShow ) ) {
357  // 失敗!
358  break;
359  }
360  // 全エレメントリストウィンドウリストを表示する
361  else if ( !m_cElementList.ShowElementListAll( this, bShow ) ) {
362  // 失敗!
363  break;
364  }
365 
366  // 成功!
367  result = true;
368  } while ( false );
369 
370  // 実行結果を返す
371  return result;
372  }
373 
374  //-------------------------------------------------------------------------
375  // 全子ウィンドウ削除関数
377  // 処理ブロック
378  bool result = false;
379  do {
380  // 全エレメントウィンドウリストを削除する
381  if ( !m_cElementList.DeleteElementListAll( this ) ) {
382  // 失敗!
383  break;
384  }
385 
386  // 基底クラスの関数を実行する
387  result = CWndPane::DeleteChildAll();
388  } while ( false );
389 
390  // 実行結果を返す
391  return result;
392  }
393 
394  //-------------------------------------------------------------------------
395  // 全ウィンドウクライアント領域更新関数
397  // 処理ブロック
398  bool result = false;
399  do {
400  // 基底クラスの関数を実行する
402  // 失敗!
403  break;
404  }
405 
406  // 巡回する
407  for ( int nIndex = 0, nCount = m_cElementList.GetCount(); nCount > nIndex; ++nIndex ) {
408  // エレメントウィンドウを取得する
409  CWndElement* pcElement = m_cElementList[ nIndex ];
410  if ( nullptr != pcElement ) {
411  // 全ウィンドウクライアント領域を更新する
412  pcElement->UpdateClientRectAll();
413  }
414  }
415 
416  // 成功!
417  result = true;
418  } while ( false );
419 
420  // 実行結果を返す
421  return result;
422  }
423 
424  //-------------------------------------------------------------------------
425  // メニューコマンド実行関数
426  bool CWndContainer::ExecMenuCommand( WORD wId, WORD wCode, HWND hCtrl ) noexcept {
427  // 処理ブロック
428  bool result = false;
429  do {
430  // コマンドIDを調べる
431  switch ( wId ) {
432  case ID_DEBUG_NEW_ELEMENT: // デバッグ::新規エレメントウィンドウ
433  // 新規エレメントウィンドウを追加する
435 
436  // 成功!
437  result = true;
438  break;
439  }
440 
441  // 実行結果を調べる
442  if ( result ) {
443  // 親またはオーナーウィンドウを取得する
444  HWND hParent = GetParentOrOwner( m_hWnd );
445 
446  // WM_NOTIFY_CHILD_COMMANDメッセージを送信する
447  ::SendMessageW( hParent, WM_NOTIFY_CHILD_COMMAND, 0, reinterpret_cast< LPARAM >( m_hWnd ) );
448 
449  // 終了!
450  break;
451  }
452 
453  // 基底クラスの関数を実行する
454  result = CWndPane::ExecMenuCommand( wId, wCode, hCtrl );
455  } while ( false );
456 
457  // 実行結果を返す
458  return result;
459  }
460 
461  //-------------------------------------------------------------------------
462  // デバッグメニュー追加関数
463  bool CWndContainer::AppendDebugMenu( HMENU hMenu ) noexcept {
464  // 処理ブロック
465  bool result = false;
466  do {
467  // 基底クラスの関数を実行する
468  if ( !CWndPane::AppendDebugMenu( hMenu ) ) {
469  // 失敗!
470  break;
471  }
472  // エレメントウィンドウリストデバッグサブメニューを追加する
474  // 失敗!
475  break;
476  }
477 
478  // 成功!
479  result = true;
480  } while ( false );
481 
482  // 実行結果を返す
483  return result;
484  }
485 
486  //-------------------------------------------------------------------------
487  // 新規エレメントウィンドウ追加関数
489  // 処理ブロック
490  bool result = false;
491  do {
492  // 新規エレメントウィンドウを追加する
494  if ( nullptr == pcElement ) {
495  // 失敗!
496  break;
497  }
498 
499  // WM_SIZEメッセージを送信する
500  ::SendMessageW( m_hWnd, WM_SIZE, 0, 0 );
501  ::UpdateWindow( m_hWnd );
502 
503  // フォーカスウィンドウを設定する
504  ::SetFocus( pcElement->GetHandle() );
505 
506  // 成功!
507  result = true;
508  } while ( false );
509 
510  // 実行結果を返す
511  return result;
512  }
513 
514  //=========================================================================
515  // 静的限定公開文字列定数
516  wchar_t const* const CWndContainer::KEY_FOCUS_ELEMENT = L"エレメントウィンドウフォーカス有効";
517 }
518 
519 #pragma managed( pop )
virtual HWND & GetHandle() noexcept
ウィンドウハンドル取得関数
Definition: CWndBase.h:69
virtual bool ShowChildAll(bool bShow) noexcept
全子ウィンドウ表示関数
Definition: CWndPane.h:543
virtual LRESULT WmNotifyChildSetFocus() noexcept override
ユーザ定義メッセージ処理関数
ウィンドウユーティリティライブラリヘッダファイル
virtual bool Create(HWND hParent=nullptr, HMENU hMenu=nullptr) noexcept override
ウィンドウ作成関数
Definition: CWndPane.cpp:50
virtual bool InitConfig(CJsonConfig &rcConfig) noexcept override
ウィンドウ構成情報初期化関数
コマンドID定義ヘッダファイル
virtual bool ShowChildAll(bool bShow) noexcept override
全子ウィンドウ表示関数
virtual bool ResumeElementListConfig(CJsonConfig &rcConfig, wchar_t const *pszElementName) noexcept
エレメントウィンドウリスト構成情報復元関数
Definition: CWndList.cpp:331
virtual CWndElement * GetElementWindow(HWND hWnd) const noexcept
エレメントウィンドウ取得関数
Definition: CWndList.cpp:234
virtual bool CreateListWindow(HWND hParent=nullptr, HMENU hMenu=nullptr) noexcept
エレメントウィンドウリスト作成関数
Definition: CWndList.cpp:73
コンテナウィンドウクラス
Definition: CWndContainer.h:31
bool m_bFocusElement
エレメントウィンドウフォーカス有効フラグ
CWndElement *(* m_pfnCreateElement)()
新規エレメントウィンドウ作成関数ポインタ
virtual bool UpdateClientRectAll() noexcept
全ウィンドウクライアント領域更新関数
Definition: CWndPane.cpp:757
virtual CWndElement * GetShowCurrentElement() const noexcept
表示状態カレントエレメントウィンドウ取得関数
Definition: CWndList.cpp:192
virtual bool ResumeConfig(CJsonConfig &rcConfig) noexcept override
ウィンドウ構成情報復元関数
virtual bool UpdateClientRectAll() noexcept override
全ウィンドウクライアント領域更新関数
virtual bool SaveConfig(CJsonConfig &rcConfig) noexcept override
ウィンドウ構成情報保存関数
配列クラス実装ヘッダファイル
virtual bool ResumeConfig(CJsonConfig &rcConfig) noexcept
ウィンドウ構成情報復元関数
Definition: CWndPane.cpp:395
コンテナウィンドウクラスヘッダファイル
virtual bool ExecMenuCommand(WORD wId, WORD wCode, HWND hCtrl) noexcept
メニューコマンド実行関数
Definition: CWndPane.cpp:938
virtual bool AppendDebugMenu(HMENU hMenu) noexcept override
デバッグメニュー追加関数
virtual CWndPane * GetElementListOrderPane(int *pnOrder) noexcept
エレメントウィンドウリストオーダー番号ペインウィンドウ取得関数
Definition: CWndList.cpp:537
virtual bool DeleteChildAll() noexcept
全子ウィンドウ削除関数
Definition: CWndPane.h:556
HWND m_hWnd
ウィンドウハンドル
Definition: CWndBase.h:1539
JSON構成情報クラス
Definition: CJsonConfig.h:31
CWndContainer(CWndElement *(*pfnCreateElement)(), wchar_t const *pszElementName) noexcept
コンストラクタ
virtual bool GetChildElementListInfo(CWndPane *pcParent, SChildPaneInfo &rsChildInfo) noexcept
子エレメントウィンドウリスト情報取得関数
Definition: CWndList.cpp:449
static HWND s_hFocus
フォーカスウィンドウ保存ハンドル
Definition: CWndPane.h:697
virtual LRESULT WmNotifyChildSetFocus() noexcept
ユーザ定義メッセージ処理関数
Definition: CWndPane.cpp:335
ウィンドウライブラリ名前空間
Definition: CommandIdDef.h:22
CWndList m_cElementList
エレメントウィンドウリスト
static wchar_t const *const KEY_FOCUS_ELEMENT
エレメントウィンドウフォーカス有効状態キー文字列
virtual bool SaveConfig(CJsonConfig &rcConfig) noexcept
ウィンドウ構成情報保存関数
Definition: CWndPane.cpp:419
virtual bool DeleteChildWindow(CWndPane *pcChild) noexcept override
子ウィンドウ削除関数
LIB_WINDOW_API HWND GetParentOrOwner(HWND hWnd) noexcept
親またはオーナーウィンドウ取得関数
virtual bool InitConfig(CJsonConfig &rcConfig) noexcept
ウィンドウ構成情報初期化関数
Definition: CWndPane.h:336
virtual bool RemoveElementWindow(CWndElement *pcElement) noexcept
エレメントウィンドウ削除関数
Definition: CWndList.h:196
virtual int GetOrderIndex(CWndPane *pcPane=nullptr, int *pnOrder=nullptr) noexcept override
ペインウィンドウオーダー番号取得関数
virtual LRESULT WmSetFocus() noexcept override
Definition: CWndPane.cpp:171
virtual bool AppendDebugMenu(HMENU hMenu) noexcept
デバッグメニュー追加関数
Definition: CWndPane.cpp:1055
LPARAM m_lParam
メッセージ第2引数
Definition: CWndBase.h:1542
virtual bool AppendElementListDebugSubMenu(HMENU hMenu, CWndPane *pcParent, wchar_t const *pszElementName, WORD wIdNew) noexcept
エレメントウィンドウリストデバッグサブメニュー追加関数
Definition: CWndList.cpp:720
virtual bool ShowElementListAll(CWndPane *pcParent, bool bShow) noexcept
全エレメントウィンドウリスト表示関数
Definition: CWndList.cpp:563
virtual int GetElementListOrderIndex(CWndPane *pcPane, int *pnOrder) noexcept
エレメントウィンドウリストオーダー番号取得関数
Definition: CWndList.cpp:511
virtual bool GetChildPaneInfo(SChildPaneInfo &rsChildInfo) noexcept override
子ペインウィンドウ情報取得関数
virtual bool DeleteElementListAll(CWndPane *pcParent) noexcept
全エレメントウィンドウリスト削除関数
Definition: CWndList.cpp:605
ペインウィンドウクラス
Definition: CWndPane.h:74
virtual CWndElement * AppendNewElementWindow(HWND hParent, CWndElement *(*pfnCreateElement)()) noexcept
新規エレメントウィンドウ追加関数
Definition: CWndList.cpp:682
virtual bool SetCurrentElement(CWndElement *pcElement) noexcept
カレントエレメントウィンドウ設定関数
Definition: CWndList.h:172
virtual bool AppendNewElementWindow() noexcept
新規エレメントウィンドウ追加関数
virtual LRESULT WmSetFocus() noexcept override
各種メッセージ処理関数
virtual bool Create(HWND hParent=nullptr, HMENU hMenu=nullptr) noexcept override
ウィンドウ作成関数
virtual bool GetChildPaneInfo(SChildPaneInfo &rsChildInfo) noexcept
子ペインウィンドウ情報取得関数
Definition: CWndPane.cpp:497
virtual bool ExecMenuCommand(WORD wId, WORD wCode, HWND hCtrl) noexcept override
メニューコマンド実行関数
virtual CWndPane * GetOrderPane(int *pnOrder) noexcept override
オーダー番号ペインウィンドウ取得関数
virtual CWndPane * GetOrderPane(int *pnOrder) noexcept
オーダー番号ペインウィンドウ取得関数
Definition: CWndPane.cpp:551
virtual bool SaveElementListConfig(CJsonConfig &rcConfig, wchar_t const *pszElementName) noexcept
エレメントウィンドウリスト構成情報保存関数
Definition: CWndList.cpp:383
virtual bool DeleteChildAll() noexcept override
全子ウィンドウ削除関数
子ペインウィンドウ情報構造体
Definition: CWndPane.h:43
constexpr WORD const ID_DEBUG_NEW_ELEMENT
デバッグ::新規エレメントウィンドウ
Definition: CommandIdDef.h:73
wchar_t const * m_pszElementName
エレメントウィンドウ名
constexpr UINT const WM_NOTIFY_CHILD_COMMAND
子ウィンドウコマンド実行通知
Definition: CWndPane.h:32
virtual bool InitElementListConfig(CJsonConfig &rcConfig, CWndElement *(*pfnCreateElement)(), wchar_t const *pszElementName) noexcept
エレメントウィンドウリスト構成情報初期化関数
Definition: CWndList.cpp:259
virtual int GetCount() const noexcept
配列要素数取得関数
Definition: CArray.h:149
LIB_WINDOW_API bool IsOwnOrChild(HWND hWnd, HWND hChild) noexcept
自分または子ウィンドウ判定関数
virtual bool DeleteChildWindow(CWndPane *pcChild) noexcept
子ウィンドウ削除関数
Definition: CWndPane.h:530
virtual int GetOrderIndex(CWndPane *pcPane=nullptr, int *pnOrder=nullptr) noexcept
ペインウィンドウオーダー番号取得関数
Definition: CWndPane.cpp:511