Windows2000/private/windbg64/windbg/memwin.c
2020-09-30 17:12:32 +02:00

1876 lines
54 KiB
C

/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
Memwin.c
Abstract:
This module contains the main line code for display of multiple memory
windows and the subclassed win proc to handle editing, display, etc.
Author:
Griffith Wm. Kadnier (v-griffk) 26-Jul-1992
Environment:
Win32, User Mode
--*/
#include "precomp.h"
#pragma hdrstop
#include <ime.h>
extern unsigned int InMemUpdate; // prevent multiple viemem() calls
BOOL IsDBCSCharSet(DWORD cs);
extern CXF CxfIp;
void FAR * PASCAL MMLpvLockMb(HDEP hmem);
void PASCAL MMbUnlockMb(HDEP hmem);
static void NEAR GetMemText (void);
int RgbFmts[] = MEM_FORMATS;
struct memWinDesc MemWinDesc[MAX_VIEWS];
struct memWinDesc TempMemWinDesc;
char memText[MAX_MSG_TXT];
char cMem[MAX_MSG_TXT]; //temp for edit/validation
char cMemTemp[MAX_MSG_TXT]; //temp for edit/validation
char cDoc[MAX_USER_LINE];
BOOL fAscii = FALSE; // is memwin edit taking place in an ascii field
// with MW_BYTE / twofield representation?
enum {
GOTO_FIRST,
GOTO_LAST,
GOTO_FIRSTONLINE,
GOTO_LASTONLINE,
GOTO_NEXT,
GOTO_PREVIOUS
};
enum {
STARTED,
INPROGRESS,
FINISHED
};
/*** UnformatDataItem
** Synopsis:
** Entry:
** Returns:
** Description:
*/
BOOL
UnformatDataItem (
char * lpch,
char * lpb
)
{
ULONG cBits;
FMTTYPE fmtType;
EERADIX uradix;
ULONG fTwoFields;
ULONG cchMax;
char *lpIndx;
EESTATUS eeErr = EENOERROR;
Dbg(CPFormatEnumerate(MemWinDesc[memView].iFormat,
&cBits,
&fmtType,
&uradix,
&fTwoFields,
&cchMax,
NULL) == EENOERROR);
switch (MemWinDesc[memView].iFormat) {
case MW_ASCII:
if ((*lpch > 0x00) && (*lpch < 0x7F)) {
*lpb = *lpch;
return TRUE;
} else {
return FALSE;
}
case MW_BYTE:
if (fAscii == TRUE) {
if ((*lpch > 0x00) && (*lpch < 0x7F)) {
*lpb = *lpch;
return TRUE;
} else {
return FALSE;
}
}
case MW_SHORT:
case MW_SHORT_HEX:
case MW_SHORT_UNSIGNED:
case MW_LONG:
case MW_LONG_HEX:
case MW_LONG_UNSIGNED:
case MW_QUAD:
case MW_QUAD_HEX:
case MW_QUAD_UNSIGNED:
if ((eeErr = CPUnformatMemory ((PUCHAR) lpb, lpch, cBits,
fmtType | fmtOverRide, uradix)) == EENOERROR) {
return TRUE;
} else {
return FALSE;
}
case MW_REAL:
case MW_REAL_LONG:
case MW_REAL_TEN:
lpIndx = lpch;
do {
if (!(isdigit (*lpIndx))
&& ((*lpIndx != '.')
&& (*lpIndx != '+')
&& (*lpIndx != '-')
&& (*lpIndx != ' ')
&& (*lpIndx != 'e')
&& (*lpIndx != 'E')) )
{
return (FALSE);
}
lpIndx++;
} while (*lpIndx != '\0');
if ((eeErr = CPUnformatMemory ( (PUCHAR) lpb, lpch, cBits,
fmtType | fmtOverRide, uradix)) == EENOERROR) {
return TRUE;
}
default:
return FALSE;
}
return FALSE;
} /* UnformatDataItem() */
/*** GotoField
** Synopsis:
** void = GotoField(action)
** Entry:
** action
** Returns:
** Description:
*/
static void NEAR
GotoField(
WORD action
)
{
int n = 0;
int startX = Views[memView].X;
int startY = Views[memView].Y;
if (!DebuggeeActive() || !DebuggeeAlive()) {
return;
}
if (memView == -1) {
return;
}
if (MemWinDesc[memView].lpMi == NULL) {
PosXY(memView, 0, 0, FALSE);
}
if (startX < MemWinDesc[memView].lpMi[1].iStart) {
PosXY(memView, MemWinDesc[memView].lpMi[1].iStart, startY, FALSE);
GetMemText ();
return;
}
switch (action) {
case GOTO_FIRST:
startY = 0;
//fall through to set line element
case GOTO_FIRSTONLINE:
if ((MemWinDesc[memView].iFormat == MW_BYTE) && (fAscii == TRUE)) {
n = (MemWinDesc[memView].cMi / 2) + 1;
} else {
n = 1;
}
break;
case GOTO_LAST:
startY = (Docs[Views[memView].Doc].NbLines - 1);
//fall through to set line element
case GOTO_LASTONLINE:
if ((MemWinDesc[memView].iFormat == MW_BYTE) && (fAscii == FALSE)) {
n = (MemWinDesc[memView].cMi / 2);
} else {
n = MemWinDesc[memView].cMi - 1;
}
break;
case GOTO_NEXT:
for (n =
((MemWinDesc[memView].iFormat == MW_BYTE) && (fAscii == TRUE)) ?
((int)((MemWinDesc[memView].cMi / 2) + 1))
: 1;
// kcarlos - BUGBUG -> BUGCAST
// n < (MemWinDesc[memView].iFormat == MW_BYTE) ?
n < (int) (MemWinDesc[memView].iFormat == MW_BYTE) ?
((fAscii == TRUE) ?
((int)(MemWinDesc[memView].cMi)-1)
: ((int)(MemWinDesc[memView].cMi / 2)))
: ((int)(MemWinDesc[memView].cMi)-1);
n++)
{
if (((int)(MemWinDesc[memView].lpMi[n].iStart) <= startX) &&
(startX < MemWinDesc[memView].lpMi[n+1].iStart)) {
break;
}
}
n += 1;
// kcarlos
// if ( (n >= ((MemWinDesc[memView].iFormat == MW_BYTE) ?
if ( (n >= (int) ((MemWinDesc[memView].iFormat == MW_BYTE) ?
((fAscii == TRUE) ? ((int)MemWinDesc[memView].cMi)
: ((int)(MemWinDesc[memView].cMi / 2) + 1))
: (int)MemWinDesc[memView].cMi)
)
&& ((startY + 1) < Docs[Views[memView].Doc].NbLines))
{
// user moving to next element (in next line of displayed data)
startY += 1;
if ((MemWinDesc[memView].iFormat == MW_BYTE) && (fAscii == TRUE)) {
n = (MemWinDesc[memView].cMi / 2) + 1;
} else {
n = 1;
}
} else if ((n >= ((MemWinDesc[memView].iFormat == MW_BYTE)
? ((fAscii == TRUE)
? ((int)MemWinDesc[memView].cMi)
: ((int)(MemWinDesc[memView].cMi / 2)))
: (int)MemWinDesc[memView].cMi))
&& ((startY + 1) >= Docs[Views[memView].Doc].NbLines))
{
n = (MemWinDesc[memView].iFormat == MW_BYTE)
? ((fAscii == TRUE)
? MemWinDesc[memView].cMi - 1
: ((MemWinDesc[memView].cMi / 2)))
//user trying to move beyond last element
: MemWinDesc[memView].cMi - 1;
}
break;
case GOTO_PREVIOUS:
for (n = ((MemWinDesc[memView].iFormat == MW_BYTE) && (fAscii == TRUE))
? ((int)((MemWinDesc[memView].cMi / 2) + 1))
: 1;
// kcarlos - BUGBUG -> BUGCAST
// n < (MemWinDesc[memView].iFormat == MW_BYTE)
n < (int) (MemWinDesc[memView].iFormat == MW_BYTE)
? ((fAscii == TRUE)
? ((int)MemWinDesc[memView].cMi)
: ((int)(MemWinDesc[memView].cMi / 2)))
: ((int)MemWinDesc[memView].cMi);
n++)
{
if (((int)(MemWinDesc[memView].lpMi[n].iStart) <= startX) &&
(startX < MemWinDesc[memView].lpMi[n].iStart +
MemWinDesc[memView].lpMi[n].cch)) {
break;
}
}
n -= 1;
if (n < ((MemWinDesc[memView].iFormat == MW_BYTE)
? ((fAscii == TRUE)
? (int)((MemWinDesc[memView].cMi / 2) + 1) : 1) : 1)) {
if (startY == 0) {
return; // user trying to move to element before 1st
}
startY -= 1;
n = (MemWinDesc[memView].iFormat == MW_BYTE)
? ((fAscii == TRUE)
? (MemWinDesc[memView].cMi - 1)
: ((MemWinDesc[memView].cMi / 2)))
: MemWinDesc[memView].cMi - 1;
}
break;
}
//Put the cursor at new location and save the text
PosXY(memView, MemWinDesc[memView].lpMi[n].iStart, startY, FALSE);
GetMemText ();
return;
} /* GotoField() */
/*** RecreateAsciiStrings
** Synopsis:
** Entry:
** Returns:
** Description:
** This function will recreate ASCII and Shift JIS strings
** in the right part of 'Byte Memory Window'.
*/
VOID RecreateAsciiPart(int doc, UINT cBits, BOOL fTwoFields)
{
UINT cb;
int nbLines;
int nbPerLine;
int x;
long y;
BOOL bDBCS;
char FAR * lpb;
char FAR * lpb2;
char FAR * lpbData;
int x1, x2, x3;
LPLINEREC pl = NULL;
LPBLOCKDEF pb = NULL;
HCURSOR hOldCursor;
int nHead;
DWORD dwRet;
hOldCursor = SetCursor(LoadCursor((HINSTANCE)NULL, IDC_WAIT));
// Compute number of lines for MAX_CHUNK_TOREAD k of data
nbPerLine = MemWinDesc[memView].cPerLine;
nbLines = ((MAX_CHUNK_TOREAD / nbPerLine) / (cBits / 8));
nHead = fTwoFields ? nbPerLine + 1 : 1;
// Compute number of bytes to malloc for this space
cb = ((nbPerLine * nbLines) * (cBits / 8));
lpbData = (PSTR) malloc( cb );
OSDReadMemory(LppdCur->hpid,
LptdCur->htid,
&MemWinDesc[memView].addr,
lpbData,
cb,
&dwRet
);
bDBCS = FALSE;
for (y = 0, lpb = lpbData; y < nbLines; y++) {
lpb2 = lpb;
// Now deal with the line data
for (x = 0; x < nbPerLine; x++) {
if (bDBCS) {
bDBCS = FALSE;
if (x == 0) {
//This means that current *lpb is the 2nd byte
//of a splited DBCS
*lpb = '.';
}
} else if (IsDBCSLeadByte(*lpb)) {
bDBCS = TRUE;
}
else if (!((BYTE)*lpb >= (BYTE)0x20 && (BYTE)*lpb <= (BYTE)0x7E)
&& !IsDBCSLeadByte(*lpb))
//not ascii and 'Hankaku Kana' displayable
{
*lpb = '.'; // replace with .
}
lpb++;
}
x1 = MemWinDesc[memView].lpMi[nHead].iStart;
x2 = MemWinDesc[memView].lpMi[nHead + x - 1].iStart;
x3 = x2;
if (FirstLine(doc, &pl, &y, &pb)) {
if (elLen > x2 + 1) {
//This means that 2nd byte of DBCS has been added.
x2++;
}
CloseLine(doc, &pl, y, &pb);
//FirstLine() incremented 'y', so we have to decrement it.
y--;
if (DeleteBlock(doc, x1, y, x2 + 1, y)) {
if (bDBCS) {
//If DBC is separated by new line, add 2nd byte.
x3++;
}
InsertBlock(doc, x1, y, x3 - x1 + 1, lpb2);
} else {
MessageBeep(0);
}
}
}
// Free up used space
free(lpbData);
InvalidateLines(memView, 0, y-1, FALSE);
SetCursor (hOldCursor);
}
/*** FValidateEdit
** Synopsis:
** Entry:
** Returns:
** Description:
** This function will get the current character stream from the
** memory window and attempt to convert it a memory pattern and
** write it back to the users memory. If it is not convertable
** or is not writable then the function will return FALSE.
*/
static BOOL PASCAL NEAR
FValidateEdit(
UINT iArea,
UINT x,
UINT y
)
{
int doc = Views[memView].Doc;
char rgch[30];
char rgb[30];
ULONG off;
ADDR addr2;
int xs, xe, cnt;
ULONG cBits;
FMTTYPE fmtType;
EERADIX uradix;
ULONG fTwoFields;
ULONG cchMax;
EESTATUS eeErr = EENOERROR;
char cMemChar[5];
DWORD dwRet;
if (!DebuggeeActive() || !DebuggeeAlive()) {
return FALSE;
}
if (memView == -1) {
return FALSE;
}
Dbg(CPFormatEnumerate(MemWinDesc[memView].iFormat,
&cBits,
&fmtType,
&uradix,
&fTwoFields,
&cchMax,
NULL) == EENOERROR);
switch (MemWinDesc[memView].iFormat) {
case MW_REAL:
case MW_REAL_LONG:
xs = x; /* MemWinDesc[memView].lpMi[iArea].iStart; */
xe = MemWinDesc[memView].lpMi[iArea].iStart +
MemWinDesc[memView].lpMi[iArea].cch;
if ((xs == MemWinDesc[memView].lpMi[iArea].iStart) ||
(xs == ((MemWinDesc[memView].lpMi[iArea].iStart +
MemWinDesc[memView].lpMi[iArea].cch) - 4))) {
GetTextAtLine(Views[memView].Doc, y, xs,xs+1, cMemChar);
if (cMemChar[0] != '+' && cMemChar[0] != '-' &&
cMemChar[0] != ' ') {
if (xs == MemWinDesc[memView].lpMi[iArea].iStart) {
ReplaceCharInBlock (doc, xs, y, cMem[0]);
} else {
ReplaceCharInBlock (doc, xs, y,
cMem[MemWinDesc[memView].lpMi[iArea].cch - 4]);
}
PosXY(memView, x, y, FALSE);
return(FALSE);
}
} else if (xs == ((MemWinDesc[memView].lpMi[iArea].iStart +
MemWinDesc[memView].lpMi[iArea].cch) - 5)) {
GetTextAtLine(Views[memView].Doc, y, xs,xs+1, cMemChar);
if (cMemChar[0] != 'E' && cMemChar[0] != 'e') {
ReplaceCharInBlock (doc, xs, y,
cMem[MemWinDesc[memView].lpMi[iArea].cch - 5]);
PosXY(memView, x, y, FALSE);
return(FALSE);
}
} else if (xs == (MemWinDesc[memView].lpMi[iArea].iStart + 2)) {
GetTextAtLine(Views[memView].Doc, y, xs,xs+1, cMemChar);
if (cMemChar[0] != '.') {
ReplaceCharInBlock (doc, xs, y, cMem[2]);
}
} else {
GetTextAtLine(Views[memView].Doc, y, xs,xs+1, cMemChar);
if (cMemChar[0] < '0' || cMemChar[0] > '9') {
ReplaceCharInBlock (doc, xs, y,
cMem[xs - MemWinDesc[memView].lpMi[iArea].iStart]);
PosXY(memView, x, y, FALSE);
return(FALSE);
}
}
break;
case MW_REAL_TEN:
xs = x; /* MemWinDesc[memView].lpMi[iArea].iStart; */
xe = MemWinDesc[memView].lpMi[iArea].iStart +
MemWinDesc[memView].lpMi[iArea].cch;
if ((xs == MemWinDesc[memView].lpMi[iArea].iStart) ||
(xs == ((MemWinDesc[memView].lpMi[iArea].iStart +
MemWinDesc[memView].lpMi[iArea].cch) - 5))) {
GetTextAtLine(Views[memView].Doc, y, xs,xs+1, cMemChar);
if (cMemChar[0] != '+' && cMemChar[0] != '-' &&
cMemChar[0] != ' ') {
if (xs == MemWinDesc[memView].lpMi[iArea].iStart) {
ReplaceCharInBlock (doc, xs, y, cMem[0]);
} else {
ReplaceCharInBlock (doc, xs, y,
cMem[MemWinDesc[memView].lpMi[iArea].cch - 5]);
}
PosXY(memView, x, y, FALSE);
return(FALSE);
}
} else if (xs == ((MemWinDesc[memView].lpMi[iArea].iStart +
MemWinDesc[memView].lpMi[iArea].cch) - 6)) {
GetTextAtLine(Views[memView].Doc, y, xs,xs+1, cMemChar);
if (cMemChar[0] != 'E' && cMemChar[0] != 'e') {
ReplaceCharInBlock (doc, xs, y,
cMem[MemWinDesc[memView].lpMi[iArea].cch - 6]);
PosXY(memView, x, y, FALSE);
return(FALSE);
}
} else if (xs == (MemWinDesc[memView].lpMi[iArea].iStart + 2)) {
GetTextAtLine(Views[memView].Doc, y, xs,xs+1, cMemChar);
if (cMemChar[0] != '.') {
ReplaceCharInBlock (doc, xs, y, cMem[2]);
}
} else {
GetTextAtLine(Views[memView].Doc, y, xs,xs+1, cMemChar);
if (cMemChar[0] < '0' || cMemChar[0] > '9') {
ReplaceCharInBlock (doc, xs, y,
cMem[xs - MemWinDesc[memView].lpMi[iArea].iStart]);
PosXY(memView, x, y, FALSE);
return(FALSE);
}
}
}
// If no changes have been made then it is a valid edit
if (MemWinDesc[memView].fEdit == FALSE) {
return TRUE;
}
// Get the new buffer from the window/editor
Assert(MemWinDesc[memView].lpMi[iArea].cch < sizeof(rgch));
GetTextAtLine(doc,
Views[memView].Y,
MemWinDesc[memView].lpMi[iArea].iStart,
MemWinDesc[memView].lpMi[iArea].iStart +
MemWinDesc[memView].lpMi[iArea].cch,
rgch);
rgch[MemWinDesc[memView].lpMi[iArea].cch] = 0;
strcpy (cMemTemp, rgch); // make a copy
// Convert the character buffer into a byte buffer
Assert(RgbFmts[MemWinDesc[memView].iFormat] <= sizeof(rgb));
if (!UnformatDataItem(rgch, rgb)) {
xs = x; /* MemWinDesc[memView].lpMi[iArea].iStart; */
xe = MemWinDesc[memView].lpMi[iArea].iStart +
MemWinDesc[memView].lpMi[iArea].cch;
cnt = x - MemWinDesc[memView].lpMi[iArea].iStart; //initialize
while (xs < xe) {
ReplaceCharInBlock (doc, xs, Views[memView].Y, cMem[cnt++]);
xs++;
}
PosXY(memView, x, y, FALSE);
return FALSE;
} else {
// Write the byte buffer back into users memory space
// Compute the address to write the memory to
off = (Views[memView].Y * MemWinDesc[memView].cPerLine +
(
(MemWinDesc[memView].iFormat == MW_BYTE) ?
((fAscii == TRUE)?
iArea - (MemWinDesc[memView].cMi / 2)
: iArea
)
: iArea
) - 1
) * RgbFmts[MemWinDesc[memView].iFormat];
addr2 = MemWinDesc[memView].addr;
addr2.addr.off += off;
OSDWriteMemory( LppdCur->hpid,
LptdCur->htid,
&addr2,
rgb,
RgbFmts[MemWinDesc[memView].iFormat],
&dwRet
);
// M00BUG -- highlight the changed area
// If a two character format then we need to repaint the
// window since there are "updates"
if (MemWinDesc[memView].iFormat == MW_BYTE) {
Dbg(CPFormatMemory(rgch, 3, (PUCHAR) rgb, 8, fmtZeroPad| fmtInt, 16) ==
EENOERROR);
if (!fAscii) {
BYTE by;
ULONG ul;
LPSTR lpszStop = NULL;
char sz[3];
memset(sz, 0, sizeof(sz));
memcpy(sz, rgch, 2);
ul = strtoul(sz, &lpszStop, uradix);
Assert(0 == errno);
ReplaceCharInBlock (doc,
MemWinDesc[memView].
lpMi[iArea + ((MemWinDesc[memView].cMi / 2))].
iStart,
Views[memView].Y,
LOBYTE(LOWORD(ul)) );
//******
//* In this case, we have to recreate ASCII(& Shift JIS) *
//* string. But it takes long time to recreate whole *
//* string of ASCII side. *
//******
if (IsDBCSCharSet(Views[memView].wCharSet)) {
RecreateAsciiPart(doc, cBits, TRUE);
}
} else {
ReplaceCharInBlock (doc,
MemWinDesc[memView].
lpMi[iArea - ((MemWinDesc[memView].cMi / 2))].
iStart,
Views[memView].Y,
rgch[0]);
ReplaceCharInBlock (doc,
MemWinDesc[memView].
lpMi[iArea - ((MemWinDesc[memView].cMi / 2))].
iStart+1,
Views[memView].Y,
rgch[1]);
if (IsDBCSCharSet(Views[memView].wCharSet)) {
RecreateAsciiPart(doc, cBits, TRUE);
}
}
}
else if (MemWinDesc[memView].iFormat == MW_ASCII &&
IsDBCSCharSet(Views[memView].wCharSet)) {
RecreateAsciiPart(doc, cBits, FALSE);
}
}
return TRUE;
} /* FValidateEdit() */
/*** InEntryArea
** Synopsis:
** word = InEntryArea(pui)
** Entry:
** Returns:
** Description:
*/
static BOOL NEAR
InEntryArea(
UINT * pui
)
{
int startX = Views[memView].X;
int n;
if (!DebuggeeActive() || !DebuggeeAlive()) {
return FALSE;
}
if (memView == -1) {
return FALSE;
}
for (n=1; n < ((int)(MemWinDesc[memView].cMi)-1); n++) {
if (((int)(MemWinDesc[memView].lpMi[n].iStart) <= startX) &&
(startX < MemWinDesc[memView].lpMi[n+1].iStart)) {
break;
}
}
if (startX >= MemWinDesc[memView].lpMi[n].iStart +
MemWinDesc[memView].lpMi[n].cch) {
return FALSE;
}
if (startX < MemWinDesc[memView].lpMi[1].iStart) {
return FALSE;
}
*pui = n;
return TRUE;
} /* InEntryArea() */
/*
** Synopsis:
** Entry:
** Returns:
** Description:
*/
BOOL RestoreDBCS(char *pszSrc, char *pszTgt, int x, BOOL bDBCS)
{
if (bDBCS) {
if (x == 0) {
//This means that current *pszSrc is the 2nd byte
//of a splited DBCS
pszTgt[x] = '.';
} else {
//This DBC is changed to '.' by CPFormatMemory().
//So I restore it.
pszTgt[x - 1] = *(pszSrc - 1);
pszTgt[x] = *pszSrc;
pszTgt[x + 1] = '\0';
}
bDBCS = FALSE;
} else if (IsDBCSLeadByte(*pszSrc)) {
bDBCS = TRUE;
}
else if (IsDBCSLeadByte(*pszSrc)) {
//'Hankaku Kana' is changed to '.' by CPFormatMemory().
pszTgt[x] = *pszSrc;
pszTgt[x + 1] = '\0';
}
return bDBCS;
}
/*** ViewMem
** Synopsis:
** void = ViewMem(view, fVoidCache)
** Entry:
** view - Index of document to update the information in
** Returns:
** nothing
** Description:
** This function will update the contents of the window to reflect
** the current memory patterns.
*/
void
ViewMem(
int view,
BOOL fVoidCache
)
{
int doc = Views[memView].Doc;
int n, x, y;
char rgch[MAX_MSG_TXT];
char rgchT[MAX_MSG_TXT]; // Temp formatting buffer
char rgchT2[MAX_MSG_TXT]; // Temp formatting buffer
RECT rc;
int cbWindowX; // Number of characters across window
int cAddrWidth; // # of characters in address display
ADDR addr; // Address for current display
ADDR FAR * lpAddr = &addr;
RTMI ri;
HTI hti = (HTI) NULL;
PTI pTi = (PTI)NULL;
HTM hTm = (HTM) NULL;
ULONG us;
char FAR * lpb;
char FAR * lpbData;
UINT cbt;
UINT cb;
long cbRead;
ULONG cBits;
FMTTYPE fmtType;
EERADIX uradix;
ULONG fTwoFields;
ULONG cchMax;
int nbLines, nbPerLine, nNewbPerLine, nPower;
LPDOCREC d = &Docs[doc];
HCURSOR hOldCursor, hWaitCursor;
EESTATUS eeErr = EENOERROR;
XOSD xosd;
BOOL bDBCS = FALSE;
char *psz;
Assert(memView != -1);
// Keep using GetParent(hwndClient),
// instead of hwndFrame (could be not assigned)
if (IsIconic(GetParent(Views[memView].hwndClient))) {
return;
}
// First clean out all of the information currently in the window
DeleteAll(doc);
if (!DebuggeeActive() || !DebuggeeAlive()) {
return;
}
// Set hourglass cursor
hWaitCursor = LoadCursor ((HINSTANCE)NULL, IDC_WAIT);
hOldCursor = SetCursor (hWaitCursor);
// Get the size of the memory window for sizing
GetClientRect(Views[memView].hwndClient, &rc);
cbWindowX = Pix2Pos(memView, rc.right, 0) - 1;
if (cbWindowX > MAX_USER_LINE) {
cbWindowX = (MAX_USER_LINE -1);
}
// Get the format information
Dbg(CPFormatEnumerate(MemWinDesc[memView].iFormat,
&cBits,
&fmtType,
&uradix,
&fTwoFields,
&cchMax,
NULL) == EENOERROR);
// If necessary compute the address of the expression
if (!(MemWinDesc[memView].fLive) && (MemWinDesc[memView].fHaveAddr)) {
addr = MemWinDesc[memView].addr;
} else {
GetAtomName(MemWinDesc[memView].atmAddress, rgch, sizeof(rgch));
if ((EEParse(rgch, radix, fCaseSensitive, &hTm, &us) != EENOERROR) ||
(EEBindTM(&hTm, SHpCXTFrompCXF( &CxfIp ), TRUE, FALSE) !=
EENOERROR) ||
(EEvaluateTM(&hTm, SHhFrameFrompCXF( &CxfIp ), EEHORIZONTAL) !=
EENOERROR)) {
LoadString (g_hInst,ERR_Memory_Context,cDoc,MAX_MSG_TXT);
cbt = strlen (cDoc);
InsertBlock(doc, 0, 0, cbt, cDoc);
InvalidateRect(Views[memView].hwndClient, (LPRECT)NULL, TRUE);
SendMessage(Views[memView].hwndClient, WM_PAINT, 0, 0L);
return;
}
memset( &ri, 0, sizeof(ri));
ri.fAddr = TRUE;
eeErr = EEInfoFromTM(&hTm, &ri, &hti);
// Extract the desired information
if (eeErr == EENOERROR) {
if ((hti == 0) || (pTi = (PTI) MMLpvLockMb( hti )) == 0) {
return;
} else {
if (pTi->fResponse.fAddr) {
*lpAddr = pTi->AI;
} else if (pTi->fResponse.fValue &&
pTi->fResponse.fSzBytes &&
pTi->cbValue >= sizeof(WORD)) {
switch( pTi->cbValue ) {
case sizeof(WORD):
SetAddrOff( lpAddr, *((WORD *) pTi->Value));
break;
case sizeof(DWORD):
SE_SetAddrOff( lpAddr, *((DWORD *) pTi->Value));
break;
case sizeof(DWORDLONG):
SetAddrOff( lpAddr, *((DWORDLONG *) pTi->Value));
break;
}
// set the segment
if ((pTi->SegType & EEDATA) == EEDATA) {
ADDR addrData = {0};
OSDGetAddr(LppdCur->hpid, LptdCur->htid, adrData,
&addrData );
SetAddrSeg( lpAddr, (SEGMENT) GetAddrSeg( addrData ));
ADDR_IS_FLAT(*lpAddr) = ADDR_IS_FLAT(addrData);
SYUnFixupAddr ( lpAddr );
} else if ((pTi->SegType & EECODE) == EECODE) {
ADDR addrPC = {0};
OSDGetAddr(LppdCur->hpid,LptdCur->htid, adrPC, &addrPC);
SetAddrSeg( lpAddr, (SEGMENT) GetAddrSeg( addrPC ));
ADDR_IS_FLAT(*lpAddr) = ADDR_IS_FLAT(addrPC);
SYUnFixupAddr( lpAddr );
} else {
ADDR addrData = {0};
OSDGetAddr(LppdCur->hpid, LptdCur->htid, adrData,
&addrData );
SetAddrSeg( lpAddr, (SEGMENT) GetAddrSeg( addrData ));
ADDR_IS_FLAT(*lpAddr) = ADDR_IS_FLAT(addrData);
SYUnFixupAddr ( lpAddr );
}
}
MMbUnlockMb( hti );
}
}
// Free up any handles
if (hTm) {
EEFreeTM (&hTm);
}
if (hti) {
EEFreeTI (&hti);
}
SYFixupAddr(&addr);
MemWinDesc[memView].addr = addr;
MemWinDesc[memView].fHaveAddr = TRUE;
// save orig address
_fmemcpy (&MemWinDesc[memView].orig_addr, &addr, sizeof(ADDR));
}
// Now compute how many memory locations will fit on one line
EEFormatAddress(&MemWinDesc[memView].addr, rgchT, 20,
(g_contWorkspace_WkSp.m_bShowSegVal != FALSE) ? EEFMT_SEG : 0);
cAddrWidth = strlen(rgchT);
if (fmtType != fmtAscii) {
nbPerLine = (int)((cbWindowX - cAddrWidth) /
(cchMax + 1 + (fTwoFields ? 1 : 0)));
} else {
nbPerLine = (int)((cbWindowX - cAddrWidth) / cchMax);
}
if (nbPerLine < 1) {
// Force at least one memory item to be displayed on the line
return;
}
if (MemWinDesc[memView].fFill == FALSE) {
// now we hold the number of items per line to a power of 2
nNewbPerLine = nbPerLine / 2; // normalize and round
nPower = 1;
while (nNewbPerLine >= 1) {
nNewbPerLine /= 2;
nPower++;
}
nbPerLine = (int) pow (2.0, ((double)nPower - 1.0));
}
MemWinDesc[memView].cPerLine = nbPerLine;
// Now read in the new memory space
Assert((cBits % 8) == 0); // Only display evenly divisable items
// Compute number of lines for MAX_CHUNK_TOREAD k of data
nbLines = ((MAX_CHUNK_TOREAD / nbPerLine) / (cBits / 8));
if ((nbPerLine * nbLines) < MAX_CHUNK_TOREAD) {
nbLines++;
}
// Compute number of bytes to malloc for this space
cb = ((nbPerLine * nbLines) * (cBits / 8));
lpbData = (PSTR) malloc( cb );
xosd = OSDReadMemory( LppdCur->hpid,
LptdCur->htid,
&addr,
lpbData,
cb,
(PULONG) &cbRead
);
if (xosd == xosdNone && cbRead > 0) {
MemWinDesc[memView].cbRead = cbRead; // save for VK_PRIOR;
MemWinDesc[memView].fBadRead = FALSE;
} else {
MemWinDesc[memView].cbRead = cb;
MemWinDesc[memView].fBadRead = TRUE;
}
// If necessary clean up the formatted area and re-compute
if (MemWinDesc[memView].lpMi)
free(MemWinDesc[memView].lpMi);
MemWinDesc[memView].cMi = nbPerLine + 1;
if (MemWinDesc[memView].iFormat == MW_BYTE) {
MemWinDesc[memView].cMi += nbPerLine;
}
MemWinDesc[memView].lpMi = (struct memItem *)
malloc( sizeof(struct memItem) * MemWinDesc[memView].cMi);
/*
** Now, we know exactly the layout, display memory
*/
if (fVoidCache) {
DeleteAll (doc); // void the window first
}
//Initialize
bDBCS = FALSE;
for (y=0, lpb = lpbData; y < nbLines; y++) {
x = 0;
// Place the current address out
EEFormatAddress(&addr, rgchT, 20,
(g_contWorkspace_WkSp.m_bShowSegVal != FALSE) ? EEFMT_SEG : 0);
cb = strlen(rgchT);
strcpy (cDoc,rgchT);
if (y == 0) {
MemWinDesc[memView].lpMi[0].iStart = (char)x;
MemWinDesc[memView].lpMi[0].cch = (char) cb;
MemWinDesc[memView].lpMi[0].iFmt = -1;
}
x += cb;
if (fmtType == fmtAscii) {
strcat (cDoc," ");
x += 1;
}
psz = cDoc + x;
// Now deal with the line data
for (n=0; n<nbPerLine; n++) {
// Format the data
if ((cbRead >= (long)RgbFmts[MemWinDesc[memView].iFormat]) &&
(MemWinDesc[memView].fBadRead == FALSE)) {
Dbg(CPFormatMemory(rgchT, cchMax + 1, (PUCHAR) lpb, cBits,
fmtType|fmtZeroPad, uradix) == EENOERROR);
if (fTwoFields) {
Dbg(CPFormatMemory(&rgchT2[n], 2, (PUCHAR) lpb, 8, fmtAscii, 10) ==
EENOERROR);
if (IsDBCSCharSet(Views[memView].wCharSet)) {
bDBCS = RestoreDBCS(lpb, rgchT2, n, bDBCS);
}
}
else if (MemWinDesc[memView].iFormat == MW_ASCII &&
IsDBCSCharSet(Views[memView].wCharSet)) {
psz[n] = rgchT[0];
psz[n+1] = '\0';
bDBCS = RestoreDBCS(lpb, psz, n, bDBCS);
rgchT[0] = psz[n];
psz[n] = '\0';
}
cb = strlen( rgchT );
} else {
memset(rgchT, '?', cchMax);
rgchT[cchMax] = '\0';
cb = cchMax;
if (fTwoFields) {
rgchT2[n] = '.';
rgchT2[n+1] = '\0';
}
}
if (cb < cchMax) {
strncat (cDoc," ",(cchMax-cb));
x += cchMax - cb;
}
if (fmtType != fmtAscii) {
strcat (cDoc," ");
x++;
}
strcat (cDoc,rgchT);
if (y == 0) {
MemWinDesc[memView].lpMi[1+n].iStart = (char)x;
MemWinDesc[memView].lpMi[1+n].cch = (char) cb;
MemWinDesc[memView].lpMi[1+n].iFmt = (char) fmtType;
}
// Update the loop variables
x += cb;
lpb += RgbFmts[MemWinDesc[memView].iFormat];
addr.addr.off += RgbFmts[MemWinDesc[memView].iFormat];
cbRead -= (long)(min((UINT)RgbFmts[MemWinDesc[memView].iFormat],
(UINT)cbRead));
}
if (fTwoFields) {
if (bDBCS && IsDBCSCharSet(Views[memView].wCharSet)) {
//If DBC is separated by new line, add 2nd byte.
//This DBC is changed to '.' by CPFormatMemory().
//So I restore it.
rgchT2[n - 1] = *(lpb - 1);
rgchT2[n] = *lpb;
rgchT2[n + 1] = '\0';
}
strcat (cDoc," ");
x++;
strcat (cDoc,rgchT2);
if (y == 0) {
for (n=0; n<nbPerLine; n++) {
MemWinDesc[memView].lpMi[1+n+nbPerLine].iStart =
(char)(x+n);
MemWinDesc[memView].lpMi[1+n+nbPerLine].cch = 1;
MemWinDesc[memView].lpMi[1+n+nbPerLine].iFmt =
(char)MemWinDesc[memView].iFormat;
}
}
x += n;
}
else if (MemWinDesc[memView].iFormat == MW_ASCII &&
IsDBCSCharSet(Views[memView].wCharSet)) {
if (bDBCS) {
//If DBC is separated by new line, add 2nd byte.
//This DBC is changed to '.' by CPFormatMemory().
//So I restore it.
psz[n-1] = *(lpb - 1);
psz[n ] = *lpb;
psz[n+1] = '\0';
}
}
// Now add the CR/LF at the end of all lines except last line
if (y < (nbLines - 1)) {
strcat (cDoc,"\r\n");
}
cbt = strlen (cDoc);
InsertBlock(doc, 0, y, cbt, cDoc);
}
// Set original cursor
hOldCursor = SetCursor (hOldCursor);
//Now everything is ready, so refresh the screen.
//PosXY(memView, MemWinDesc[memView].lpMi[1].iStart, 0, FALSE);
PosXY(memView, Views[memView].X, Views[memView].Y, FALSE);
InvalidateLines(memView, 0, LAST_LINE, FALSE);
EnsureScrollBars(memView,TRUE);
SetVerticalScrollBar(memView, FALSE);
// update address in struct
_fmemcpy (&MemWinDesc[memView].old_addr, &addr, sizeof (ADDR));
// Free up used space
free(lpbData);
GetMemText ();
return;
} /* ViewMem() */
/*** CheckByteFields
** Synopsis:
** void CheckByteFields (void)
** Entry:
** Returns:
** Description:
** Makes sure of which field the caret is in when MW_BYTE
*/
static void NEAR
CheckByteFields (
void
)
{
UINT iArea2;
BOOL fInEntry;
if (!DebuggeeActive() || !DebuggeeAlive() || (memView == -1)) {
return;
}
if (MemWinDesc[memView].iFormat == MW_BYTE) {
if ((fInEntry = InEntryArea(&iArea2)) == FALSE) {
while ((fInEntry = InEntryArea(&iArea2)) == FALSE) {
if (Views[memView].X > MemWinDesc[memView].lpMi[1].iStart) {
PosXY(memView, (Views[memView].X)-1, Views[memView].Y,
FALSE);
GetMemText ();
} else {
GotoField ((WORD) GOTO_NEXT);
break;
}
}
}
fInEntry = InEntryArea(&iArea2);
if ((fAscii == TRUE) && (iArea2 < (MemWinDesc[memView].cMi / 2) + 1)) {
fAscii = FALSE;
} else if ((fAscii == FALSE) &&
(iArea2 > (MemWinDesc[memView].cMi / 2))) {
fAscii = TRUE;
}
}
}
/*** GetMemText
** Synopsis:
** void GetMemText (void)
** Entry:
** Returns:
** Description:
** Gets text of memory item
*/
static void NEAR
GetMemText (
void
)
{
UINT iArea2;
BOOL fInEntry;
int memY = Views[memView].Y;
if (!DebuggeeActive() || !DebuggeeAlive() || (memView == -1)) {
return;
}
fInEntry = InEntryArea(&iArea2); //got the area
if (fInEntry) {
GetTextAtLine(Views[memView].Doc,
memY,
MemWinDesc[memView].lpMi[iArea2].iStart,
MemWinDesc[memView].lpMi[iArea2].iStart +
MemWinDesc[memView].lpMi[iArea2].cch,
cMem);
}
}
LRESULT
WINAPI
MemoryEditProc(
HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam
)
/*++
Routine Description:
Arguments:
hwnd - window handle to CPU window
message - message to be processed
wParam - info about message
lParam - info about message
Return Value:
--*/
{
UINT iArea;
UINT x, y;
BOOL fInEntry = FALSE;
SHORT isShiftDown;
SHORT isCtrlDown;
static BOOL bOldImeStatus;
switch (message) {
case WU_INITDEBUGWIN:
// WARNING : lParam is NOT a pointer to a Valid CREATESTRUCT,
// but holds the view number.
Assert(lParam >= 0 && lParam < MAX_VIEWS);
// Set Doc to forced overtype
Docs[Views[(WORD)lParam].Doc].forcedOvertype = TRUE;
// Set cursor on First mem item
_fmemcpy (&MemWinDesc[(WORD)lParam],
&TempMemWinDesc,
sizeof(struct memWinDesc));
PostMessage(hwnd, WM_KEYDOWN, VK_HOME, 0L);
return FALSE; //Never call original proc or you are Dead...
case WM_KEYDOWN:
if (!DebuggeeActive() ||
!DebuggeeAlive() ||
!(MemWinDesc[memView].fHaveAddr)) {
// First clean out all of the information currently in the window
InvalidateRect(hwnd, (LPRECT)NULL, TRUE);
SendMessage(hwnd, WM_PAINT, 0, 0L);
return CallWindowProc(lpfnEditProc, hwnd, message, wParam, lParam);
}
isShiftDown = (GetKeyState(VK_SHIFT) < 0);
isCtrlDown = (GetKeyState(VK_CONTROL) < 0);
if ((memView != -1) && (MemWinDesc[memView].fHaveAddr)) {
GetMemText ();
if (!isShiftDown) {
CheckByteFields ();
fInEntry = InEntryArea(&iArea);
}
switch (wParam) {
case VK_F6:
if (MemWinDesc[memView].iFormat == MW_BYTE) {
if (fAscii == FALSE) {
fAscii = TRUE;
} else {
fAscii = FALSE;
}
GotoField(GOTO_FIRSTONLINE);
}
return FALSE;
case VK_NEXT:
//if we had a bad read, return now-no mem movement allowed
if (MemWinDesc[memView].fBadRead == TRUE) {
return FALSE;
}
if (hwnd == Views[memView].hwndClient) {
MemWinDesc[memView].addr.addr.seg =
MemWinDesc[memView].old_addr.addr.seg;
// set for NEXT
MemWinDesc[memView].addr.addr.off =
MemWinDesc[memView].old_addr.addr.off;
ViewMem(memView, FALSE);
}
InvalidateRect(hwnd, (LPRECT)NULL, TRUE);
return FALSE;
case VK_PRIOR:
//if we had a bad read, return now-no mem movement allowed
if (MemWinDesc[memView].fBadRead == TRUE) {
return FALSE;
}
if (hwnd == Views[memView].hwndClient) {
if ((MemWinDesc[memView].addr.addr.off -
MemWinDesc[memView].cbRead)
>= MemWinDesc[memView].orig_addr.addr.off)
{
MemWinDesc[memView].addr.addr.off -=
MemWinDesc[memView].cbRead;
ViewMem(memView, FALSE);
}
}
InvalidateRect(hwnd, (LPRECT)NULL, TRUE);
return FALSE;
case VK_RETURN:
case VK_TAB:
if (fInEntry) {
GotoField ((WORD)((GetKeyState (VK_SHIFT) >= 0) ?
GOTO_NEXT : GOTO_PREVIOUS));
}
return FALSE;
case VK_BACK:
if (fInEntry &&
(Views[memView].X > MemWinDesc[memView].lpMi[1].iStart)) {
PosXY(memView,
(Views[memView].X)-1,
Views[memView].Y, FALSE);
GetMemText ();
} else if (fInEntry &&
(Views[memView].X <= MemWinDesc[memView].lpMi[1].iStart)) {
if (Views[memView].Y <= 0) {
PosXY(memView,
(MemWinDesc[memView].lpMi[1].iStart),
(Views[memView].Y),
FALSE);
GetMemText ();
} else {
PosXY(memView,
(MemWinDesc[memView].iFormat == MW_BYTE) ?
(fAscii == TRUE) ?
((MemWinDesc[memView].lpMi[MemWinDesc[memView].cMi].iStart) + MemWinDesc[memView].lpMi[MemWinDesc[memView].cMi].cch)
: ((MemWinDesc[memView].lpMi[MemWinDesc[memView].cMi / 2].iStart) + MemWinDesc[memView].lpMi[MemWinDesc[memView].cMi / 2].cch)
: ((MemWinDesc[memView].lpMi[MemWinDesc[memView].cMi - 1].iStart) + MemWinDesc[memView].lpMi[MemWinDesc[memView].cMi - 1].cch),
(Views[memView].Y) - 1,
FALSE);
GetMemText ();
}
}
if ((fInEntry = InEntryArea(&iArea)) == FALSE) {
while ((fInEntry = InEntryArea(&iArea)) == FALSE) {
if (Views[memView].X >
MemWinDesc[memView].lpMi[1].iStart) {
PosXY(memView,
(Views[memView].X)-1,
Views[memView].Y,
FALSE);
GetMemText ();
} else {
GotoField ((WORD) GOTO_NEXT);
break;
}
}
}
return FALSE;
case VK_END:
if (fInEntry) {
if (GetKeyState(VK_CONTROL) < 0) {
GotoField(GOTO_LAST);
} else {
GotoField(GOTO_LASTONLINE);
}
}
return FALSE;
case VK_HOME:
if (!fInEntry) {
GotoField(GOTO_FIRST);
} else if (GetKeyState(VK_CONTROL) < 0) {
GotoField(GOTO_FIRST);
} else {
GotoField(GOTO_FIRSTONLINE);
}
return FALSE;
case VK_RIGHT:
if ((wParam == VK_RIGHT) && isShiftDown) {
KeyDown((WORD) GetWindowWord(hwnd, GWW_VIEW), wParam,
isShiftDown, isCtrlDown);
return(FALSE);
}
if (fInEntry) {
PosXY(memView,
(Views[memView].X)+1,
Views[memView].Y,
FALSE);
GetMemText ();
}
fInEntry = InEntryArea(&iArea);
if (!fInEntry) {
ClearSelection(memView);
GotoField ((WORD) GOTO_NEXT);
}
return FALSE;
case VK_LEFT:
if (isShiftDown) {
KeyDown((WORD) GetWindowWord(hwnd, GWW_VIEW), wParam,
isShiftDown, isCtrlDown);
return(FALSE);
}
if (fInEntry &&
(Views[memView].X >
(((MemWinDesc[memView].iFormat == MW_BYTE) &&
(fAscii == TRUE)) ?
MemWinDesc[memView].lpMi[(MemWinDesc[memView].cMi / 2) + 1].iStart
: MemWinDesc[memView].lpMi[1].iStart)))
{
PosXY(memView,
(Views[memView].X)-1,
Views[memView].Y,
FALSE);
GetMemText ();
} else {
if (fInEntry && (Views[memView].X <= (((MemWinDesc[memView].iFormat == MW_BYTE) && (fAscii == TRUE)) ? MemWinDesc[memView].lpMi[(MemWinDesc[memView].cMi / 2) + 1].iStart : MemWinDesc[memView].lpMi[1].iStart)))
{
if (Views[memView].Y > 0) {
PosXY(memView, (MemWinDesc[memView].iFormat == MW_BYTE)
? (fAscii == TRUE)
? ((MemWinDesc[memView].lpMi[MemWinDesc[memView].cMi - 1].iStart) + MemWinDesc[memView].lpMi[MemWinDesc[memView].cMi - 1].cch)
: ((MemWinDesc[memView].lpMi[MemWinDesc[memView].cMi / 2].iStart) + MemWinDesc[memView].lpMi[MemWinDesc[memView].cMi / 2].cch)
: ((MemWinDesc[memView].lpMi[MemWinDesc[memView].cMi - 1].iStart) + MemWinDesc[memView].lpMi[MemWinDesc[memView].cMi - 1].cch)
, (Views[memView].Y) - 1, FALSE);
GetMemText ();
} else {
PosXY(memView,
(((MemWinDesc[memView].iFormat == MW_BYTE) && (fAscii == TRUE)) ? MemWinDesc[memView].lpMi[(MemWinDesc[memView].cMi / 2) + 1].iStart : MemWinDesc[memView].lpMi[1].iStart),
(Views[memView].Y),
FALSE);
GetMemText ();
}
}
}
if ((fInEntry = InEntryArea(&iArea)) == FALSE) {
ClearSelection(memView);
while ((fInEntry = InEntryArea(&iArea)) == FALSE) {
if (Views[memView].X > (((MemWinDesc[memView].iFormat == MW_BYTE) && (fAscii == TRUE)) ? MemWinDesc[memView].lpMi[(MemWinDesc[memView].cMi / 2) + 1].iStart : MemWinDesc[memView].lpMi[1].iStart))
{
PosXY(memView, (Views[memView].X)-1, Views[memView].Y, FALSE);
GetMemText ();
} else {
GotoField ((WORD) GOTO_NEXT);
break;
}
}
}
return FALSE;
case VK_DELETE:
case VK_INSERT:
return (FALSE);
}
}
break;
case WM_IME_REPORT:
return TRUE;
break;
case WM_SETFOCUS:
bOldImeStatus = ImeWINNLSEnableIME(NULL, FALSE);
break;
case WM_KILLFOCUS:
ImeWINNLSEnableIME(NULL, bOldImeStatus);
break;
case WM_CHAR:
if (!DebuggeeActive() ||
!DebuggeeAlive() ||
!(MemWinDesc[memView].fHaveAddr)) {
return FALSE;
}
//if we had a bad read, return now-no edits allowed
if (MemWinDesc[memView].fBadRead == TRUE) {
return FALSE;
}
CheckByteFields ();
if (Views[memView].X < MemWinDesc[memView].lpMi[1].iStart) {
// keep user out of mem address display
return FALSE;
}
switch (wParam) {
//case VK_F6:
case VK_RETURN:
case VK_TAB:
case VK_BACK:
return FALSE;
case VK_SPACE:
if (!fAscii) {
return FALSE;
}
break;
default:
break;
}
// See if we are at a cursor position where entry is allowed
if (InEntryArea(&iArea)) {
// Now perform validation on the character about to be replaced
// based upon what is present and type of field
x = Views[memView].X;
y = Views[memView].Y;
Docs[Views[memView].Doc].ismodified = FALSE;
CallWindowProc(lpfnEditProc, hwnd, message, wParam, lParam);
if (Docs[Views[memView].Doc].ismodified) {
MemWinDesc[memView].fEdit = TRUE;
}
if (FValidateEdit(iArea, x, y)) {
// if (MemWinDesc[memView].iFormat != MW_ASCII) {
if (!InEntryArea(&iArea)) {
GotoField ((WORD) GOTO_NEXT);
}
// }
}
}
return FALSE;
case WM_LBUTTONDBLCLK:
CallWindowProc(lpfnEditProc, hwnd, message, wParam, lParam);
fInEntry = InEntryArea(&iArea);
if (fInEntry) {
BOOL lookAround = FALSE;
char memField[MAX_MSG_TXT];
*memField = '\0';
if (GetSelectedText (curView, &lookAround, (LPSTR)&memField,
MAX_MSG_TXT, 0, 0)) {
// hmm. there's nothing here...
}
}
return FALSE;
case WM_FONTCHANGE:
if (!DebuggeeActive() || !DebuggeeAlive()) {
return FALSE;
}
ViewMem(memView, TRUE);
return FALSE;
case WM_SIZE:
if (wParam != SIZEICONIC) {
if (!DebuggeeActive() || !DebuggeeAlive()) {
return FALSE;
}
if ((hwnd == Views[memView].hwndClient) &&
(InMemUpdate == STARTED)) {
InMemUpdate = INPROGRESS;
ViewMem(memView, TRUE);
}
InvalidateRect(hwnd, (LPRECT)NULL, TRUE);
}
WindowTitle( memView, 0 );
return FALSE;
case WM_DESTROY:
MemWinDesc[memView].fHaveAddr = FALSE;
//Destroy the instance of this window proc
FreeProcInstance((FARPROC)SetWindowLongPtr(hwnd,
GWLP_WNDPROC,
(DWORD_PTR)lpfnEditProc));
break;
}
return CallWindowProc(lpfnEditProc, hwnd, message, wParam, lParam);
} /* MemoryEditProc() */
BOOL IsDBCSCharSet ( DWORD cs )
/* cs is charset to check for dbcs-ness */
{
switch(cs) {
case SHIFTJIS_CHARSET:
case HANGEUL_CHARSET:
case GB2312_CHARSET:
case CHINESEBIG5_CHARSET:
case JOHAB_CHARSET:
return TRUE;
default:
return FALSE;
}
}