TNB Library
TnbMfcColorListBox.h
[詳解]
1#pragma once
11#include "TnbMfcListBoxCp.h"
12#include "TnbPointerHandle.h"
13#include "TnbQueue.h"
14
15
16
17//TNB Library
18namespace TNB {
19namespace MFC {
20
21
22
54{
55 DEFSUPER(CListBoxCp);
56public:
57
59 CColorListBox(void) : _super(), m_itemHeight(-1), m_itemWidth(-1), m_margin(0), m_isView(true)
60 , m_currentTextColor(::GetSysColor(COLOR_WINDOWTEXT)), m_currentBackColor(::GetSysColor(COLOR_WINDOW))
61 {
62 }
63
69 void SetMaxLine(int maxLine)
70 {
71 m_lineDatas.SetQueueSize(maxLine + 1);
72 _super::SetMaxLine(maxLine);
73 }
74
80 void SetBackColor(COLORREF color = CLR_AUTOSELECT)
81 {
82 if ( m_backBrush.GetSafeHandle() != NULL )
83 {
84 m_backBrush.DeleteObject();
85 }
86 if ( IS_RGBVALUE(color) )
87 {
88 m_backBrush.CreateSolidBrush(color);
89 ASSERT( m_backBrush.GetSafeHandle() != NULL );
90 }
91 }
92
99 void SetCurrentColor(COLORREF textColor, COLORREF backColor)
100 {
101 m_currentTextColor = textColor;
102 m_currentBackColor = backColor;
103 }
104
112 void SetColor(int nIndex, COLORREF textColor, COLORREF backColor)
113 {
114 if ( m_lineDatas.IsInRange(nIndex) )
115 {
116 TParam& p = m_lineDatas[nIndex];
117 p.textColor = textColor;
118 p.backColor = backColor;
119 RedrawWindow();
120 }
121 }
122
127 void SetMargin(DWORD m)
128 {
129 m_margin = m;
130 m_itemHeight = -1;
131 }
132
138 void SetPostViewMode(bool isView)
139 {
140 m_isView = isView;
141 }
142
154 void PostString(int nIndex, LPCTSTR lpszItem, COLORREF textColor = 0, COLORREF backColor = 0)
155 {
156 if ( ::IsWindow(m_hWnd) )
157 {
158 TParam* P = new TParam(lpszItem, textColor, backColor);
159 if ( ! _super::PostMessage(WM_CLB_POSTSTRING, nIndex, reinterpret_cast<LPARAM>(P)) )
160 {
161 delete P;
162 }
163 }
164 }
165
176 int InsertString(int nIndex, LPCTSTR lpszItem)
177 {
178 return _super::InsertString(nIndex, lpszItem);
179 }
180
189 int AddString(LPCTSTR lpszItem)
190 {
191 return _super::AddString(lpszItem);
192 }
193
198 virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
199 {
200 if ( lpDrawItemStruct->CtlType != ODT_LISTBOX || lpDrawItemStruct->hwndItem != _super::GetSafeHwnd() )
201 {
202 return;
203 }
204 UINT nIndex = lpDrawItemStruct->itemID;
205 if ( ! m_lineDatas.IsInRange(nIndex) )
206 {
207 return;
208 }
209 const TParam& p = m_lineDatas[nIndex];
210 CString strText = p.viewItem;
211 COLORREF textColor = p.textColor;
212 COLORREF backColor = p.backColor;
213 if ( (lpDrawItemStruct->itemState & ODS_SELECTED) != 0 )
214 {
215 Swap(textColor, backColor);
216 }
217 //
218 CDC dc;
219 dc.Attach(lpDrawItemStruct->hDC);
220 //
221 COLORREF currenttextColor = dc.SetTextColor(textColor);
222 int currentBkMode = dc.SetBkMode(TRANSPARENT);
223 //
224 dc.FillSolidRect(&(lpDrawItemStruct->rcItem), backColor);
225 RECT rect = lpDrawItemStruct->rcItem;
226 rect.top += m_margin;
227 dc.DrawText(strText, &rect, DT_SINGLELINE | DT_NOPREFIX);
228 if ( (lpDrawItemStruct->itemState & ODS_FOCUS) != 0 )
229 {
230 dc.DrawFocusRect(&(lpDrawItemStruct->rcItem)); //破線
231 }
232 dc.SetBkMode(currentBkMode);
233 dc.SetTextColor(currenttextColor);
234 dc.Detach();
235 }
236
241 virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
242 {
243 if ( lpMeasureItemStruct->CtlType != ODT_LISTBOX || ToInt(lpMeasureItemStruct->CtlID) != _super::GetDlgCtrlID() )
244 {
245 return;
246 }
247 if ( m_itemHeight < 0 )
248 {
249 LOGFONT lf;
250 GetFont()->GetLogFont(&lf);
251 m_itemHeight = lf.lfHeight;
252 if ( m_itemHeight < 0 )
253 {
254 m_itemHeight = -m_itemHeight;
255 }
256 m_itemHeight += m_margin * 2;
257 }
258 lpMeasureItemStruct->itemHeight = m_itemHeight;
259 }
260
261protected:
262
273 virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
274 {
275 int index = ToInt(wParam);
276 LPTSTR lpsz = reinterpret_cast<LPTSTR>(lParam);
277 //
278 switch ( message )
279 {
280 case WM_PAINT:
281 if ( GetCount() == 0 )
282 {
283 CPaintDC dc(this);
284 return 0;
285 }
286 break;
287 case WM_ERASEBKGND: //背景
288 {
289 CDC dc;
290 dc.Attach(reinterpret_cast<HDC>(wParam));
291 CRect rect;
292 GetClientRect(rect);
293 int y = (GetCount() - GetTopIndex()) * m_itemHeight;
294 int h = rect.Height();
295 if( h > y )
296 {
297 if ( y < 0 )
298 {
299 y = 0;
300 }
301 CBrush* B = &m_backBrush;
302 if ( B->GetSafeHandle() == NULL )
303 {
304 B = dc.GetCurrentBrush();
305 }
306 dc.FillRect(CRect(0, y, rect.Width(), h), B);
307 }
308 dc.Detach();
309 }
310 return 0;
311 case WM_SETFOCUS:
312 case WM_KILLFOCUS:
313 RedrawWindow();
314 break;
315 case LB_GETTEXTLEN: //文字列長取得
316 // @param index INDEX
317 // @return 長さ
318 if ( m_lineDatas.IsInRange(index) )
319 {
320 return m_lineDatas[index].item.GetLength();
321 }
322 return LB_ERR;
323 case LB_GETTEXT: //文字列取得
324 // @param[in] index INDEX
325 // @param[out] lParam 格納先
326 if ( m_lineDatas.IsInRange(index) )
327 {
328 CStr s = m_lineDatas[index].item;
329 STRLIB::Copy(lpsz, s);
330 return s.GetLength();
331 }
332 return LB_ERR;
333 case LB_DELETESTRING: //削除
334 // @param index INDEX
335 if ( index == 0 )
336 {
337 m_lineDatas.TakeElements(1);
338 }
339 else if ( m_lineDatas.IsInRange(index) )
340 {
341 m_lineDatas.Remove(index);
342 }
343 break;
344 case LB_ADDSTRING: //追加
345 // @param lParam 文字列アドレス
346 // @note 実際コントロールに設定するのは ""
347 {
348 ASSERTLIB( ToInt(m_lineDatas.GetSize()) == _super::GetCount() );
349 TParam p(lpsz, m_currentTextColor, m_currentBackColor);
350 m_lineDatas.Add(p);
351 m_CheckWidth(p.item);
352 }
353 lParam = reinterpret_cast<LPARAM>(_T(""));
354 break;
355 case LB_INSERTSTRING: //挿入
356 // @param index INDEX
357 // @param lParam 文字列アドレス
358 // @note 実際コントロールに設定するのは ""
359 if ( index < 0 )
360 {
361 TParam p(lpsz, m_currentTextColor, m_currentBackColor);
362 m_lineDatas.Add(p);
363 m_CheckWidth(p.item);
364 }
365 else if ( IsInRange(index, m_lineDatas.GetSize() + 1) )
366 {
367 TParam p(lpsz, m_currentTextColor, m_currentBackColor);
368 m_lineDatas.Insert(index, p);
369 m_CheckWidth(p.item);
370 }
371 lParam = reinterpret_cast<LPARAM>(_T(""));
372 break;
373 case LB_RESETCONTENT: //全消し
374 m_lineDatas.RemoveAll();
375 m_itemWidth = -1;
376 _super::SetHorizontalExtent(m_itemWidth);
377 break;
378 case WM_CLB_POSTSTRING:
379 {
380 TParam* P = reinterpret_cast<TParam*>(lParam);
381 if ( P->textColor != P->backColor )
382 {
383 m_currentTextColor = P->textColor;
384 m_currentBackColor = P->backColor;
385 }
386 if ( ::IsWindow(m_hWnd) )
387 {
388 LRESULT r = _super::InsertString(index, P->item);
389 if ( m_isView )
390 {
391 _super::SetTopIndex(ToInt(r));
392 }
393 }
394 delete P;
395 return 0;
396 }
397 break;
398 case WM_DESTROY:
399 {
400 MSG msg;
401 while ( ::PeekMessage(&msg, m_hWnd, WM_CLB_POSTSTRING, WM_CLB_POSTSTRING, PM_REMOVE) )
402 {
403 if ( msg.message == WM_CLB_POSTSTRING )
404 {
405 TParam* P = reinterpret_cast<TParam*>(msg.lParam);
406 delete P;
407 }
408 }
409 }
410 break;
411 }
412 return _super::WindowProc(message, wParam, lParam);
413 }
414
420 virtual void PreSubclassWindow(void)
421 {
422 #ifdef _DEBUG
423 DWORD dwStyle = _super::GetStyle();
424 ASSERT( dwStyle & LBS_EXTENDEDSEL );
425 ASSERT( m_lineDatas.GetSize() == 0 );
426 #ifndef _WIN32_WCE
427 ASSERT( (dwStyle & LBS_OWNERDRAWVARIABLE) != 0 );
428// ASSERT( (dwStyle & LBS_HASSTRINGS) == 0 );
429 #endif
430 #endif
431 _super::PreSubclassWindow();
432 m_lineDatas.SetQueueSize(_super::GetMaxLine() + 1);
433 }
434
438 virtual void PostNcDestroy(void)
439 {
440 m_lineDatas.RemoveAll();
441 _super::PostNcDestroy();
442 }
443
444private:
446 struct TParam
447 {
448 CStr item;
449 CStr viewItem;
450 COLORREF textColor;
451 COLORREF backColor;
452 TParam(void){}
453 TParam(LPCTSTR lpsz, COLORREF ct, COLORREF cb) : item(lpsz), textColor(ct), backColor(cb)
454 {
455 viewItem = item;
456 const int TABSTOP = 4;
457 while ( true )
458 {
459 INT_PTR tabPos = viewItem.Find('\t');
460 if ( tabPos < 0)
461 {
462 break;
463 }
464 CStr s = viewItem.Mid(tabPos + 1);
465 viewItem = viewItem.Left(tabPos)
466 + CStr::Lineup(' ', TABSTOP - (tabPos % TABSTOP)) + s;
467 }
468 }
469 };
470 int m_itemHeight;
471 int m_itemWidth;
472 CBrush m_backBrush;
473 COLORREF m_currentTextColor;
474 COLORREF m_currentBackColor;
475 CRingQueueT<TParam> m_lineDatas;
476 DWORD m_margin;
477 bool m_isView;
478 //
479 DWORD m_lastPostIndex;
480
484 void m_CheckWidth(LPCTSTR lpszItem)
485 {
486 CDC* pDC = GetDC();
487 CFont* pFont = _super::GetFont();
488 CFont* pFontOld = pDC->SelectObject(pFont);
489 const CSize& size = pDC->GetTextExtent(lpszItem);
490 if ( m_itemWidth < size.cx )
491 {
492 m_itemWidth = size.cx;
493 _super::SetHorizontalExtent(m_itemWidth);
494 }
495 pDC->SelectObject(pFontOld);
496 ReleaseDC(pDC);
497 }
498};
499
500
501
502}; // MFC
503}; // TNB
コピー機能付ListBox関係のヘッダ
ポインタハンドル関係のヘッダ
キュー型情報管理関係のヘッダ
virtual size_t GetSize(void) const
[取得] 要素数取得
Definition: TnbQueue.h:249
void SetQueueSize(size_t size)
[設定] リングキューサイズ指定.
Definition: TnbQueue.h:230
virtual bool Remove(INDEX index)
[削除] 要素一つ削除.
Definition: TnbQueue.h:291
virtual size_t TakeElements(size_t size, TYP *P=NULL)
[取得] 複数要素取り出し.
Definition: TnbQueue.h:392
virtual bool RemoveAll(void)
[削除] データ全削除.
Definition: TnbQueue.h:322
virtual INDEX Add(const TYP &t)
[追加] 要素追加.
Definition: TnbQueue.h:277
CStrT Left(size_t iSize) const
[作成] 範囲取得.
Definition: TnbStr.h:801
size_t GetLength(void) const
[取得] 文字列長
Definition: TnbStr.h:518
INT_PTR Find(TYP t, INDEX iFromIndex=0) const
[確認] 検索.
Definition: TnbStr.h:540
static CStrT Lineup(TCHAR t, size_t length)
[作成] 指定文字を並べた文字列作成
Definition: TnbStr.h:1222
CStrT Mid(INDEX iOffset, size_t iSize=INVALID_SIZE) const
[作成] 範囲取得.
Definition: TnbStr.h:766
カラーListBoxコントロール
void SetMaxLine(int maxLine)
[設定] 最大ライン数設定.
void SetCurrentColor(COLORREF textColor, COLORREF backColor)
[設定] 文字色設定.
CColorListBox(void)
コンストラクタ
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
[通知] オーナードロー通知.
virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
[通知] オーナードロー計算通知.
void SetColor(int nIndex, COLORREF textColor, COLORREF backColor)
[設定] 文字色設定.
virtual void PostNcDestroy(void)
[通知] 破棄終了後通知
void SetMargin(DWORD m)
[設定] マージン設定
virtual void PreSubclassWindow(void)
[通知] subclassing/unsubclassing functions.
int InsertString(int nIndex, LPCTSTR lpszItem)
[追加] 文字列追加.
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
[通知] for processing Windows messages.
void SetPostViewMode(bool isView)
[設定] PostString表示モード設定.
void SetBackColor(COLORREF color=CLR_AUTOSELECT)
[設定] 背景色設定.
int AddString(LPCTSTR lpszItem)
[追加] 文字列追加.
void PostString(int nIndex, LPCTSTR lpszItem, COLORREF textColor=0, COLORREF backColor=0)
[追加] 文字列追加.
文字列コピー機能付ListBoxコントロール
void Copy(LPSTR _dst, LPCSTR src)
[複製] 文字列コピー(ASCII/SJIS用)
Definition: TnbStrLib.h:89
int ToInt(LPCSTR lpsz, int iBase=10)
[変換] INT変換(ASCII/SJIS用).
Definition: TnbStrLib.h:367
void Swap(T &t1, T &t2)
[変換] スワッパー.
Definition: TnbDef.h:963
bool IsInRange(INDEX value, size_t size)
[確認] 範囲チェック.
Definition: TnbDef.h:421
TNB Library
Definition: TnbDoxyTitle.txt:2
virtual bool Insert(INDEX index, const TYP &t)
[追加] 要素一つ挿入.
bool IsInRange(INDEX index) const
[確認] INDEXの有効確認.