home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / sdktools / winnt / walker / pview.c < prev    next >
C/C++ Source or Header  |  1997-10-05  |  16KB  |  668 lines

  1.  
  2. /******************************************************************************\
  3. *       This is a part of the Microsoft Source Code Samples. 
  4. *       Copyright (C) 1993-1997 Microsoft Corporation.
  5. *       All rights reserved. 
  6. *       This source code is only intended as a supplement to 
  7. *       Microsoft Development Tools and/or WinHelp documentation.
  8. *       See these sources for detailed information regarding the 
  9. *       Microsoft samples programs.
  10. \******************************************************************************/
  11.  
  12. #include "pwalk.h"
  13.  
  14. #define BYTE_WIN_WIDTH        77
  15. #define CLINESSHOW   8
  16. #define ABS(x) ((x) < 0? -(x) : (x))
  17.  
  18. /* externally defined system constants */
  19. extern int            xChar,
  20.                 yChar,
  21.                 xScreen,
  22.                 yScreen,
  23.                 yFrame,
  24.                 xFrame,
  25.                 yCaption,
  26.                 xVScrollBar;
  27. extern HFONT hFont;
  28. extern HWND  hMemWnd;
  29.  
  30. void    WINAPI VScrollBytes (HWND, int, int, LPMEMVIEW);
  31. void    WINAPI KeyToScrollMsg (HWND, WPARAM);
  32. void    WINAPI DisplayBytes (HDC, LPRECT, LPMEMVIEW, LPMEMVIEW);
  33. void    WINAPI GetBytesLine (LPBYTE, UINT, DWORD, int, char *);
  34. BOOL    WINAPI parcmp (LPBYTE, LPBYTE, int, LPBYTE);
  35.  
  36.  
  37.  
  38.  
  39. HWND   WINAPI EnumViewWindows (
  40.     HWND    hWndParent,
  41.     HWND    hWndLast)
  42. {
  43.  
  44.     HMENU   hMenu = GetMenu (hWndParent);
  45.     HMENU   hViewMenu = GetSubMenu (hMenu, 2);
  46.     char    szClass[MAX_PATH];
  47.     char    szCaption[MAX_PATH];
  48.     HWND    hWnd;
  49.     int     i;
  50.  
  51. static      int      nWindows;
  52. static      ATOM      *aMenuItems = NULL;
  53. static      int      iWnd;
  54.  
  55.     /* load window class name */
  56.     LoadString (GetModuleHandle (NULL), IDS_MEMVIEWCLASS, szClass, MAX_PATH);
  57.  
  58.     if (hWndLast == NULL)
  59.     {
  60.     /* start with first window in menu list */
  61.     iWnd = 0;
  62.  
  63.     /* determine number of windows */
  64.     nWindows = GetMenuItemCount (hViewMenu) - 5;
  65.  
  66.     /* if no popup windows, just return */
  67.     if (nWindows <= 0)
  68.         return NULL;
  69.  
  70.     /* free memory from last time, if any */
  71.     if (aMenuItems != NULL)
  72.         LocalFree ((HANDLE)aMenuItems);
  73.  
  74.     /* get menuitem IDs */
  75.     aMenuItems = (ATOM *)LocalAlloc (LPTR, nWindows*sizeof (ATOM));
  76.     for (i=5; i-5<nWindows; i++)
  77.         aMenuItems[i-5] = (ATOM)GetMenuItemID (hViewMenu, i);
  78.     }
  79.  
  80.     else
  81.     if (iWnd >= nWindows)
  82.         return (NULL);
  83.  
  84.     GetAtomName (aMenuItems[iWnd], szCaption, MAX_PATH);
  85.     hWnd = FindWindow (szClass, szCaption);
  86.     iWnd++;
  87.  
  88.     return (hWnd);
  89. }
  90.  
  91.  
  92.  
  93. /* activate view window identified by atom */
  94. void   WINAPI ActivateViewWindow (
  95.     ATOM    aCaption)
  96. {
  97.     char    szClass[MAX_PATH];
  98.     char    szCaption[MAX_PATH];
  99.     HWND    hWnd;
  100.  
  101.     GetAtomName (aCaption, szCaption, MAX_PATH);
  102.     LoadString (GetModuleHandle (NULL), IDS_MEMVIEWCLASS, szClass, MAX_PATH);
  103.     hWnd = FindWindow (szClass, szCaption);
  104.     BringWindowToTop (hWnd);
  105. }
  106.  
  107.  
  108.  
  109. /* function creates a window for viewing memory */
  110. HWND  WINAPI ViewMemory (
  111.     HWND      hWndParent,
  112.     char      *lpszObject,
  113.     LPVOID    lpMem,
  114.     int       nSize,
  115.     int       nBase)
  116. {
  117.     char      szClass[MAX_PATH];
  118.  
  119.     /* load resource strings for class and window title */
  120.     LoadString (GetModuleHandle (NULL), IDS_MEMVIEWCLASS, szClass, MAX_PATH);
  121.  
  122.     /* create memory view window */
  123.     return (CreateWindow (szClass,
  124.               lpszObject,
  125.               WS_POPUPWINDOW | WS_VISIBLE | WS_CAPTION |
  126.               WS_VSCROLL | WS_THICKFRAME | WS_MAXIMIZEBOX,
  127.               nSize,   /* use xposition to pass memory size to window */
  128.               nBase,   /* use yposition to pass base memory location  */
  129.               BYTE_WIN_WIDTH * xChar + xVScrollBar + 2*xFrame + xChar,
  130.               yScreen/2,
  131.               hWndParent,
  132.               NULL,
  133.               GetModuleHandle (NULL),
  134.               lpMem));
  135. }
  136.  
  137.  
  138.  
  139. LONG WINAPI MemWndProc (
  140.     HWND      hWnd,
  141.     UINT      uMsg,
  142.     WPARAM    wParam,
  143.     LPARAM    lParam)
  144. {
  145.     LONG       lRet = 1;
  146.     MEMVIEW    *pmv = (LPMEMVIEW)GetWindowLong (hWnd, WXB_LPMEMVIEW);
  147.  
  148.     
  149.     switch (uMsg)
  150.     {
  151.     case WM_CREATE:
  152.         pmv = (LPMEMVIEW)LocalAlloc (LPTR, sizeof (MEMVIEW));
  153.         SetWindowLong (hWnd, WXB_LPMEMVIEW, (LONG)pmv);
  154.         SetWindowLong (hWnd, WXB_LPOLDMEMVIEW, 0);
  155.  
  156.         pmv->lpMem = ((LPCREATESTRUCT)lParam)->lpCreateParams;
  157.         pmv->nSize = ((LPCREATESTRUCT)lParam)->x;
  158.         pmv->nBase = ((LPCREATESTRUCT)lParam)->y;
  159.         pmv->nLines = (pmv->nSize+15)/16;
  160.         pmv->nExtraBytes = (pmv->nSize & 0x0000000F);
  161.         pmv->PosV = 0;
  162.  
  163.         /* reposition window with proper x,y positions */
  164.         MoveWindow (hWnd,
  165.             15,
  166.             15,
  167.             ((LPCREATESTRUCT)lParam)->cx,
  168.             ((LPCREATESTRUCT)lParam)->cy,
  169.             TRUE);
  170.             break;
  171.  
  172.     case WM_SIZE:
  173.         pmv->xWin = LOWORD (lParam);
  174.         pmv->yWin = HIWORD (lParam);
  175.  
  176.         pmv->RangeV = pmv->nLines-pmv->yWin/yChar;
  177.  
  178.         if (pmv->RangeV < 0)
  179.         pmv->RangeV = 0;
  180.  
  181.         if (pmv->PosV > pmv->RangeV)
  182.         pmv->PosV = pmv->RangeV;
  183.  
  184.         SetScrollRange (hWnd, SB_VERT, 0, pmv->RangeV, FALSE);
  185.         SetScrollPos (hWnd, SB_VERT, pmv->PosV, TRUE);
  186.             break;
  187.  
  188.     case WM_PAINT:
  189.         {
  190.         PAINTSTRUCT    ps;
  191.  
  192.         BeginPaint (hWnd, &ps);
  193.         DisplayBytes (ps.hdc,
  194.               &(ps.rcPaint),
  195.               pmv,
  196.               (LPMEMVIEW)GetWindowLong (hWnd, WXB_LPOLDMEMVIEW));
  197.         EndPaint (hWnd, &ps);
  198.         }
  199.             break;
  200.  
  201.     case UM_UPDATE:
  202.         InvalidateRect (hWnd, NULL, TRUE);
  203.         UpdateWindow (hWnd);
  204.         break;
  205.  
  206.         case WM_KEYDOWN:
  207.         KeyToScrollMsg (hWnd, wParam);
  208.             break;
  209.  
  210.         case WM_VSCROLL:
  211.         VScrollBytes (hWnd, LOWORD (wParam), GetScrollPos (hWnd, SB_VERT), pmv);
  212.             break;
  213.  
  214.     case WM_DESTROY:
  215.         {
  216.         char     szCaption[MAX_PATH];
  217.         LPMEMVIEW     lpmv;
  218.  
  219.         /* free virtual memory block  and local memory buffer */
  220.         VirtualFree (pmv->lpMem, 0, MEM_RELEASE);
  221.         LocalFree ((HANDLE)pmv);
  222.  
  223.         /* remove any old view memory */
  224.         if ((lpmv = (LPMEMVIEW)GetWindowLong (hWnd, WXB_LPOLDMEMVIEW)) != NULL)
  225.         {
  226.         VirtualFree (lpmv->lpMem, 0, MEM_RELEASE);
  227.         LocalFree ((HANDLE)lpmv);
  228.         }
  229.  
  230.         /* send message to parent to remove menuitem */
  231.         GetWindowText (hWnd, szCaption, MAX_PATH);
  232.         SendMessage (GetParent (hWnd), WM_COMMAND, IDM_REMOVEVIEWWND, (LONG)szCaption);
  233.         }
  234.             break;
  235.  
  236.         default:
  237.         return (DefWindowProc(hWnd, uMsg, wParam, lParam));
  238.             break;
  239.     }
  240.     return 0L;
  241. }
  242.  
  243.  
  244.  
  245.  
  246. void  WINAPI VScrollBytes (
  247.     HWND     hWnd,
  248.     int      cmd,
  249.     int      pos,
  250.     LPMEMVIEW     lpmv)
  251. {
  252.     int    nScrollInc;
  253.  
  254.     switch (cmd)
  255.     {
  256.         case SB_TOP:
  257.         nScrollInc = -lpmv->PosV;
  258.             break ;
  259.  
  260.         case SB_BOTTOM:
  261.         nScrollInc = lpmv->RangeV - lpmv->PosV;
  262.             break ;
  263.  
  264.         case SB_LINEUP:
  265.             nScrollInc = -1;
  266.             break;
  267.  
  268.         case SB_LINEDOWN:
  269.             nScrollInc = 1;
  270.             break;
  271.  
  272.         case SB_PAGEDOWN:
  273.         nScrollInc = max (1, lpmv->yWin/yChar);
  274.             break;
  275.  
  276.         case SB_PAGEUP:
  277.         nScrollInc = min (-1, -(lpmv->yWin/yChar));
  278.             break;
  279.     
  280.         case SB_THUMBPOSITION:
  281.         nScrollInc = pos - lpmv->PosV;
  282.             break;
  283.  
  284.     case SB_THUMBTRACK:
  285.         nScrollInc = pos - lpmv->PosV;
  286.             break;
  287.  
  288.         default:
  289.             nScrollInc = 0;
  290.     }
  291.  
  292.     if (nScrollInc > lpmv->RangeV-lpmv->PosV)
  293.     nScrollInc = lpmv->RangeV-lpmv->PosV;
  294.  
  295.     if (nScrollInc < -lpmv->PosV)
  296.     nScrollInc = -lpmv->PosV;
  297.  
  298.     if (nScrollInc)
  299.     {
  300.     lpmv->PosV += nScrollInc;
  301.  
  302.     if (ABS (nScrollInc) < lpmv->yWin/yChar)
  303.         ScrollWindow (hWnd, 0, -(yChar*nScrollInc), NULL, NULL);
  304.     else
  305.         InvalidateRect (hWnd, NULL, TRUE);
  306.  
  307.     SetScrollPos (hWnd, SB_VERT, lpmv->PosV, TRUE);
  308.     UpdateWindow(hWnd);
  309.     }
  310. }
  311.  
  312.  
  313.  
  314. void  WINAPI KeyToScrollMsg (
  315.     HWND      hWnd,
  316.     WPARAM    wParam)
  317. {
  318.     int       i, nKeys;
  319.     static    struct
  320.     {
  321.         WORD wVirtKey;
  322.         int  iMessage;
  323.         WORD wRequest;
  324.     }key2scroll [] = {
  325.              VK_HOME,  WM_VSCROLL, SB_TOP,      VK_END,   WM_VSCROLL,
  326.              SB_BOTTOM, VK_PRIOR, WM_VSCROLL, SB_PAGEUP, VK_NEXT,
  327.              WM_VSCROLL, SB_PAGEDOWN, VK_UP,    WM_VSCROLL, SB_LINEUP,
  328.              VK_DOWN,  WM_VSCROLL, SB_LINEDOWN, VK_LEFT,  WM_HSCROLL,
  329.              SB_LINEUP, VK_RIGHT, WM_HSCROLL, SB_LINEDOWN,
  330.              };
  331.  
  332.     nKeys = sizeof key2scroll / sizeof key2scroll[0];
  333.  
  334.     for (i=0; i<nKeys; i++)
  335.     {
  336.         if (wParam == key2scroll[i].wVirtKey)   
  337.         {
  338.             SendMessage (hWnd, key2scroll[i].iMessage, key2scroll[i].wRequest, 0L);
  339.             return;
  340.         }
  341.     }
  342. }
  343.  
  344.  
  345.  
  346. void  WINAPI DisplayBytes (
  347.     HDC      hDC,
  348.     RECT     *pRect,
  349.     LPMEMVIEW     lpmv,
  350.     LPMEMVIEW     lpmvOld)
  351. {
  352.     UINT      i, r, iFirst, iLast, y;
  353.     char      szBuf[MAX_PATH], szText[MAX_PATH];
  354.     LPBYTE    pMem = (LPBYTE)lpmv->lpMem;
  355.     LPBYTE    pOldMem;
  356.     BYTE      bRes[16];
  357.     COLORREF  crOldColor = 0;
  358.     SIZE      sz;
  359.     int       cx;
  360.  
  361.     if (lpmvOld != NULL)
  362.     {
  363.     pOldMem = (LPBYTE)lpmvOld->lpMem;
  364.  
  365.     /* normalize to beginning of section relative to current memory */
  366.     (int)pOldMem += lpmvOld->nBase - lpmv->nBase;
  367.     }
  368.  
  369.     SelectObject (hDC, hFont);
  370.     SetTextColor (hDC, GetSysColor (COLOR_WINDOWTEXT));
  371.     SetBkColor (hDC, GetSysColor (COLOR_WINDOW));
  372.  
  373.     y = lpmv->PosV;
  374.  
  375.     iFirst = y + pRect->top/yChar-1;
  376.  
  377.     if (iFirst == 0xFFFFFFFFL)
  378.     iFirst = 0;
  379.  
  380.     iLast = min (y + pRect->bottom/yChar+1, (UINT)lpmv->nLines-1);
  381.     pMem += iFirst << 4;
  382.     pOldMem += iFirst << 4;
  383.  
  384.     if (lpmv->nExtraBytes)
  385.         iLast--;
  386.  
  387.     /* paint complete lines (lines with 16 bytes) */
  388.     GetBytesLine (NULL, 0, 0, 0, NULL);
  389.  
  390.     y = (iFirst - y) * yChar;
  391.     for (i = iFirst; i<iLast; i++)
  392.     {
  393.     GetBytesLine (pMem, i, lpmv->nBase, 16, szBuf);
  394.  
  395.     if (lpmvOld != NULL &&
  396.         ((int)pMem-(int)lpmv->lpMem + lpmv->nBase) >= lpmvOld->nBase &&
  397.         ((int)pMem-(int)lpmv->lpMem + lpmv->nBase) < (lpmvOld->nBase + lpmvOld->nSize) &&
  398.         !parcmp (pMem, pOldMem, 16, bRes))
  399.         {
  400.         /* write line number and leading space */
  401.         strncpy (szText, szBuf, 12);
  402.         szText[12] = 0;
  403.         GetTextExtentPoint (hDC, szText, 12, &sz);
  404.         cx = xChar;
  405.         SetTextColor (hDC, GetSysColor (COLOR_HIGHLIGHTTEXT));
  406.         TextOut (hDC, cx, LOWORD (y), szText, 12);
  407.  
  408.         /* check each hex byte for change */
  409.         for (r=0; r<16; r++)
  410.         {
  411.         if (bRes[r])
  412.             SetTextColor (hDC, RGB (191, 0, 0));
  413.         else
  414.             SetTextColor (hDC, GetSysColor(COLOR_WINDOWTEXT));
  415.  
  416.         /* draw next byte */
  417.         szText[0] = szBuf[3*r+12];
  418.         szText[1] = szBuf[3*r+1+12];
  419.         szText[2] = szBuf[3*r+2+12];
  420.         szText[3] = 0;
  421.         cx += sz.cx;
  422.         GetTextExtentPoint (hDC, szText, 3, &sz);
  423.         TextOut (hDC, cx, LOWORD (y), szText, 3);
  424.         }
  425.  
  426.         /* check each ascii byte */
  427.         for (r=0; r<16; r++)
  428.         {
  429.         if (bRes[r])
  430.             SetTextColor (hDC, RGB (191, 0, 0));
  431.         else
  432.             SetTextColor (hDC, GetSysColor(COLOR_WINDOWTEXT));
  433.  
  434.         /* draw next byte */
  435.         szText[0] = szBuf[r+60];
  436.         szText[1] = 0;
  437.         cx += sz.cx;
  438.         GetTextExtentPoint (hDC, szText, 1, &sz);
  439.         TextOut (hDC, cx, LOWORD (y), szText, 3);
  440.         }
  441.         }
  442.  
  443.     else
  444.         {
  445.         SetTextColor (hDC, GetSysColor(COLOR_WINDOWTEXT));
  446.         TextOut (hDC, xChar, LOWORD (y), szBuf, lstrlen (szBuf));
  447.         }
  448.  
  449.     pMem += 16;
  450.     pOldMem += 16;
  451.     y += yChar;
  452.     }
  453.  
  454.     /* paint last partial line if any (line with less than 16 bytes) */
  455.     if (lpmv->nExtraBytes)
  456.     {
  457.     GetBytesLine (pMem, i, lpmv->nBase, lpmv->nExtraBytes, szBuf);
  458.  
  459.     if (lpmvOld != NULL &&
  460.         ((int)pMem-(int)lpmv->lpMem + lpmv->nBase) >= lpmvOld->nBase &&
  461.         ((int)pMem-(int)lpmv->lpMem + lpmv->nBase) < (lpmvOld->nBase + lpmvOld->nSize) &&
  462.         !parcmp (pMem, pOldMem, lpmv->nExtraBytes, bRes))
  463.         {
  464.         /* write line number and leading space */
  465.         strncpy (szText, szBuf, 12);
  466.         szText[12] = 0;
  467.         GetTextExtentPoint (hDC, szText, 12, &sz);
  468.         cx = xChar;
  469.         SetTextColor (hDC, RGB (191, 0, 0));
  470.         TextOut (hDC, cx, LOWORD (y), szText, 12);
  471.  
  472.         /* check each hex byte for change */
  473.         for (r=0; r<(UINT)lpmv->nExtraBytes; r++)
  474.         {
  475.         if (bRes[r])
  476.             SetTextColor (hDC, RGB (191, 0, 0));
  477.         else
  478.             SetTextColor (hDC, GetSysColor(COLOR_WINDOWTEXT));
  479.  
  480.         /* draw next byte */
  481.         szText[0] = szBuf[3*r+12];
  482.         szText[1] = szBuf[3*r+1+12];
  483.         szText[2] = szBuf[3*r+2+12];
  484.         szText[3] = 0;
  485.         cx += sz.cx;
  486.         GetTextExtentPoint (hDC, szText, 3, &sz);
  487.         TextOut (hDC, cx, LOWORD (y), szText, 3);
  488.         }
  489.  
  490.         /* check each ascii byte */
  491.         for (r=0; r<(UINT)lpmv->nExtraBytes; r++)
  492.         {
  493.         if (bRes[r])
  494.             SetTextColor (hDC, RGB (191, 0, 0));
  495.         else
  496.             SetTextColor (hDC, GetSysColor(COLOR_WINDOWTEXT));
  497.  
  498.         /* draw next byte */
  499.         szText[0] = szBuf[r+60];
  500.         szText[1] = 0;
  501.         cx += sz.cx;
  502.         GetTextExtentPoint (hDC, szText, 1, &sz);
  503.         TextOut (hDC, cx, LOWORD (y), szText, 1);
  504.         }
  505.         }
  506.  
  507.     else
  508.         {
  509.         SetTextColor (hDC, GetSysColor(COLOR_WINDOWTEXT));
  510.         TextOut(hDC, xChar, y, szBuf, lstrlen (szBuf));
  511.         }
  512.     }
  513.  
  514.     SelectObject(hDC, GetStockObject(SYSTEM_FONT));
  515. }
  516.  
  517.  
  518.  
  519.  
  520.  
  521. void  WINAPI GetBytesLine (
  522.     LPBYTE   pBytes,
  523.     UINT     LineNum,
  524.     DWORD    dwBase,
  525.     int      nBytes,
  526.     char     *szLine)
  527. {
  528.     int          j;
  529.     unsigned char    ch;
  530.     char         szAscii[18];
  531.     static BOOL      bDBCS;
  532.  
  533.     if (NULL == pBytes) {
  534.     bDBCS = FALSE;
  535.     return;
  536.     }
  537.  
  538.     wsprintf (szLine, "%#08lx  ", dwBase + (LineNum*16));
  539.         
  540.     for (j = 0; j < nBytes; j++)
  541.     {
  542.     ch = *pBytes++;
  543.     wsprintf (szLine, "%s%02X ", (LPSTR)szLine, (WORD)ch);
  544.  
  545.     if (bDBCS)
  546.         {
  547.         szAscii[j] = (0 == j) ? '.' : ch;
  548.         bDBCS = FALSE;
  549.         }
  550.     else if (IsDBCSLeadByte(ch))
  551.         {
  552.         szAscii[j] = ch;
  553.         bDBCS = TRUE;
  554.         }
  555.     else
  556.         {
  557.         szAscii[j] = ((ch & 0x7F) >= ' ') ? ch : '.';
  558.         }
  559.     }
  560.  
  561.     if (bDBCS && 16 == nBytes)
  562.     szAscii[j++] = *pBytes;
  563.     szAscii[j] = 0;
  564.     wsprintf(szLine, "%-59s%s", (LPSTR)szLine, (LPSTR)szAscii);
  565. }
  566.  
  567.  
  568.  
  569.  
  570. BOOL    WINAPI parcmp (
  571.     LPBYTE    pMem,
  572.     LPBYTE    pOldMem,
  573.     int       nWidth,
  574.     LPBYTE    pRes)
  575. {
  576.     BOOL    bResult = TRUE;
  577.     int     i;
  578.  
  579.     /* clear result array */
  580.     for (i=0; i<16; i++)
  581.     pRes[i] = 0;
  582.  
  583.     for (i=0; i<nWidth; i++)
  584.     {
  585.     if (pMem[i] ^ pOldMem[i])
  586.         {
  587.         pRes[i] = 1;
  588.         bResult = FALSE;
  589.         }
  590.     }
  591.  
  592.     return bResult;
  593. }
  594.  
  595.  
  596.  
  597.  
  598. BOOL WINAPI AddrDlgProc (
  599.     HWND      hDlg,
  600.     UINT      uMsg,
  601.     WPARAM    wParam,
  602.     LPARAM    lParam)
  603. {
  604.     BOOL    bRet = TRUE;
  605.     char    szAddr[MAX_PATH];
  606.     int     nAddr;
  607.     HWND    hAddr = GetDlgItem (hDlg, IDC_ADDR);
  608.  
  609.     switch (uMsg)
  610.     {
  611.     case WM_INITDIALOG:
  612.         SetFocus (hAddr);
  613.         bRet = FALSE;
  614.         break;
  615.  
  616.     case WM_COMMAND:
  617.         switch (LOWORD (wParam))
  618.         {
  619.         case IDC_HEX:
  620.             if (HIWORD (wParam) == BN_CLICKED)
  621.             {
  622.             GetWindowText (hAddr, szAddr, MAX_PATH);
  623.  
  624.             if (SendMessage (GetDlgItem (hDlg, IDC_HEX), BM_GETCHECK, 0, 0))
  625.                 {
  626.                 /* convert to hex and return to control */
  627.                 nAddr = atoi (szAddr);
  628.                 wsprintf (szAddr, "%16x", nAddr);
  629.                 SetWindowText (hAddr, szAddr);
  630.                 }
  631.             else
  632.                 {
  633.                 /* convert to decimal and return to control */
  634.                 sscanf (szAddr, "%16x", &nAddr);
  635.                 SetWindowText (hAddr, itoa (nAddr, szAddr, 10));
  636.                 }
  637.  
  638.             /* select entire string for easy change */
  639.             SendMessage (hAddr, EM_SETSEL, 0, (LONG)-1);
  640.             SetFocus (hAddr);
  641.             }
  642.             break;
  643.  
  644.         case IDOK:
  645.             GetWindowText (hAddr, szAddr, MAX_PATH);
  646.  
  647.             /* if hex, convert to decimal integer */
  648.             if (SendMessage (GetDlgItem (hDlg, IDC_HEX), BM_GETCHECK, 0, 0))
  649.             sscanf (szAddr, "%16x", &nAddr);
  650.             else
  651.             nAddr = atoi (szAddr);
  652.  
  653.             EndDialog (hDlg, nAddr);
  654.             break;
  655.  
  656.         case IDCANCEL:
  657.             EndDialog (hDlg, 0);
  658.             break;
  659.         }
  660.         break;
  661.  
  662.     default:
  663.         bRet = FALSE;
  664.     }
  665.  
  666.     return (bRet);
  667. }
  668.