rlm@1
|
1 // MemoryViewer.cpp : implementation file
|
rlm@1
|
2 //
|
rlm@1
|
3
|
rlm@1
|
4 #include "stdafx.h"
|
rlm@1
|
5 #include "resource.h"
|
rlm@1
|
6 #include "MemoryViewer.h"
|
rlm@1
|
7
|
rlm@1
|
8 extern int emulating;
|
rlm@1
|
9
|
rlm@1
|
10 /////////////////////////////////////////////////////////////////////////////
|
rlm@1
|
11 // MemoryViewer
|
rlm@1
|
12
|
rlm@1
|
13 bool MemoryViewer::isRegistered = false;
|
rlm@1
|
14
|
rlm@1
|
15 MemoryViewer::MemoryViewer()
|
rlm@1
|
16 {
|
rlm@1
|
17 address = 0;
|
rlm@1
|
18 addressSize = 0;
|
rlm@1
|
19 dataSize = 0;
|
rlm@1
|
20 editAddress = 0;
|
rlm@1
|
21 editNibble = 0;
|
rlm@1
|
22 displayedLines = 0;
|
rlm@1
|
23 hasCaret = false;
|
rlm@1
|
24 maxNibble = 0;
|
rlm@1
|
25 font = (HFONT)GetStockObject(SYSTEM_FIXED_FONT);
|
rlm@1
|
26 fontSize.cx = fontSize.cy = 0;
|
rlm@1
|
27 beginAscii = 0;
|
rlm@1
|
28 beginHex = 0;
|
rlm@1
|
29 dlg = NULL;
|
rlm@1
|
30 registerClass();
|
rlm@1
|
31 }
|
rlm@1
|
32
|
rlm@1
|
33 MemoryViewer::~MemoryViewer()
|
rlm@1
|
34 {}
|
rlm@1
|
35
|
rlm@1
|
36 BEGIN_MESSAGE_MAP(MemoryViewer, CWnd)
|
rlm@1
|
37 //{{AFX_MSG_MAP(MemoryViewer)
|
rlm@1
|
38 ON_WM_ERASEBKGND()
|
rlm@1
|
39 ON_WM_PAINT()
|
rlm@1
|
40 ON_WM_VSCROLL()
|
rlm@1
|
41 ON_WM_GETDLGCODE()
|
rlm@1
|
42 ON_WM_LBUTTONDOWN()
|
rlm@1
|
43 ON_WM_SETFOCUS()
|
rlm@1
|
44 ON_WM_KILLFOCUS()
|
rlm@1
|
45 ON_WM_KEYDOWN()
|
rlm@1
|
46 //}}AFX_MSG_MAP
|
rlm@1
|
47 ON_MESSAGE(WM_CHAR, OnWMChar)
|
rlm@1
|
48 END_MESSAGE_MAP()
|
rlm@1
|
49
|
rlm@1
|
50 /////////////////////////////////////////////////////////////////////////////
|
rlm@1
|
51 // MemoryViewer message handlers
|
rlm@1
|
52
|
rlm@1
|
53 void MemoryViewer::setDialog(IMemoryViewerDlg *d)
|
rlm@1
|
54 {
|
rlm@1
|
55 dlg = d;
|
rlm@1
|
56 }
|
rlm@1
|
57
|
rlm@1
|
58 void MemoryViewer::setAddress(u32 a)
|
rlm@1
|
59 {
|
rlm@1
|
60 address = a;
|
rlm@1
|
61 if (displayedLines)
|
rlm@1
|
62 {
|
rlm@1
|
63 if (addressSize)
|
rlm@1
|
64 {
|
rlm@1
|
65 u16 addr = address;
|
rlm@1
|
66 if ((u16)((addr+(displayedLines<<4)) & 0xFFFF) < addr)
|
rlm@1
|
67 {
|
rlm@1
|
68 address = 0xffff - (displayedLines<<4) + 1;
|
rlm@1
|
69 }
|
rlm@1
|
70 }
|
rlm@1
|
71 else
|
rlm@1
|
72 {
|
rlm@1
|
73 if ((address+(displayedLines<<4)) < address)
|
rlm@1
|
74 {
|
rlm@1
|
75 address = 0xffffffff - (displayedLines<<4) + 1;
|
rlm@1
|
76 }
|
rlm@1
|
77 }
|
rlm@1
|
78 }
|
rlm@1
|
79 if (addressSize)
|
rlm@1
|
80 address &= 0xffff;
|
rlm@1
|
81 setCaretPos();
|
rlm@1
|
82 InvalidateRect(NULL, TRUE);
|
rlm@1
|
83 }
|
rlm@1
|
84
|
rlm@1
|
85 void MemoryViewer::setSize(int s)
|
rlm@1
|
86 {
|
rlm@1
|
87 dataSize = s;
|
rlm@1
|
88 if (s == 0)
|
rlm@1
|
89 maxNibble = 1;
|
rlm@1
|
90 else if (s == 1)
|
rlm@1
|
91 maxNibble = 3;
|
rlm@1
|
92 else
|
rlm@1
|
93 maxNibble = 7;
|
rlm@1
|
94
|
rlm@1
|
95 InvalidateRect(NULL, TRUE);
|
rlm@1
|
96 }
|
rlm@1
|
97
|
rlm@1
|
98 void MemoryViewer::setDecimal(bool decimalDisplayMode)
|
rlm@1
|
99 {
|
rlm@1
|
100 decimalDisplay = decimalDisplayMode;
|
rlm@1
|
101 InvalidateRect(NULL, TRUE);
|
rlm@1
|
102 }
|
rlm@1
|
103
|
rlm@1
|
104 BOOL MemoryViewer::OnEraseBkgnd(CDC*pDC)
|
rlm@1
|
105 {
|
rlm@1
|
106 return TRUE;
|
rlm@1
|
107 }
|
rlm@1
|
108
|
rlm@1
|
109 void MemoryViewer::updateScrollInfo(int lines)
|
rlm@1
|
110 {
|
rlm@1
|
111 int page = lines * 16;
|
rlm@1
|
112 SCROLLINFO si;
|
rlm@1
|
113 ZeroMemory(&si, sizeof(si));
|
rlm@1
|
114 si.cbSize = sizeof(si);
|
rlm@1
|
115 si.fMask = SIF_PAGE | SIF_RANGE | SIF_DISABLENOSCROLL | SIF_POS;
|
rlm@1
|
116 si.nMin = 0;
|
rlm@1
|
117 if (addressSize)
|
rlm@1
|
118 {
|
rlm@1
|
119 si.nMax = 0x10000/page;
|
rlm@1
|
120 si.nPage = 1;
|
rlm@1
|
121 }
|
rlm@1
|
122 else
|
rlm@1
|
123 {
|
rlm@1
|
124 si.nMax = 0xa000000 / page;
|
rlm@1
|
125 si.nPage = page;
|
rlm@1
|
126 }
|
rlm@1
|
127
|
rlm@1
|
128 si.nPos = address / page;
|
rlm@1
|
129 SetScrollInfo(SB_VERT,
|
rlm@1
|
130 &si,
|
rlm@1
|
131 TRUE);
|
rlm@1
|
132 }
|
rlm@1
|
133
|
rlm@1
|
134 void MemoryViewer::OnPaint()
|
rlm@1
|
135 {
|
rlm@1
|
136 CPaintDC dc(this); // device context for painting
|
rlm@1
|
137
|
rlm@1
|
138 RECT rect;
|
rlm@1
|
139 GetClientRect(&rect);
|
rlm@1
|
140 int w = rect.right - rect.left;
|
rlm@1
|
141 int h = rect.bottom - rect.top - 6;
|
rlm@1
|
142
|
rlm@1
|
143 CDC memDC;
|
rlm@1
|
144 memDC.CreateCompatibleDC(&dc);
|
rlm@1
|
145 CBitmap bitmap, *pOldBitmap;
|
rlm@1
|
146 bitmap.CreateCompatibleBitmap(&dc, w, rect.bottom - rect.top);
|
rlm@1
|
147 pOldBitmap = memDC.SelectObject(&bitmap);
|
rlm@1
|
148
|
rlm@1
|
149 memDC.FillRect(&rect, CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH)));
|
rlm@1
|
150 memDC.DrawEdge(&rect, EDGE_ETCHED, BF_RECT);
|
rlm@1
|
151
|
rlm@1
|
152 CFont *oldFont = memDC.SelectObject(CFont::FromHandle(font));
|
rlm@1
|
153
|
rlm@1
|
154 fontSize = memDC.GetTextExtent("0", 1);
|
rlm@1
|
155
|
rlm@1
|
156 int lines = h / fontSize.cy;
|
rlm@1
|
157
|
rlm@1
|
158 displayedLines = lines;
|
rlm@1
|
159
|
rlm@1
|
160 updateScrollInfo(lines);
|
rlm@1
|
161
|
rlm@1
|
162 u32 addr = address;
|
rlm@1
|
163
|
rlm@1
|
164 memDC.SetTextColor(RGB(0, 0, 0));
|
rlm@1
|
165
|
rlm@1
|
166 u8 data[32];
|
rlm@1
|
167
|
rlm@1
|
168 RECT r;
|
rlm@1
|
169 r.top = 3;
|
rlm@1
|
170 r.left = 3;
|
rlm@1
|
171 r.bottom = r.top+fontSize.cy;
|
rlm@1
|
172 r.right = rect.right-3;
|
rlm@1
|
173
|
rlm@1
|
174 int line = 0;
|
rlm@1
|
175
|
rlm@1
|
176 for (int i = 0; i < lines; i++)
|
rlm@1
|
177 {
|
rlm@1
|
178 CString buffer;
|
rlm@1
|
179 if (addressSize)
|
rlm@1
|
180 buffer.Format("%04X", addr);
|
rlm@1
|
181 else
|
rlm@1
|
182 buffer.Format("%08X", addr);
|
rlm@1
|
183 memDC.DrawText(buffer, &r, DT_TOP | DT_LEFT | DT_NOPREFIX);
|
rlm@1
|
184 r.left += 10*fontSize.cx;
|
rlm@1
|
185 beginHex = r.left;
|
rlm@1
|
186 readData(addr, 16, data);
|
rlm@1
|
187
|
rlm@1
|
188 int j;
|
rlm@1
|
189
|
rlm@1
|
190 if (dataSize == 0)
|
rlm@1
|
191 {
|
rlm@1
|
192 for (j = 0; j < 16; j++)
|
rlm@1
|
193 {
|
rlm@1
|
194 const int nextRLeft = r.left + 3*fontSize.cx;
|
rlm@1
|
195 if (!decimalDisplay)
|
rlm@1
|
196 buffer.Format("%02X", data[j]);
|
rlm@1
|
197 else
|
rlm@1
|
198 {
|
rlm@1
|
199 const signed char num = data[j];
|
rlm@1
|
200 if (num < -9 || num > 99)
|
rlm@1
|
201 r.left -= fontSize.cx;
|
rlm@1
|
202 if (num >= -99 && num <= 99)
|
rlm@1
|
203 buffer.Format("%2d", num);
|
rlm@1
|
204 else
|
rlm@1
|
205 buffer.Format("");
|
rlm@1
|
206 }
|
rlm@1
|
207 memDC.DrawText(buffer, &r, DT_TOP | DT_LEFT | DT_NOPREFIX);
|
rlm@1
|
208 r.left = nextRLeft;
|
rlm@1
|
209 }
|
rlm@1
|
210 }
|
rlm@1
|
211 if (dataSize == 1)
|
rlm@1
|
212 {
|
rlm@1
|
213 for (j = 0; j < 16; j += 2)
|
rlm@1
|
214 {
|
rlm@1
|
215 const int nextRLeft = r.left + 5*fontSize.cx;
|
rlm@1
|
216 if (!decimalDisplay)
|
rlm@1
|
217 buffer.Format("%04X", data[j] | data[j+1]<<8);
|
rlm@1
|
218 else
|
rlm@1
|
219 {
|
rlm@1
|
220 const signed short num = data[j] | data[j+1]<<8;
|
rlm@1
|
221 if (num < -999 || num > 9999)
|
rlm@1
|
222 r.left -= fontSize.cx;
|
rlm@1
|
223 if (num >= -9999 && num <= 9999)
|
rlm@1
|
224 buffer.Format("%4d", num);
|
rlm@1
|
225 else
|
rlm@1
|
226 buffer.Format("");
|
rlm@1
|
227 }
|
rlm@1
|
228 memDC.DrawText(buffer, &r, DT_TOP | DT_LEFT | DT_NOPREFIX);
|
rlm@1
|
229 r.left = nextRLeft;
|
rlm@1
|
230 }
|
rlm@1
|
231 }
|
rlm@1
|
232 if (dataSize == 2)
|
rlm@1
|
233 {
|
rlm@1
|
234 for (j = 0; j < 16; j += 4)
|
rlm@1
|
235 {
|
rlm@1
|
236 if (!decimalDisplay)
|
rlm@1
|
237 buffer.Format("%08X", data[j] | data[j+1]<<8 | data[j+2] << 16 | data[j+3] << 24);
|
rlm@1
|
238 else
|
rlm@1
|
239 {
|
rlm@1
|
240 const signed long num = data[j] | data[j+1]<<8 | data[j+2] << 16 | data[j+3] << 24;
|
rlm@1
|
241 if (num >= -9999999 && num <= 99999999)
|
rlm@1
|
242 buffer.Format("%8d", num);
|
rlm@1
|
243 else
|
rlm@1
|
244 buffer.Format("");
|
rlm@1
|
245 }
|
rlm@1
|
246 memDC.DrawText(buffer, &r, DT_TOP | DT_LEFT | DT_NOPREFIX);
|
rlm@1
|
247 r.left += 9*fontSize.cx;
|
rlm@1
|
248 }
|
rlm@1
|
249 }
|
rlm@1
|
250
|
rlm@1
|
251 line = r.left;
|
rlm@1
|
252
|
rlm@1
|
253 r.left += fontSize.cx;
|
rlm@1
|
254 beginAscii = r.left;
|
rlm@1
|
255 buffer.Empty();
|
rlm@1
|
256 for (j = 0; j < 16; j++)
|
rlm@1
|
257 {
|
rlm@1
|
258 char c = data[j];
|
rlm@1
|
259 if (c >= 32 && c <= 127)
|
rlm@1
|
260 {
|
rlm@1
|
261 buffer += c;
|
rlm@1
|
262 }
|
rlm@1
|
263 else
|
rlm@1
|
264 buffer += '.';
|
rlm@1
|
265 }
|
rlm@1
|
266
|
rlm@1
|
267 memDC.DrawText(buffer, &r, DT_TOP | DT_LEFT | DT_NOPREFIX);
|
rlm@1
|
268 addr += 16;
|
rlm@1
|
269 if (addressSize)
|
rlm@1
|
270 addr &= 0xffff;
|
rlm@1
|
271 r.top += fontSize.cy;
|
rlm@1
|
272 r.bottom += fontSize.cy;
|
rlm@1
|
273 r.left = 3;
|
rlm@1
|
274 }
|
rlm@1
|
275 CPen pen;
|
rlm@1
|
276 pen.CreatePen(PS_SOLID, 1, RGB(0, 0, 0));
|
rlm@1
|
277 CPen *old = memDC.SelectObject(&pen);
|
rlm@1
|
278
|
rlm@1
|
279 memDC.MoveTo(3+fontSize.cx*9, 3);
|
rlm@1
|
280 memDC.LineTo(3+fontSize.cx*9, 3+displayedLines*fontSize.cy);
|
rlm@1
|
281
|
rlm@1
|
282 memDC.MoveTo(line, 3);
|
rlm@1
|
283 memDC.LineTo(line, 3+displayedLines*fontSize.cy);
|
rlm@1
|
284
|
rlm@1
|
285 memDC.SelectObject(old);
|
rlm@1
|
286 pen.DeleteObject();
|
rlm@1
|
287
|
rlm@1
|
288 memDC.SelectObject(oldFont);
|
rlm@1
|
289
|
rlm@1
|
290 dc.BitBlt(0, 0, w, rect.bottom - rect.top, &memDC, 0, 0, SRCCOPY);
|
rlm@1
|
291
|
rlm@1
|
292 memDC.SelectObject(pOldBitmap);
|
rlm@1
|
293 memDC.DeleteDC();
|
rlm@1
|
294 bitmap.DeleteObject();
|
rlm@1
|
295 }
|
rlm@1
|
296
|
rlm@1
|
297 void MemoryViewer::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar*pScrollBar)
|
rlm@1
|
298 {
|
rlm@1
|
299 int address = this->address;
|
rlm@1
|
300 switch (nSBCode)
|
rlm@1
|
301 {
|
rlm@1
|
302 case SB_BOTTOM:
|
rlm@1
|
303 address = 0xffffff00;
|
rlm@1
|
304 break;
|
rlm@1
|
305 case SB_LINEDOWN:
|
rlm@1
|
306 address += 0x10;
|
rlm@1
|
307 break;
|
rlm@1
|
308 case SB_LINEUP:
|
rlm@1
|
309 address -= 0x10;
|
rlm@1
|
310 break;
|
rlm@1
|
311 case SB_PAGEDOWN:
|
rlm@1
|
312 address += (displayedLines<<4);
|
rlm@1
|
313 break;
|
rlm@1
|
314 case SB_PAGEUP:
|
rlm@1
|
315 address -= (displayedLines<<4);
|
rlm@1
|
316 break;
|
rlm@1
|
317 case SB_TOP:
|
rlm@1
|
318 address = 0;
|
rlm@1
|
319 break;
|
rlm@1
|
320 case SB_THUMBTRACK:
|
rlm@1
|
321 {
|
rlm@1
|
322 int page = displayedLines * 16;
|
rlm@1
|
323 SCROLLINFO si;
|
rlm@1
|
324 ZeroMemory(&si, sizeof(si));
|
rlm@1
|
325 si.cbSize = sizeof(si);
|
rlm@1
|
326 si.fMask = SIF_TRACKPOS;
|
rlm@1
|
327 GetScrollInfo(SB_VERT, &si);
|
rlm@1
|
328 address = page * si.nTrackPos;
|
rlm@1
|
329 break;
|
rlm@1
|
330 }
|
rlm@1
|
331 }
|
rlm@1
|
332 setAddress(address);
|
rlm@1
|
333 }
|
rlm@1
|
334
|
rlm@1
|
335 UINT MemoryViewer::OnGetDlgCode()
|
rlm@1
|
336 {
|
rlm@1
|
337 return DLGC_WANTALLKEYS;
|
rlm@1
|
338 }
|
rlm@1
|
339
|
rlm@1
|
340 void MemoryViewer::createEditCaret(int w, int h)
|
rlm@1
|
341 {
|
rlm@1
|
342 if (!hasCaret || caretWidth != w || caretHeight != h)
|
rlm@1
|
343 {
|
rlm@1
|
344 hasCaret = true;
|
rlm@1
|
345 caretWidth = w;
|
rlm@1
|
346 caretHeight = h;
|
rlm@1
|
347 ::CreateCaret(m_hWnd, (HBITMAP)0, w, h);
|
rlm@1
|
348 }
|
rlm@1
|
349 }
|
rlm@1
|
350
|
rlm@1
|
351 void MemoryViewer::destroyEditCaret()
|
rlm@1
|
352 {
|
rlm@1
|
353 hasCaret = false;
|
rlm@1
|
354 DestroyCaret();
|
rlm@1
|
355 }
|
rlm@1
|
356
|
rlm@1
|
357 void MemoryViewer::setCaretPos()
|
rlm@1
|
358 {
|
rlm@1
|
359 if (GetFocus() != this)
|
rlm@1
|
360 {
|
rlm@1
|
361 destroyEditCaret();
|
rlm@1
|
362 return;
|
rlm@1
|
363 }
|
rlm@1
|
364
|
rlm@1
|
365 if (dlg)
|
rlm@1
|
366 dlg->setCurrentAddress(editAddress);
|
rlm@1
|
367
|
rlm@1
|
368 if (editAddress < address || editAddress > (address -1 + (displayedLines<<4)))
|
rlm@1
|
369 {
|
rlm@1
|
370 destroyEditCaret();
|
rlm@1
|
371 return;
|
rlm@1
|
372 }
|
rlm@1
|
373
|
rlm@1
|
374 int subAddress = (editAddress - address);
|
rlm@1
|
375
|
rlm@1
|
376 int x = 3+10*fontSize.cx+editNibble*fontSize.cx;
|
rlm@1
|
377 int y = 3+fontSize.cy*((editAddress-address)>>4);
|
rlm@1
|
378
|
rlm@1
|
379 if (editAscii)
|
rlm@1
|
380 {
|
rlm@1
|
381 x = beginAscii + fontSize.cx*(subAddress&15);
|
rlm@1
|
382 }
|
rlm@1
|
383 else
|
rlm@1
|
384 {
|
rlm@1
|
385 switch (dataSize)
|
rlm@1
|
386 {
|
rlm@1
|
387 case 0:
|
rlm@1
|
388 x += 3*fontSize.cx*(subAddress & 15);
|
rlm@1
|
389 break;
|
rlm@1
|
390 case 1:
|
rlm@1
|
391 x += 5*fontSize.cx*((subAddress>>1) & 7);
|
rlm@1
|
392 break;
|
rlm@1
|
393 case 2:
|
rlm@1
|
394 x += 9*fontSize.cx*((subAddress>>2) & 3);
|
rlm@1
|
395 break;
|
rlm@1
|
396 }
|
rlm@1
|
397 }
|
rlm@1
|
398
|
rlm@1
|
399 RECT r;
|
rlm@1
|
400 GetClientRect(&r);
|
rlm@1
|
401 r.right -= 3;
|
rlm@1
|
402 if (x >= r.right)
|
rlm@1
|
403 {
|
rlm@1
|
404 destroyEditCaret();
|
rlm@1
|
405 return;
|
rlm@1
|
406 }
|
rlm@1
|
407 int w = fontSize.cx;
|
rlm@1
|
408 if ((x+fontSize.cx) >= r.right)
|
rlm@1
|
409 w = r.right - x;
|
rlm@1
|
410 createEditCaret(w, fontSize.cy);
|
rlm@1
|
411 ::SetCaretPos(x, y);
|
rlm@1
|
412 ShowCaret();
|
rlm@1
|
413 }
|
rlm@1
|
414
|
rlm@1
|
415 void MemoryViewer::OnLButtonDown(UINT nFlags, CPoint point)
|
rlm@1
|
416 {
|
rlm@1
|
417 int x = point.x;
|
rlm@1
|
418 int y = point.y;
|
rlm@1
|
419 int line = (y-3)/fontSize.cy;
|
rlm@1
|
420 int beforeAscii = beginHex;
|
rlm@1
|
421 int inc = 1;
|
rlm@1
|
422 int sub = 3*fontSize.cx;
|
rlm@1
|
423 switch (dataSize)
|
rlm@1
|
424 {
|
rlm@1
|
425 case 0:
|
rlm@1
|
426 beforeAscii += 47*fontSize.cx;
|
rlm@1
|
427 break;
|
rlm@1
|
428 case 1:
|
rlm@1
|
429 beforeAscii += 39*fontSize.cx;
|
rlm@1
|
430 inc = 2;
|
rlm@1
|
431 sub = 5*fontSize.cx;
|
rlm@1
|
432 break;
|
rlm@1
|
433 case 2:
|
rlm@1
|
434 beforeAscii += 35*fontSize.cx;
|
rlm@1
|
435 inc = 4;
|
rlm@1
|
436 sub = 9*fontSize.cx;
|
rlm@1
|
437 break;
|
rlm@1
|
438 }
|
rlm@1
|
439
|
rlm@1
|
440 editAddress = address + (line<<4);
|
rlm@1
|
441 if (x >= beginHex && x < beforeAscii)
|
rlm@1
|
442 {
|
rlm@1
|
443 x -= beginHex;
|
rlm@1
|
444 editNibble = 0;
|
rlm@1
|
445 while (x > 0)
|
rlm@1
|
446 {
|
rlm@1
|
447 x -= sub;
|
rlm@1
|
448 if (x >= 0)
|
rlm@1
|
449 editAddress += inc;
|
rlm@1
|
450 else
|
rlm@1
|
451 {
|
rlm@1
|
452 editNibble = (x + sub)/fontSize.cx;
|
rlm@1
|
453 }
|
rlm@1
|
454 }
|
rlm@1
|
455 editAscii = false;
|
rlm@1
|
456 }
|
rlm@1
|
457 else if (x >= beginAscii)
|
rlm@1
|
458 {
|
rlm@1
|
459 int afterAscii = beginAscii+16*fontSize.cx;
|
rlm@1
|
460 if (x >= afterAscii)
|
rlm@1
|
461 x = afterAscii-1;
|
rlm@1
|
462 editAddress += (x-beginAscii)/fontSize.cx;
|
rlm@1
|
463 editNibble = 0;
|
rlm@1
|
464 editAscii = true;
|
rlm@1
|
465 }
|
rlm@1
|
466 else
|
rlm@1
|
467 {
|
rlm@1
|
468 return;
|
rlm@1
|
469 }
|
rlm@1
|
470
|
rlm@1
|
471 if (editNibble > maxNibble)
|
rlm@1
|
472 editNibble = maxNibble;
|
rlm@1
|
473 SetFocus();
|
rlm@1
|
474 setCaretPos();
|
rlm@1
|
475 }
|
rlm@1
|
476
|
rlm@1
|
477 void MemoryViewer::OnSetFocus(CWnd*pOldWnd)
|
rlm@1
|
478 {
|
rlm@1
|
479 setCaretPos();
|
rlm@1
|
480 InvalidateRect(NULL, TRUE);
|
rlm@1
|
481 }
|
rlm@1
|
482
|
rlm@1
|
483 void MemoryViewer::OnKillFocus(CWnd*pNewWnd)
|
rlm@1
|
484 {
|
rlm@1
|
485 destroyEditCaret();
|
rlm@1
|
486 InvalidateRect(NULL, TRUE);
|
rlm@1
|
487 }
|
rlm@1
|
488
|
rlm@1
|
489 void MemoryViewer::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
|
rlm@1
|
490 {
|
rlm@1
|
491 bool isShift = (GetKeyState(VK_SHIFT) & 0x80000000) == 0x80000000;
|
rlm@1
|
492
|
rlm@1
|
493 switch (nChar)
|
rlm@1
|
494 {
|
rlm@1
|
495 case VK_RIGHT:
|
rlm@1
|
496 if (editAscii)
|
rlm@1
|
497 moveAddress(1, 0);
|
rlm@1
|
498 else if (isShift)
|
rlm@1
|
499 moveAddress((maxNibble+1)>>1, 0);
|
rlm@1
|
500 else
|
rlm@1
|
501 moveAddress(0, 1);
|
rlm@1
|
502 break;
|
rlm@1
|
503 case VK_LEFT:
|
rlm@1
|
504 if (editAscii)
|
rlm@1
|
505 moveAddress(-1, 0);
|
rlm@1
|
506 else if (isShift)
|
rlm@1
|
507 moveAddress(-((maxNibble+1)>>1), 0);
|
rlm@1
|
508 else
|
rlm@1
|
509 moveAddress(0, -1);
|
rlm@1
|
510 break;
|
rlm@1
|
511 case VK_DOWN:
|
rlm@1
|
512 moveAddress(16, 0);
|
rlm@1
|
513 break;
|
rlm@1
|
514 case VK_UP:
|
rlm@1
|
515 moveAddress(-16, 0);
|
rlm@1
|
516 break;
|
rlm@1
|
517 case VK_TAB:
|
rlm@1
|
518 GetNextDlgTabItem(GetParent(), isShift)->SetFocus();
|
rlm@1
|
519 break;
|
rlm@1
|
520 }
|
rlm@1
|
521 }
|
rlm@1
|
522
|
rlm@1
|
523 void MemoryViewer::moveAddress(s32 offset, int nibbleOff)
|
rlm@1
|
524 {
|
rlm@1
|
525 if (offset == 0)
|
rlm@1
|
526 {
|
rlm@1
|
527 if (nibbleOff == -1)
|
rlm@1
|
528 {
|
rlm@1
|
529 editNibble--;
|
rlm@1
|
530 if (editNibble == -1)
|
rlm@1
|
531 {
|
rlm@1
|
532 editAddress -= (maxNibble + 1) >> 1;
|
rlm@1
|
533 editNibble = maxNibble;
|
rlm@1
|
534 }
|
rlm@1
|
535 if (address == 0 && (editAddress >= (u32)(displayedLines<<4)))
|
rlm@1
|
536 {
|
rlm@1
|
537 editAddress = 0;
|
rlm@1
|
538 editNibble = 0;
|
rlm@1
|
539 beep();
|
rlm@1
|
540 }
|
rlm@1
|
541 if (editAddress < address)
|
rlm@1
|
542 setAddress(address - 16);
|
rlm@1
|
543 }
|
rlm@1
|
544 else
|
rlm@1
|
545 {
|
rlm@1
|
546 editNibble++;
|
rlm@1
|
547 if (editNibble > maxNibble)
|
rlm@1
|
548 {
|
rlm@1
|
549 editNibble = 0;
|
rlm@1
|
550 editAddress += (maxNibble + 1) >> 1;
|
rlm@1
|
551 }
|
rlm@1
|
552 if (editAddress < address)
|
rlm@1
|
553 {
|
rlm@1
|
554 editAddress -= (maxNibble + 1) >> 1;
|
rlm@1
|
555 editNibble = maxNibble;
|
rlm@1
|
556 beep();
|
rlm@1
|
557 }
|
rlm@1
|
558 if (editAddress >= (address+(displayedLines<<4)))
|
rlm@1
|
559 setAddress(address+16);
|
rlm@1
|
560 }
|
rlm@1
|
561 }
|
rlm@1
|
562 else
|
rlm@1
|
563 {
|
rlm@1
|
564 editAddress += offset;
|
rlm@1
|
565 if (offset < 0 && editAddress > (address-1+(displayedLines<<4)))
|
rlm@1
|
566 {
|
rlm@1
|
567 editAddress -= offset;
|
rlm@1
|
568 beep();
|
rlm@1
|
569 return;
|
rlm@1
|
570 }
|
rlm@1
|
571 if (offset > 0 && (editAddress < address))
|
rlm@1
|
572 {
|
rlm@1
|
573 editAddress -= offset;
|
rlm@1
|
574 beep();
|
rlm@1
|
575 return;
|
rlm@1
|
576 }
|
rlm@1
|
577 if (editAddress < address)
|
rlm@1
|
578 {
|
rlm@1
|
579 if (offset & 15)
|
rlm@1
|
580 setAddress((address+offset-16) & ~15);
|
rlm@1
|
581 else
|
rlm@1
|
582 setAddress(address+offset);
|
rlm@1
|
583 }
|
rlm@1
|
584 else if (editAddress > (address - 1 + (displayedLines<<4)))
|
rlm@1
|
585 {
|
rlm@1
|
586 if (offset & 15)
|
rlm@1
|
587 setAddress((address+offset+16) & ~15);
|
rlm@1
|
588 else
|
rlm@1
|
589 setAddress(address+offset);
|
rlm@1
|
590 }
|
rlm@1
|
591 }
|
rlm@1
|
592
|
rlm@1
|
593 setCaretPos();
|
rlm@1
|
594 }
|
rlm@1
|
595
|
rlm@1
|
596 LRESULT MemoryViewer::OnWMChar(WPARAM wParam, LPARAM LPARAM)
|
rlm@1
|
597 {
|
rlm@1
|
598 if (OnEditInput(wParam))
|
rlm@1
|
599 return 0;
|
rlm@1
|
600 return 1;
|
rlm@1
|
601 }
|
rlm@1
|
602
|
rlm@1
|
603 bool MemoryViewer::OnEditInput(UINT c)
|
rlm@1
|
604 {
|
rlm@1
|
605 if (c > 255 || !emulating)
|
rlm@1
|
606 {
|
rlm@1
|
607 beep();
|
rlm@1
|
608 return false;
|
rlm@1
|
609 }
|
rlm@1
|
610
|
rlm@1
|
611 if (!editAscii)
|
rlm@1
|
612 c = tolower(c);
|
rlm@1
|
613
|
rlm@1
|
614 u32 value = 256;
|
rlm@1
|
615
|
rlm@1
|
616 if (c >= 'a' && c <= 'f')
|
rlm@1
|
617 value = 10 + (c - 'a');
|
rlm@1
|
618 else if (c >= '0' && c <= '9')
|
rlm@1
|
619 value = (c - '0');
|
rlm@1
|
620 if (editAscii)
|
rlm@1
|
621 {
|
rlm@1
|
622 editData(editAddress, 8, 0, c);
|
rlm@1
|
623 moveAddress(1, 0);
|
rlm@1
|
624 InvalidateRect(NULL, TRUE);
|
rlm@1
|
625 }
|
rlm@1
|
626 else
|
rlm@1
|
627 {
|
rlm@1
|
628 if (value != 256)
|
rlm@1
|
629 {
|
rlm@1
|
630 value <<= 4*(maxNibble-editNibble);
|
rlm@1
|
631 u32 mask = ~(15 << 4*(maxNibble - editNibble));
|
rlm@1
|
632 switch (dataSize)
|
rlm@1
|
633 {
|
rlm@1
|
634 case 0:
|
rlm@1
|
635 editData(editAddress, 8, mask, value);
|
rlm@1
|
636 break;
|
rlm@1
|
637 case 1:
|
rlm@1
|
638 editData(editAddress, 16, mask, value);
|
rlm@1
|
639 break;
|
rlm@1
|
640 case 2:
|
rlm@1
|
641 editData(editAddress, 32, mask, value);
|
rlm@1
|
642 break;
|
rlm@1
|
643 }
|
rlm@1
|
644 moveAddress(0, 1);
|
rlm@1
|
645 InvalidateRect(NULL, TRUE);
|
rlm@1
|
646 }
|
rlm@1
|
647 }
|
rlm@1
|
648 return true;
|
rlm@1
|
649 }
|
rlm@1
|
650
|
rlm@1
|
651 void MemoryViewer::beep()
|
rlm@1
|
652 {
|
rlm@1
|
653 MessageBeep((UINT)-1);
|
rlm@1
|
654 }
|
rlm@1
|
655
|
rlm@1
|
656 void MemoryViewer::registerClass()
|
rlm@1
|
657 {
|
rlm@1
|
658 if (!isRegistered)
|
rlm@1
|
659 {
|
rlm@1
|
660 WNDCLASS wc;
|
rlm@1
|
661 ZeroMemory(&wc, sizeof(wc));
|
rlm@1
|
662 wc.style = CS_PARENTDC | CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS;
|
rlm@1
|
663 wc.lpfnWndProc = (WNDPROC) ::DefWindowProc;
|
rlm@1
|
664 wc.hInstance = AfxGetInstanceHandle();
|
rlm@1
|
665 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
rlm@1
|
666 wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
|
rlm@1
|
667 wc.lpszMenuName = NULL;
|
rlm@1
|
668 wc.lpszClassName = "VbaMemoryViewer";
|
rlm@1
|
669 AfxRegisterClass(&wc);
|
rlm@1
|
670 isRegistered = true;
|
rlm@1
|
671 }
|
rlm@1
|
672 }
|
rlm@1
|
673
|
rlm@1
|
674 void MemoryViewer::setAddressSize(int s)
|
rlm@1
|
675 {
|
rlm@1
|
676 addressSize = s;
|
rlm@1
|
677 }
|
rlm@1
|
678
|
rlm@1
|
679 u32 MemoryViewer::getCurrentAddress()
|
rlm@1
|
680 {
|
rlm@1
|
681 return editAddress;
|
rlm@1
|
682 }
|
rlm@1
|
683
|
rlm@1
|
684 int MemoryViewer::getSize()
|
rlm@1
|
685 {
|
rlm@1
|
686 return dataSize;
|
rlm@1
|
687 }
|
rlm@1
|
688
|