⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hwmonit.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
字号:
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/


#include "heapwalk.h"
#include <string.h>

#define   MONITOR_TIMER         500
#define   REFRESH_TIME          500

#define   BAR_HITE              10
#define   BAR_LENGTH            1000
#define   BAR_XPOS              ( ( MONITOR_WIDTH - BAR_LENGTH ) / 8 )

#define   MONITOR_WIDTH         1600
#define   MONITOR_HITE          130

#define   TICK_LENGTH           10
#define   TEXT_HITE             ( ( MONITOR_HITE - TEXT_SPACE - \
                                 2 * BAR_HITE ) / ( SIZE_CNT + 1 ) )
#define   TEXT_SPACE            10

#define   SECTION_WIDTH(x, y)   ( ( (DWORD)BAR_LENGTH * (DWORD)(x) ) / ( y ) )

/*
 * indices for the sizes array in the LocalMonInfo struct
 */
enum {
    STATIC_SIZE = 0,
    STACK_SIZE,
    FIXED_SIZE,
    MOVE_SIZE,
    FREE_SIZE,
    OTHER_SIZE,
    SIZE_CNT            /* this entry must always be last */
};

typedef struct {
    HANDLE      instance;
    HTASK       task_hdl;
    HGLOBAL     handle;
    WORD        sizes[SIZE_CNT];
    WORD        total_size;
    WORD        stack_used;
} LocalMonInfo;

typedef struct {
    WORD        use_cnt;
    HBRUSH      brush[ SIZE_CNT ];
} MonitorTools;

static COLORREF         BarColors[ SIZE_CNT ] = {
                                RGB( 0, 0, 0 ),
                                RGB( 0, 255, 0 ),
                                RGB( 255, 0, 0 ),
                                RGB( 170, 170, 170 ),
                                RGB( 0, 0, 255 ),
                                RGB( 255, 255, 255 )
                        };

static BOOL             LabelsInitialized = FALSE;
static char             *MonitorLabels[ SIZE_CNT ];
static MonitorTools     Brushes;


/*
 * GetMonitorInfo - refresh information about the local heap being monitored
 */
static BOOL GetMonitorInfo( LocalMonInfo *info ) {

    LocalMonInfo        old_info;
    TASKENTRY           taskinfo;
    LOCALENTRY          localinfo;
    BOOL                ret;
    WORD                i;

    old_info = *info;

    memset( &localinfo, 0, sizeof( LOCALENTRY ) );
    localinfo.dwSize = sizeof( LOCALENTRY );
    memset( &taskinfo, 0, sizeof( TASKENTRY ) );
    taskinfo.dwSize = sizeof( TASKENTRY );

    TaskFindHandle( &taskinfo, info->task_hdl );
    info->sizes[ STATIC_SIZE ] = taskinfo.wStackTop;
    info->sizes[ STACK_SIZE ] = taskinfo.wStackBottom - taskinfo.wStackTop;
    info->sizes[ FIXED_SIZE ] = 0;
    info->sizes[ MOVE_SIZE ] = 0;
    info->sizes[ FREE_SIZE ] = 0;

    ret = LocalFirst( &localinfo, info->handle );
    while( ret ) {
        switch( localinfo.wFlags ) {
        case LF_FIXED:
            info->sizes[ FIXED_SIZE ] += localinfo.wSize;
            break;
        case LF_MOVEABLE:
            info->sizes[ MOVE_SIZE ] += localinfo.wSize;
            break;
        case LF_FREE:
            info->sizes[ FREE_SIZE ] += localinfo.wSize;
            break;
        }
        ret = LocalNext( &localinfo );
    }
    info->stack_used = taskinfo.wStackBottom - taskinfo.wStackMinimum;
    if( !memcmp( info, &old_info, sizeof( LocalMonInfo ) ) ) {
        return( FALSE );
    }
    info->sizes[ OTHER_SIZE ] = info->total_size;
    for( i=0; i < SIZE_CNT; i++ ) {
        if( i != OTHER_SIZE ) info->sizes[ OTHER_SIZE ] -= info->sizes[i];
    }
    return( TRUE );
}

/*
 * PaintMonitor - redraw the monitor window
 */
static void PaintMonitor( HWND hwnd, HDC dc, LocalMonInfo *info ) {

    RECT        area;
    WORD        i;
    char        buf[80];
    WORD        xpos, ypos;
    HBRUSH      white;

    SaveDC( dc );
    GetClientRect( hwnd, &area );
    white = GetStockObject( WHITE_BRUSH );
    FillRect( dc, &area, white );
    SetMapMode( dc, MM_ANISOTROPIC );
    SetWindowOrg( dc, 0, 0 );
    SetWindowExt( dc, MONITOR_WIDTH, MONITOR_HITE );
    SetViewportOrg( dc, 0, 0 );
    SetViewportExt( dc, area.right, area.bottom );

    area.top = BAR_HITE;
    area.bottom = 2 * BAR_HITE;
    area.left = BAR_XPOS;
    for( i=0; i < SIZE_CNT; i++ ) {
        if( info->sizes[i] == 0 ) continue;
        area.right = area.left + SECTION_WIDTH( info->sizes[i],
                                                info->total_size );
        FillRect( dc, &area, Brushes.brush[i] );

        xpos = ( area.left + area.right ) / 2;
        MoveTo( dc, xpos, area.bottom );
        ypos = area.bottom + TEXT_SPACE + ( SIZE_CNT - i ) * TEXT_HITE;
        LineTo( dc, xpos, ypos );
        xpos += TICK_LENGTH;
        LineTo( dc, xpos, ypos );
        if( i == STACK_SIZE ) {
            sprintf( buf, MonitorLabels[i], info->sizes[i],
                     info->stack_used );
        } else {
            sprintf( buf, MonitorLabels[i], info->sizes[i] );
        }
        TextOut( dc, xpos, ypos, buf, strlen( buf ) );
        area.left = area.right;
    }

    area.left = BAR_XPOS;
    area.right = area.left + BAR_LENGTH;
    MoveTo( dc, area.left, area.top );
    LineTo( dc, area.right, area.top );
    LineTo( dc, area.right, area.bottom );
    LineTo( dc, area.left, area.bottom );
    LineTo( dc, area.left, area.top );

    TextOut( dc, 0, BAR_HITE, "0", 1 );
    sprintf( buf, "%u", info->total_size );
    TextOut( dc, area.right + area.left, BAR_HITE, buf, strlen( buf ) );
    RestoreDC( dc, -1 );
}

/*
 * LocalMonitorProc - handle messages while monitoring a local heap
 */

BOOL __export FAR PASCAL LocalMonitorProc( HWND hwnd, WORD msg, WORD wparam,
                                    DWORD lparam )
{
    LocalMonInfo        *info;
    HDC                 dc;
    WORD                i;
    PAINTSTRUCT         paint;
    char                *msgtitle;

    info = (LocalMonInfo *)GetWindowLong( hwnd, 0 );
    switch( msg ) {
    case WM_CREATE:
        info = (LocalMonInfo *)( ( (CREATESTRUCT *)lparam )->lpCreateParams );
        SetWindowLong( hwnd, 0, (DWORD)info );
        if( !SetTimer( hwnd, MONITOR_TIMER, REFRESH_TIME, NULL ) ) {
            msgtitle = AllocRCString( STR_MONITOR_LCL_HEAP );
            RCMessageBox( NULL, STR_CANT_OPEN_LCL_MONITOR, msgtitle,
                        MB_OK | MB_TASKMODAL | MB_ICONINFORMATION );
            FreeRCString( msgtitle );
            DestroyWindow( hwnd );
        }
        GetMonitorInfo( info );
        break;
    case WM_PAINT:
        dc = BeginPaint( hwnd, &paint );
        PaintMonitor( hwnd, dc, info );
        EndPaint( hwnd, &paint );
        break;
    case WM_TIMER:
        if( GetMonitorInfo( info ) ) {
            dc = GetDC( hwnd );
            PaintMonitor( hwnd, dc, info );
            ReleaseDC( hwnd, dc );
        }
        break;
    case WM_SIZE:
        dc = GetDC( hwnd );
        PaintMonitor( hwnd, dc, info );
        ReleaseDC( hwnd, dc );
        break;
    case WM_DESTROY:
        KillTimer( hwnd, MONITOR_TIMER );
        Brushes.use_cnt --;
        if( Brushes.use_cnt == 0 ) {
            for( i=0; i < SIZE_CNT; i++ ) {
                DeleteObject( Brushes.brush[i] );
            }
        }
        MemFree( info );
        break;
    default:
        return( DefWindowProc( hwnd, msg, wparam, lparam ) );
    }
    return( NULL );
}

/*
 * GetTaskHdl - return the task handle associated with the given instance
 *              handle
 */

static HTASK GetTaskHdl( HANDLE instance ) {

    TASKENTRY           taskinfo;
    BOOL                ret;

    memset( &taskinfo, 0, sizeof( TASKENTRY ) );
    taskinfo.dwSize = sizeof( TASKENTRY );
    ret = TaskFirst( &taskinfo );
    while( ret ) {
        if( taskinfo.hInst == instance ) {
            return( taskinfo.hTask );
        }
        ret = TaskNext( &taskinfo );
    }
    return( NULL );
}

/*
 * BeginMonitor - begin to monitor a local heap
 */

void BeginMonitor( heap_list *item ) {

    HWND                hwnd;
    char                title[50];
    int                 width;
    int                 hight;
    LocalMonInfo        *info;
    WORD                i;
    char                *msgtitle;

    if( !LabelsInitialized ) {
        MonitorLabels[ STATIC_SIZE ] = GetRCString( STR_STATIC_DATA );
        MonitorLabels[ STACK_SIZE ] = GetRCString( STR_STACK_ALLOCATED );
        MonitorLabels[ FIXED_SIZE ] = GetRCString( STR_FIXED_HEAP );
        MonitorLabels[ MOVE_SIZE ] = GetRCString( STR_MOVEABLE_HEAP );
        MonitorLabels[ FREE_SIZE ] = GetRCString( STR_FREE_HEAP );
        MonitorLabels[ OTHER_SIZE ] = GetRCString( STR_MONITOR_UNKNOWN );
        LabelsInitialized = TRUE;
    }
    if( Brushes.use_cnt == 0 ) {
        for( i=0; i < SIZE_CNT; i++ ) {
            Brushes.brush[i] = CreateSolidBrush( BarColors[i] );
        }
    }
    Brushes.use_cnt++;
    width = GetSystemMetrics( SM_CXSCREEN );
    hight = GetSystemMetrics( SM_CYSCREEN );
    RCsprintf( title, STR_LCL_MONITOR_TITLE, item->szModule );

    info = MemAlloc( sizeof( LocalMonInfo ) );
    memset( info, 0, sizeof( LocalMonInfo ) );
    info->instance = item->info.ge.hBlock;
    info->task_hdl = GetTaskHdl( info->instance );
    info->total_size = item->info.ge.dwBlockSize;
    info->handle = item->info.ge.hBlock;

    hwnd = CreateWindow(
        LOCAL_MONITOR_CLASS,            /* Window class name */
        title,                          /* Window caption */
        WS_OVERLAPPED|WS_CAPTION
        |WS_SYSMENU|WS_THICKFRAME
        |WS_MAXIMIZEBOX,                /* Window style */
        width/12,                       /* Initial X position */
        hight/4,                        /* Initial Y position */
        5*width/6,                      /* Initial X size */
        hight/2,                        /* Initial Y size */
        HeapWalkMainWindow,             /* Parent window handle */
        NULL,                           /* Window menu handle */
        Instance,                       /* Program instance handle */
        info );                         /* Create parameters */
    if( hwnd == NULL ) {
        msgtitle = AllocRCString( STR_MONITOR_LCL_HEAP );
        RCMessageBox( NULL, STR_CANT_OPEN_LCL_MONITOR, HeapWalkName,
                    MB_OK | MB_TASKMODAL | MB_ICONINFORMATION );
        FreeRCString( msgtitle );
    }
    ShowWindow( hwnd, SW_SHOWNORMAL );
    UpdateWindow( hwnd );
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -