TNB Library
TnbMfcDrawingComboBox.h
[詳解]
1#pragma once
11#include "TnbMfcCommon.h"
13#include "TnbMfcDrawingButton.h"
14
15
16
17//TNB Library
18namespace TNB {
19namespace MFC {
20
21
22
40class CDrawingComboBox : public CComboBox
41{
42 DEFSUPER(CComboBox);
43public:
44
46 CDrawingComboBox(void) : _super(), m_isUseDrawingButton(false)
47 {
48 }
49
52 {
53 }
54
61 const IDrawable* GetDrawing(int index) const
62 {
63 return m_listBox.GetDrawing(index);
64 }
65
73 int AddString(LPCTSTR lpszItem)
74 {
75 return _super::AddString(lpszItem);
76 }
77
85 int AddDrawing(const IDrawable& draw)
86 {
87 m_InitListBox();
88 int r = _super::AddString(_T(""));
89 if ( r >= 0 )
90 {
91 if ( m_listBox.ResetDrawing(r, draw) )
92 {
93 m_CheckHeight(draw);
94 }
95 else
96 {
97 _super::DeleteString(r);
98 r = LB_ERR;
99 }
100 }
101 return r;
102 }
103
112 int InsertString(int index, LPCTSTR lpszItem)
113 {
114 return _super::InsertString(index, lpszItem);
115 }
116
125 int InsertDrawing(int index, const IDrawable& draw)
126 {
127 m_InitListBox();
128 int r = _super::InsertString(index, _T(""));
129 if ( r >= 0 )
130 {
131 if ( m_listBox.ResetDrawing(r, draw) )
132 {
133 m_CheckHeight(draw);
134 }
135 else
136 {
137 _super::DeleteString(r);
138 r = LB_ERR;
139 }
140 }
141 return r;
142 }
143
150 int DeleteDrawing(UINT index)
151 {
152 m_InitListBox();
153 _super::DeleteString(index);
154 return m_listBox.DeleteDrawing(index);
155 }
156
163 int DeleteString(UINT index)
164 {
165 return DeleteDrawing(index);
166 }
167
171 void ResetContent(void)
172 {
173 m_InitListBox();
174 _super::ResetContent();
175 m_listBox.ResetContent();
176 }
177
183 {
184 m_listBox.SetDefaultMarkDrawer();
185 }
186
194 {
195 return m_listBox.SetBackgroundDrawer(draw);
196 }
197
207 {
208 return m_listBox.SetSelectMarkDrawer(draw, type);
209 }
210
220 {
221 return m_listBox.SetSelectMarkDrawer(draw1, draw2, type);
222 }
223
231 {
232 return m_listBox.SetFocusMarkDrawer(draw);
233 }
234
239 void SetBackColor(COLORREF color)
240 {
241 m_listBox.SetBackColor(color);
242 }
243
249 void SetTextDrawer(const CTextDrawer& text)
250 {
251 m_listBox.SetTextDrawer(text);
252 }
253
261 {
262 return m_button;
263 }
264
271 void UseDrawingButton(bool r = true)
272 {
273 m_isUseDrawingButton = r;
274 if ( ::IsWindow(m_button) )
275 {
276 if ( ! r )
277 {
278 m_button.DestroyWindow();
279 }
280 RedrawWindow();
281 }
282 }
283
284protected:
285
296 virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
297 {
298 switch ( message )
299 {
300 case WM_ERASEBKGND: //背景
301 return 0;
302 case WM_SETFOCUS:
303 case WM_KILLFOCUS:
304 Invalidate();
305 break;
306 case WM_DESTROY:
307 m_listBox.ResetContent();
308 if ( m_listBox.GetSafeHwnd() != NULL )
309 {
310 m_listBox.UnsubclassWindow();
311 }
312 m_button.DestroyWindow();
313 break;
314 case WM_CTLCOLORLISTBOX:
315 if ( m_listBox.GetSafeHwnd() == NULL )
316 {
317 m_listBox.SubclassWindow(reinterpret_cast<HWND>(lParam));
318 m_listBox.SetOwner(this);
319 }
320 break;
321 case WM_SETREDRAW:
322 if ( m_listBox.GetSafeHwnd() != NULL )
323 {
324 m_listBox.SendMessage(WM_SETREDRAW, wParam, lParam);
325 }
326 break;
327 case WM_LBUTTONDOWN:
328 case WM_LBUTTONDBLCLK:
329 if ( ::IsWindow(m_button) )
330 {
331 if ( ! m_validRect.PtInRect(CPoint(lParam)) )
332 {
333 return 0;
334 }
335 }
336 break;
337 case WM_COMMAND:
338 if ( wParam == BUTTON_CTRLID )
339 {
340 SetFocus();
341 ShowDropDown();
342 m_listBox.RedrawWindow();
343 }
344 break;
345 }
346 return _super::WindowProc(message, wParam, lParam);
347 }
348
354 virtual void PreSubclassWindow(void)
355 {
356 #ifdef _DEBUG
357 DWORD dwStyle = _super::GetStyle();
358 ASSERT0(dwStyle & (CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE), "CDrawingComboBox", "[オーナー描画]を[なし]以外にしてください");
359 ASSERT0(dwStyle & CBS_DROPDOWNLIST, "CDrawingComboBox", "[]を[ドロップダウンリスト]にしてください");
360 ASSERT0(dwStyle & CBS_HASSTRINGS, "CDrawingComboBox", "[文字列]を[あり]にしてください");
361 ASSERT0((dwStyle & CBS_SORT) == 0, "CDrawingComboBox", "[ソート]を[false]にしてください");
362 #endif
363 _super::PreSubclassWindow();
364 const int _CB_GETCOMBOBOXINFO = 0x0164;
365 _COMBOBOXINFO cbi;
366 cbi.cbSize = sizeof(cbi);
367 if ( SendMessage(_CB_GETCOMBOBOXINFO, 0, reinterpret_cast<LPARAM>(&cbi)) )
368 {
369 if ( m_listBox.GetSafeHwnd() == NULL )
370 {
371 HWND h = cbi.hwndList;
372 m_listBox.SubclassWindow(h);
373 m_listBox.SetOwner(this);
374 }
375 }
376 }
377
383 virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
384 {
385 if ( lpDrawItemStruct->CtlType != ODT_COMBOBOX || lpDrawItemStruct->hwndItem != _super::GetSafeHwnd() )
386 {
387 return;
388 }
389 const CRect& rc = lpDrawItemStruct->rcItem;
390 if ( m_isUseDrawingButton && ! ::IsWindow(m_button) )
391 {
392 m_validRect = rc;
393 DWORD style = BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE;
394 int x = ::GetSystemMetrics(SM_CXVSCROLL);
395 CRect r(rc.right + 1, rc.top, rc.right + x + 1, rc.bottom + 1);
396 if ( (GetExStyle() & WS_EX_RIGHT) != 0 )
397 {
398 r.left = rc.left - x - 1;
399 r.right = rc.left - 1;
400 }
401 m_button.Create(_T("Button"), _T(""), style, r, this, BUTTON_CTRLID);
402
403 }
404 if ( ::IsWindow(m_listBox) )
405 {
406 lpDrawItemStruct->CtlType = ODT_LISTBOX;
407 lpDrawItemStruct->hwndItem = m_listBox.GetSafeHwnd();
408 lpDrawItemStruct->CtlID = m_listBox.GetDlgCtrlID();
409 m_listBox.MyDrawItem(lpDrawItemStruct);
410 }
411 }
412
418 virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
419 {
420 if ( lpMeasureItemStruct->CtlType != ODT_COMBOBOX || ToInt(lpMeasureItemStruct->CtlID) != _super::GetDlgCtrlID() )
421 {
422 return;
423 }
424 if ( ::IsWindow(m_listBox) )
425 {
426 lpMeasureItemStruct->CtlType = ODT_LISTBOX;
427 lpMeasureItemStruct->CtlID = m_listBox.GetDlgCtrlID();
428 m_listBox.MyMeasureItem(lpMeasureItemStruct);
429 }
430 }
431
432private:
434 class CMyListBox : public CDrawingListBox
435 {
436 DEFSUPER(CDrawingListBox);
437 public:
438 virtual void MyMeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
439 {
440 _super::MeasureItem(lpMeasureItemStruct);
441 }
442 virtual void MyDrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
443 {
444 _super::DrawItem(lpDrawItemStruct);
445 }
446 };
448 struct _COMBOBOXINFO
449 {
450 DWORD cbSize;
451 RECT rcItem;
452 RECT rcButton;
453 DWORD stateButton;
454 HWND hwndCombo;
455 HWND hwndItem;
456 HWND hwndList;
457 };
462 void m_InitListBox(void)
463 {
464 if ( m_listBox.GetSafeHwnd() == NULL )
465 {
466 CRect rc;
467 GetClientRect(&rc);
468 MFCLIB::ChangeClientSize(this, -1, rc.bottom + 100);
469 ShowDropDown();
470 ShowDropDown(FALSE);
471 MFCLIB::ChangeClientSize(this, -1, rc.bottom);
472 }
473 }
475 void m_CheckHeight(const IDrawable& draw)
476 {
477 int h = _super::GetItemHeight(-1);
478 SIZE sz;
479 if ( draw.GetSize(sz) )
480 {
481 if ( h < sz.cy )
482 {
483 _super::SetItemHeight(-1, sz.cy);
484 m_button.DestroyWindow();
485 }
486 }
487 }
488 enum { BUTTON_CTRLID = 100 };
489 CMyListBox m_listBox;
490 CDrawingButton m_button;
491 bool m_isUseDrawingButton;
492 CRect m_validRect;
493};
494
495
496
497}; // MFC
498}; // TNB
MFCコントロール共通のヘッダ
描画情報ボタン関係のヘッダ
描画情報ListBox関係のヘッダ
テキスト描画クラス
Definition: TnbTextDrawer.h:52
ESelectMarkType
セレクトマークタイプ
@ OVERLAP
アイテム描画上に描画
描画情報ボタンコントロール
描画情報ListBoxコントロール
void SetTextDrawer(const CTextDrawer &text)
[設定] テキスト描画情報指定
int DeleteString(UINT index)
[削除] 一行削除.
int AddDrawing(const IDrawable &draw)
[追加] 描画情報一行追加.
int InsertString(int index, LPCTSTR lpszItem)
[追加] 文字列一行挿入.
int InsertDrawing(int index, const IDrawable &draw)
[追加] 描画情報一行挿入.
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
[通知] オーナードロー処理.
void ResetContent(void)
[削除] 全描画情報削除.
bool SetBackgroundDrawer(const IDrawable &draw)
[設定] 背景描画指定.
virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
オーナードロー時.
void SetBackColor(COLORREF color)
[設定] 背景色設定.
const IDrawable * GetDrawing(int index) const
[取得] 描画情報取得.
bool SetSelectMarkDrawer(const IDrawable &draw1, const IDrawable &draw2, CAbstractDrawingCtrl::ESelectMarkType type=CAbstractDrawingCtrl::OVERLAP)
[設定] 選択マーク描画指定.
void SetDefaultMarkDrawer(void)
[設定] デフォルトのマーク描画指定.
virtual void PreSubclassWindow(void)
[通知] subclassing/unsubclassing functions.
bool SetFocusMarkDrawer(const IDrawable &draw)
[設定] フォーカスマーク描画指定.
int DeleteDrawing(UINT index)
[削除] 一行削除.
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
[通知] for processing Windows messages.
CDrawingButton & ReferButtonControl(void)
[参照] ボタンコントロールクラス参照.
bool SetSelectMarkDrawer(const IDrawable &draw, CAbstractDrawingCtrl::ESelectMarkType type=CAbstractDrawingCtrl::OVERLAP)
[設定] 選択マーク描画指定.
~CDrawingComboBox(void)
デストラクタ
CDrawingComboBox(void)
コンストラクタ
int AddString(LPCTSTR lpszItem)
[追加] 文字列一行追加.
void UseDrawingButton(bool r=true)
[設定] ボタン設定.
描画情報ListBoxコントロール
bool ChangeClientSize(CWnd *pWnd, int cx=-1, int cy=-1)
[設定] クライアントサイズ設定.
Definition: TnbMfcCommon.h:102
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 GetSize(SIZE &_size) const =0
[取得] サイズ取得.