TNB Library
TnbMfcLightListBox.h
[詳解]
1#pragma once
11#include "TnbMfcListBoxCp.h"
12#include "TnbMfcDelayedRedraw.h"
13#include "TnbPointerHandle.h"
14#include "TnbQueue.h"
15
16
17
18//TNB Library
19namespace TNB {
20namespace MFC {
21
22
23
56class CLightListBox : public CDelayedRedrawAddinT<CListBoxCp>
57{
59public:
60
63
65 CLightListBox(void) : _super(), m_itemHeight(-1), m_margin(0)
66 {
67 m_clientSize.cx = -1;
68 SetMaxLine(10 * 10000);
69 }
70
76 void SetMaxLine(int maxLine)
77 {
78 _super::SetMaxLine(maxLine);
79 m_lineDatas.SetQueueSize(maxLine);
80 }
81
86 void SetMargin(DWORD m)
87 {
88 m_margin = m;
89 m_itemHeight = -1;
90 }
91
99 void PostString(int nIndex, LPCTSTR lpszItem)
100 {
101 LPTSTR P = CloneString(lpszItem);
102 if ( ! _super::PostMessage(WM_CLB_POSTSTRING, nIndex, reinterpret_cast<LPARAM>(P)) )
103 {
104 delete P;
105 }
106 }
107
118 int InsertString(int nIndex, LPCTSTR lpszItem)
119 {
120 LPTSTR P = CloneString(lpszItem);
121 return m_InsertString(nIndex, P);
122 }
123
132 int AddString(LPCTSTR lpszItem)
133 {
134 return InsertString(-1, lpszItem);
135 }
136
144 virtual int GetText(int nIndex, LPTSTR lpszBuffer) const
145 {
146 if ( m_lineDatas.IsInRange(nIndex) )
147 {
148 STRLIB::Copy(lpszBuffer, m_lineDatas[nIndex]);
149 return STRLIB::GetLen(m_lineDatas[nIndex]);
150 }
151 return LB_ERR;
152 }
153
159 virtual void GetText(int nIndex, CString& rString) const
160 {
161 if ( m_lineDatas.IsInRange(nIndex) )
162 {
163 rString = m_lineDatas[nIndex];
164 }
165 }
166
172 void SetAllString(const CDatas& datas, int index = -1)
173 {
174 int l = ToInt(datas.GetQueueSize());
175 if ( l != GetMaxLine() )
176 {
177 _super::SetMaxLine(l);
178 }
179 m_lineDatas = datas;
180 m_Settle(ToInt((index < 0) ? (datas.GetSize() - 1) : index));
181 }
182
187 const CDatas& GetAllString(void) const
188 {
189 return m_lineDatas;
190 }
191
198 static LPTSTR CloneString(LPCTSTR lpszText)
199 {
200 size_t len = STRLIB::GetLen(lpszText) + 1;
201 LPTSTR P = new TCHAR[len];
202 MemCopy(P, lpszText, len);
203 return P;
204 }
205
206protected:
207
212 virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
213 {
214 if ( lpDrawItemStruct->CtlType != ODT_LISTBOX || lpDrawItemStruct->hwndItem != _super::GetSafeHwnd() )
215 {
216 return;
217 }
218 UINT index = lpDrawItemStruct->itemID;
219 if ( ! m_lineDatas.IsInRange(index) )
220 {
221 return;
222 }
223 LPTSTR P = m_lineDatas[index];
224 HDC dc = lpDrawItemStruct->hDC;
225 COLORREF textColor = 0;
226 HBRUSH backBrush = NULL;
227 if ( (lpDrawItemStruct->itemState & ODS_SELECTED) == 0 )
228 {
229 textColor = ::GetSysColor(COLOR_WINDOWTEXT);
230 backBrush = ::GetSysColorBrush(COLOR_WINDOW);
231 }
232 else
233 {
234 textColor = ::GetSysColor(COLOR_HIGHLIGHTTEXT);
235 backBrush = ::GetSysColorBrush(COLOR_HIGHLIGHT);
236 }
237 COLORREF currentTextColor = ::SetTextColor(dc, textColor);
238 int currentBkMode = ::SetBkMode(dc, TRANSPARENT);
239 ::FillRect(dc, &(lpDrawItemStruct->rcItem), backBrush);
240 RECT rect = lpDrawItemStruct->rcItem;
241 rect.top += m_margin;
242 ::DrawText(dc, P, -1, &rect, DT_SINGLELINE | DT_NOPREFIX);
243 if ( (lpDrawItemStruct->itemState & ODS_FOCUS) != 0 )
244 {
245 ::SetTextColor(dc, 0);
246 ::DrawFocusRect(dc, &(lpDrawItemStruct->rcItem)); //破線
247 }
248 ::SetBkMode(dc, currentBkMode);
249 ::SetTextColor(dc, currentTextColor);
250 }
251
256 virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
257 {
258 }
259
270 virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
271 {
272 int index = ToInt(wParam);
273 switch ( message )
274 {
275 case WM_SETFONT:
276 {
277 LRESULT r = _super::WindowProc(message, wParam, lParam);
278 m_itemHeight = -1;
279 m_Settle();
280 return r;
281 }
282 break;
283 case WM_ERASEBKGND: //背景
284 {
285 if ( m_clientSize.cx < 0 )
286 {
287 CRect rc;
288 _super::GetClientRect(rc);
289 m_clientSize.cy = rc.Height();
290 m_clientSize.cx = rc.Width();
291 }
292 HDC dc = reinterpret_cast<HDC>(wParam);
293 int y = (_super::GetCount() - _super::GetTopIndex()) * m_itemHeight;
294 int h = m_clientSize.cy;
295 if( h > y )
296 {
297 if ( y < 0 )
298 {
299 y = 0;
300 }
301 HBRUSH b = static_cast<HBRUSH>(::GetCurrentObject(dc, OBJ_BRUSH));
302 ::FillRect(dc, CRect(0, y, m_clientSize.cx, h), b);
303 }
304 }
305 return 0;
306 case WM_SIZE:
307 m_clientSize.cy = HIWORD(lParam);
308 m_clientSize.cx = LOWORD(lParam);
309 break;
310 case WM_SETFOCUS:
311 case WM_KILLFOCUS:
312 _super::RedrawWindow();
313 break;
314 case WM_CLB_POSTSTRING:
315 {
316 LPTSTR P = reinterpret_cast<LPTSTR>(lParam);
317 m_InsertString(index, P);
318 return 0;
319 }
320 break;
321 case LB_GETTEXTLEN: //文字列長取得
322 // @param index INDEX
323 // @return 長さ
324 if ( m_lineDatas.IsInRange(index) )
325 {
326 return STRLIB::GetLen(m_lineDatas[index]);
327 }
328 return LB_ERR;
329 case LB_GETTEXT: //文字列取得
330 // @param[in] index INDEX
331 // @param[out] lParam 格納先
332 if ( m_lineDatas.IsInRange(index) )
333 {
334 STRLIB::Copy(reinterpret_cast<TCHAR*>(lParam), m_lineDatas[index]);
335 return STRLIB::GetLen(m_lineDatas[index]);
336 }
337 return LB_ERR;
338 case LB_DELETESTRING:
339 if ( lParam != MAGIC_LPARAM )
340 {
341 if ( m_lineDatas.IsInRange(index) )
342 {
343 m_lineDatas.Remove(index);
344 m_Settle();
345 }
346 return 0;
347 }
348 break;
349 case LB_RESETCONTENT:
350 if ( lParam != MAGIC_LPARAM )
351 {
352 if ( m_lineDatas.GetSize() > 0 )
353 {
354 m_lineDatas.RemoveAll();
355 m_Settle();
356 }
357 }
358 break;
359 case WM_DESTROY:
360 {
361 UINT wm = WM_CLB_POSTSTRING;
362 MSG msg;
363 while ( ::PeekMessage(&msg, _super::GetSafeHwnd(), wm, wm, PM_REMOVE) )
364 {
365 if ( msg.message == wm )
366 {
367 LPTSTR P = reinterpret_cast<LPTSTR>(msg.lParam);
368 delete P;
369 }
370 }
371 }
372 break;
373 }
374 return _super::WindowProc(message, wParam, lParam);
375 }
376
382 virtual void PreSubclassWindow(void)
383 {
384 #ifdef _DEBUG
385 DWORD dwStyle = _super::GetStyle();
386 ASSERT( (dwStyle & LBS_OWNERDRAWFIXED) != 0 );
387 ASSERT( (dwStyle & LBS_HASSTRINGS) == 0 );
388 ASSERT( (dwStyle & LBS_MULTICOLUMN) == 0 );
389 ASSERT( m_lineDatas.GetSize() == 0 );
390 #ifndef _WIN32_WCE
391 ASSERT( (dwStyle & LBS_NODATA) != 0 );
392 #endif
393 #endif
394 _super::PreSubclassWindow();
395 }
396
400 virtual void PostNcDestroy(void)
401 {
402 m_lineDatas.RemoveAll();
403 _super::PostNcDestroy();
404 }
405
406private:
407 enum {
408 MAGIC_LPARAM = 'Tllb' // CE用
409 };
410 // 確定
411 void m_Settle(int index = -1)
412 {
413 int l = ToInt(m_lineDatas.GetSize());
414 #ifndef _WIN32_WCE
415 _super::SendMessage(LB_SETCOUNT, l ,0);
416 #else
417 if ( l == 0 )
418 {
419 _super::SendMessage(LB_RESETCONTENT, 0, MAGIC_LPARAM);
420 }
421 else
422 {
423 size_t ll = _super::GetCount();
424 int d = ll - l;
425 if ( d < 0 )
426 {
427 loop ( i, -d )
428 {
429 _super::SendMessage(LB_ADDSTRING, 0, reinterpret_cast<LPARAM>(_T("")));
430 }
431 }
432 else if ( d > 0 )
433 {
434 loop ( i, d )
435 {
436 _super::SendMessage(LB_DELETESTRING, 0, MAGIC_LPARAM);
437 }
438 }
439 }
440 ASSERT( l == _super::GetCount() );
441 #endif
442 if ( index >= 0 )
443 {
444 _super::SetTopIndex(index);
445 }
446 if ( m_itemHeight < 0 )
447 {
448 LOGFONT lf;
449 _super::GetFont()->GetLogFont(&lf);
450 m_itemHeight = lf.lfHeight;
451 if ( m_itemHeight < 0 )
452 {
453 m_itemHeight = -m_itemHeight;
454 }
455 m_itemHeight += m_margin * 2;
456 _super::SetItemHeight(0, m_itemHeight);
457 }
458 _super::DelayedRedraw();
459 }
462 int m_InsertString(int index, LPTSTR lpszItem)
463 {
464 CArrayPtrHandleT<TCHAR> p = lpszItem;
465 INDEX r = m_lineDatas.Add(p);
466 if ( r == INVALID_INDEX )
467 {
468 int ml = _super::GetMaxLine();
469 int ll = (ml > 1000) ? 20 : 5;
470 m_lineDatas.TakeElements(ll);
471 r = m_lineDatas.Add(p);
472 }
473 if ( r != INVALID_INDEX )
474 {
475 m_Settle(ToInt(r));
476 return ToInt(r);
477 }
478 return -1;
479 }
480 int m_itemHeight;
481 CDatas m_lineDatas;
482 DWORD m_margin;
483 SIZE m_clientSize;
484};
485
486
487
488}; //MFC
489}; //TNB
#define loop(VAR, CNT)
loop構文.
Definition: TnbDef.h:343
遅延再描画コントロール処理関係のヘッダ
コピー機能付ListBox関係のヘッダ
ポインタハンドル関係のヘッダ
キュー型情報管理関係のヘッダ
リング式キュー型情報管理テンプレート
Definition: TnbQueue.h:160
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
size_t GetQueueSize(void) const
[取得] リングキューサイズ取得.
Definition: TnbQueue.h:240
遅延再描画アドイン
LightListBoxコントロール
CRingQueueT< CArrayPtrHandleT< TCHAR > > CDatas
データ管理型
void SetMaxLine(int maxLine)
[設定] 最大ライン数設定.
void PostString(int nIndex, LPCTSTR lpszItem)
[追加] 文字列追加.
virtual int GetText(int nIndex, LPTSTR lpszBuffer) const
[取得] 文字列取得.
static LPTSTR CloneString(LPCTSTR lpszText)
[作成] 文字列クローン作成.
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
[通知] オーナードロー通知.
virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
[通知] オーナードロー計算通知.
virtual void PostNcDestroy(void)
[通知] 破棄終了後通知
void SetMargin(DWORD m)
[設定] マージン設定
virtual void PreSubclassWindow(void)
[通知] subclassing/unsubclassing functions.
const CDatas & GetAllString(void) const
[取得] 全文字列取得.
int InsertString(int nIndex, LPCTSTR lpszItem)
[追加] 文字列追加.
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
[通知] for processing Windows messages.
CLightListBox(void)
コンストラクタ
void SetAllString(const CDatas &datas, int index=-1)
[設定] 全文字列設定.
int AddString(LPCTSTR lpszItem)
[追加] 文字列追加.
virtual void GetText(int nIndex, CString &rString) const
[取得] 文字列取得.
int GetMaxLine(void) const
[取得] 最大ライン数取得.
size_t GetLen(LPCSTR lpsz)
[計算] 文字列長計算(ASCII/SJIS用)
Definition: TnbStrLib.h:44
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
TNB Library
Definition: TnbDoxyTitle.txt:2
void MemCopy(T *_pDst, const void *pSrc, size_t len)
[複製] メモリコピー
Definition: TnbDef.h:376
bool IsInRange(INDEX index) const
[確認] INDEXの有効確認.