TNB Library
TnbMfcLayoutDialog.h
[詳解]
1#pragma once
11#include "TnbLayout.h"
12
13
15#define classCLayoutDialog classCDialog
16
17
18
19//TNB Library
20namespace TNB {
21namespace MFC {
22
23
24
38{
39 DEFSUPER(ILayout);
40public:
41
46 CControlLayoutItem(HWND hWnd) : m_hWnd(hWnd)
47 {
48 ms_GetSize(m_hWnd, m_size);
49 }
50
56 CControlLayoutItem(HWND hWnd, const SIZE& sz) : m_hWnd(hWnd), m_size(sz)
57 {
58 }
59
65 virtual ILayout* Clone(void) const
66 {
67 return new CControlLayoutItem(m_hWnd);
68 }
69
77 virtual bool GetSize(SIZE& _size) const
78 {
79 return ms_GetSize(m_hWnd, _size);
80 }
81
89 virtual bool GetMinimumSize(SIZE& _size) const
90 {
91 _size = m_size;
92 return true;
93 }
94
102 virtual bool Resize(const SIZE& size)
103 {
104 ::SetWindowPos(m_hWnd, NULL, 0, 0, size.cx, size.cy, SWP_NOMOVE | SWP_NOZORDER | SWP_NOREDRAW);
105 return true;
106 }
107
116 virtual void Decide(int x, int y, WPARAM wParam, LPARAM lParam)
117 {
118 if ( y >= 0 && wParam == 'HWND' )
119 {
120 //-- Zオーダー変更
121 HWND* pPrevHwnd = reinterpret_cast<HWND*>(lParam);
122 ASSERT( ! ::IsBadWritePtr(pPrevHwnd, sizeof(HWND)) );
123 ::SetWindowPos(m_hWnd, *pPrevHwnd, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW);
124 *pPrevHwnd = m_hWnd;
125 }
126 ms_MoveControlPos(m_hWnd, x, y);
127 }
128
135 friend CControlLayoutItem Li(CWnd* pWnd);
136
144 friend CControlLayoutItem Li(UINT ctrlId, CWnd* pParent);
145
146private:
147 // コントロールのクライアント座標、サイズ取得
148 static bool ms_GetControlPos(POINT& _pos, HWND hWnd)
149 {
150 HWND hParent = ::GetParent(hWnd);
151 RECT rc;
152 if ( hParent != NULL && ::GetWindowRect(hWnd, &rc) )
153 {
154 POINT po = { rc.left, rc.top };
155 if ( ::ScreenToClient(hParent, &po) )
156 {
157 _pos = po;
158 return true;
159 }
160 }
161 return false;
162 }
163 /*
164 * コントロール位置設定.
165 * コントロールを、(親ウィンドウの)指定のクライアント座標に移動します。
166 * @param hWnd コントロール。
167 * @param x クライアント X座標。-1なら移動なし。
168 * @param y クライアント Y座標。-1なら移動なし。
169 */
170 static bool ms_MoveControlPos(HWND hWnd, int x, int y)
171 {
172 POINT po;
173 if ( ms_GetControlPos(po, hWnd) )
174 {
175 int xx = (x < 0) ? po.x : x;
176 int yy = (y < 0) ? po.y : y;
177 ::SetWindowPos(hWnd, NULL, xx, yy, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOREDRAW);
178 return true;
179 }
180 return false;
181 }
183 static bool ms_GetSize(HWND hWnd, SIZE& _size)
184 {
185 RECT rc;
186 if ( ::GetWindowRect(hWnd, &rc) )
187 {
188 _size.cx = rc.right - rc.left;
189 _size.cy = rc.bottom - rc.top;
190 return true;
191 }
192 _size.cx = 0;
193 _size.cy = 0;
194 return false;
195 }
196 HWND m_hWnd;
197 SIZE m_size;
198};
199
200
201
202// レイアウトアイテム作成
204{
205 ASSERT( pWnd != NULL );
206 return CControlLayoutItem(pWnd->GetSafeHwnd());
207}
208
209// レイアウトアイテム作成
210inline CControlLayoutItem Li(UINT ctrlId, CWnd* pParent)
211{
212 return Li(pParent->GetDlgItem(ctrlId));
213}
214
215
216
285class CLayoutDialog : public CDialog
286{
287 DEFSUPER(CDialog);
288public:
289
291 CLayoutDialog(void) : _super()
292 {
293 }
294
302 CLayoutDialog(LPCTSTR lpszTemplateName, CWnd* pParentWnd = NULL)
303 : _super(lpszTemplateName, pParentWnd)
304 {
305 }
306
314 CLayoutDialog(UINT nIDTemplate, CWnd* pParentWnd = NULL)
315 : _super(nIDTemplate, pParentWnd)
316 {
317 }
318
325 void SetResizeMode(bool canHorizontalResize = true, bool canVerticalResize = true)
326 {
327 m_param.canHorizontalResize = canHorizontalResize;
328 m_param.canVerticalResize = canVerticalResize;
329 }
330
341 bool SetLayout(ILayout& lay, HWND zorderTop = HWND_TOP)
342 {
343 m_pLayout = lay.Clone();
344 if ( ! m_pLayout.IsNull() && Decide(this, *m_pLayout, zorderTop) )
345 {
346 CRect winRc;
347 _super::GetWindowRect(winRc);
348 return !! _super::SetWindowPos(NULL, 0, 0, winRc.Width(), winRc.Height(), SWP_NOMOVE | SWP_NOZORDER);
349 }
350 return false;
351 }
352
359 bool ChangeClientSize(const SIZE& sz)
360 {
361 CRect winRc;
362 CRect cliRc;
363 _super::GetWindowRect(winRc);
364 _super::GetClientRect(cliRc);
365 CSize s = winRc.Size() - cliRc.Size();
366 return !! _super::SetWindowPos(NULL, 0, 0, sz.cx + s.cx, sz.cy + s.cy, SWP_NOMOVE | SWP_NOZORDER);
367 }
368
376 {
377 if ( ! m_pLayout.IsNull() )
378 {
379 CSize sz;
380 if ( m_pLayout->GetMinimumSize(sz) )
381 {
382 return ChangeClientSize(sz);
383 }
384 }
385 return false;
386 }
387
396 void Decide(int x, int y, WPARAM wParam, LPARAM lParam)
397 {
398 if ( ! m_pLayout.IsNull() )
399 {
400 m_pLayout->Decide(x, y, wParam, lParam);
401 }
402 }
403
413 static bool Decide(const RECT& rect, ILayout& lay, HWND zorderTop = HWND_TOP)
414 {
415 WPARAM wParam = 0;
416 LPARAM lParam = 0;
417 if ( zorderTop != HWND_NOTOPMOST && zorderTop != HWND_BOTTOM && zorderTop != HWND_TOPMOST)
418 {
419 wParam = 'HWND';
420 lParam = reinterpret_cast<LPARAM>(&zorderTop);
421 }
422 SIZE sz = { rect.right - rect.left, rect.bottom - rect.top };
423 bool r = lay.Resize(sz);
424 lay.Decide(rect.left, rect.top, wParam, lParam);
425 return r;
426 }
427
437 static bool Decide(CWnd* pWnd, ILayout& lay, HWND zorderTop = HWND_TOP)
438 {
439 bool r = false;
440 if ( ::IsWindow(pWnd->GetSafeHwnd()) )
441 {
442 CRect rc;
443 pWnd->GetClientRect(&rc);
444 r = Decide(rc, lay, zorderTop);
445 pWnd->Invalidate(FALSE);
446 }
447 return r;
448 }
449
450protected:
451
461 virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
462 {
463 if ( ! m_pLayout.IsNull() )
464 {
465 if ( message == WM_SIZE )
466 {
467 int h = HIWORD(lParam);
468 int w = LOWORD(lParam);
469 m_pLayout->Resize(CSize(w, h));
470 m_pLayout->Decide(0, 0, 0, 0);
471 _super::RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN);
472 }
473 #ifndef _WIN32_WCE
474 {
475 if ( message == WM_GETMINMAXINFO )
476 {
477 MINMAXINFO* P = reinterpret_cast<MINMAXINFO*>(lParam);
478 CRect winRc;
479 CRect cliRc;
480 _super::GetWindowRect(winRc);
481 _super::GetClientRect(cliRc);
482 CSize sz;
483 if ( m_pLayout->GetMinimumSize(sz) )
484 {
485 CSize s = winRc.Size() - cliRc.Size();
486 P->ptMinTrackSize.x = sz.cx + s.cx;
487 P->ptMinTrackSize.y = sz.cy + s.cy;
488 if ( ! m_param.canHorizontalResize )
489 {
490 P->ptMaxTrackSize.x = P->ptMinTrackSize.x;
491 }
492 if ( ! m_param.canVerticalResize )
493 {
494 P->ptMaxTrackSize.y = P->ptMinTrackSize.y;
495 }
496 }
497 }
498 }
499 #endif
500 }
501 return _super::WindowProc(message, wParam, lParam);
502 }
503
504private:
505
507 struct TParam
508 {
509 bool canHorizontalResize;
510 bool canVerticalResize;
512 TParam(void) : canHorizontalResize(true), canVerticalResize(true)
513 {}
514 };
515 TParam m_param;
516 ILayout::Ptr m_pLayout;
517};
518
519
520
521}; // MFC
522}; // TNB
レイアウト関係のヘッダ
ウィンドウ管理.
HWND GetSafeHwnd(void) const
[取得] ウィンドウハンドル取得.
bool IsNull(void) const
[確認] NULLチェック
コントロールレイアウトアイテムクラス.
friend CControlLayoutItem Li(CWnd *pWnd)
[作成] レイアウトアイテム作成.
virtual bool GetMinimumSize(SIZE &_size) const
[取得] 最小サイズ取得.
virtual ILayout * Clone(void) const
[作成] クローン作成.
CControlLayoutItem(HWND hWnd)
コンストラクタ.
virtual void Decide(int x, int y, WPARAM wParam, LPARAM lParam)
[処理] 決定.
CControlLayoutItem(HWND hWnd, const SIZE &sz)
コンストラクタ.
virtual bool Resize(const SIZE &size)
[設定] サイズ設定.
virtual bool GetSize(SIZE &_size) const
[取得] サイズ取得.
レイアウトダイアログクラス.
static bool Decide(const RECT &rect, ILayout &lay, HWND zorderTop=HWND_TOP)
[設定] レイアウト指定.
bool ChangeMinimumSize(void)
[設定] 最小サイズ化.
bool ChangeClientSize(const SIZE &sz)
[設定] サイズ変更.
bool SetLayout(ILayout &lay, HWND zorderTop=HWND_TOP)
[設定] レイアウト設定.
void Decide(int x, int y, WPARAM wParam, LPARAM lParam)
[処理] 決定.
CLayoutDialog(UINT nIDTemplate, CWnd *pParentWnd=NULL)
コンストラクタ
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
[通知] for processing Windows messages.
CLayoutDialog(void)
コンストラクタ
static bool Decide(CWnd *pWnd, ILayout &lay, HWND zorderTop=HWND_TOP)
[設定] レイアウト指定.
CLayoutDialog(LPCTSTR lpszTemplateName, CWnd *pParentWnd=NULL)
コンストラクタ
void SetResizeMode(bool canHorizontalResize=true, bool canVerticalResize=true)
[設定] リサイズモード設定.
CControlLayoutItem Li(CWnd *pWnd)
TNB Library
Definition: TnbDoxyTitle.txt:2
レイアウトインターフェース.
Definition: TnbLayout.h:34
virtual bool Resize(const SIZE &size)=0
[設定] サイズ設定.
virtual bool GetMinimumSize(SIZE &_size) const =0
[取得] 最小サイズ取得.
virtual void Decide(int x, int y, WPARAM wParam, LPARAM lParam)=0
[処理] 決定.
virtual ILayout * Clone(void) const =0
[作成] クローン作成.