vmalloc.dpr

来自「一本已经绝版的好书」· DPR 代码 · 共 317 行

DPR
317
字号

// Module name: VMAlloc.C ->> VMAlloc.dpr
// Notices: Copyright (c) 1995-1997 Jeffrey Richter
// Translator: 刘麻子, Liu_mazi@126.com

program VMAlloc;

{$R 'VMAlloc.res' 'VMAlloc.rc'}

uses
  Windows, Messages,
  Other in '..\Other.pas', CmnHdr in '..\CmnHdr.pas', WindowsX in '..\WindowsX.pas';

const
  IDD_VMALLOC        =  1;
  IDC_PAGESIZE       =  100;
  IDC_RESERVE        =  101;
  IDI_VMALLOC        =  101;
  IDC_INDEXTEXT      =  102;
  IDC_INDEX          =  103;
  IDC_INDEXSCRL      =  104;
  IDC_USE            =  105;
  IDC_CLEAR          =  106;
  IDC_GARBAGECOLLECT =  107;
  IDC_MEMMAP         =  108;

type
  PSomeData = ^TSomeData;
  TSomeData = packed record
    fAllocated: BOOL;
    bOtherData: array[1..2048-SizeOf(BOOL)] of Byte;
  end;

type
  PDataArray = ^TDataArray;
  TDataArray = array[0..0] of TSomeData;

const
  MAX_SOMEDATA = 50;

var
  g_uPageSize: UINT = 0;
  g_pSomeData: PDataArray = nil;
  g_rcMemMap: TRect;

  // WM_INITDIALOG
function Dlg_OnInitDialog(hWnd, hWndFocus: HWND; lParam: LPARAM): BOOL;
var
  szBuf: array[0..10] of Char;
begin
  chSETDLGICONS(hWnd, IDI_VMALLOC, IDI_VMALLOC);

  EnableWindow(GetDlgItem(hWnd, IDC_INDEXTEXT), FALSE);
  EnableWindow(GetDlgItem(hWnd, IDC_INDEX), FALSE);
  ScrollBar_SetRange(GetDlgItem(hWnd, IDC_INDEXSCRL), 0, MAX_SOMEDATA - 1, FALSE);
  ScrollBar_SetPos(GetDlgItem(hWnd, IDC_INDEXSCRL), 0,TRUE);
  EnableWindow(GetDlgItem(hWnd, IDC_INDEXSCRL), FALSE);
  EnableWindow(GetDlgItem(hWnd, IDC_USE), FALSE);
  EnableWindow(GetDlgItem(hWnd, IDC_CLEAR), FALSE);
  EnableWindow(GetDlgItem(hWnd, IDC_GARBAGECOLLECT), FALSE);

  GetWindowRect(GetDlgItem(hWnd, IDC_MEMMAP), g_rcMemMap);
  MapWindowPoints(0, hWnd, g_rcMemMap, 2);
  DestroyWindow(GetDlgItem(hWnd, IDC_MEMMAP));

  SetDlgItemInt(hWnd, IDC_INDEX, 0, FALSE);

  _wvsprintf(szBuf, '%d KB', [ g_uPageSize shr 10 ]);
  SetDlgItemText(hWnd, IDC_PAGESIZE, szBuf);

  Result := TRUE;
end;

  // WM_DESTROY
procedure Dlg_OnDestroy(hWnd: HWND);
begin
  if (g_pSomeData <> nil) then VirtualFree(g_pSomeData, 0, MEM_RELEASE);
end;

  // WM_COMMAND
procedure Dlg_OnCommand(hWnd: HWND; id: Integer; hWndCtl: HWND; codeNotify: UINT);
var
  uIndex, uIndexLast, uPage, uMaxPages: UINT;
  fTranslated, fOk, fAnyAllocs: BOOL;
  MemoryBasicInfo: TMemoryBasicInformation;
begin
  case (id) of
    IDC_RESERVE: // 保留
      begin
        g_pSomeData := VirtualAlloc(nil, MAX_SOMEDATA * SizeOf(TSomeData), MEM_RESERVE, PAGE_READWRITE);

        EnableWindow(GetDlgItem(hWnd, IDC_RESERVE), FALSE);
        EnableWindow(GetDlgItem(hWnd, IDC_INDEXTEXT), TRUE);
        EnableWindow(GetDlgItem(hWnd, IDC_INDEX), TRUE);
        EnableWindow(GetDlgItem(hWnd, IDC_INDEXSCRL), TRUE);
        EnableWindow(GetDlgItem(hWnd, IDC_USE), TRUE);
        EnableWindow(GetDlgItem(hWnd, IDC_GARBAGECOLLECT), TRUE);
        SetFocus(GetDlgItem(hWnd, IDC_INDEX));

        InvalidateRect(hWnd, @g_rcMemMap, TRUE);
      end;

    IDC_INDEX: // 下标
      begin
        if (codeNotify <> EN_CHANGE) then Exit;

        uIndex := GetDlgItemInt(hWnd, id, fTranslated, FALSE);
        if (g_pSomeData = nil) or (uIndex >= MAX_SOMEDATA) then fTranslated := FALSE;

        if (fTranslated) then
        begin
          VirtualQuery(@g_pSomeData[uIndex], MemoryBasicInfo, SizeOf(MemoryBasicInfo));
          fOk := (MemoryBasicInfo.State = MEM_COMMIT);
          if (fOk) then fOk := g_pSomeData[uIndex].fAllocated;

          EnableWindow(GetDlgItem(hWnd, IDC_USE), not fOk);
          EnableWindow(GetDlgItem(hWnd, IDC_CLEAR), fOk);
          ScrollBar_SetPos(GetDlgItem(hWnd, IDC_INDEXSCRL), uIndex, TRUE);
        end else
        begin
          EnableWindow(GetDlgItem(hWnd, IDC_USE), FALSE);
          EnableWindow(GetDlgItem(hWnd, IDC_CLEAR), FALSE);
        end;
      end;

    IDC_USE: // 占用
      begin
        uIndex := GetDlgItemInt(hWnd, IDC_INDEX, fTranslated, FALSE);
        if (uIndex >= MAX_SOMEDATA) then fTranslated := FALSE;

        if (fTranslated) then
        begin
          VirtualAlloc(@g_pSomeData[uIndex], SizeOf(TSomeData), MEM_COMMIT, PAGE_READWRITE);
          g_pSomeData[uIndex].fAllocated := TRUE;

          EnableWindow(GetDlgItem(hWnd, IDC_USE), FALSE);
          EnableWindow(GetDlgItem(hWnd, IDC_CLEAR), TRUE);
          SetFocus(GetDlgItem(hWnd, IDC_CLEAR));

          InvalidateRect(hWnd, @g_rcMemMap, FALSE);
        end;
      end;

    IDC_CLEAR: // 丢弃
      begin
        uIndex := GetDlgItemInt(hWnd, IDC_INDEX, fTranslated, FALSE);
        if (uIndex >= MAX_SOMEDATA) then fTranslated := FALSE;

        if (fTranslated) then
        begin
          g_pSomeData[uIndex].fAllocated := FALSE;

          EnableWindow(GetDlgItem(hWnd, IDC_USE), TRUE);
          EnableWindow(GetDlgItem(hWnd, IDC_CLEAR), FALSE);
          
          SetFocus(GetDlgItem(hWnd, IDC_USE));
        end;
      end;

    IDC_GARBAGECOLLECT: // 回收
      begin
        uMaxPages := MAX_SOMEDATA * SizeOf(TSomeData) div g_uPageSize;
        for uPage := 0 to uMaxPages - 1 do
        begin
          fAnyAllocs := FALSE; // 均未占用
          
          uIndex := uPage * g_uPageSize div SizeOf(TSomeData);
          uIndexLast := uIndex + g_uPageSize div SizeOf(TSomeData);

          while (uIndex < uIndexLast) do
          begin
            VirtualQuery(@g_pSomeData[uIndex], MemoryBasicInfo, SizeOf(MemoryBasicInfo));
            if (MemoryBasicInfo.State = MEM_COMMIT) and (g_pSomeData[uIndex].fAllocated) then
            begin
              fAnyAllocs := TRUE;
              Break;
            end;
                    
            Inc(uIndex);
          end;

          if (fAnyAllocs = FALSE) then
            VirtualFree(@g_pSomeData[uIndexLast - 1], SizeOf(TSomeData), MEM_DECOMMIT);
        end;

        InvalidateRect(hWnd, @g_rcMemMap, FALSE);
      end;

    IDCANCEL: // 关闭
      begin
        EndDialog(hWnd, id);
      end;
   end;
end;

  // WM_HSCROLL
procedure Dlg_OnHScroll(hWnd, hWndCtl: HWND; code: UINT; nPos: Integer);
var
  nScrlPos: Integer;
begin
  if (GetDlgItem(hWnd, IDC_INDEXSCRL) <> hWndCtl) then Exit;

  nScrlPos := ScrollBar_GetPos(hWndCtl);
  case (code) of
    SB_LINELEFT  : Dec(nScrlPos);
    SB_LINERIGHT : Inc(nScrlPos);
    SB_PAGELEFT  : Dec(nScrlPos, g_uPageSize div SizeOf(TSomeData));
    SB_PAGERIGHT : Inc(nScrlPos, g_uPageSize div SizeOf(TSomeData));
    SB_THUMBTRACK: nScrlPos := nPos;
    SB_LEFT      : nScrlPos := 0;
    SB_RIGHT     : nScrlPos := MAX_SOMEDATA - 1;
  end;

  if (nScrlPos < 0) then
    nScrlPos := 0
  else
    if (nScrlPos >= MAX_SOMEDATA) then
      nScrlPos := MAX_SOMEDATA - 1;

  ScrollBar_SetPos(hWndCtl, nScrlPos, TRUE);
  SetDlgItemInt(hWnd, IDC_INDEX, nScrlPos, TRUE);
end;

  // WM_PAINT
procedure Dlg_OnPaint(hWnd: HWND);
var
  uPage, uIndex, uIndexLast, uMemMapWidth, uMaxPages: UINT;
  MemoryBasicInfo: TMemoryBasicInformation;
  ps: TPaintStruct;
begin
  uMaxPages := MAX_SOMEDATA * SizeOf(TSomeData) div g_uPageSize;

  BeginPaint(hWnd, ps);

  if (g_pSomeData = nil) then
  begin
    Rectangle(ps.hdc, g_rcMemMap.Left, g_rcMemMap.Top, g_rcMemMap.Right, g_rcMemMap.Bottom);
  end else
  begin
    for uPage := 0 to uMaxPages - 1 do
    begin
      uIndex := uPage * g_uPageSize div SizeOf(TSomeData);
      uIndexLast := uIndex + g_uPageSize div SizeOf(TSomeData);

      while (uIndex < uIndexLast) do
      begin
        VirtualQuery(@g_pSomeData[uIndex], MemoryBasicInfo, SizeOf(MemoryBasicInfo));
        case (MemoryBasicInfo.State) of
          MEM_FREE:    SelectObject(ps.hdc, GetStockObject(WHITE_BRUSH));
          MEM_RESERVE: SelectObject(ps.hdc, GetStockObject(GRAY_BRUSH));
          MEM_COMMIT:  SelectObject(ps.hdc, GetStockObject(BLACK_BRUSH));
        end;

        uMemMapWidth := g_rcMemMap.Right - g_rcMemMap.Left;
        Rectangle(ps.hdc,
          g_rcMemMap.Left + Integer(uMemMapWidth div uMaxPages * uPage),
          g_rcMemMap.Top,
          g_rcMemMap.Left + Integer(uMemMapWidth div uMaxPages * (uPage + 1)),
          g_rcMemMap.Bottom);
              
        Inc(uIndex);
      end;
    end; // END: for .. 
  end;

  EndPaint(hWnd, ps);
end;

  // 对话回调
function Dlg_Proc(hWnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): BOOL; stdcall;
begin
  case (uMsg) of
    WM_INITDIALOG:
      begin
        Result := SetDlgMsgResult(hWnd, LRESULT(Dlg_OnInitDialog(hWnd, wParam, lParam)));
      end;

    WM_COMMAND:
      begin
        Dlg_OnCommand(hWnd, LOWORD(wParam), lParam, HIWORD(wParam));
        Result := TRUE;
      end;

    WM_HSCROLL:
      begin
        Dlg_OnHScroll(hWnd, lParam, LOWORD(wParam), HIWORD(wParam));
        Result := TRUE;
      end;

    WM_PAINT:
      begin
        Dlg_OnPaint(hWnd);
        Result := TRUE;
      end;

    WM_DESTROY:
      begin
        Dlg_OnDestroy(hWnd);
        Result := TRUE;
      end;

    else Result := FALSE;  
  end;
end;

  // 程序入口
var
  SystemInfo: TSystemInfo;
begin
  chWARNIFUNICODEUNDERWIN95();

  GetSystemInfo(SystemInfo);
  g_uPageSize := SystemInfo.dwPageSize;

  DialogBox(HInstance, MakeIntResource(IDD_VMALLOC), 0, @Dlg_Proc);
end.

⌨️ 快捷键说明

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