TNB Library
TnbMfcEditValue.h
[詳解]
1#pragma once
11#include "TnbMfcEditAscii.h"
12#ifdef _WIN32_WCE
13 #include "TnbCeMfcGesture.h"
14#endif
15
16#ifdef _WIN32_WCE
17 #define _TnbEDIT_Spin_Horz
18#endif
19
20
21
22
23//TNB Library
24namespace TNB {
25namespace MFC {
26
27
28
74template<typename TYP, LONGLONG TMIN, LONGLONG TMAX>
75class CEditValueT : public CEditAscii
76{
77 DEFSUPER(CEditAscii);
78public:
79
80 typedef TYP TYPE;
81
84 : _super(_T("-0123456789")), m_boOnPaint(false), m_iZeroPlace(0)
85 , m_xMin(TMIN), m_xMax(TMAX), m_step(1)
86 {
87 }
88
90 virtual ~CEditValueT(void)
91 {
92 if ( ::IsWindow(*this) )
93 {
94 _super::DestroyWindow();
95 }
96 }
97
103 virtual CString ValueToString(TYPE xValue) const
104 {
105 LONGLONG l = AdjustValue(static_cast<LONGLONG>(xValue));
106 return ToString(l);
107 }
108
113 virtual void SetValue(TYPE xValue)
114 {
115 _super::SetText(ValueToString(xValue));
116 }
117
124 virtual bool GetValue(TYPE& _xValue) const
125 {
126 CString s = m_lastText;//_super::GetText();
127 if ( s.IsEmpty() )
128 {
129 return false;
130 }
131 _xValue = static_cast<TYPE>(AdjustValue(ToInteger(s)));
132 return true;
133 }
134
140 TYPE GetValue(void) const
141 {
142 TYPE v;
143 if ( GetValue(v) )
144 {
145 return v;
146 }
147 return TYPE();
148 }
149
156 void GetRange(TYPE& _xMin, TYPE& _xMax, TYPE& _step)
157 {
158 _xMin = static_cast<TYPE>(m_xMin);
159 _xMax = static_cast<TYPE>(m_xMax);
160 _step = static_cast<TYPE>(m_step);
161 }
162
169 virtual void SetRange(TYPE xMin, TYPE xMax, TYPE step = 0)
170 {
171 m_xMin = static_cast<LONGLONG>(xMin);
172 m_xMax = static_cast<LONGLONG>(xMax);
173 if ( m_xMin > m_xMax )
174 {
176 }
177 if ( TMAX < m_xMax )
178 {
179 m_xMax = TMAX;
180 }
181 if ( TMIN > m_xMin )
182 {
183 m_xMin = TMIN;
184 }
185 if ( step <= 0 )
186 {
187 step = 1;
188 }
189 m_step = ToInt(step);
191 }
192
197 void SetPlace(int ii)
198 {
199 m_iZeroPlace = ii;
200 }
201
206 void AddSpinButton(int dummy = 0)
207 {
208 if ( ! ::IsWindow(m_spin) )
209 {
210 CRect rect;
211 _super::GetClientRect(&rect);
212 m_spinHeight = rect.Height();
213 DWORD style = UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS;
214 #ifdef _TnbEDIT_Spin_Horz
215 style |= UDS_HORZ;
216 #endif
217 m_spin.Create(style, rect, this, 1000);
218 UDACCEL udacl[] =
219 {
220 { 0, 1}, // 1づつ
221 { 2, 5}, // 2秒後からは5づつ
222 { 4, 10}, // 4秒後からは10づつ
223 { 6, 50}, // 6秒後からは50づつ
224 };
225 m_spin.SetAccel(4, udacl);
226 m_spin.SetRange(10000, -10000);
227 m_spin.SetPos(0);
228 m_AdjustSpinAndEdit();
229 }
230 }
231
232protected:
233
245 virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* _pResult)
246 {
247 NMUPDOWN* pNmUpDown = reinterpret_cast<NMUPDOWN *>(lParam);
248 if ( pNmUpDown->hdr.code == UDN_DELTAPOS )
249 {
250 if ( pNmUpDown->iDelta != 0 )
251 {
252 m_SetDelta(pNmUpDown->iDelta);
253 }
254 m_spin.SetPos(0);
255 return TRUE;
256 }
257 return _super::OnNotify(wParam, lParam, _pResult);
258 }
259
260 #ifndef _WIN32_WCE
261
274 virtual BOOL OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* _pResult)
275 {
276 if ( message == WM_CTLCOLORSTATIC || message == WM_CTLCOLOREDIT )
277 {
278 if ( ::IsWindow(m_spin) && m_spin.IsWindowVisible() )
279 {
280 HDC dc = reinterpret_cast<HDC>(wParam);
281 CPoint winPos(0, 0);
282 if ( ! m_boOnPaint )
283 {
284 _super::ClientToScreen(&winPos);
285 }
286 else
287 {
288 m_boOnPaint = false;
289 CRect winRect;
290 _super::GetWindowRect(&winRect);
291 winPos = winRect.TopLeft();
292 }
293 CRect spinRect;
294 m_spin.GetWindowRect(&spinRect);
295 CPoint po = spinRect.TopLeft() - winPos;
296 HRGN rgn = ::CreateRectRgnIndirect(CRect(po, spinRect.Size()));
297 ::ExtSelectClipRgn(dc, rgn, RGN_DIFF);
298 _DeleteObject(rgn);
299 }
300 }
301 return _super::OnChildNotify(message, wParam, lParam, _pResult);
302 }
303
304 #endif //_WIN32_WCE
305
315 virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
316 {
317 if ( ::IsWindow(m_spin) )
318 {
319 if ( message == WM_TIMER )
320 {
321 if ( lParam == TIMERID_SPIN_REPOS )
322 {
323 KillTimer(TIMERID_SPIN_REPOS);
324 m_AdjustSpinAndEdit();
325 }
326 }
327 else if ( message == 0x031A/*WM_THEMECHANGED*/ )
328 {
329 SetTimer(TIMERID_SPIN_REPOS, 1, NULL);
330 }
331 else if ( message == WM_MOUSEWHEEL )
332 {
333 short d = HIWORD(wParam);
334 d /= 120;
335 if ( d != 0 )
336 {
337 m_SetDelta(-d);
338 }
339 return 0;
340 }
341 else if ( message == WM_KEYDOWN || message == WM_KEYUP )
342 {
343 if ( wParam == VK_DOWN || wParam == VK_UP )
344 {
345 UINT msg = (message == WM_KEYDOWN) ? WM_LBUTTONDOWN : WM_LBUTTONUP;
346 #ifndef _TnbEDIT_Spin_Horz
347 int x = 0;
348 int y = (wParam == VK_DOWN) ? m_spinHeight - 1 : 0;
349 #else
350 int x = (wParam == VK_DOWN) ? m_spinHeight + 1 : 0;
351 int y = 0;
352 #endif
353 m_spin.SendMessage(msg, 0, MAKELONG(x, y));
354 return 0;
355 }
356 #ifdef _WIN32_WCE
357 if ( message == WM_KEYDOWN && (wParam == VK_LEFT || wParam == VK_RIGHT) )
358 {
359 DWORD s1 = GetSel();
360 LRESULT r = _super::WindowProc(message, wParam, lParam);
361 CWnd* pPrev = GetParent();
362 if ( s1 == GetSel() && pPrev != NULL )
363 {
364 CWnd* P = pPrev->GetNextDlgTabItem(this, (wParam == VK_LEFT));
365 if ( P != NULL )
366 {
367 LRESULT cd = P->SendMessage(WM_GETDLGCODE);
368 if ( (cd & DLGC_HASSETSEL) != 0 )
369 {
370 P->SendMessage(EM_SETSEL, 0, 0x7FFFFFFE);
371 }
372 P->SetFocus();
373 }
374 }
375 return r;
376 }
377 #endif //_WIN32_WCE
378 }
379 else if ( message == WM_PAINT || message == WM_PRINT )
380 {
381 m_boOnPaint = true;
382 LRESULT r = _super::WindowProc(message, wParam, lParam);
383 m_spin.RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
384 return r;
385 }
386 else if ( message == WM_DESTROY )
387 {
388 m_spin.SetParent(GetParent());
389 }
390 else if ( message == WM_PRINTCLIENT )
391 {
392 #ifndef _WIN32_WCE
393 LRESULT r = _super::WindowProc(message, wParam, lParam);
394 if ( m_spin.IsWindowVisible() )
395 {
396 HDC dc = reinterpret_cast<HDC>(wParam);
397 CPoint winPos(0, 0);
398 _super::ClientToScreen(&winPos);
399 CPoint clientPos(0, 0);
400 m_spin.ClientToScreen(&clientPos);
401 CPoint orgOrg;
402 ::GetWindowOrgEx(dc, &orgOrg);
403 CPoint po = orgOrg - (clientPos - winPos);
404 ::SetWindowOrgEx(dc, po.x, po.y, NULL);
405 m_spin.SendMessage(WM_PRINT, wParam, lParam);
406 ::SetWindowOrgEx(dc, orgOrg.x, orgOrg.y, NULL);
407 }
408 return r;
409 #endif //_WIN32_WCE
410 }
411 else if ( message == EM_SETREADONLY )
412 {
413 m_spin.EnableWindow(wParam == 0);
414 }
415 else if ( message == WM_ENABLE )
416 {
417 m_spin.EnableWindow(wParam != 0);
418 }
419 else if ( message == WM_GETDLGCODE )
420 {
421 #ifdef _WIN32_WCE
422 return _super::WindowProc(message, wParam, lParam) | DLGC_WANTARROWS;
423 #endif
424 }
425 }
426 return _super::WindowProc(message, wParam, lParam);
427 }
428
437 virtual bool IsValidChar(UINT& _nChar, LONG& _lFlags, const CString& strNowText)
438 {
439 if ( _nChar == '-' )
440 {
441 if ( m_xMin >= 0 )
442 {
443 return false;
444 }
445 DWORD g =_super::GetSel();
446 if ( strNowText.Find('-') >= 0 )
447 {
448 if ( LOWORD(g) == 0 && HIWORD(g) > 0 )
449 {
450 return true;
451 }
452 return false;
453 }
454 return LOWORD(g) == 0;
455 }
456 return _super::IsValidChar(_nChar, _lFlags, strNowText);
457 }
458
463 virtual void OnUpdateChar(void)
464 {
465 m_lastText = _super::GetText(); //変更状態を記憶しておく
466 LONGLONG i = ToInteger(m_lastText);
467 LONGLONG ii = i;
468 if ( i > m_xMax )
469 {
470 i = m_xMax;
471 if ( m_step != 1 )
472 {
473 i -= (i % m_step);
474 }
475 _super::SetText(ToString(i), true);
476 if ( i != ii )
477 {
478 ::MessageBeep(MB_ICONASTERISK); //入力制限より内容が変化した時
479 }
480 }
481 }
482
486 virtual void OnEditEnd(void)
487 {
488 CString s = _super::GetText();
489 if ( ! s.IsEmpty() )
490 {
491 LONGLONG i = ToInteger(s);
492 LONGLONG ii = AdjustValue(i);
493 CString s = ToString(ii);
494 if ( _super::GetText() != s )
495 {
496 _super::SetText(s);
497 }
498 if ( i != ii )
499 {
500 ::MessageBeep(MB_ICONASTERISK); //入力制限より内容が変化した時
501 }
502 }
503 }
504
508 virtual void OnChangeRange(void)
509 {
510 }
511
518 virtual CString ToString(LONGLONG ll) const
519 {
520 CString str;
521 if ( m_iZeroPlace > 0 )
522 {
523 CString s;
524 s.Format(_T("%%0%dI64d"), (ll >= 0) ? m_iZeroPlace : (m_iZeroPlace + 1));
525 str.Format(s, ll);
526 }
527 else
528 {
529 str.Format(_T("%I64d"), ll);
530 }
531 return str;
532 }
533
540 virtual LONGLONG ToInteger(LPCTSTR s) const
541 {
542 return _ttoi64(s);
543 }
544
551 virtual LONGLONG AdjustValue(LONGLONG l) const
552 {
553 if ( l > m_xMax )
554 {
555 l = m_xMax;
556 }
557 if ( l < m_xMin )
558 {
559 l = m_xMin;
560 }
561 if ( m_step != 1 )
562 {
563 if ( m_xMin > 0 )
564 {
565 l -= m_xMin;
566 l -= (l % m_step);
567 l += m_xMin;
568 }
569 else
570 {
571 l -= (l % m_step);
572 }
573 }
574 return l;
575 }
576
581 CSpinButtonCtrl& ReferSpinButton(void)
582 {
583 return m_spin;
584 }
585
586 LONGLONG m_xMin;
587 LONGLONG m_xMax;
589 int m_step;
590 CString m_lastText;
591
592private:
593 enum
594 {
595 TIMERID_SPIN_REPOS = 1
596 };
597 #ifndef _WIN32_WCE
598 CSpinButtonCtrl m_spin;
599 #else
600 CSpinButtonCtrlDg m_spin;
601 #endif
602 int m_spinHeight;
603 bool m_boOnPaint;
604 // デルタ
605 void m_SetDelta(int delta)
606 {
607 if ( (GetStyle() & ES_READONLY) != 0 )
608 {
609 return;
610 }
611 ASSERTLIB( delta != 0 );
612 LONGLONG d = delta;
613 LONGLONG d0 = (d < 0) ? -d : d;
614 LONGLONG r = ToInteger(GetText());
615 LONGLONG r0 = r;
616 LONGLONG step = (m_step == 1) ? d0 : m_step;
617 d0 = m_step * d0;
618 if ( delta > 0 )
619 {
620 d0 = -d0;
621 }
622 d0 -= (r % step);
623 r += d0;
624 if ( r > m_xMax )
625 {
626 r = m_xMax;
627 }
628 else if ( r < m_xMin )
629 {
630 r = m_xMin;
631 }
632 if ( r0 != r )
633 {
634 SetFocus();
635 SetText(ToString(r), true);
636 SetSel(0, 0);
637 }
638 }
639 // スピンボタン調整
640 void m_AdjustSpinAndEdit(void)
641 {
642 CRect rect;
643 _super::GetClientRect(&rect);
644 CRect rc;
645 m_spin.GetWindowRect(&rc);
646 UINT h = rc.Width();
647 ASSERT( rc.Height() == m_spinHeight );
648 #ifdef _TnbEDIT_Spin_Horz
649 h = rc.Height() * 2;
650 MFCLIB::ChangeClientSize(&m_spin, h, -1);
651 #endif
652 _super::SetMargins(3, 3 + h);
653 MFCLIB::SetControlPos(&m_spin, rect.Width() - h, -1);
654 m_spin.ShowWindow(SW_SHOW);
655 }
656};
657
658
659
670class CEditULongLong : public CEditValueT<ULONGLONG, 0, 99999999999999999>
671{
672public:
675 {}
676};
677
678
679
688class CEditDword : public CEditValueT<DWORD, 0, 0xFFFFFFFF>
689{
690public:
693 {}
694};
695
696
697
706class CEditInt : public CEditValueT<int, -(0x7FFFFFFF), 0x7FFFFFFE>
707{
708public:
711 {}
712};
713
714
715
724class CEditWord : public CEditValueT<WORD, 0, 65535>
725{
726public:
729 {}
730};
731
732
733
742class CEditShort : public CEditValueT<short, -32768, 32767>
743{
744public:
747 {}
748};
749
750
751
760class CEditByte : public CEditValueT<BYTE, 0, 255>
761{
762public:
765 {}
766};
767
768
769
778class CEditChar : public CEditValueT<char, -128, 127>
779{
780public:
783 {}
784};
785
786
787
802template<typename TYP, size_t WIDTH>
803class CEditHexValueT : public TYP
804{
805 DEFSUPER(TYP);
806public:
807
809 CEditHexValueT(void) : _super()
810 {
811 _super::SetValidChars(_T("1234567890") _T("abcdef") _T("ABCDEF"));
812 }
813
818 void AddSpinButton(int dummy = 0)
819 {
820 _super::AddSpinButton(dummy);
821 UDACCEL udacl[] =
822 {
823 { 0, 0x01}, // 1づつ
824 { 2, 0x08}, // 2秒後からは0x08づつ
825 { 4, 0x10}, // 4秒後からは0x10づつ
826 { 6, 0x20}, // 6秒後からは0x20づつ
827 };
828 ReferSpinButton().SetAccel(4, udacl);
829 }
830
831protected:
832
838 virtual CString ToString(LONGLONG ll) const
839 {
840 CString s;
841 s.Format(_T("%08I64X"), ll);
842 return s.Right(WIDTH);
843 }
844
850 virtual LONGLONG ToInteger(LPCTSTR s) const
851 {
852// return _tcstoul(s, NULL, 16);
853 LONGLONG r = 0;
854 while ( true )
855 {
856 int c = *s++;
857 if ( c >= 'a' && c <= 'f' )
858 {
859 c = (c - 'a') + 10;
860 }
861 else if ( c >= 'A' && c <= 'F' )
862 {
863 c = (c - 'A') + 10;
864 }
865 else if ( c >= '0' && c <= '9' )
866 {
867 c = c - '0';
868 }
869 else
870 {
871 break;
872 }
873 r *= 16;
874 r += c;
875 }
876 return r;
877 }
878};
879
880
881
897class CEditHexDword : public CEditHexValueT<CEditDword, 8>
898{
899public:
902 {}
903};
904
905
906
923class CEditHexWord : public CEditHexValueT<CEditWord, 4>
924{
925public:
928 {}
929};
930
931
932
949class CEditHexByte : public CEditHexValueT<CEditByte, 2>
950{
951public:
954 {}
955};
956
957
958
970template<typename TYP>
971class CNonEmptyEditValueT : public TYP
972{
973 DEFSUPER(TYP);
974protected:
975
979 virtual void OnChangeRange(void)
980 {
981 if ( _super::GetText().IsEmpty() )
982 {
983 _super::SetValue(static_cast<TYPE>(_super::m_xMin));
984 }
985 }
986
992 virtual void PreSubclassWindow(void)
993 {
994 _super::SetText(ToString(_super::m_xMin));
995 _super::PreSubclassWindow();
996 }
997
1002 virtual void OnEditEnd(void)
1003 {
1004 if ( _super::GetText().IsEmpty() )
1005 {
1006 _super::SetValue(static_cast<TYPE>(_super::m_xMin));
1007 }
1008 _super::OnEditEnd();
1009 }
1010};
1011
1012
1013
1014}; //MFC
1015}; //TNB
CE タップ&ホールドジェスチャー関係のヘッダ
文字入力Edit関係のヘッダ
ウィンドウ管理.
DWORD GetStyle(void) const
[取得] ウィンドウスタイル取得.
タップ&ホールドジェスチャー禁止アドイン(CE専用).
ASCII文字専用Editコントロール
void SetText(LPCTSTR lpszText, bool boIsNomoveSel=false)
[設定] 文字列設定
CString GetText(void) const
[取得] 入力文字取得
BYTE 型数値 Edit コントロール
CEditByte(void)
コンストラクタ
char 型数値 Edit コントロール
CEditChar(void)
コンストラクタ
DWORD 型数値 Edit コントロール
CEditDword(void)
コンストラクタ
BYTE 型数値 HEX入力 Edit コントロール
CEditHexByte(void)
コンストラクタ
DWORD 型数値 HEX入力 Edit コントロール
CEditHexDword(void)
コンストラクタ
HEX 入力 Editコントロールテンプレート
CEditHexValueT(void)
コンストラクタ
virtual CString ToString(LONGLONG ll) const
[変換] 数値から文字列作成
virtual LONGLONG ToInteger(LPCTSTR s) const
[変換] 文字列から数値作成
void AddSpinButton(int dummy=0)
[設定] スピンボタン追加
WORD 型数値 HEX入力 Edit コントロール
CEditHexWord(void)
コンストラクタ
Int 型数値 Edit コントロール
CEditInt(void)
コンストラクタ
short 型数値 Edit コントロール
CEditShort(void)
コンストラクタ
ULONGLONG 型数値 Edit コントロール
CEditULongLong(void)
コンストラクタ
数値専用 Edit コントロールテンプレート
virtual CString ValueToString(TYPE xValue) const
[変換] 値文字列化
int m_iZeroPlace
ゼロパディング
virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT *_pResult)
[通知] for notifications from parent
CSpinButtonCtrl & ReferSpinButton(void)
[参照] スピンボタン参照.
virtual void OnChangeRange(void)
[通知] レンジが変わったときにコール
LONGLONG m_xMin
入力可能最小値
virtual ~CEditValueT(void)
デストラクタ
virtual BOOL OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam, LRESULT *_pResult)
[通知] for notifications from parent
int m_step
ステップ数
virtual CString ToString(LONGLONG ll) const
[変換] 数値から文字列作成.
void SetPlace(int ii)
[設定] ゼロパディング桁数設定
virtual LONGLONG ToInteger(LPCTSTR s) const
[変換] 文字列から数値作成.
virtual bool GetValue(TYPE &_xValue) const
[取得] 値取得
virtual void SetRange(TYPE xMin, TYPE xMax, TYPE step=0)
[設定] 範囲指定
virtual LONGLONG AdjustValue(LONGLONG l) const
[変換] 数値丸め.
virtual bool IsValidChar(UINT &_nChar, LONG &_lFlags, const CString &strNowText)
[確認] 入力許可チェック
CEditValueT(void)
コンストラクタ
void AddSpinButton(int dummy=0)
[設定] スピンボタン追加
virtual void SetValue(TYPE xValue)
[設定] 値設定
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
[通知] for processing Windows messages.
LONGLONG m_xMax
入力可能最大値
virtual void OnEditEnd(void)
[通知] フォーカスを失った時にコール
void GetRange(TYPE &_xMin, TYPE &_xMax, TYPE &_step)
[取得] 範囲取得
virtual void OnUpdateChar(void)
[通知] 入力時にコール
TYPE GetValue(void) const
[取得] 値取得
CString m_lastText
最終文字列
WORD 型数値 Edit コントロール
CEditWord(void)
コンストラクタ
空状態無し 数値入力 Editコントロールテンプレート
virtual void OnChangeRange(void)
[通知] レンジが変わったときにコール
virtual void PreSubclassWindow(void)
[通知] subclassing/unsubclassing functions.
virtual void OnEditEnd(void)
[通知] フォーカスを失った時にコール
bool ChangeClientSize(CWnd *pWnd, int cx=-1, int cy=-1)
[設定] クライアントサイズ設定.
Definition: TnbMfcCommon.h:102
bool SetControlPos(CWnd *pWnd, int x, int y, bool boIsRepaint=false)
[設定] コントロール位置設定.
Definition: TnbMfcCommon.h:59
int ToInt(LPCSTR lpsz, int iBase=10)
[変換] INT変換(ASCII/SJIS用).
Definition: TnbStrLib.h:367
void Swap(T &t1, T &t2)
[変換] スワッパー.
Definition: TnbDef.h:963
TNB Library
Definition: TnbDoxyTitle.txt:2
CStr ToString(const CSingleSetT< TYP > &v, TCHAR period=_T(','))
[変換] 文字列化.
Definition: TnbNumberList.h:75