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