1 #include "win32/Font.h"
2 #include "win32/ClientDeviceContext.h"
3 #include "win32/DpiUtils.h"
4 #include "RegViewPage.h"
5
6 #define CLSNAME _T("CRegViewPage")
7
CRegViewPage(HWND hParent,const RECT & rect)8 CRegViewPage::CRegViewPage(HWND hParent, const RECT& rect)
9 : m_font(Framework::Win32::CreateFont(_T("Courier New"), 8))
10 {
11 //Fill in render metrics
12 {
13 auto fontSize = GetFixedFontSize(m_font);
14 m_renderMetrics.xmargin = Framework::Win32::PointsToPixels(6);
15 m_renderMetrics.yspace = Framework::Win32::PointsToPixels(4);
16 m_renderMetrics.ymargin = Framework::Win32::PointsToPixels(5);
17 m_renderMetrics.fontSizeX = fontSize.cx;
18 m_renderMetrics.fontSizeY = fontSize.cy;
19 }
20
21 if(!DoesWindowClassExist(CLSNAME))
22 {
23 WNDCLASSEX w;
24 memset(&w, 0, sizeof(WNDCLASSEX));
25 w.cbSize = sizeof(WNDCLASSEX);
26 w.lpfnWndProc = CWindow::WndProc;
27 w.lpszClassName = CLSNAME;
28 w.hbrBackground = NULL;
29 w.hInstance = GetModuleHandle(NULL);
30 w.hCursor = LoadCursor(NULL, IDC_ARROW);
31 RegisterClassEx(&w);
32 }
33
34 Create(0, CLSNAME, _T(""), WS_CHILD | WS_VSCROLL, rect, hParent, NULL);
35 SetClassPtr();
36 }
37
SetDisplayText(const char * text)38 void CRegViewPage::SetDisplayText(const char* text)
39 {
40 m_text = text;
41 UpdateScroll();
42 }
43
Update()44 void CRegViewPage::Update()
45 {
46 UpdateScroll();
47 Redraw();
48 }
49
OnVScroll(unsigned int nType,unsigned int nThumbPos)50 long CRegViewPage::OnVScroll(unsigned int nType, unsigned int nThumbPos)
51 {
52 unsigned int nPosition = GetScrollPosition();
53 switch(nType)
54 {
55 case SB_LINEDOWN:
56 nPosition++;
57 break;
58 case SB_LINEUP:
59 nPosition--;
60 break;
61 case SB_PAGEDOWN:
62 nPosition += 10;
63 break;
64 case SB_PAGEUP:
65 nPosition -= 10;
66 break;
67 case SB_THUMBPOSITION:
68 case SB_THUMBTRACK:
69 nPosition = GetScrollThumbPosition();
70 break;
71 default:
72 return FALSE;
73 break;
74 }
75
76 SCROLLINFO si;
77 memset(&si, 0, sizeof(SCROLLINFO));
78 si.cbSize = sizeof(SCROLLINFO);
79 si.nPos = nPosition;
80 si.fMask = SIF_POS;
81 SetScrollInfo(m_hWnd, SB_VERT, &si, TRUE);
82
83 Redraw();
84 return TRUE;
85 }
86
OnSize(unsigned int nX,unsigned int nY,unsigned int nType)87 long CRegViewPage::OnSize(unsigned int nX, unsigned int nY, unsigned int nType)
88 {
89 Framework::Win32::CCustomDrawn::OnSize(nX, nY, nType);
90 Update();
91 return TRUE;
92 }
93
OnMouseWheel(int x,int y,short z)94 long CRegViewPage::OnMouseWheel(int x, int y, short z)
95 {
96 if(z < 0)
97 {
98 OnVScroll(SB_LINEDOWN, 0);
99 }
100 else
101 {
102 OnVScroll(SB_LINEUP, 0);
103 }
104 return TRUE;
105 }
106
OnLeftButtonDown(int nX,int nY)107 long CRegViewPage::OnLeftButtonDown(int nX, int nY)
108 {
109 SetFocus();
110 return TRUE;
111 }
112
GetLineCount(const char * sText)113 unsigned int CRegViewPage::GetLineCount(const char* sText)
114 {
115 unsigned int nLines = 0;
116
117 const char* sNext = strchr(sText, '\n');
118 while(sNext != NULL)
119 {
120 nLines++;
121 sNext = strchr(sNext + 1, '\n');
122 }
123
124 return nLines;
125 }
126
GetVisibleLineCount()127 unsigned int CRegViewPage::GetVisibleLineCount()
128 {
129 auto clientRect = GetClientRect();
130 unsigned int lineStep = (m_renderMetrics.fontSizeY + m_renderMetrics.yspace);
131 unsigned int lines = (clientRect.Bottom() - (m_renderMetrics.ymargin * 2)) / lineStep;
132 return lines;
133 }
134
Paint(HDC hDC)135 void CRegViewPage::Paint(HDC hDC)
136 {
137 RECT rwin = GetClientRect();
138
139 BitBlt(hDC, 0, 0, rwin.right, rwin.bottom, NULL, 0, 0, WHITENESS);
140
141 unsigned int nFontCY = m_renderMetrics.fontSizeY;
142 unsigned int nTotal = GetVisibleLineCount();
143 unsigned int nScrollPos = GetScrollPosition();
144
145 SelectObject(hDC, m_font);
146
147 unsigned int nCurrent = 0;
148 unsigned int nCount = 0;
149 unsigned int nX = m_renderMetrics.xmargin;
150 unsigned int nY = m_renderMetrics.ymargin;
151
152 const char* sLine = m_text.c_str();
153 while(sLine != NULL)
154 {
155 const char* sNext = strchr(sLine, '\n');
156 if(sNext != NULL)
157 {
158 sNext++;
159 }
160
161 if(nCurrent < nScrollPos)
162 {
163 nCurrent++;
164 sLine = sNext;
165 continue;
166 }
167
168 int textLength = (sNext == NULL) ? strlen(sLine) : static_cast<int>(sNext - sLine - 2);
169 DrawTextA(hDC, sLine, textLength, Framework::Win32::CRect(nX, nY, nX, nY), DT_NOCLIP | DT_EXPANDTABS);
170 nY += (nFontCY + m_renderMetrics.yspace);
171
172 nCurrent++;
173 sLine = sNext;
174
175 nCount++;
176 if(nCount >= nTotal)
177 {
178 break;
179 }
180 }
181 }
182
UpdateScroll()183 void CRegViewPage::UpdateScroll()
184 {
185 int nTotal = GetLineCount(m_text.c_str()) - GetVisibleLineCount();
186
187 if(nTotal < 0)
188 {
189 nTotal = 0;
190 }
191
192 SCROLLINFO si;
193 memset(&si, 0, sizeof(SCROLLINFO));
194 si.cbSize = sizeof(SCROLLINFO);
195 si.fMask = SIF_RANGE;
196 si.nMin = 0;
197 si.nMax = nTotal;
198 SetScrollInfo(m_hWnd, SB_VERT, &si, TRUE);
199 }
200
GetScrollPosition()201 unsigned int CRegViewPage::GetScrollPosition()
202 {
203 SCROLLINFO si;
204 memset(&si, 0, sizeof(SCROLLINFO));
205 si.cbSize = sizeof(SCROLLINFO);
206 si.fMask = SIF_POS;
207 GetScrollInfo(m_hWnd, SB_VERT, &si);
208 return si.nPos;
209 }
210
GetScrollThumbPosition()211 unsigned int CRegViewPage::GetScrollThumbPosition()
212 {
213 SCROLLINFO si;
214 memset(&si, 0, sizeof(SCROLLINFO));
215 si.cbSize = sizeof(SCROLLINFO);
216 si.fMask = SIF_TRACKPOS;
217 GetScrollInfo(m_hWnd, SB_VERT, &si);
218 return si.nTrackPos;
219 }
220