-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLOGVIEW.CPP
273 lines (239 loc) · 6.74 KB
/
LOGVIEW.CPP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
// LogView.cpp: implementation of the CLogView class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Virtual Robot.h"
#include "LogView.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNCREATE(CLogView, CEditView)
CLogView::CLogView()
{
m_bCanPaint = TRUE;
}
CLogView::~CLogView()
{
}
BEGIN_MESSAGE_MAP(CLogView, CEditView)
//{{AFX_MSG_MAP(CLogView)
ON_CONTROL_REFLECT(EN_CHANGE, OnChange)
ON_WM_CREATE()
ON_WM_PAINT()
ON_WM_KEYDOWN()
ON_WM_LBUTTONDOWN()
ON_WM_CHAR()
ON_WM_MOUSEMOVE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// Zeichnung CLogView
void CLogView::OnDraw(CDC* pDC)
{
CDocument* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// ZU ERLEDIGEN: Code zum Zeichnen hier einfügen
}
/////////////////////////////////////////////////////////////////////////////
// Diagnose CLogView
#ifdef _DEBUG
void CLogView::AssertValid() const
{
CEditView::AssertValid();
}
void CLogView::Dump(CDumpContext& dc) const
{
CEditView::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// Behandlungsroutinen für Nachrichten CLogView
int CLogView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CEditView::OnCreate(lpCreateStruct) == -1)
return -1;
GetEditCtrl().ModifyStyle(WS_BORDER,
WS_VISIBLE|ES_MULTILINE|ES_READONLY |ES_AUTOHSCROLL |ES_AUTOVSCROLL |ES_WANTRETURN);
return 0;
}
int CLogView::GetCaretLine()
{
int nStart, nEnd;
GetEditCtrl().GetSel(nStart, nEnd);
ASSERT(nStart <= nEnd);
CPoint ptEnd, ptCaret;
ptEnd = GetEditCtrl().PosFromChar(nEnd);
ptCaret = GetCaretPos();
// the caret position is not always the end of selection
if (ptEnd.y == ptCaret.y)
return GetEditCtrl().LineFromChar(nEnd);
else
return GetEditCtrl().LineFromChar(nStart);
}
void CLogView::GetLineRect(int nLine, LPRECT lpRect)
{
// if using CRichEditView, it will be not so complicated
// EM_POSFROMCHAR will not return correct pos of the last line,
// so we have to calcluate it
if (nLine == 0) // the first line;
{
GetEditCtrl().GetRect(lpRect);
lpRect->bottom = lpRect->top + m_sizeChar.cy;
}
else if (nLine == GetEditCtrl().GetLineCount() - 1) // the last line
{
// we get previous line's rect, then offset it by one line height.
int nLineIndex = GetEditCtrl().LineIndex(nLine - 1);
CPoint ptPos = GetEditCtrl().PosFromChar(nLineIndex);
GetEditCtrl().GetRect(lpRect);
lpRect->top = ptPos.y;
lpRect->bottom = lpRect->top + m_sizeChar.cy;
OffsetRect(lpRect, 0, m_sizeChar.cy);
}
else // lines between first and last
{
int nLineIndex = GetEditCtrl().LineIndex(nLine);
CPoint ptPos = GetEditCtrl().PosFromChar(nLineIndex);
GetEditCtrl().GetRect(lpRect);
lpRect->top = ptPos.y;
lpRect->bottom = lpRect->top + m_sizeChar.cy;
}
}
void CLogView::DrawCaretLine(BOOL bInPaint)
{
int nLine = GetCaretLine();
// for effective we need not redraw when we
// just move caret in the same line using arrow keys, simply return.
if (nLine == m_nCaretLine && !bInPaint)
return;
CRect rectClip;
GetEditCtrl().GetRect(rectClip);
CClientDC dc(this);
dc.IntersectClipRect(rectClip);
int nLineFirst = GetEditCtrl().GetFirstVisibleLine();
int nLineLast = GetEditCtrl().LineFromChar(GetEditCtrl().CharFromPos(rectClip.BottomRight()));
// hide caret, else it will be ugly.
HideCaret();
if (m_nCaretLine >= nLineFirst && m_nCaretLine <= nLineLast)
{
// in this section we must not make WM_PAINT a loop
// so don't let OnPaint() call our DrawCaretLine()
m_bCanPaint = FALSE;
CRect rect;
GetLineRect(m_nCaretLine, rect);
InvalidateRect(rect, FALSE);
// update immediately
UpdateWindow();
m_bCanPaint = TRUE;
}
// we change the caret line color by ROP
if (nLine >= nLineFirst && nLine <= nLineLast)
{
CRect rect;
GetLineRect(nLine, rect);
CDC dcMem;
dcMem.CreateCompatibleDC(&dc);
CBitmap bmp;
bmp.CreateCompatibleBitmap(&dc, rect.Width(), rect.Height());
CBitmap* pSaveBmp = dcMem.SelectObject(&bmp);
CBrush br(RGB(0, 0, 255));
dcMem.FillRect(CRect(0, 0, rect.Width(), rect.Height()), &br);
// "capture" the line into our memory dc, and "INVERT" it
dcMem.BitBlt(0, 0, rect.Width(), rect.Height(), &dc, rect.left, rect.top, SRCINVERT);
// blt it back to origin place, but change colors
dc.BitBlt(rect.left, rect.top, rect.Width(), rect.Height(), &dcMem, 0, 0, SRCCOPY);
dcMem.SelectObject(pSaveBmp);
}
ShowCaret();
m_nCaretLine = nLine;
}
void CLogView::OnKeyDown(UINT /*nChar*/, UINT /*nRepCnt*/, UINT /*nFlags*/)
{
Default();
DrawCaretLine();
}
void CLogView::OnLButtonDown(UINT /*nFlags*/, CPoint /*point*/)
{
Default();
DrawCaretLine();
}
void CLogView::OnChar(UINT /*nChar*/, UINT /*nRepCnt*/, UINT /*nFlags*/)
{
Default();
// if using CRichEditView, these steps are not needed.
int nLine = GetCaretLine();
if (m_nCaretLine == nLine)
{
CRect rect;
GetLineRect(m_nCaretLine, rect);
InvalidateRect(rect, FALSE);
UpdateWindow();
}
else
{
CRect rect;
GetLineRect(m_nCaretLine, rect);
InvalidateRect(rect, FALSE);
UpdateWindow();
m_nCaretLine = nLine;
}
}
void CLogView::OnMouseMove(UINT nFlags, CPoint /*point*/)
{
Default();
if (nFlags & MK_LBUTTON)
{
int nLine = GetCaretLine();
// if (m_nCaretLine != nLine)
{
CRect rect;
GetLineRect(m_nCaretLine, rect);
InvalidateRect(rect, FALSE);
UpdateWindow();
m_nCaretLine = nLine;
}
/* else
{
CRect rect;
GetLineRect(m_nCaretLine, rect);
InvalidateRect(rect, FALSE);
UpdateWindow();
m_nCaretLine = nLine;
}*/ }
}
void CLogView::OnPaint()
{
Default();
if (m_bCanPaint)
DrawCaretLine(TRUE);
}
void CLogView::OnInitialUpdate()
{
CEditView::OnInitialUpdate();
// set default font to "Courier New"
// because it is more clearly and equal-widen,
CClientDC dc(this);
m_fontDefault.CreateFont(-MulDiv(10, dc.GetDeviceCaps(LOGPIXELSX), 72), 0, 0, 0, 0, 0, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, _T("Courier New"));
SetFont(&m_fontDefault);
CFont* pSaveFont = dc.SelectObject(GetFont());
// then get the char size and save for further use.
m_sizeChar = dc.GetTextExtent(_T("W"));
dc.SelectObject(pSaveFont);
m_nCaretLine = GetCaretLine();
// this is not the right way to set tabstops
// see MSDN for details
SetTabStops(16);
}
void CLogView::OnChange()
{
// TODO: If this is a RICHEDIT control, the control will not
// send this notification unless you override the CEditView::OnInitDialog()
// function and call CRichEditCtrl().SetEventMask()
// with the ENM_CHANGE flag ORed into the mask.
// TODO: Add your control notification handler code here
}