home *** CD-ROM | disk | FTP | other *** search
- #include <windows.h>
- #include <string.h> /* strcat & strlen */
- #include "toolhelp.h"
- #include "hpeep2.h"
-
-
- /* brush colors */
- #define BLACK 0x000000L
- #define MAGENTA 0xFF00FFL
- #define BLUE 0xFF0000L
- #define YELLOW 0x00FFFFL
- #define RED 0x0000FFL
-
- static HBRUSH hbr [7] ,
- hbrMAGENTA ,
- hbrBLUE ,
- hbrRED ,
- hbrYELLOW ;
-
- static HFONT hfont ;
-
-
- typedef struct tagDEFAULTDATASEGMENT
- {
- HANDLE hinstActive, // instance handle of active app
- htaskActive; // task handle of active app
- HWND hwndActive, // window handle of active app
- hwndClient; // window we draw bar graph in.
- WORD wSize, // size (bytes) of Data Segment.
- wStaticData, // size (bytes) of static data.
- wStackMax, // size (bytes) of stack size defined in .DEF
- wStackUsed, // size (bytes) of stack actually used.
- wHeapMoveable, // size (bytes) of heap allocation (moveable).
- wHeapFixed, // size (bytes) of heap allocation (fixed).
- wHeapFree, // size (bytes) of free space in heap.
- wOther, // size (bytes) of remaining allocated space in DS.
- wUnused; // size (bytes) of heap unused.
- } DEFAULTDATASEGMENT;
-
- static DEFAULTDATASEGMENT DDS ;
-
-
-
-
- void dds_create (HWND hwndClient)
- {
- HDC hdc = GetDC (hwndClient);
-
-
- // Create brushes.
- //
- if (GetDeviceCaps (hdc, NUMCOLORS) == 2)
- {
- // create pattern brushes for monochrome display
- //
- hbrMAGENTA = CreateHatchBrush (HS_DIAGCROSS ,BLACK);
- hbrBLUE = CreateHatchBrush (HS_BDIAGONAL ,BLACK);
- hbrYELLOW = CreateHatchBrush (HS_FDIAGONAL ,BLACK);
- hbrRED = CreateHatchBrush (HS_BDIAGONAL ,BLACK);
- }
- else
- {
- // create color brushes for color display
- //
- hbrMAGENTA = CreateSolidBrush (MAGENTA);
- hbrBLUE = CreateSolidBrush (BLUE) ;
- hbrYELLOW = CreateSolidBrush (YELLOW) ;
- hbrRED = CreateSolidBrush (RED) ;
- }
-
- hbr [0] = (HBRUSH)GetStockObject (BLACK_BRUSH);
- hbr [1] = (HBRUSH)GetStockObject (LTGRAY_BRUSH) ;
- hbr [2] = hbrMAGENTA ;
- hbr [3] = hbrBLUE ;
- hbr [4] = hbrYELLOW ;
- hbr [5] = hbrRED ;
- hbr [6] = (HBRUSH)GetStockObject (WHITE_BRUSH);
-
- // Create nice display font
- //
- {
- static LOGFONT lf;
- lf.lfHeight = 8;
- lf.lfWeight = 700;
- lf.lfCharSet = ANSI_CHARSET ;
- lf.lfQuality = PROOF_QUALITY;
-
- lf.lfPitchAndFamily = VARIABLE_PITCH | FF_SWISS;
-
- hfont = CreateFontIndirect (&lf);
- }
-
- ReleaseDC (hwndClient, hdc);
- DDS.hwndClient = hwndClient;
- }
-
-
-
- void dds_destroy (void)
- {
- DeleteObject (hbrBLUE) ;
- DeleteObject (hbrMAGENTA);
- DeleteObject (hbrYELLOW) ;
- DeleteObject (hbrRED) ;
-
- DeleteObject (hfont) ;
- }
-
-
-
-
- void dds_paint ()
- {
- RECT rcClient;
- long lTextExt;
- WORD wTextWidth;
- PAINTSTRUCT ps;
-
- BeginPaint (DDS.hwndClient, &ps);
-
- SelectObject (ps.hdc, hfont) ;
-
- SetMapMode (ps.hdc, MM_ANISOTROPIC);
- SetWindowOrg (ps.hdc, 0, 0) ;
- SetWindowExt (ps.hdc, 1300, 130) ;
-
- /*
- * Set viewport to be the entire client area.
- *
- */
- GetClientRect (DDS.hwndClient, &rcClient);
- SetViewportOrg (ps.hdc, 0, 0);
- SetViewportExt (ps.hdc, rcClient.right, rcClient.bottom);
-
- /*
- * Draw bar : StaticData = BLACK
- * Stack = LTGRAY
- * Fixed = MAGENTA
- * Moveable = YELLOW
- * Free = BLUE
- * Other = RED
- * Unused = WHITE
- *
- */
- {
- int xBar[8] ,
- yBar[2] ,
- i ,
- nMinWidth ;
-
- POINT pt[2];
-
- double dPercentStaticData ,
- dPercentStackMax ,
- dPercentFixed ,
- dPercentMoveable ,
- dPercentFree ,
- dPercentOther ,
- dPercentUnused ,
- dDiv = 0xFFFF/1000.; // makes bar 1000 logical units wide
- // eg, each 1% is represented by
- // 10 logical units.
-
- dPercentStaticData = (double)DDS.wStaticData /dDiv ;
- dPercentStackMax = (double)DDS.wStackMax /dDiv ;
- dPercentFixed = (double)DDS.wHeapFixed /dDiv ;
- dPercentMoveable = (double)DDS.wHeapMoveable /dDiv ;
- dPercentFree = (double)DDS.wHeapFree /dDiv ;
- dPercentOther = (double)DDS.wOther /dDiv ;
- dPercentUnused = (double)DDS.wUnused /dDiv ;
-
- // Compute a logical width that corresponds to a 2 pixel width.
- // This will be used as a minimum width for any bar section, and will
- // ensure that a section is always displayed at least 1 pixel wide.
- // (FillRect will output 1 pixel less than the rect's width)
- //
- pt[0].x = 0 ;
- pt[0].y = 0 ;
- pt[1].x = 1 ;
- pt[1].y = 0 ;
- DPtoLP (ps.hdc, &pt[0], 2) ;
- nMinWidth = max ((pt[1].x - pt[0].x), 1) ;
-
- xBar[0] = 50;
- xBar[1] = xBar[0] + max ( (int)dPercentStaticData, nMinWidth);
- xBar[2] = xBar[1] + max ( (int)dPercentStackMax , nMinWidth);
- xBar[3] = xBar[2] + max ( (int)dPercentFixed , nMinWidth);
- xBar[4] = xBar[3] + max ( (int)dPercentMoveable , nMinWidth);
- xBar[5] = xBar[4] + max ( (int)dPercentFree , nMinWidth);
- xBar[6] = xBar[5] + max ( (int)dPercentOther , nMinWidth);
- xBar[7] = xBar[6] + max ( (int)dPercentUnused , nMinWidth);
-
- yBar[0] = 20;
- yBar[1] = 30;
-
- /* Active window's Caption */
- if (IsWindow (DDS.hwndActive))
- {
- char szText [65],
- szCaption [40];
- BOOL bTruncate = (GetWindowTextLength (DDS.hwndActive) > 39);
- int cch;
-
- cch = GetWindowText (DDS.hwndActive, szCaption, 39);
- szCaption [cch] = '\0';
-
- if (bTruncate) strcpy (&szCaption [36], "...");
-
- wsprintf (szText, "%.39s [hInstance = %4.4X]", (LPSTR) szCaption,
- DDS.hinstActive);
- SetTextAlign (ps.hdc, TA_BOTTOM);
- TextOut (ps.hdc, 250, 18, szText, strlen (szText) );
- SetTextAlign (ps.hdc, TA_TOP);
- }
-
- /* label at left end */
- lTextExt = GetTextExtent (ps.hdc,"0", 1);
- wTextWidth = LOWORD (lTextExt);
- TextOut (ps.hdc, (xBar[0]-wTextWidth-10), yBar[0] + 2, "0", strlen("0") );
-
- /* label at right end */
- TextOut (ps.hdc, (xBar[7]+10), yBar[0] + 2, "64K", 3);
-
- for (i=0; i<=6; i++)
- {
- POINT ptA, ptB, ptC, ptD;
- RECT rect;
- char sz [40];
-
- ptA.x = (xBar[i+1] + xBar[i])/2 ;
- if ((xBar[i+1] - xBar[i]) <= (3*nMinWidth)/2 ) ptA.x = xBar[i] ;
-
- ptA.y = yBar[1] ;
- ptB.x = ptA.x ;
- ptB.y = 120 - (10*i) ;
- ptC.x = ptB.x + 20 ;
- ptC.y = ptB.y ;
- ptD.x = ptC.x + 10 ;
- ptD.y = ptC.y - 4 ;
-
- rect.left = xBar [i] ;
- rect.top = yBar [0] ;
- rect.right = xBar [i+1];
- rect.bottom = yBar [1] ;
- FillRect (ps.hdc, &rect, hbr[i]);
-
- MoveTo (ps.hdc, ptA.x, ptA.y);
- LineTo (ps.hdc, ptB.x, ptB.y);
- LineTo (ps.hdc, ptC.x, ptC.y);
-
- switch (i)
- {
- case 0: wsprintf (sz, "static data (%u)", DDS.wStaticData); break;
- case 1: wsprintf (sz, "stack allocated (%u), used (%u)",
- DDS.wStackMax, DDS.wStackUsed); break;
- case 2: wsprintf (sz, "fixed heap (%u)", DDS.wHeapFixed); break;
- case 3: wsprintf (sz, "moveable heap (%u)", DDS.wHeapMoveable);break;
- case 4: wsprintf (sz, "free heap (%u)", DDS.wHeapFree); break;
- case 5: wsprintf (sz, "other (%u)", DDS.wOther); break;
- case 6: wsprintf (sz, "room to grow (%u)", DDS.wUnused); break;
- }
-
- TextOut (ps.hdc, ptD.x, ptD.y, sz, strlen(sz));
- }
-
- SelectObject (ps.hdc, (HBRUSH)GetStockObject (NULL_BRUSH));
- Rectangle (ps.hdc, xBar[0], yBar[0], xBar[7], yBar[1]);
- }
-
- EndPaint (DDS.hwndClient, &ps);
- }
-
-
-
-
-
- void dds_walk ()
- {
- LOCALINFO localinfo;
- LOCALENTRY localentry;
- TASKENTRY taskentry;
-
- static DEFAULTDATASEGMENT OldDDS;
-
-
- // First, initialize the data segment values.
- //
- //
- DDS.wSize = 0;
- DDS.wStaticData = 0;
- DDS.wStackMax = 0;
- DDS.wStackUsed = 0;
- DDS.wHeapMoveable = 0;
- DDS.wHeapFixed = 0;
- DDS.wHeapFree = 0;
- DDS.wUnused = 0;
-
-
- // Now, get the window that has the focus.
- //
- //
- DDS.hwndActive = GetActiveWindow ();
-
-
- // Is it a valid window?
- //
- //
- if ( !IsWindow (DDS.hwndActive) ) return;
-
-
- // If this is a different window than before,
- // get a new task & instance handle.
- //
- //
- if (DDS.hwndActive != OldDDS.hwndActive)
- {
- // Loop through the task list
-
- DDS.htaskActive = GetWindowTask (DDS.hwndActive);
- taskentry.dwSize = sizeof (TASKENTRY);
-
- if ( TaskFirst (&taskentry) )
- do
- {
- if (DDS.htaskActive == taskentry.hTask)
- {
- DDS.hinstActive = taskentry.hInst ;
- break;
- }
- }
- while (TaskNext(&taskentry));
- }
-
- /*
- * Remember, the stack grows "down" (higher to lower address), so
- * to compute the stack sizes, we use these equations:
- *
- * wStackMax = pStackBottom - pStackTop ;
- * wStackUsed = pStackBottom - pStackMin ;
- *
- *
- */
- taskentry.dwSize = sizeof (TASKENTRY);
- TaskFindHandle (&taskentry, DDS.htaskActive);
-
- DDS.wStackMax = taskentry.wStackBottom - taskentry.wStackTop ;
- DDS.wStackUsed = taskentry.wStackBottom - taskentry.wStackMinimum ;
- DDS.wStaticData = taskentry.wStackTop ;
-
-
- // walk the local heap
-
- localinfo.dwSize = sizeof (LOCALINFO);
- LocalInfo (&localinfo, DDS.hinstActive);
-
- localentry.dwSize = sizeof (LOCALENTRY);
- if (LocalFirst (&localentry, DDS.hinstActive))
- {
- do
- {
- if (localentry.wFlags & LF_FREE)
- DDS.wHeapFree += localentry.wSize;
-
- else if (localentry.wFlags & LF_FIXED)
- DDS.wHeapFixed += localentry.wSize;
-
- else if (localentry.wFlags & LF_MOVEABLE)
- DDS.wHeapMoveable += localentry.wSize;
- }
- while (LocalNext (&localentry));
- }
-
- /*
- * At this point, heap traversal is done.
- * However, the heap can grow until the size of DS is 64K (0xFFFF).
- * Determine how many additional Kbytes the heap can grow.
- *
- */
- DDS.wSize = GlobalSize (DDS.hinstActive);
- DDS.wUnused = (0xFFFF - DDS.wSize);
-
-
- /*
- * Is there anything else we didn't account for?
- *
- */
- DDS.wOther = DDS.wSize - DDS.wStaticData
- - DDS.wStackMax
- - DDS.wHeapFixed
- - DDS.wHeapFree
- - DDS.wHeapMoveable ;
-
-
- // If anything has changed since last walk, update client window.
- //
-
- if (DDS.hwndActive != OldDDS.hwndActive ||
- DDS.wHeapFree != OldDDS.wHeapFree ||
- DDS.wHeapFixed != OldDDS.wHeapFixed ||
- DDS.wHeapMoveable != OldDDS.wHeapMoveable ||
- DDS.wOther != OldDDS.wOther ||
- DDS.wSize != OldDDS.wSize ||
- DDS.wStackUsed != OldDDS.wStackUsed)
- {
- InvalidateRect (DDS.hwndClient, NULL, TRUE);
- UpdateWindow (DDS.hwndClient);
-
- OldDDS = DDS;
- }
- }
-
-
-
-
-