TNB Library
TnbMfcDrawingTreeCtrl.h
[詳解]
1#pragma once
13#include "TnbMap.h"
14
15
16
17//TNB Library
18namespace TNB {
19namespace MFC {
20
21
22
24#define TVC_CHECKCHANGED 0xFFFF
25
26
27
44{
45 DEFSUPER(CTreeCtrl);
48
50 void m_DrawSelectMaker(HDC dc, const RECT& rect, HTREEITEM h)
51 {
52 if ( (GetItemState(h, TVIS_SELECTED ) & TVIS_SELECTED) != 0 )
53 {
54 _mark::DrawSelectMark(dc, rect, ::GetFocus() == m_hWnd);
55 }
56 }
57
59 void m_DeleteItem(HTREEITEM h)
60 {
61 HTREEITEM hh = _super::GetChildItem(h);
62 while ( hh != NULL )
63 {
64 m_DeleteItem(hh);
65 hh = _super::GetNextSiblingItem(hh);
66 }
67 m_map.RemoveKey(h);
68 }
69
70 void m_NotifyParent(HTREEITEM h)
71 {
72 NMTREEVIEW nm = { 0 };
73 nm.hdr.hwndFrom = *this;
74 nm.hdr.idFrom = GetDlgCtrlID();
75 nm.hdr.code = TVN_SELCHANGED;
76 nm.action = TVC_CHECKCHANGED;
77 nm.itemOld.hItem = h;
78 nm.itemNew.hItem = h;
79 GetParent()->SendMessage(WM_NOTIFY, GetDlgCtrlID(), reinterpret_cast<LPARAM>(&nm));
80 }
81
82protected:
83
93 virtual void OnBeginItemPaint(HDC dc)
94 {
95 m_lowLine = 0;
97 }
98
105 virtual void OnEndItemPaint(HDC dc)
106 {
107 bool r = _mark::EndItemPaint();
108 // 描画していないところを描画
109 CRect rc;
110 GetClientRect(rc);
111 rc.top = m_lowLine;
112 _mark::DrawBackColor(dc, rc);
113 // 再描画
114 if ( r )
115 {
116 Invalidate();
117 }
118 }
119
128 virtual LRESULT OnItemPainting(TDrawParam* P)
129 {
130 HRGN rgn = ::CreateRectRgnIndirect(&P->rect);
131 ::ExtSelectClipRgn(P->dc, rgn, RGN_DIFF);
132 _DeleteObject(rgn);
133 m_lowLine = max(m_lowLine, P->rect.bottom);
134 // チェックボックスの周りが透過するので書いておく
135 _mark::DrawBackColor(P->dc, CRect(0, P->rect.top, P->rect.left, P->rect.bottom));
136 return CDRF_NOTIFYITEMDRAW; // チェックボックス、線を描いてもらう
137 }
138
144 virtual void OnItemPainted(const TDrawParam* P)
145 {
146 HTREEITEM h = reinterpret_cast<HTREEITEM>(P->itemNo);
147 ::SelectClipRgn(P->dc, NULL);
148 //
149 CString str = GetItemText(h);
150 IDrawable* pDraw = m_map[h];
151 CRect rc = P->rect;
152 //
153 if ( pDraw != NULL && ! str.IsEmpty() )
154 {
155 // BG持ち描画情報用処理
156 pDraw->Resize(rc.Size());
157 pDraw->Draw(P->dc, rc.left, rc.top);
158 pDraw->Draw(NULL, rc.left, rc.top);
160 {
161 m_DrawSelectMaker(P->dc, rc, h);
162 }
163 if ( (P->state & CDIS_FOCUS) != 0 )
164 {
165 _mark::DrawFocusMark(P->dc, rc);
166 }
167 return;
168 }
169 rc.OffsetRect(-rc.TopLeft());
170 CBitmapImage bi;
171 bi.Set(rc.Width(), rc.Height(), _mark::GetBackColor());
172 if ( ! bi.IsEmpty() )
173 {
174 CBitmapDC dc(&bi);
175 _mark::DrawBackground(dc, rc);
177 {
178 m_DrawSelectMaker(dc, rc, h);
179 }
180 if ( pDraw != NULL )
181 {
182 pDraw->Resize(rc.Size());
183 pDraw->Draw(dc, 0, 0);
184 }
185 else
186 {
188 _mark::DrawText(dc, rc, str);
189 }
191 {
192 m_DrawSelectMaker(dc, rc, h);
193 }
194 if ( (P->state & CDIS_FOCUS) != 0 )
195 {
196 _mark::DrawFocusMark(dc, rc);
197 }
198 dc.Draw(P->dc, P->rect.left, P->rect.top);
199 if ( pDraw != NULL )
200 {
201 pDraw->Draw(NULL, P->rect.left, P->rect.top);
202 }
203 }
204 }
205
211 virtual bool HasSubItem(void) const
212 {
213 return false;
214 }
215
223 virtual void OnCalcItemRect(TDrawParam& _pa, bool isSub)
224 {
225 CRect rc;
226 _super::GetItemRect(reinterpret_cast<HTREEITEM>(_pa.itemNo), rc, TRUE);
227 _pa.rect.left = rc.left; // テキストの始まる線にする
228 }
229
242 virtual BOOL OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* _pResult)
243 {
244 if ( message == WM_NOTIFY )
245 {
246 LPNMHDR lpNmHdr = reinterpret_cast<LPNMHDR>(lParam);
247 if ( lpNmHdr->hwndFrom == m_hWnd)
248 {
249 if ( _custom::OnChildNotify(message, wParam, lParam, _pResult) )
250 {
251 return TRUE;
252 }
253 }
254 }
255 return _super::OnChildNotify(message, wParam, lParam, _pResult);
256 }
257
268 virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
269 {
270 switch ( message )
271 {
272 case TVM_DELETEITEM:
273 {
274 HTREEITEM h = reinterpret_cast<HTREEITEM>(lParam);
275 if ( h == TVI_ROOT )
276 {
277 m_map.RemoveAll();
278 }
279 else
280 {
281 m_DeleteItem(h);
282 }
283 }
284 break;
285 case WM_KEYDOWN:
286 if ( wParam == ' ' )
287 {
288 HTREEITEM h = _super::GetSelectedItem();
289 if ( h != NULL )
290 {
291 BOOL old = GetCheck(h);
292 LRESULT r =_super::WindowProc(message, wParam, lParam);
293 if ( old != GetCheck(h) )
294 {
295 m_NotifyParent(h);
296 }
297 return r;
298 }
299 }
300 break;
301 case WM_LBUTTONDOWN:
302 {
303// CPoint pos(LOWORD(lParam), HIWORD(lParam));
304 CPoint pos(lParam);
305 UINT fg;
306 HTREEITEM h = _super::HitTest(pos, &fg);
307 if ( h != NULL )
308 {
309 if ( (fg & TVHT_ONITEMRIGHT) != 0 )
310 {
311 _super::SelectItem(h);
312 }
313 else if ( (fg & TVHT_ONITEMSTATEICON) != 0 )
314 {
315 BOOL old = GetCheck(h);
316 LRESULT r =_super::WindowProc(message, wParam, lParam);
317 ASSERT( old != GetCheck(h) );
318 m_NotifyParent(h);
319 return r;
320 }
321 }
322 }
323 break;
324 case WM_SETFOCUS:
325 case WM_KILLFOCUS:
326 case WM_SIZE:
327 Invalidate();
328 break;
329 case WM_VSCROLL:
330 case WM_MOUSEWHEEL:
331 {
332 _super::SetRedraw(FALSE);
333 LRESULT r = _super::WindowProc(message, wParam, lParam);
334 _super::SetRedraw(TRUE);
335 return r;
336 }
337 break;
338 case WM_ERASEBKGND:
339 return 1;
340 case TVM_SETBKCOLOR:
341 SetBackColor(lParam);
342 break;
343 case WM_DESTROY:
345 break;
346 }
347 return _super::WindowProc(message, wParam, lParam);
348 }
349
355 virtual void PreSubclassWindow(void)
356 {
357 _super::PreSubclassWindow();
358 if ( (_super::GetStyle() & TVS_CHECKBOXES) != 0 )
359 {
360 // バグ?「チェックボックスがある場合、一度スタイルをなくす」
361 _super::ModifyStyle(TVS_CHECKBOXES, 0, 0);
362 _super::ModifyStyle(0, TVS_CHECKBOXES, 0);
363 }
364 _super::ModifyStyle(0, TVS_NONEVENHEIGHT, 0);
365 SetBackColor(GetBkColor());
366 }
367
370
371public:
372
375 {
376 }
377
387 HTREEITEM InsertItem(const IDrawable &draw, HTREEITEM hParent = TVI_ROOT, HTREEITEM hInsertAfter = TVI_LAST, bool hasBg = false)
388 {
389 HTREEITEM h = _super::InsertItem(hasBg ? _T("*") : _T(""), hParent, hInsertAfter);
390 if ( h != NULL )
391 {
392 m_map[h] = draw.Clone();
393 }
394 return h;
395 }
396
405 HTREEITEM InsertItem(LPCTSTR lpszItem, HTREEITEM hParent = TVI_ROOT, HTREEITEM hInsertAfter = TVI_LAST)
406 {
407 return _super::InsertItem(lpszItem, hParent, hInsertAfter);
408 }
409
416 IDrawable* GetItemDrawer(HTREEITEM item)
417 {
418 return m_map[item];
419 }
420
426 COLORREF SetLineColor(COLORREF clrNew = CLR_DEFAULT)
427 {
428 return TreeView_SetLineColor(*this, clrNew);
429 }
430
436 UINT GetState(HTREEITEM hItem) const
437 {
438 ASSERT(::IsWindow(m_hWnd));
439 TVITEM item;
440 item.mask = TVIF_HANDLE | TVIF_STATE;
441 item.hItem = hItem;
442 item.stateMask = TVIS_STATEIMAGEMASK;
443 VERIFY(::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item));
444 return item.state >> 12;
445 }
446
454 bool SetState(HTREEITEM hItem, UINT state)
455 {
456 ASSERT(::IsWindow(m_hWnd));
457 TVITEM item;
458 item.mask = TVIF_HANDLE | TVIF_STATE;
459 item.hItem = hItem;
460 item.stateMask = TVIS_STATEIMAGEMASK;
461 item.state = INDEXTOSTATEIMAGEMASK(state);
462 return !! ::SendMessage(m_hWnd, TVM_SETITEM, 0, (LPARAM)&item);
463 }
464};
465
466
467
468}; // MFC
469}; // TNB
マップ型情報管理関係のヘッダ
カスタム描画抽象コントロール関係のヘッダ
描画情報コントロール抽象クラス関係のヘッダ
#define TVC_CHECKCHANGED
チェックボックスの変更
ツリーコントロール.
ビットマップイメージ管理クラス
bool IsEmpty(void) const
[確認] Empty状態確認.
bool Set(int cx, int cy, COLORREF color=CLR_INVALID)
[設定] イメージ設定.
マップ型情報管理テンプレート
Definition: TnbMap.h:66
カスタム描画抽象コントロール
BOOL OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam, LRESULT *_pResult)
[通知] for notifications from parent
描画情報コントロール抽象クラス
@ OVERLAP
アイテム描画上に描画
bool EndItemPaint(void)
[処理] 描画終了.
COLORREF GetBackColor(void) const
[取得] 背景色取得.
void DrawBackground(HDC dc, const RECT &rect, LPARAM lParam=0)
[描画] 背景表示
void DrawText(HDC dc, const RECT &rect, LPCTSTR lpsz, LPARAM lParam=0)
[描画] 文字列描画
void SetBackColor(COLORREF color)
[設定] 背景色設定.
void DrawSelectMark(HDC dc, const RECT &rect, bool isActive, LPARAM lParam=0)
[描画] 選択マーク表示
ESelectMarkType GetSelectMarkType(void) const
[取得] セレクトマークタイプ
void AllReset(void)
[設定] 全設定リセット.
void DrawFocusMark(HDC dc, const RECT &rect, LPARAM lParam=0)
[描画] フォーカスマーク表示
void BeginItemPaint(void)
[処理] 描画開始.
void DrawBackColor(HDC dc, const RECT &rect)
[描画] 背景色描画
void SetDefaultTextDrawer(CWnd *pWnd)
[設定] テキスト描画情報設定.
ビットマップデバイスコンテキストクラス
bool Draw(HDC dc, int x=0, int y=0) const
[処理] イメージ描画.
描画情報TreeCtrlコントロール
HTREEITEM InsertItem(LPCTSTR lpszItem, HTREEITEM hParent=TVI_ROOT, HTREEITEM hInsertAfter=TVI_LAST)
[追加] アイテム追加.
virtual void OnEndItemPaint(HDC dc)
[通知] 描画終了.
COLORREF SetLineColor(COLORREF clrNew=CLR_DEFAULT)
[設定] 線色指定
bool SetState(HTREEITEM hItem, UINT state)
[設定] アイテム状態設定
CDrawingTreeCtrl(void)
コンストラクタ
virtual void OnBeginItemPaint(HDC dc)
[通知] 描画開始.
virtual BOOL OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam, LRESULT *_pResult)
[通知] for notifications from parent
virtual bool HasSubItem(void) const
[確認] サブアイテム概念の有無
HTREEITEM InsertItem(const IDrawable &draw, HTREEITEM hParent=TVI_ROOT, HTREEITEM hInsertAfter=TVI_LAST, bool hasBg=false)
[追加] アイテム追加
virtual void OnItemPainted(const TDrawParam *P)
[通知] アイテム描画終わり.
virtual void PreSubclassWindow(void)
[通知] subclassing/unsubclassing functions.
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
[通知] for processing Windows messages.
virtual void OnCalcItemRect(TDrawParam &_pa, bool isSub)
[確認] アイテムRECT計算
UINT GetState(HTREEITEM hItem) const
[取得] アイテム状態取得
CMapT< HTREEITEM, IDrawable::Ptr > m_map
HTREEITEM と 描画情報の関連
virtual LRESULT OnItemPainting(TDrawParam *P)
[通知] アイテム描画.
IDrawable * GetItemDrawer(HTREEITEM item)
[取得] アイテムの描画情報取得.
TNB Library
Definition: TnbDoxyTitle.txt:2
描画情報インターフェース
Definition: TnbDrawable.h:37
virtual bool Resize(const SIZE &size)=0
[設定] サイズ設定.
virtual IDrawable * Clone(void) const =0
[作成] クローン作成.
virtual void Draw(HDC dc, int x=0, int y=0) const =0
[描画] 描画.
DWORD_PTR itemNo
アイテムナンバー