diff 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
line wrap: on
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/win32/MemoryViewer.cpp	Sat Mar 03 10:31:27 2012 -0600
     1.3 @@ -0,0 +1,688 @@
     1.4 +// MemoryViewer.cpp : implementation file
     1.5 +//
     1.6 +
     1.7 +#include "stdafx.h"
     1.8 +#include "resource.h"
     1.9 +#include "MemoryViewer.h"
    1.10 +
    1.11 +extern int emulating;
    1.12 +
    1.13 +/////////////////////////////////////////////////////////////////////////////
    1.14 +// MemoryViewer
    1.15 +
    1.16 +bool MemoryViewer::isRegistered = false;
    1.17 +
    1.18 +MemoryViewer::MemoryViewer()
    1.19 +{
    1.20 +	address        = 0;
    1.21 +	addressSize    = 0;
    1.22 +	dataSize       = 0;
    1.23 +	editAddress    = 0;
    1.24 +	editNibble     = 0;
    1.25 +	displayedLines = 0;
    1.26 +	hasCaret       = false;
    1.27 +	maxNibble      = 0;
    1.28 +	font        = (HFONT)GetStockObject(SYSTEM_FIXED_FONT);
    1.29 +	fontSize.cx = fontSize.cy = 0;
    1.30 +	beginAscii  = 0;
    1.31 +	beginHex    = 0;
    1.32 +	dlg         = NULL;
    1.33 +	registerClass();
    1.34 +}
    1.35 +
    1.36 +MemoryViewer::~MemoryViewer()
    1.37 +{}
    1.38 +
    1.39 +BEGIN_MESSAGE_MAP(MemoryViewer, CWnd)
    1.40 +//{{AFX_MSG_MAP(MemoryViewer)
    1.41 +ON_WM_ERASEBKGND()
    1.42 +ON_WM_PAINT()
    1.43 +ON_WM_VSCROLL()
    1.44 +ON_WM_GETDLGCODE()
    1.45 +ON_WM_LBUTTONDOWN()
    1.46 +ON_WM_SETFOCUS()
    1.47 +ON_WM_KILLFOCUS()
    1.48 +ON_WM_KEYDOWN()
    1.49 +//}}AFX_MSG_MAP
    1.50 +ON_MESSAGE(WM_CHAR, OnWMChar)
    1.51 +END_MESSAGE_MAP()
    1.52 +
    1.53 +/////////////////////////////////////////////////////////////////////////////
    1.54 +// MemoryViewer message handlers
    1.55 +
    1.56 +void MemoryViewer::setDialog(IMemoryViewerDlg *d)
    1.57 +{
    1.58 +	dlg = d;
    1.59 +}
    1.60 +
    1.61 +void MemoryViewer::setAddress(u32 a)
    1.62 +{
    1.63 +	address = a;
    1.64 +	if (displayedLines)
    1.65 +	{
    1.66 +		if (addressSize)
    1.67 +		{
    1.68 +			u16 addr = address;
    1.69 +			if ((u16)((addr+(displayedLines<<4)) & 0xFFFF) < addr)
    1.70 +			{
    1.71 +				address = 0xffff - (displayedLines<<4) + 1;
    1.72 +			}
    1.73 +		}
    1.74 +		else
    1.75 +		{
    1.76 +			if ((address+(displayedLines<<4)) < address)
    1.77 +			{
    1.78 +				address = 0xffffffff - (displayedLines<<4) + 1;
    1.79 +			}
    1.80 +		}
    1.81 +	}
    1.82 +	if (addressSize)
    1.83 +		address &= 0xffff;
    1.84 +	setCaretPos();
    1.85 +	InvalidateRect(NULL, TRUE);
    1.86 +}
    1.87 +
    1.88 +void MemoryViewer::setSize(int s)
    1.89 +{
    1.90 +	dataSize = s;
    1.91 +	if (s == 0)
    1.92 +		maxNibble = 1;
    1.93 +	else if (s == 1)
    1.94 +		maxNibble = 3;
    1.95 +	else
    1.96 +		maxNibble = 7;
    1.97 +
    1.98 +	InvalidateRect(NULL, TRUE);
    1.99 +}
   1.100 +
   1.101 +void MemoryViewer::setDecimal(bool decimalDisplayMode)
   1.102 +{
   1.103 +	decimalDisplay = decimalDisplayMode;
   1.104 +	InvalidateRect(NULL, TRUE);
   1.105 +}
   1.106 +
   1.107 +BOOL MemoryViewer::OnEraseBkgnd(CDC*pDC)
   1.108 +{
   1.109 +	return TRUE;
   1.110 +}
   1.111 +
   1.112 +void MemoryViewer::updateScrollInfo(int lines)
   1.113 +{
   1.114 +	int        page = lines * 16;
   1.115 +	SCROLLINFO si;
   1.116 +	ZeroMemory(&si, sizeof(si));
   1.117 +	si.cbSize = sizeof(si);
   1.118 +	si.fMask  = SIF_PAGE | SIF_RANGE | SIF_DISABLENOSCROLL | SIF_POS;
   1.119 +	si.nMin   = 0;
   1.120 +	if (addressSize)
   1.121 +	{
   1.122 +		si.nMax  = 0x10000/page;
   1.123 +		si.nPage = 1;
   1.124 +	}
   1.125 +	else
   1.126 +	{
   1.127 +		si.nMax  = 0xa000000 / page;
   1.128 +		si.nPage = page;
   1.129 +	}
   1.130 +
   1.131 +	si.nPos = address / page;
   1.132 +	SetScrollInfo(SB_VERT,
   1.133 +	              &si,
   1.134 +	              TRUE);
   1.135 +}
   1.136 +
   1.137 +void MemoryViewer::OnPaint()
   1.138 +{
   1.139 +	CPaintDC dc(this); // device context for painting
   1.140 +
   1.141 +	RECT rect;
   1.142 +	GetClientRect(&rect);
   1.143 +	int w = rect.right - rect.left;
   1.144 +	int h = rect.bottom - rect.top - 6;
   1.145 +
   1.146 +	CDC memDC;
   1.147 +	memDC.CreateCompatibleDC(&dc);
   1.148 +	CBitmap bitmap, *pOldBitmap;
   1.149 +	bitmap.CreateCompatibleBitmap(&dc, w, rect.bottom - rect.top);
   1.150 +	pOldBitmap = memDC.SelectObject(&bitmap);
   1.151 +
   1.152 +	memDC.FillRect(&rect, CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH)));
   1.153 +	memDC.DrawEdge(&rect, EDGE_ETCHED, BF_RECT);
   1.154 +
   1.155 +	CFont *oldFont = memDC.SelectObject(CFont::FromHandle(font));
   1.156 +
   1.157 +	fontSize = memDC.GetTextExtent("0", 1);
   1.158 +
   1.159 +	int lines = h / fontSize.cy;
   1.160 +
   1.161 +	displayedLines = lines;
   1.162 +
   1.163 +	updateScrollInfo(lines);
   1.164 +
   1.165 +	u32 addr = address;
   1.166 +
   1.167 +	memDC.SetTextColor(RGB(0, 0, 0));
   1.168 +
   1.169 +	u8 data[32];
   1.170 +
   1.171 +	RECT r;
   1.172 +	r.top    = 3;
   1.173 +	r.left   = 3;
   1.174 +	r.bottom = r.top+fontSize.cy;
   1.175 +	r.right  = rect.right-3;
   1.176 +
   1.177 +	int line = 0;
   1.178 +
   1.179 +	for (int i = 0; i < lines; i++)
   1.180 +	{
   1.181 +		CString buffer;
   1.182 +		if (addressSize)
   1.183 +			buffer.Format("%04X", addr);
   1.184 +		else
   1.185 +			buffer.Format("%08X", addr);
   1.186 +		memDC.DrawText(buffer, &r, DT_TOP | DT_LEFT | DT_NOPREFIX);
   1.187 +		r.left  += 10*fontSize.cx;
   1.188 +		beginHex = r.left;
   1.189 +		readData(addr, 16, data);
   1.190 +
   1.191 +		int j;
   1.192 +
   1.193 +		if (dataSize == 0)
   1.194 +		{
   1.195 +			for (j = 0; j < 16; j++)
   1.196 +			{
   1.197 +				const int nextRLeft = r.left + 3*fontSize.cx;
   1.198 +				if (!decimalDisplay)
   1.199 +					buffer.Format("%02X", data[j]);
   1.200 +				else
   1.201 +				{
   1.202 +					const signed char num = data[j];
   1.203 +					if (num < -9 || num > 99)
   1.204 +						r.left -= fontSize.cx;
   1.205 +					if (num >= -99 && num <= 99)
   1.206 +						buffer.Format("%2d", num);
   1.207 +					else
   1.208 +						buffer.Format("");
   1.209 +				}
   1.210 +				memDC.DrawText(buffer, &r, DT_TOP | DT_LEFT | DT_NOPREFIX);
   1.211 +				r.left = nextRLeft;
   1.212 +			}
   1.213 +		}
   1.214 +		if (dataSize == 1)
   1.215 +		{
   1.216 +			for (j = 0; j < 16; j += 2)
   1.217 +			{
   1.218 +				const int nextRLeft = r.left + 5*fontSize.cx;
   1.219 +				if (!decimalDisplay)
   1.220 +					buffer.Format("%04X", data[j] | data[j+1]<<8);
   1.221 +				else
   1.222 +				{
   1.223 +					const signed short num = data[j] | data[j+1]<<8;
   1.224 +					if (num < -999 || num > 9999)
   1.225 +						r.left -= fontSize.cx;
   1.226 +					if (num >= -9999 && num <= 9999)
   1.227 +						buffer.Format("%4d", num);
   1.228 +					else
   1.229 +						buffer.Format("");
   1.230 +				}
   1.231 +				memDC.DrawText(buffer, &r, DT_TOP | DT_LEFT | DT_NOPREFIX);
   1.232 +				r.left = nextRLeft;
   1.233 +			}
   1.234 +		}
   1.235 +		if (dataSize == 2)
   1.236 +		{
   1.237 +			for (j = 0; j < 16; j += 4)
   1.238 +			{
   1.239 +				if (!decimalDisplay)
   1.240 +					buffer.Format("%08X", data[j] | data[j+1]<<8 | data[j+2] << 16 | data[j+3] << 24);
   1.241 +				else
   1.242 +				{
   1.243 +					const signed long num = data[j] | data[j+1]<<8 | data[j+2] << 16 | data[j+3] << 24;
   1.244 +					if (num >= -9999999 && num <= 99999999)
   1.245 +						buffer.Format("%8d", num);
   1.246 +					else
   1.247 +						buffer.Format("");
   1.248 +				}
   1.249 +				memDC.DrawText(buffer, &r, DT_TOP | DT_LEFT | DT_NOPREFIX);
   1.250 +				r.left += 9*fontSize.cx;
   1.251 +			}
   1.252 +		}
   1.253 +
   1.254 +		line = r.left;
   1.255 +
   1.256 +		r.left    += fontSize.cx;
   1.257 +		beginAscii = r.left;
   1.258 +		buffer.Empty();
   1.259 +		for (j = 0; j < 16; j++)
   1.260 +		{
   1.261 +			char c = data[j];
   1.262 +			if (c >= 32 && c <= 127)
   1.263 +			{
   1.264 +				buffer += c;
   1.265 +			}
   1.266 +			else
   1.267 +				buffer += '.';
   1.268 +		}
   1.269 +
   1.270 +		memDC.DrawText(buffer, &r, DT_TOP | DT_LEFT | DT_NOPREFIX);
   1.271 +		addr += 16;
   1.272 +		if (addressSize)
   1.273 +			addr &= 0xffff;
   1.274 +		r.top    += fontSize.cy;
   1.275 +		r.bottom += fontSize.cy;
   1.276 +		r.left    = 3;
   1.277 +	}
   1.278 +	CPen pen;
   1.279 +	pen.CreatePen(PS_SOLID, 1, RGB(0, 0, 0));
   1.280 +	CPen *old = memDC.SelectObject(&pen);
   1.281 +
   1.282 +	memDC.MoveTo(3+fontSize.cx*9, 3);
   1.283 +	memDC.LineTo(3+fontSize.cx*9, 3+displayedLines*fontSize.cy);
   1.284 +
   1.285 +	memDC.MoveTo(line, 3);
   1.286 +	memDC.LineTo(line, 3+displayedLines*fontSize.cy);
   1.287 +
   1.288 +	memDC.SelectObject(old);
   1.289 +	pen.DeleteObject();
   1.290 +
   1.291 +	memDC.SelectObject(oldFont);
   1.292 +
   1.293 +	dc.BitBlt(0, 0, w, rect.bottom - rect.top, &memDC, 0, 0, SRCCOPY);
   1.294 +
   1.295 +	memDC.SelectObject(pOldBitmap);
   1.296 +	memDC.DeleteDC();
   1.297 +	bitmap.DeleteObject();
   1.298 +}
   1.299 +
   1.300 +void MemoryViewer::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar*pScrollBar)
   1.301 +{
   1.302 +	int address = this->address;
   1.303 +	switch (nSBCode)
   1.304 +	{
   1.305 +	case SB_BOTTOM:
   1.306 +		address = 0xffffff00;
   1.307 +		break;
   1.308 +	case SB_LINEDOWN:
   1.309 +		address += 0x10;
   1.310 +		break;
   1.311 +	case SB_LINEUP:
   1.312 +		address -= 0x10;
   1.313 +		break;
   1.314 +	case SB_PAGEDOWN:
   1.315 +		address += (displayedLines<<4);
   1.316 +		break;
   1.317 +	case SB_PAGEUP:
   1.318 +		address -= (displayedLines<<4);
   1.319 +		break;
   1.320 +	case SB_TOP:
   1.321 +		address = 0;
   1.322 +		break;
   1.323 +	case SB_THUMBTRACK:
   1.324 +	{
   1.325 +		int        page = displayedLines * 16;
   1.326 +		SCROLLINFO si;
   1.327 +		ZeroMemory(&si, sizeof(si));
   1.328 +		si.cbSize = sizeof(si);
   1.329 +		si.fMask  = SIF_TRACKPOS;
   1.330 +		GetScrollInfo(SB_VERT, &si);
   1.331 +		address = page * si.nTrackPos;
   1.332 +		break;
   1.333 +	}
   1.334 +	}
   1.335 +	setAddress(address);
   1.336 +}
   1.337 +
   1.338 +UINT MemoryViewer::OnGetDlgCode()
   1.339 +{
   1.340 +	return DLGC_WANTALLKEYS;
   1.341 +}
   1.342 +
   1.343 +void MemoryViewer::createEditCaret(int w, int h)
   1.344 +{
   1.345 +	if (!hasCaret || caretWidth != w || caretHeight != h)
   1.346 +	{
   1.347 +		hasCaret    = true;
   1.348 +		caretWidth  = w;
   1.349 +		caretHeight = h;
   1.350 +		::CreateCaret(m_hWnd, (HBITMAP)0, w, h);
   1.351 +	}
   1.352 +}
   1.353 +
   1.354 +void MemoryViewer::destroyEditCaret()
   1.355 +{
   1.356 +	hasCaret = false;
   1.357 +	DestroyCaret();
   1.358 +}
   1.359 +
   1.360 +void MemoryViewer::setCaretPos()
   1.361 +{
   1.362 +	if (GetFocus() != this)
   1.363 +	{
   1.364 +		destroyEditCaret();
   1.365 +		return;
   1.366 +	}
   1.367 +
   1.368 +	if (dlg)
   1.369 +		dlg->setCurrentAddress(editAddress);
   1.370 +
   1.371 +	if (editAddress < address || editAddress > (address -1 + (displayedLines<<4)))
   1.372 +	{
   1.373 +		destroyEditCaret();
   1.374 +		return;
   1.375 +	}
   1.376 +
   1.377 +	int subAddress = (editAddress - address);
   1.378 +
   1.379 +	int x = 3+10*fontSize.cx+editNibble*fontSize.cx;
   1.380 +	int y = 3+fontSize.cy*((editAddress-address)>>4);
   1.381 +
   1.382 +	if (editAscii)
   1.383 +	{
   1.384 +		x = beginAscii + fontSize.cx*(subAddress&15);
   1.385 +	}
   1.386 +	else
   1.387 +	{
   1.388 +		switch (dataSize)
   1.389 +		{
   1.390 +		case 0:
   1.391 +			x += 3*fontSize.cx*(subAddress & 15);
   1.392 +			break;
   1.393 +		case 1:
   1.394 +			x += 5*fontSize.cx*((subAddress>>1) & 7);
   1.395 +			break;
   1.396 +		case 2:
   1.397 +			x += 9*fontSize.cx*((subAddress>>2) & 3);
   1.398 +			break;
   1.399 +		}
   1.400 +	}
   1.401 +
   1.402 +	RECT r;
   1.403 +	GetClientRect(&r);
   1.404 +	r.right -= 3;
   1.405 +	if (x >= r.right)
   1.406 +	{
   1.407 +		destroyEditCaret();
   1.408 +		return;
   1.409 +	}
   1.410 +	int w = fontSize.cx;
   1.411 +	if ((x+fontSize.cx) >= r.right)
   1.412 +		w = r.right - x;
   1.413 +	createEditCaret(w, fontSize.cy);
   1.414 +	::SetCaretPos(x, y);
   1.415 +	ShowCaret();
   1.416 +}
   1.417 +
   1.418 +void MemoryViewer::OnLButtonDown(UINT nFlags, CPoint point)
   1.419 +{
   1.420 +	int x           = point.x;
   1.421 +	int y           = point.y;
   1.422 +	int line        = (y-3)/fontSize.cy;
   1.423 +	int beforeAscii = beginHex;
   1.424 +	int inc         = 1;
   1.425 +	int sub         = 3*fontSize.cx;
   1.426 +	switch (dataSize)
   1.427 +	{
   1.428 +	case 0:
   1.429 +		beforeAscii += 47*fontSize.cx;
   1.430 +		break;
   1.431 +	case 1:
   1.432 +		beforeAscii += 39*fontSize.cx;
   1.433 +		inc          = 2;
   1.434 +		sub          = 5*fontSize.cx;
   1.435 +		break;
   1.436 +	case 2:
   1.437 +		beforeAscii += 35*fontSize.cx;
   1.438 +		inc          = 4;
   1.439 +		sub          = 9*fontSize.cx;
   1.440 +		break;
   1.441 +	}
   1.442 +
   1.443 +	editAddress = address + (line<<4);
   1.444 +	if (x >= beginHex && x < beforeAscii)
   1.445 +	{
   1.446 +		x -= beginHex;
   1.447 +		editNibble = 0;
   1.448 +		while (x > 0)
   1.449 +		{
   1.450 +			x -= sub;
   1.451 +			if (x >= 0)
   1.452 +				editAddress += inc;
   1.453 +			else
   1.454 +			{
   1.455 +				editNibble = (x + sub)/fontSize.cx;
   1.456 +			}
   1.457 +		}
   1.458 +		editAscii = false;
   1.459 +	}
   1.460 +	else if (x >= beginAscii)
   1.461 +	{
   1.462 +		int afterAscii = beginAscii+16*fontSize.cx;
   1.463 +		if (x >= afterAscii)
   1.464 +			x = afterAscii-1;
   1.465 +		editAddress += (x-beginAscii)/fontSize.cx;
   1.466 +		editNibble   = 0;
   1.467 +		editAscii    = true;
   1.468 +	}
   1.469 +	else
   1.470 +	{
   1.471 +		return;
   1.472 +	}
   1.473 +
   1.474 +	if (editNibble > maxNibble)
   1.475 +		editNibble = maxNibble;
   1.476 +	SetFocus();
   1.477 +	setCaretPos();
   1.478 +}
   1.479 +
   1.480 +void MemoryViewer::OnSetFocus(CWnd*pOldWnd)
   1.481 +{
   1.482 +	setCaretPos();
   1.483 +	InvalidateRect(NULL, TRUE);
   1.484 +}
   1.485 +
   1.486 +void MemoryViewer::OnKillFocus(CWnd*pNewWnd)
   1.487 +{
   1.488 +	destroyEditCaret();
   1.489 +	InvalidateRect(NULL, TRUE);
   1.490 +}
   1.491 +
   1.492 +void MemoryViewer::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
   1.493 +{
   1.494 +	bool isShift = (GetKeyState(VK_SHIFT) & 0x80000000) == 0x80000000;
   1.495 +
   1.496 +	switch (nChar)
   1.497 +	{
   1.498 +	case VK_RIGHT:
   1.499 +		if (editAscii)
   1.500 +			moveAddress(1, 0);
   1.501 +		else if (isShift)
   1.502 +			moveAddress((maxNibble+1)>>1, 0);
   1.503 +		else
   1.504 +			moveAddress(0, 1);
   1.505 +		break;
   1.506 +	case VK_LEFT:
   1.507 +		if (editAscii)
   1.508 +			moveAddress(-1, 0);
   1.509 +		else if (isShift)
   1.510 +			moveAddress(-((maxNibble+1)>>1), 0);
   1.511 +		else
   1.512 +			moveAddress(0, -1);
   1.513 +		break;
   1.514 +	case VK_DOWN:
   1.515 +		moveAddress(16, 0);
   1.516 +		break;
   1.517 +	case VK_UP:
   1.518 +		moveAddress(-16, 0);
   1.519 +		break;
   1.520 +	case VK_TAB:
   1.521 +		GetNextDlgTabItem(GetParent(), isShift)->SetFocus();
   1.522 +		break;
   1.523 +	}
   1.524 +}
   1.525 +
   1.526 +void MemoryViewer::moveAddress(s32 offset, int nibbleOff)
   1.527 +{
   1.528 +	if (offset == 0)
   1.529 +	{
   1.530 +		if (nibbleOff == -1)
   1.531 +		{
   1.532 +			editNibble--;
   1.533 +			if (editNibble == -1)
   1.534 +			{
   1.535 +				editAddress -= (maxNibble + 1) >> 1;
   1.536 +				editNibble   = maxNibble;
   1.537 +			}
   1.538 +			if (address == 0 && (editAddress >= (u32)(displayedLines<<4)))
   1.539 +			{
   1.540 +				editAddress = 0;
   1.541 +				editNibble  = 0;
   1.542 +				beep();
   1.543 +			}
   1.544 +			if (editAddress < address)
   1.545 +				setAddress(address - 16);
   1.546 +		}
   1.547 +		else
   1.548 +		{
   1.549 +			editNibble++;
   1.550 +			if (editNibble > maxNibble)
   1.551 +			{
   1.552 +				editNibble   = 0;
   1.553 +				editAddress += (maxNibble + 1) >> 1;
   1.554 +			}
   1.555 +			if (editAddress < address)
   1.556 +			{
   1.557 +				editAddress -= (maxNibble + 1) >> 1;
   1.558 +				editNibble   = maxNibble;
   1.559 +				beep();
   1.560 +			}
   1.561 +			if (editAddress >= (address+(displayedLines<<4)))
   1.562 +				setAddress(address+16);
   1.563 +		}
   1.564 +	}
   1.565 +	else
   1.566 +	{
   1.567 +		editAddress += offset;
   1.568 +		if (offset < 0 && editAddress > (address-1+(displayedLines<<4)))
   1.569 +		{
   1.570 +			editAddress -= offset;
   1.571 +			beep();
   1.572 +			return;
   1.573 +		}
   1.574 +		if (offset > 0 && (editAddress < address))
   1.575 +		{
   1.576 +			editAddress -= offset;
   1.577 +			beep();
   1.578 +			return;
   1.579 +		}
   1.580 +		if (editAddress < address)
   1.581 +		{
   1.582 +			if (offset & 15)
   1.583 +				setAddress((address+offset-16) & ~15);
   1.584 +			else
   1.585 +				setAddress(address+offset);
   1.586 +		}
   1.587 +		else if (editAddress > (address - 1 + (displayedLines<<4)))
   1.588 +		{
   1.589 +			if (offset & 15)
   1.590 +				setAddress((address+offset+16) & ~15);
   1.591 +			else
   1.592 +				setAddress(address+offset);
   1.593 +		}
   1.594 +	}
   1.595 +
   1.596 +	setCaretPos();
   1.597 +}
   1.598 +
   1.599 +LRESULT MemoryViewer::OnWMChar(WPARAM wParam, LPARAM LPARAM)
   1.600 +{
   1.601 +	if (OnEditInput(wParam))
   1.602 +		return 0;
   1.603 +	return 1;
   1.604 +}
   1.605 +
   1.606 +bool MemoryViewer::OnEditInput(UINT c)
   1.607 +{
   1.608 +	if (c > 255 || !emulating)
   1.609 +	{
   1.610 +		beep();
   1.611 +		return false;
   1.612 +	}
   1.613 +
   1.614 +	if (!editAscii)
   1.615 +		c = tolower(c);
   1.616 +
   1.617 +	u32 value = 256;
   1.618 +
   1.619 +	if (c >= 'a' && c <= 'f')
   1.620 +		value = 10 + (c - 'a');
   1.621 +	else if (c >= '0' && c <= '9')
   1.622 +		value = (c - '0');
   1.623 +	if (editAscii)
   1.624 +	{
   1.625 +		editData(editAddress, 8, 0, c);
   1.626 +		moveAddress(1, 0);
   1.627 +		InvalidateRect(NULL, TRUE);
   1.628 +	}
   1.629 +	else
   1.630 +	{
   1.631 +		if (value != 256)
   1.632 +		{
   1.633 +			value <<= 4*(maxNibble-editNibble);
   1.634 +			u32 mask = ~(15 << 4*(maxNibble - editNibble));
   1.635 +			switch (dataSize)
   1.636 +			{
   1.637 +			case 0:
   1.638 +				editData(editAddress, 8, mask, value);
   1.639 +				break;
   1.640 +			case 1:
   1.641 +				editData(editAddress, 16, mask, value);
   1.642 +				break;
   1.643 +			case 2:
   1.644 +				editData(editAddress, 32, mask, value);
   1.645 +				break;
   1.646 +			}
   1.647 +			moveAddress(0, 1);
   1.648 +			InvalidateRect(NULL, TRUE);
   1.649 +		}
   1.650 +	}
   1.651 +	return true;
   1.652 +}
   1.653 +
   1.654 +void MemoryViewer::beep()
   1.655 +{
   1.656 +	MessageBeep((UINT)-1);
   1.657 +}
   1.658 +
   1.659 +void MemoryViewer::registerClass()
   1.660 +{
   1.661 +	if (!isRegistered)
   1.662 +	{
   1.663 +		WNDCLASS wc;
   1.664 +		ZeroMemory(&wc, sizeof(wc));
   1.665 +		wc.style         = CS_PARENTDC | CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS;
   1.666 +		wc.lpfnWndProc   = (WNDPROC) ::DefWindowProc;
   1.667 +		wc.hInstance     = AfxGetInstanceHandle();
   1.668 +		wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
   1.669 +		wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
   1.670 +		wc.lpszMenuName  = NULL;
   1.671 +		wc.lpszClassName = "VbaMemoryViewer";
   1.672 +		AfxRegisterClass(&wc);
   1.673 +		isRegistered = true;
   1.674 +	}
   1.675 +}
   1.676 +
   1.677 +void MemoryViewer::setAddressSize(int s)
   1.678 +{
   1.679 +	addressSize = s;
   1.680 +}
   1.681 +
   1.682 +u32 MemoryViewer::getCurrentAddress()
   1.683 +{
   1.684 +	return editAddress;
   1.685 +}
   1.686 +
   1.687 +int MemoryViewer::getSize()
   1.688 +{
   1.689 +	return dataSize;
   1.690 +}
   1.691 +