TNB Library
TnbMfcDrawingHeaderCtrl.h
[詳解]
1#pragma once
11#include "TnbVector.h"
12#include "TnbBitmapImage.h"
13#include "TnbTextDrawer.h"
14#include "TnbPartsDrawable.h"
15
16
17
18//TNB Library
19namespace TNB {
20namespace MFC {
21
22
23
41class CDrawingHeaderCtrl : public CHeaderCtrl
42{
43 DEFSUPER(CHeaderCtrl);
44public:
45
47 CDrawingHeaderCtrl(void) : m_isStateChecking(false), m_isAutoAdjustWidth(true)
48 , m_textColor(::GetSysColor(COLOR_WINDOWTEXT)), m_backColor(CLR_INVALID), m_isEnableChangeWidth(true)
49 {
50 m_pPartsDraw = &m_standardParts;
51 }
52
59 void SetTextColor(COLORREF color)
60 {
61 m_textColor = color;
62 }
63
69 void SetBackground(const IPartsDrawable* pParts, COLORREF color = CLR_INVALID)
70 {
71 m_pPartsDraw = pParts;
72 m_backColor = color;
73 if ( m_backBrush.GetSafeHandle() != NULL )
74 {
75 m_backBrush.DeleteObject();
76 }
77 }
78
86 bool SetColumnDrawer(int col, const IDrawable& draw)
87 {
88 if ( col >=0 && _super::GetItemCount() > col )
89 {
90 return m_columnDrawers.Set(col, draw.Clone());
91 }
92 return false;
93 }
94
100 void SetAdjustWidthMode(bool b = true)
101 {
102 m_isAutoAdjustWidth = b;
103 }
104
110 bool IsAdjustWidthMode(void) const
111 {
112 return m_isAutoAdjustWidth;
113 }
114
119 void EnableChangeWidth(bool b = true)
120 {
121 m_isEnableChangeWidth = b;
122 }
123
129 bool IsWindow(void) const
130 {
131 return !! ::IsWindow(_super::GetSafeHwnd());
132 }
133
139 int GetItemCount() const
140 {
141 return IsWindow() ? _super::GetItemCount() : 1;
142 }
143
148 void _deprecated Reset(void)
149 {
150 }
151
152protected:
153
159 virtual void PreSubclassWindow(void)
160 {
161 if ( (GetStyle() & HDS_BUTTONS) == 0 )
162 {
163 m_isEnableChangeWidth = false;
164 }
165 _super::PreSubclassWindow();
166 }
167
179 virtual BOOL OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* _pResult)
180 {
181 if ( message == WM_NOTIFY )
182 {
183 LPNMHDR lpNmHdr = reinterpret_cast<LPNMHDR>(lParam);
184 if ( lpNmHdr->code == NM_CUSTOMDRAW )
185 {
186 LPNMLVCUSTOMDRAW P = reinterpret_cast<LPNMLVCUSTOMDRAW>(lParam);
187 *_pResult = CDRF_DODEFAULT;
188 switch ( P->nmcd.dwDrawStage )
189 {
190 case CDDS_PREPAINT:
191 *_pResult = CDRF_NOTIFYITEMDRAW | CDRF_NOTIFYPOSTPAINT;
192 break;
193 case CDDS_ITEMPREPAINT:
194 m_columnStates.Set(P->nmcd.dwItemSpec, P->nmcd.uItemState);
195 break;
196 }
197 return TRUE;
198 }
199 }
200 return FALSE;
201 }
202
213 virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
214 {
215 switch ( message )
216 {
217 case WM_PAINT:
218 m_Draw(CPaintDC(this));
219 return 0;
220 break;
221 case WM_PRINTCLIENT:
222 if ( ! m_isStateChecking )
223 {
224 HDC dc = reinterpret_cast<HDC>(wParam);
225 m_Draw(dc);
226 return 0;
227 }
228 break;
229 case WM_ERASEBKGND:
230 if ( ! m_isStateChecking )
231 {
232 return 0;
233 }
234 break;
235 case WM_MOUSEMOVE:
236 case WM_SETCURSOR:
237 case WM_LBUTTONDBLCLK:
238 if ( ! m_isEnableChangeWidth )
239 {
240 return 0;
241 }
242 break;
243 case HDM_DELETEITEM:
244 {
245 INDEX col = wParam;
246 LRESULT r = _super::WindowProc(message, wParam, lParam);
247 if ( r != 0 )
248 {
249 m_columnDrawers.Remove(col);
250 }
251 return r;
252 }
253 break;
254 }
255 return _super::WindowProc(message, wParam, lParam);
256 }
257
258private:
259
261 void m_Draw(HDC dc)
262 {
263 CRect clientRect;
264 _super::GetClientRect(&clientRect);
265 // 状態チェックする
266 m_isStateChecking = true;
267 CBitmapImage orgImg;
268 orgImg.SetFromClient(*this, clientRect, CLR_AUTOSELECT); //WM_PRINTCLIENT でカスタムドローを動かし、状態を拾う
269 m_isStateChecking = false;
270 // アイテム取得オブジェクト用意
271 HDITEM hdi;
272 enum { sizeOfBuffer = 256 };
273 TCHAR lpBuffer[sizeOfBuffer];
274 hdi.mask = HDI_TEXT | HDI_WIDTH | HDI_FORMAT;
275 hdi.pszText = lpBuffer;
276 hdi.cchTextMax = sizeOfBuffer;
277 // 各値用意
278 CPoint pushOffset;
279 m_pPartsDraw->GetPushedOffset(pushOffset);
280 CPoint edgeOffset;
281 m_pPartsDraw->GetEdgeOffset(edgeOffset);
282 int right = clientRect.right;
283 CRect parentRect;
284 bool isEnabled = !! _super::IsWindowEnabled();
285 CWnd* pParent = _super::GetParent();
286 if ( pParent != NULL )
287 {
288 pParent->GetClientRect(&parentRect);
289 right = parentRect.right;
290 isEnabled = !! pParent->IsWindowEnabled();
291 }
292 // 幅自動調整
293 if ( m_isAutoAdjustWidth )
294 {
295 CRect rc = clientRect;
296 int cnt = _super::GetItemCount();
297 for ( int i = 0; i < cnt; i++ )
298 {
299 if ( ! _super::GetItem(i, &hdi) )
300 {
301 continue;
302 }
303 rc.right = rc.left + hdi.cxy;
304 bool r = (rc.right > right);
305 if ( i + 1 == cnt )
306 {
307 r = (rc.right != right);
308 }
309 if ( r )
310 {
311 HDITEM h;
312 h.mask = HDI_WIDTH;
313 h.cxy = right - rc.left;
314 if ( h.cxy < 0 )
315 {
316 h.cxy = 0;
317 }
318 _super::SetItem(i, &h);
319 rc.right = right;
320 }
321 rc.left = rc.right;
322 }
323 }
324 // 各アイテム描画
325 CRect rc = clientRect;
326 loop ( i, _super::GetItemCount() )
327 {
328 if ( ! _super::GetItem(ToInt(i), &hdi) )
329 {
330 continue;
331 }
332 rc.right = rc.left + hdi.cxy;
333 //
334 CPoint offset = edgeOffset;
335 UINT state = DFCS_BUTTONPUSH | DFCS_ADJUSTRECT;
336 if ( (m_columnStates[i] & CDIS_SELECTED) != 0 )
337 {
338 state |= DFCS_PUSHED;
339 offset += pushOffset;
340 }
341 if ( ! isEnabled )
342 {
343 state |= DFCS_INACTIVE;
344 }
345 if ( (GetStyle() & HDS_BUTTONS) == 0 )
346 {
347 state |= DFCS_FLAT;
348 }
349 CRect r = rc;
350 ::FillRect(dc, &r, static_cast<HBRUSH>(::GetStockObject(WHITE_BRUSH)));
351 m_pPartsDraw->DrawButtonControl(dc, &r, state);
352 //
353 HRGN hRgn = ::CreateRectRgnIndirect(&r);
354 ::SelectClipRgn(dc, hRgn);
355 CSize clientSize = rc.Size() - edgeOffset - edgeOffset;
356 IDrawable* pDr = m_columnDrawers[i];
357 if ( pDr != NULL )
358 {
359 pDr->Resize(clientSize);
360 pDr->Draw(dc, rc.left + offset.x, rc.top + offset.y);
361 }
362 else
363 {
364 CFont* pFont = _super::GetFont();
365 UINT style = DT_VCENTER | DT_NOPREFIX | DT_END_ELLIPSIS;
366 if ( (hdi.fmt & HDF_CENTER) != 0 )
367 {
368 style |= DT_CENTER;
369 }
370 else if ( (hdi.fmt & HDF_RIGHT) != 0 )
371 {
372 style |= DT_RIGHT;
373 }
374 COLORREF c = isEnabled ? m_textColor : CLR_INVALID;
375 CTextDrawer d(clientSize, *pFont, c, lpBuffer, style);
376 d.Draw(dc, rc.left + offset.x, rc.top + offset.y);
377 }
378 rc.left = rc.right;
379 ::SelectClipRgn(dc, NULL);
380 _DeleteObject(hRgn);
381 }
382 // 余白描画
383 if ( rc.right < right )
384 {
385 rc.right = right;
386 if ( IS_RGBVALUE(m_backColor) )
387 {
388 if ( m_backBrush.GetSafeHandle() == NULL )
389 {
390 m_backBrush.CreateSolidBrush(m_backColor);
391 }
392 ::FillRect(dc, rc, m_backBrush);
393 }
394 else
395 {
396 UINT state = DFCS_BUTTONPUSH;
397 if ( ! _super::IsWindowEnabled() )
398 {
399 state |= DFCS_INACTIVE;
400 }
401 rc.right += 10; // 右の片を表示させないため
402 m_pPartsDraw->DrawButtonControl(dc, &rc, state);
403 }
404 }
405 }
406
407 const IPartsDrawable* m_pPartsDraw;
408 COLORREF m_backColor;
409 CBrush m_backBrush;
410 COLORREF m_textColor;
411 CAutoVectorT<IDrawable::Ptr> m_columnDrawers;
412 CAutoVectorT<UINT> m_columnStates;
413 CStandardPartsDrawer m_standardParts;
414 bool m_isStateChecking;
415 bool m_isAutoAdjustWidth;
416 bool m_isEnableChangeWidth;
417};
418
419
420
421}; // MFC
422}; // TNB
ビットマップイメージ管理関係のヘッダ
#define loop(VAR, CNT)
loop構文.
Definition: TnbDef.h:343
パーツ描画情報のヘッダ
テキスト描画関係のヘッダ
配列型情報管理関係のヘッダ
ウィンドウ管理.
virtual bool Set(INDEX index, const TYP &t)
[設定] 要素の設定.
Definition: TnbVector.h:1053
ビットマップイメージ管理クラス
bool SetFromClient(HWND hWnd, const RECT &rect, COLORREF backColor=CLR_INVALID)
[設定] クライアントからイメージ設定.
テキスト描画クラス
Definition: TnbTextDrawer.h:52
virtual bool Remove(INDEX index)
[削除] 要素一つ削除.
Definition: TnbVector.h:397
描画情報HeaderCtrlコントロール
void SetAdjustWidthMode(bool b=true)
[設定] 幅自動調整モード設定.
void SetBackground(const IPartsDrawable *pParts, COLORREF color=CLR_INVALID)
[設定] 背景設定
int GetItemCount() const
[取得] カラム数取得.
void EnableChangeWidth(bool b=true)
[設定] 幅変更モード設定.
virtual BOOL OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam, LRESULT *_pResult)
[通知] for notifications from parent メッセージ受信したらコールされます。
bool IsAdjustWidthMode(void) const
[取得] 幅自動調整モード.
bool IsWindow(void) const
[確認] コントロールが存在するか?
void _deprecated Reset(void)
[設定] 設定.
bool SetColumnDrawer(int col, const IDrawable &draw)
[設定] カラム描画情報設定
CDrawingHeaderCtrl(void)
コンストラクタ
virtual void PreSubclassWindow(void)
[通知] subclassing/unsubclassing functions.
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
[通知] for processing Windows messages.
void SetTextColor(COLORREF color)
[設定] テキストカラー設定.
標準WINDOWパーツ描画クラス
int ToInt(LPCSTR lpsz, int iBase=10)
[変換] INT変換(ASCII/SJIS用).
Definition: TnbStrLib.h:367
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
[描画] 描画.
WINDOWパーツ描画インターフェース
virtual void GetEdgeOffset(POINT &_po) const =0
[取得] エッジの幅、高さ.
virtual bool DrawButtonControl(HDC hdc, LPRECT _lprc, UINT uState) const =0
[描画] ボタンコントロール描画.
virtual void GetPushedOffset(POINT &_po) const =0
[取得] 押下状態のずれ.