annotate src/win32/MemoryViewer.cpp @ 1:f9f4f1b99eed

importing src directory
author Robert McIntyre <rlm@mit.edu>
date Sat, 03 Mar 2012 10:31:27 -0600
parents
children
rev   line source
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