TNB Library
TnbMfcLineGraphViewCtrl.h
[詳解]
1#pragma once
11#include "TnbBitmapImage.h"
12#include "TnbMfcBitmapDC.h"
13#include "TnbMap.h"
14#include "TnbTextDrawer.h"
15#include <float.h>
16#include <math.h>
17
18
19
20//TNB Library
21namespace TNB {
22namespace MFC {
23
24
25
136{
137 DEFSUPER(CWnd);
138public:
139
141 enum
142 {
143 EDGE_VALUE = 10000,
144 INTERNALLY_COLOR = RGB(1, 1, 1)
145 };
146
149 {
155 };
156
158 CLineGraphViewCtrl(void) : m_isReverseIndexMode(false), m_viewHorizontalPos(0), m_markerWidth(6), m_scrollOneStep(1)
159 , m_viewTopValue(EDGE_VALUE), m_viewbottomValue(-EDGE_VALUE), m_scrollBarHeight(::GetSystemMetrics(SM_CYHSCROLL))
160 , m_backColor(RGB(0, 0, 0)), m_isGraphImageDcLeading(false), m_isOndemandRemakeViewImage(false), m_horzIndexPixel(1)
161 , m_isMouseButtonPressed(false), m_isScrollBarUsed(true)
162 {
163 m_viewHeight = m_viewTopValue - m_viewbottomValue + 0.0; //表示範囲
164 }
165
175 bool SetBackgroundWidth(COLORREF backgroundColor, size_t graphWidth = 0)
176 {
177 if ( ::IsWindow(GetSafeHwnd()) )
178 {
179 CRect rc;
180 GetClientRect(&rc);
181 CSize sz = rc.Size();
182 m_backColor = backgroundColor;
183 if ( graphWidth == 0 )
184 {
185 graphWidth = sz.cx;
186 }
187 if ( sz.cx == 0 || sz.cy == 0 )
188 {
189 return false;
190 }
191 m_Resize(sz, graphWidth);
193 return true;
194 }
195 return false;
196 }
197
217 bool SetHorizontalIndexPixel(int pixel = 1, bool isReverseIndexMode = false)
218 {
219 if ( ::IsWindow(GetSafeHwnd()) )
220 {
221 m_horzIndexPixel = pixel;
222 if ( m_horzIndexPixel <= 0 )
223 {
224 m_horzIndexPixel = 1;
225 }
226 m_isReverseIndexMode = isReverseIndexMode;
227 m_Resize();
228 return true;
229 }
230 return false;
231 }
232
239 {
240 return m_horzIndexPixel;
241 }
242
249 size_t SetPointMakertSize(size_t width)
250 {
251 size_t r = m_markerWidth;
252 m_markerWidth = width;
253 return r;
254 }
255
261 void GetViewValueRange(double& _topValue, double& _bottomValue) const
262 {
263 _topValue = m_viewTopValue;
264 _bottomValue = m_viewbottomValue;
265 }
266
277 bool SetViewValueRange(double topValue, double bottomValue)
278 {
279 if ( ::IsWindow(GetSafeHwnd()) )
280 {
281 if ( topValue < bottomValue )
282 {
283 Swap(topValue, bottomValue);
284 }
285 if ( m_viewTopValue == topValue && m_viewbottomValue == bottomValue )
286 {
287 return true;
288 }
289 m_viewTopValue = topValue;
290 m_viewbottomValue = bottomValue;
291 m_viewHeight = m_viewTopValue - m_viewbottomValue + 0.0; //表示範囲
292 //
293 const SIZE& sz = m_graphImage.GetSize();
294 if ( m_graphImageDc.GetSafeHdc() != NULL )
295 {
296 m_graphImageDc.FillSolidRect(0, 0, sz.cx, sz.cy, INTERNALLY_COLOR);
297 }
298 m_pointMap.RemoveAll();
299 return true;
300 }
301 return false;
302 }
303
311 bool SetScrollBarHeight(int height = 0)
312 {
313 if ( ::IsWindow(GetSafeHwnd()) )
314 {
315 m_scrollBarHeight = height;
316 if ( height <= 0 )
317 {
318 m_scrollBarHeight = ::GetSystemMetrics(SM_CYHSCROLL);
319 }
320 m_isScrollBarUsed = (height >= 0);
321 m_Resize();
322 return true;
323 }
324 return false;
325 }
326
327
333 void SetScrollOneStep(size_t os = 1)
334 {
335 m_scrollOneStep = os;
336 }
337
344 void SetScaleLine(COLORREF color, ELineStyle style = LineStyle_Solid)
345 {
346 m_scaleLine.Set(style, color, 0.0);
347 }
348
359 bool SetSubScaleLine(INDEX number, ELineStyle style = LineStyle_Non, COLORREF color = 0, double step = 0.0)
360 {
361 if ( number >= 1 && number <= 3 )
362 {
363 TScaleLineInfo& I = m_subScaleLines[number - 1];
364 if ( step <= 0.0 )
365 {
366 style = LineStyle_Non;
367 }
368 I.Set(style, color, step);
369 return true;
370 }
371 return false;
372 }
373
385 bool SetOverlayText(INDEX pos, COLORREF color = RGB(0, 0, 0), LPCTSTR lpsz = NULL, HFONT hFont = NULL)
386 {
387 if ( pos > 0 && pos < 10 )
388 {
389 TTextInfo& t = m_testInfo[pos];
390 t.hFont =hFont;
391 t.text = lpsz;
392 t.color = color;
393 return true;
394 }
395 return false;
396 }
397
405 {
406 return m_isReverseIndexMode;
407 }
408
415 bool HasScrollBar(void) const
416 {
417 return !! ::IsWindow(m_scrollBar);
418 }
419
428 CDC* GetImageDC(void)
429 {
430 if ( m_isGraphImageDcLeading || m_graphImageDc.GetSafeHdc() == NULL )
431 {
432 return NULL;
433 }
434 m_isGraphImageDcLeading = true;
435 return &m_graphImageDc;
436 }
437
442 void ReleaseImageDC(void)
443 {
444 if ( m_isGraphImageDcLeading )
445 {
446 m_isGraphImageDcLeading = false;
447 }
448 }
449
455 const SIZE& GetImageSize(void) const
456 {
457 return m_graphImage.GetSize();
458 }
459
466 int HorizontalIndexToX(INDEX horizontalIndex)
467 {
468 int xx = ToInt(horizontalIndex * m_horzIndexPixel + m_horzIndexPixel / 2);
469 if ( m_isReverseIndexMode )
470 {
471 xx = (m_graphImage.GetSize().cx - 1) - xx;
472 }
473 return xx;
474 }
475
483 void Shift(int count = 1)
484 {
485 if ( m_graphImageDc.GetSafeHdc() != NULL )
486 {
487 const SIZE& sz = m_graphImage.GetSize();
488 count *= m_horzIndexPixel;
489 if ( m_isReverseIndexMode )
490 {
491 count = -count;
492 }
493 m_graphImageDc.ScrollDC(count, 0, NULL, NULL, NULL, NULL);
494 if ( count > 0 )
495 {
496 m_graphImageDc.FillSolidRect(0, 0, count, sz.cy, INTERNALLY_COLOR);
497 }
498 else if ( count < 0 )
499 {
500 m_graphImageDc.FillSolidRect(sz.cx + count, 0, -count, sz.cy, INTERNALLY_COLOR);
501 }
502 loop ( i, m_pointMap )
503 {
504 m_pointMap.Ref(i).second->point.x += count;
505 }
506 }
507 }
508
515 INDEX GetHorizontalIndexLimit(void) const
516 {
517 return m_graphImage.GetSize().cx / m_horzIndexPixel;
518 }
519
524 void ClearPoint(void)
525 {
526 if ( m_graphImageDc.GetSafeHdc() != NULL )
527 {
528 const SIZE& sz = m_graphImage.GetSize();
529 m_graphImageDc.FillSolidRect(0, 0, sz.cx, sz.cy, INTERNALLY_COLOR);
530 m_pointMap.RemoveAll();
531 }
532 }
533
544 void SetPoint(COLORREF color, double value, INDEX horizontalIndex = 0, bool withContinuousLine = true)
545 {
546 if ( m_graphImageDc.GetSafeHdc() != NULL )
547 {
548 int xx = HorizontalIndexToX(horizontalIndex);
549 m_SetMaker(m_graphImageDc, xx, value, color, withContinuousLine);
550 }
551 }
552
561 void SetVerticalLine(COLORREF color, INDEX horizontalIndex, int length = -1)
562 {
563 if ( m_graphImageDc.GetSafeHdc() != NULL )
564 {
565 int xx = HorizontalIndexToX(horizontalIndex);
566 CPen pen((length != -2) ? PS_SOLID : PS_DASH, 1, color);
567 CPen* pOldPen = m_graphImageDc.SelectObject(&pen);
568 if ( length <= 0 )
569 {
570 m_graphImageDc.MoveTo(xx, 0);
571 m_graphImageDc.LineTo(xx, m_clientSize.cy);
572 }
573 else
574 {
575 int yy = m_CalcDrawY(0.0);
576 m_graphImageDc.MoveTo(xx, yy - length);
577 m_graphImageDc.LineTo(xx, yy + length);
578 }
579 m_graphImageDc.SelectObject(pOldPen);
580 }
581 }
582
589 void Settle(bool isForce = false)
590 {
591 if ( isForce )
592 {
593 m_MakeViewImage();
594 }
595 else
596 {
598 }
599 RedrawWindow();
600 }
601
608 {
609 return m_scrollBar.GetScrollLimit();
610 }
611
616 INDEX GetViewHorizontalPos(void) const
617 {
618 return m_viewHorizontalPos / m_horzIndexPixel;
619 }
620
626 void SetViewHorizontalPos(INDEX pos)
627 {
628 if ( ::IsWindow(m_scrollBar) )
629 {
630 INDEX xx = pos;
631 if ( m_isReverseIndexMode )
632 {
633 xx = m_scrollBar.GetScrollLimit() - xx;
634 }
635 m_scrollBar.SetScrollPos(ToInt(xx));
636 xx = m_scrollBar.GetScrollPos();
637 if ( m_isReverseIndexMode )
638 {
639 xx = m_scrollBar.GetScrollLimit() - xx;
640 }
641 m_viewHorizontalPos = xx * m_horzIndexPixel;
643 RedrawWindow();
644 }
645 }
646
647protected:
648
653 {
654 m_isOndemandRemakeViewImage = true;
655 }
656
664 virtual void OnMadeViewImage(CDC* pDC, const SIZE& sz)
665 {
666 }
667
673 virtual void PreSubclassWindow(void)
674 {
675 _super::PreSubclassWindow();
676 CRect rc;
677 GetClientRect(&rc);
678 m_clientSize = rc.Size();
679 const SIZE& sz = m_clientSize;
680 m_viewImage.Set(sz.cx, sz.cy, m_backColor);
681 m_graphImageDc.Detach();
682 m_graphImage.Set(sz.cx, sz.cy, INTERNALLY_COLOR);
683 m_graphImageDc.Attach(&m_graphImage);
684 }
685
695 virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
696 {
697 switch ( message )
698 {
699 case WM_ERASEBKGND:
700 return 0;
701 case WM_PRINTCLIENT:
702 if ( m_isOndemandRemakeViewImage )
703 {
704 m_isOndemandRemakeViewImage = false;
705 m_MakeViewImage();
706 }
707 m_viewImage.Draw(reinterpret_cast<HDC>(wParam));
708 return 0;
709 case WM_PAINT:
710 if ( m_isOndemandRemakeViewImage )
711 {
712 m_isOndemandRemakeViewImage = false;
713 m_MakeViewImage();
714 }
715 m_viewImage.Draw(CPaintDC(this));
716 return 0;
717 case WM_ENABLE:
718 return 0;
719 case WM_SIZE:
720 {
721 CSize sz(LOWORD(lParam), HIWORD(lParam));
722 if ( sz != m_clientSize )
723 {
724 CSize gsz = m_graphImage.GetSize();
725 m_Resize(sz, gsz.cx);
727 }
728 }
729 break;
730 case WM_HSCROLL:
731 if ( reinterpret_cast<HWND>(lParam) == m_scrollBar )
732 {
733 int sbCode = LOWORD(wParam);
734 int nPos = HIWORD(wParam);
735 switch ( sbCode )
736 {
737 case SB_THUMBPOSITION: // 絶対位置へスクロール。現在位置はパラメータ nPos で指定されます。
738 case SB_THUMBTRACK: // スクロール ボックスを指定位置へドラッグ。現在位置はパラメータ nPos で指定されます。
739 {
740 SCROLLINFO si;
741 if ( m_scrollBar.GetScrollInfo(&si, SIF_TRACKPOS) )
742 {
743 nPos = si.nTrackPos;
744 }
745 }
746 break;
747 }
748 m_OnScrollBar(sbCode, nPos);
749 }
750 break;
751 case WM_LBUTTONDOWN:
752 if ( ::IsWindow(m_scrollBar) )
753 {
754 m_isMouseButtonPressed = true;
755 SetCapture();
756 m_pressedPos = CPoint(lParam);
757 }
758 #ifdef _WIN32_WCE
759 return _super::DefWindowProc(message, wParam, lParam);
760 #endif
761 break;
762 case WM_LBUTTONUP:
763 if ( m_isMouseButtonPressed )
764 {
765 m_isMouseButtonPressed = false;
766 ReleaseCapture();
767 }
768 break;
769 case WM_MOUSEMOVE:
770 if ( m_isMouseButtonPressed )
771 {
772 if ( GetCapture() != this )
773 {
774 m_isMouseButtonPressed = false;
775 }
776 else
777 {
778 CPoint pos(lParam);
779 int d = (pos.x - m_pressedPos.x) / m_horzIndexPixel;
780 if ( d != 0 )
781 {
782 m_OnScrollBar(SB_THUMBPOSITION, m_scrollBar.GetScrollPos() - d);
783 m_pressedPos = pos;
784 Invalidate();
785 UpdateWindow();
786 }
787 }
788 }
789 break;
790 }
791 return _super::WindowProc(message, wParam, lParam);
792 }
793
794private:
796 struct TTextInfo
797 {
798 HFONT hFont;
799 CStr text;
800 COLORREF color;
801 //コンストラクタ
802 TTextInfo(void) : hFont(NULL)
803 {
804 }
805 };
807 struct TLineInfo : CCopyImpossible
808 {
809 ELineStyle style;
810 CPen colorPen;
811 //コンストラクタ
812 TLineInfo(void) : style(LineStyle_Non)
813 {
814 }
815 void Set(ELineStyle ls, COLORREF color)
816 {
817 style = ls;
818 if ( colorPen.GetSafeHandle() != NULL )
819 {
820 colorPen.DeleteObject();
821 }
822 CPen* pPen = NULL;
823 switch ( style )
824 {
825 case LineStyle_Solid: // 実線
826 case LineStyle_EdgeDot: // 両端のみ
827 pPen = new CPen(PS_SOLID, 1, color);
828 break;
829 case LineStyle_Bold: // 太線
830 pPen = new CPen(PS_SOLID, 3, color);
831 break;
832 case LineStyle_Dot: // 破線
833 pPen = new CPen(PS_DOT, 1, color);
834 break;
835 }
836 if ( pPen != NULL )
837 {
838 colorPen.Attach(pPen->Detach());
839 delete pPen;
840 }
841 }
842 };
844 struct TScaleLineInfo : TLineInfo
845 {
846 double step;
847 void Set(ELineStyle ls, COLORREF color, double sp)
848 {
849 step = sp;
850 TLineInfo::Set(ls, color);
851 }
852 };
854 class CMyScrollBar : public CScrollBar
855 {
856 DEFSUPER(CScrollBar);
857 protected:
858 virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
859 {
860 if ( message == WM_LBUTTONDOWN )
861 {
862 return _super::DefWindowProc(message, wParam, lParam);
863 }
864 return _super::WindowProc(message, wParam, lParam);
865 }
866 };
867
868 int m_CalcDrawY(double y) const
869 {
870 double yy = (m_viewTopValue - y);
871 yy *= (m_clientSize.cy - 1);
872 yy /= m_viewHeight;
873 return down_cast<int>(yy);
874 }
875
877 void m_OnScrollBar(int sbCode, int nPos)
878 {
879 INT_PTR np = GetViewHorizontalPos();
880 INT_PTR maxPos = m_scrollBar.GetScrollLimit();
881 INT_PTR p = m_scrollBar.GetScrollPos();
882 switch ( sbCode )
883 {
884 case SB_LEFT: // 左端へスクロール。
885 p = 0;
886 break;
887 case SB_ENDSCROLL: // スクロール終了。
888 return;
889 case SB_LINELEFT: // 左へスクロール。
890 p -= m_scrollOneStep;
891 break;
892 case SB_LINERIGHT: // 右へスクロール。
893 p += m_scrollOneStep;
894 break;
895 case SB_PAGELEFT: // 1 ページ左へスクロール。
896 p -= m_clientSize.cx / m_horzIndexPixel;
897 break;
898 case SB_PAGERIGHT: // 1 ページ右へスクロール。
899 p += m_clientSize.cx / m_horzIndexPixel;
900 break;
901 case SB_RIGHT: // 右端へスクロール。
902 p = maxPos;
903 break;
904 case SB_THUMBPOSITION: // 絶対位置へスクロール。現在位置はパラメータ nPos で指定されます。
905 case SB_THUMBTRACK: // スクロール ボックスを指定位置へドラッグ。現在位置はパラメータ nPos で指定されます。
906 p = nPos;
907 break;
908 default:
909 ASSERT( false );
910 break;
911 }
912 m_scrollBar.SetScrollPos(ToInt(p));
913 p = m_scrollBar.GetScrollPos();
914 if ( m_isReverseIndexMode )
915 {
916 p = m_scrollBar.GetScrollLimit() - p;
917 }
918 if ( np != p )
919 {
921 CWnd* pParent = GetParent();
922 if ( pParent != NULL )
923 {
924 pParent->SendMessage(WM_HSCROLL, MAKELONG(SB_THUMBPOSITION, p), reinterpret_cast<LPARAM>(GetSafeHwnd()));
925 }
926 }
927 }
933 void m_Resize(const SIZE& sz, size_t graphWidth)
934 {
935 if ( sz.cx < 0 || sz.cx > 0x7FFF || sz.cy < 0 || sz.cy > 0x7FFF )
936 {
937 return;
938 }
939 m_clientSize = sz;
940 //== スクロールバーを消す
941 if ( ::IsWindow(m_scrollBar) )
942 {
943 m_scrollBar.DestroyWindow();
944 }
945 if ( ToInt(graphWidth) > m_clientSize.cx )
946 {
947 //== スクロールバー用意
948 DWORD style = SBS_HORZ | WS_CHILD;
949 if ( m_isScrollBarUsed )
950 {
951 m_clientSize.cy -= ToInt(m_scrollBarHeight);
952 style |= WS_VISIBLE;
953 }
954 m_scrollBar.Create(style, CRect(0, m_clientSize.cy, m_clientSize.cx, ToInt(m_clientSize.cy + m_scrollBarHeight)), this, 1000);
955 SCROLLINFO si;
956 m_scrollBar.GetScrollInfo(&si);
957 si.nPage = m_clientSize.cx / m_horzIndexPixel;
958 si.nMin = 0;
959 si.nMax = ToInt(graphWidth / m_horzIndexPixel);
960 if ( m_isReverseIndexMode )
961 {
962 si.nPos = si.nMax;
963 }
964 m_scrollBar.SetScrollInfo(&si);
965 }
966 m_viewImage.Set(sz.cx, sz.cy, m_backColor);
967 m_graphImageDc.Detach();
968 if ( sz.cx > 0 && sz.cy > 0 && m_clientSize.cy > 0 )
969 {
970 VERIFY( m_graphImage.Set(ToInt(graphWidth), m_clientSize.cy, INTERNALLY_COLOR) );
971 m_graphImageDc.Attach(&m_graphImage);
972 }
973 m_pointMap.RemoveAll();
974 }
975 void m_Resize(void)
976 {
977 const CSize& gsz = m_graphImage.GetSize();
978 CRect rc;
979 GetClientRect(&rc);
980 m_Resize(rc.Size(), gsz.cx);
981 }
990 void m_SetMaker(CDC& dc, int xx, double y, COLORREF color, bool withContinuousLine)
991 {
992 if ( ! IS_RGBVALUE(color) )
993 {
994 return;
995 }
996 if ( ! ::_finite(y) )
997 {
998 return;
999 }
1000 int yy = m_CalcDrawY(y);
1001 bool hasColorKey = m_pointMap.HasKey(color);
1002 //== ブラシ、ペン、作成
1003 if ( ! hasColorKey )
1004 {
1005 m_pointMap[color] = new TPointInfo(color);
1006 }
1007 TPointInfo* P = m_pointMap[color];
1008 ASSERT( P != NULL );
1009 CPen* pOldPen = dc.SelectObject(&P->pen);
1010 {
1011 //== 連続線描画
1012 if ( withContinuousLine && hasColorKey )
1013 {
1014 dc.MoveTo(P->point);
1015 dc.LineTo(xx, yy);
1016 }
1017 //== マーカー描画
1018 if ( m_markerWidth <= 1 )
1019 {
1020 dc.SetPixel(xx, yy, color);
1021 }
1022 else if ( m_markerWidth <= 3 )
1023 {
1024 int mw = ToInt(m_markerWidth);
1025 int d1 = mw / 2;
1026 dc.FillSolidRect(xx - d1, yy - d1, mw, mw, color);
1027 }
1028 else
1029 {
1030 CBrush* pOldBrush = dc.SelectObject(&P->brush);
1031 int d1 = ToInt(m_markerWidth / 2);
1032 int d2 = ToInt(m_markerWidth - d1);
1033 dc.Ellipse(xx - d1, yy - d1, xx + d2, yy + d2);
1034 dc.SelectObject(pOldBrush);
1035 }
1036 }
1037 dc.SelectObject(pOldPen);
1038 //== 記憶
1039 P->point.x = xx;
1040 P->point.y = yy;
1041 }
1047 DWORD m_ToDtStyle(INDEX idx) const
1048 {
1049 DWORD r = 0;
1050 switch ( idx )
1051 {
1052 case 1: r = DT_LEFT | DT_BOTTOM; break;
1053 case 2: r = DT_CENTER | DT_BOTTOM; break;
1054 case 3: r = DT_RIGHT | DT_BOTTOM; break;
1055 case 4: r = DT_LEFT | DT_VCENTER; break;
1056 case 5: r = DT_CENTER | DT_VCENTER; break;
1057 case 6: r = DT_RIGHT | DT_VCENTER; break;
1058 case 7: r = DT_LEFT | DT_TOP; break;
1059 case 8: r = DT_CENTER | DT_TOP; break;
1060 case 9: r = DT_RIGHT | DT_TOP; break;
1061 }
1062 return r;
1063 }
1064 // 再構築
1065 void m_MakeViewImage(void)
1066 {
1067 const SIZE& sz = m_clientSize;
1068 CBitmapDC dc(&m_viewImage);
1069 dc.FillSolidRect(0, 0, sz.cx, sz.cy, m_backColor);
1070 //== Scale描画
1071 m_DrawScaleLine(dc, m_subScaleLines[2], false);
1072 m_DrawScaleLine(dc, m_subScaleLines[1], false);
1073 m_DrawScaleLine(dc, m_subScaleLines[0], false);
1074 m_DrawScaleLine(dc, m_scaleLine, true);
1075 //== グラフ描画(重ね合わせ)
1076 if ( ! m_graphImage.IsEmpty() )
1077 {
1078 const SIZE& sz = m_graphImage.GetSize();
1079 INT_PTR x = -down_cast<INT_PTR>(m_viewHorizontalPos);
1080 if ( m_isReverseIndexMode )
1081 {
1082 x = m_clientSize.cx - sz.cx + m_viewHorizontalPos;
1083 }
1084 ::TransparentBlt(dc, ToInt(x), 0, sz.cx, sz.cy, m_graphImageDc, 0, 0, sz.cx, sz.cy, INTERNALLY_COLOR);
1085 }
1086 //== 文字描画
1087 {
1088 CRect rc(2, 2, sz.cx - 2, sz.cy - 2);
1089 CWnd* pParent = GetParent();
1090 CFont* pParentFont = GetFont();
1091 if ( pParent != NULL )
1092 {
1093 pParentFont = pParent->GetFont();
1094 }
1095 CFont* pOldFont = dc.SelectObject(GetFont());
1096 dc.SetBkMode(TRANSPARENT);
1097 loop ( i, 9 )
1098 {
1099 INDEX idx = i + 1;
1100 const TTextInfo& t = m_testInfo[idx];
1101 if ( ! t.text.IsEmpty() )
1102 {
1103 if ( t.hFont == NULL )
1104 {
1105 dc.SelectObject(pParentFont);
1106 }
1107 else
1108 {
1109 ::SelectObject(dc, t.hFont);
1110 }
1111 CTextDrawer::DrawTextRect(dc, rc, m_ToDtStyle(idx), t.color, t.text);
1112 }
1113 }
1114 dc.SelectObject(pOldFont);
1115 }
1116 //==
1117 OnMadeViewImage(&dc, sz);
1118 //==
1119 dc.Detach();
1120 }
1121 // 指定スタイル水平線描画
1122 void m_DrawStyleHorzLine(CDC& dc, bool isEdgeDotMode, int yy)
1123 {
1124 dc.MoveTo(0, yy);
1125 if ( ! isEdgeDotMode )
1126 {
1127 // 線
1128 dc.LineTo(m_clientSize.cx, yy);
1129 }
1130 else
1131 {
1132 // 両端のみ
1133 dc.LineTo(4, yy);
1134 dc.MoveTo(m_clientSize.cx, yy);
1135 dc.LineTo(m_clientSize.cx - 4, yy);
1136 }
1137 }
1138 // スケール線描画
1139 void m_DrawScaleLine(CDC& dc, TScaleLineInfo& sli, bool isMaster)
1140 {
1141 if ( sli.colorPen.GetSafeHandle() == NULL )
1142 {
1143 return;
1144 }
1145 bool isEdgeDotMode = (sli.style == LineStyle_EdgeDot);
1146 dc.SetBkColor(m_backColor);
1147 CPen* pOldPen = dc.SelectObject(&sli.colorPen);
1148 if ( isMaster )
1149 {
1150 m_DrawStyleHorzLine(dc, isEdgeDotMode, m_CalcDrawY(0));
1151 }
1152 else
1153 {
1154 double ss = sli.step;
1155 double hh = max(::fabs(m_viewTopValue), ::fabs(m_viewbottomValue));
1156 while ( ss <= hh )
1157 {
1158 m_DrawStyleHorzLine(dc, isEdgeDotMode, m_CalcDrawY(ss));
1159 m_DrawStyleHorzLine(dc, isEdgeDotMode, m_CalcDrawY(-ss));
1160 ss += sli.step;
1161 }
1162 }
1163 dc.SelectObject(pOldPen);
1164 }
1165 // ポイント管理型
1166 struct TPointInfo
1167 {
1168 CPoint point;
1169 CBrush brush;
1170 CPen pen;
1171 TPointInfo(COLORREF c) : brush(c), pen(PS_SOLID, 1, c)
1172 {
1173 }
1174 };
1175 // ポイント管理マップクラス
1176 typedef CMapT<COLORREF, CPointerHandleT<TPointInfo> > CMyPointMap;
1177
1178 bool m_isScrollBarUsed;
1179 CMyScrollBar m_scrollBar;
1180 size_t m_scrollBarHeight;
1181 size_t m_scrollOneStep;
1182 TTextInfo m_testInfo[10];
1183 CMyPointMap m_pointMap;
1184 TScaleLineInfo m_scaleLine;
1185 TScaleLineInfo m_subScaleLines[3];
1186 COLORREF m_backColor;
1187 size_t m_markerWidth;
1188 double m_viewTopValue;
1189 double m_viewbottomValue;
1190 double m_viewHeight;
1191 bool m_isReverseIndexMode;
1192 CSize m_clientSize;
1193 CBitmapDC m_graphImageDc;
1194 CBitmapImage m_graphImage;
1195 CBitmapImage m_viewImage;
1196 bool m_isGraphImageDcLeading;
1197 INDEX m_viewHorizontalPos;
1198 bool m_isOndemandRemakeViewImage;
1199 int m_horzIndexPixel;
1200 bool m_isMouseButtonPressed;
1201 CPoint m_pressedPos;
1202};
1203
1204
1205
1206};//MFC
1207};//TNB
1208
1209
1210
1211
ビットマップイメージ管理関係のヘッダ
#define loop(VAR, CNT)
loop構文.
Definition: TnbDef.h:343
マップ型情報管理関係のヘッダ
ビットマップDC関係のヘッダ
テキスト描画関係のヘッダ
ウィンドウ管理.
HWND GetSafeHwnd(void) const
[取得] ウィンドウハンドル取得.
ビットマップイメージ管理クラス
bool IsEmpty(void) const
[確認] Empty状態確認.
const SIZE & GetSize(void) const
[取得] イメージサイズ取得.
bool Set(int cx, int cy, COLORREF color=CLR_INVALID)
[設定] イメージ設定.
bool Draw(HDC hdc, int x=0, int y=0) const
[処理] イメージ描画.
[ETC] コピー不可能スーパークラス.
Definition: TnbDef.h:599
マップ型情報管理テンプレート
Definition: TnbMap.h:66
virtual CPair & Ref(INDEX index)
[取得] 要素の参照取得.
Definition: TnbMap.h:367
virtual bool RemoveAll(void)
[削除] すべてのキーと値を削除
Definition: TnbMap.h:434
bool HasKey(INK key) const
[確認] キー有無
Definition: TnbMap.h:589
SECOND second
二つ目の型の値
Definition: TnbPair.h:45
static bool DrawTextRect(RECT &_rect, HDC dc, DWORD drawStyle, const POINT &offset, COLORREF color1, COLORREF color2, LPCTSTR str)
[表示] 範囲文字表示.
ビットマップデバイスコンテキストクラス
CBitmapImage * Detach(void)
[設定] デタッチ.
bool Attach(CBitmapImage *pBI)
[設定] アタッチ
折れ線グラフコントロール.
void Settle(bool isForce=false)
[設定] 確定.
INDEX GetHorizontalIndexLimit(void) const
[取得] 横軸最大インデックス取得.
void ClearPoint(void)
[設定] ポイントクリア.
void SetScaleLine(COLORREF color, ELineStyle style=LineStyle_Solid)
[設定] スケール線設定.
bool IsReverseHorizontalIndexMode(void) const
[確認] 逆インデックスモード?.
void Shift(int count=1)
[移動] シフト.
size_t SetPointMakertSize(size_t width)
[設定] ポイントマーカーサイズ設定.
INDEX GetViewHorizontalPos(void) const
[取得] 水平表示位置取得.
bool SetBackgroundWidth(COLORREF backgroundColor, size_t graphWidth=0)
[設定] グラフ背景幅設定.
void OndemandRemakeViewImage(void)
[通知] 再構築要求通知.
const SIZE & GetImageSize(void) const
[取得] グラフイメージサイズ取得.
void SetPoint(COLORREF color, double value, INDEX horizontalIndex=0, bool withContinuousLine=true)
[設定] ポイント設定.
bool SetViewValueRange(double topValue, double bottomValue)
[設定] 垂直表示範囲設定.
void GetViewValueRange(double &_topValue, double &_bottomValue) const
[取得] 垂直表示範囲取得.
void SetVerticalLine(COLORREF color, INDEX horizontalIndex, int length=-1)
[設定] 縦スケール設定.
bool SetScrollBarHeight(int height=0)
[設定] スクロールバー高さ.
CDC * GetImageDC(void)
[取得] グラフイメージ DC 取得.
CLineGraphViewCtrl(void)
コンストラクタ.
virtual void PreSubclassWindow(void)
[通知] subclassing/unsubclassing functions.
void SetScrollOneStep(size_t os=1)
[設定] スクロールバー1ステップ幅.
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
[通知] for processing Windows messages.
bool SetHorizontalIndexPixel(int pixel=1, bool isReverseIndexMode=false)
[設定] インデックスピクセル設定.
void SetViewHorizontalPos(INDEX pos)
[設定] 水平表示位置設定.
bool SetSubScaleLine(INDEX number, ELineStyle style=LineStyle_Non, COLORREF color=0, double step=0.0)
[設定] サブスケール線設定.
bool SetOverlayText(INDEX pos, COLORREF color=RGB(0, 0, 0), LPCTSTR lpsz=NULL, HFONT hFont=NULL)
[設定] 文字列設定.
void ReleaseImageDC(void)
[設定] グラフイメージ DC 返却.
bool HasScrollBar(void) const
[確認] スクロールバーあり?.
size_t GetViewHorizontalPosLimit(void)
[取得] 水平表示最大位置取得.
virtual void OnMadeViewImage(CDC *pDC, const SIZE &sz)
[通知] 表示用イメージ作成通知.
int HorizontalIndexToX(INDEX horizontalIndex)
[取得] 横軸インデックス to X座標.
@ EDGE_VALUE
デフォルトの上下端のポイント値
@ INTERNALLY_COLOR
内部処理用カラー
int GetHorizontalIndexPixel(void) const
[取得] インデックスピクセル取得.
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