vmalloc.c
来自「一本已经绝版的好书」· C语言 代码 · 共 401 行
C
401 行
/************************************************************
Module name: VMAlloc.C
Notices: Copyright (c) 1995-1997 Jeffrey Richter
************************************************************/
#include "..\CmnHdr.H" /* See Appendix C. */
#include <windows.h>
#include <windowsx.h>
#include <tchar.h>
#include <stdio.h> // For sprintf
#include "Resource.H"
/////////////////////////////////////////////////////////////
UINT g_uPageSize = 0;
typedef struct {
BOOL fAllocated;
BYTE bOtherData[2048 - sizeof(BOOL)];
} SOMEDATA, *PSOMEDATA;
#define MAX_SOMEDATA (50)
PSOMEDATA g_pSomeData = NULL;
RECT g_rcMemMap;
/////////////////////////////////////////////////////////////
BOOL Dlg_OnInitDialog (HWND hwnd, HWND hwndFocus,
LPARAM lParam) {
TCHAR szBuf[10];
// Associate an icon with the dialog box.
chSETDLGICONS(hwnd, IDI_VMALLOC, IDI_VMALLOC);
// Initialize the dialog box by disabling all
// the nonsetup controls.
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);
// Get the coordinates of the memory map display.
GetWindowRect(GetDlgItem(hwnd, IDC_MEMMAP), &g_rcMemMap);
MapWindowPoints(NULL, hwnd, (LPPOINT) &g_rcMemMap, 2);
// Destroy the temporary window that identifies the
// location of the memory map display.
DestroyWindow(GetDlgItem(hwnd, IDC_MEMMAP));
// Put the page size in the dialog box just
// for the user's information.
_stprintf(szBuf, __TEXT("%d KB"), g_uPageSize / 1024);
SetDlgItemText(hwnd, IDC_PAGESIZE, szBuf);
// Initialize the edit control.
SetDlgItemInt(hwnd, IDC_INDEX, 0, FALSE);
return(TRUE);
}
/////////////////////////////////////////////////////////////
void Dlg_OnDestroy (HWND hwnd) {
if (g_pSomeData != NULL)
VirtualFree(g_pSomeData, 0, MEM_RELEASE);
}
/////////////////////////////////////////////////////////////
void Dlg_OnCommand (HWND hwnd, int id, HWND hwndCtl,
UINT codeNotify) {
UINT uIndex, uIndexLast, uPage, uMaxPages;
BOOL fTranslated, fOk, fAnyAllocs;
MEMORY_BASIC_INFORMATION MemoryBasicInfo;
switch (id) {
case IDC_RESERVE:
// Reserve enough address space to hold MAX_SOMEDATA
// SOMEDATA structures.
g_pSomeData = (PSOMEDATA) VirtualAlloc(NULL,
MAX_SOMEDATA * sizeof(SOMEDATA), MEM_RESERVE,
PAGE_READWRITE);
// Disable the Reserve button and
// enable all the other controls.
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);
// Force the index edit control to have the focus.
SetFocus(GetDlgItem(hwnd, IDC_INDEX));
// Invalidate the memory map display.
InvalidateRect(hwnd, &g_rcMemMap, FALSE);
break;
case IDC_INDEX:
if (codeNotify != EN_CHANGE)
break;
uIndex = GetDlgItemInt(hwnd, id, &fTranslated,
FALSE);
if ((g_pSomeData == NULL) ||
(uIndex >= MAX_SOMEDATA)) {
// If the index is out of range, assume the
// translation was unsuccessful.
fTranslated = FALSE;
}
if (fTranslated) {
VirtualQuery(&g_pSomeData[uIndex],
&MemoryBasicInfo, sizeof(MemoryBasicInfo));
fOk = (MemoryBasicInfo.State == MEM_COMMIT);
if (fOk)
fOk = g_pSomeData[uIndex].fAllocated;
EnableWindow(GetDlgItem(hwnd, IDC_USE), !fOk);
EnableWindow(GetDlgItem(hwnd, IDC_CLEAR), fOk);
ScrollBar_SetPos(GetDlgItem(hwnd, IDC_INDEXSCRL),
uIndex, TRUE);
} else {
EnableWindow(GetDlgItem(hwnd, IDC_USE), FALSE);
EnableWindow(GetDlgItem(hwnd, IDC_CLEAR), FALSE);
}
break;
case IDC_USE:
uIndex = GetDlgItemInt(hwnd, IDC_INDEX, &fTranslated,
FALSE);
if (uIndex >= MAX_SOMEDATA) {
// If the index is out of range, assume the
// translation was unsuccessful.
fTranslated = FALSE;
}
if (fTranslated) {
VirtualAlloc(&g_pSomeData[uIndex],
sizeof(SOMEDATA), MEM_COMMIT, PAGE_READWRITE);
// When pages are committed, Windows NT ensures
// that they are zeroed.
g_pSomeData[uIndex].fAllocated = TRUE;
EnableWindow(GetDlgItem(hwnd, IDC_USE), FALSE);
EnableWindow(GetDlgItem(hwnd, IDC_CLEAR), TRUE);
// Force the Clear button control to
// have the focus.
SetFocus(GetDlgItem(hwnd, IDC_CLEAR));
// Invalidate the memory map display.
InvalidateRect(hwnd, &g_rcMemMap, FALSE);
}
break;
case IDC_CLEAR:
uIndex = GetDlgItemInt(hwnd, IDC_INDEX, &fTranslated,
FALSE);
if (uIndex >= MAX_SOMEDATA) {
// If the index is out of range, assume the
// translation was unsuccessful.
fTranslated = FALSE;
}
if (fTranslated) {
g_pSomeData[uIndex].fAllocated = FALSE;
EnableWindow(GetDlgItem(hwnd, IDC_USE), TRUE);
EnableWindow(GetDlgItem(hwnd, IDC_CLEAR), FALSE);
// Force the Use button control to have the focus.
SetFocus(GetDlgItem(hwnd, IDC_USE));
}
break;
case IDC_GARBAGECOLLECT:
uMaxPages = MAX_SOMEDATA * sizeof(SOMEDATA) /
g_uPageSize;
for (uPage = 0; uPage < uMaxPages; uPage++) {
fAnyAllocs = FALSE;
uIndex = uPage * g_uPageSize / sizeof(SOMEDATA);
uIndexLast = uIndex + g_uPageSize /
sizeof(SOMEDATA);
for (; uIndex < uIndexLast; uIndex++) {
VirtualQuery(&g_pSomeData[uIndex],
&MemoryBasicInfo, sizeof(MemoryBasicInfo));
if ((MemoryBasicInfo.State == MEM_COMMIT) &&
g_pSomeData[uIndex].fAllocated) {
fAnyAllocs = TRUE;
break;
}
}
if (!fAnyAllocs) {
// No allocated structures exist in the page.
// We can safely decommit it.
VirtualFree(&g_pSomeData[uIndexLast - 1],
sizeof(SOMEDATA), MEM_DECOMMIT);
}
}
// Invalidate the memory map display.
InvalidateRect(hwnd, &g_rcMemMap, FALSE);
break;
case IDCANCEL:
EndDialog(hwnd, id);
break;
}
}
/////////////////////////////////////////////////////////////
void Dlg_OnHScroll (HWND hwnd, HWND hwndCtl,
UINT code, int pos) {
INT nScrlPos;
if (hwndCtl != GetDlgItem(hwnd, IDC_INDEXSCRL))
return;
nScrlPos = ScrollBar_GetPos(hwndCtl);
switch (code) {
case SB_LINELEFT:
nScrlPos--;
break;
case SB_LINERIGHT:
nScrlPos++;
break;
case SB_PAGELEFT:
nScrlPos -= g_uPageSize / sizeof(SOMEDATA);
break;
case SB_PAGERIGHT:
nScrlPos += g_uPageSize / sizeof(SOMEDATA);
break;
case SB_THUMBTRACK:
nScrlPos = pos;
break;
case SB_LEFT:
nScrlPos = 0;
break;
case SB_RIGHT:
nScrlPos = MAX_SOMEDATA - 1;
break;
}
if (nScrlPos < 0)
nScrlPos = 0;
if (nScrlPos >= MAX_SOMEDATA)
nScrlPos = MAX_SOMEDATA - 1;
ScrollBar_SetPos(hwndCtl, nScrlPos, TRUE);
SetDlgItemInt(hwnd, IDC_INDEX, nScrlPos, TRUE);
}
/////////////////////////////////////////////////////////////
void Dlg_OnPaint (HWND hwnd) {
UINT uPage, uIndex, uIndexLast, uMemMapWidth;
UINT uMaxPages = MAX_SOMEDATA * sizeof(SOMEDATA) /
g_uPageSize;
MEMORY_BASIC_INFORMATION MemoryBasicInfo;
PAINTSTRUCT ps;
BeginPaint(hwnd, &ps);
if (g_pSomeData == NULL) {
// The memory has yet to be reserved.
Rectangle(ps.hdc, g_rcMemMap.left, g_rcMemMap.top,
g_rcMemMap.right, g_rcMemMap.bottom);
}
// Walk the virtual address space, adding
// entries to the list box.
uPage = 0;
while ((g_pSomeData != NULL) && uPage < uMaxPages) {
uIndex = uPage * g_uPageSize / sizeof(SOMEDATA);
uIndexLast = uIndex + g_uPageSize / sizeof(SOMEDATA);
for (; uIndex < uIndexLast; uIndex++) {
VirtualQuery(&g_pSomeData[uIndex], &MemoryBasicInfo,
sizeof(MemoryBasicInfo));
switch (MemoryBasicInfo.State) {
case MEM_FREE:
SelectObject(ps.hdc,
GetStockObject(WHITE_BRUSH));
break;
case MEM_RESERVE:
SelectObject(ps.hdc,
GetStockObject(GRAY_BRUSH));
break;
case MEM_COMMIT:
SelectObject(ps.hdc,
GetStockObject(BLACK_BRUSH));
break;
}
uMemMapWidth = g_rcMemMap.right - g_rcMemMap.left;
Rectangle(ps.hdc,
g_rcMemMap.left +
uMemMapWidth / uMaxPages * uPage,
g_rcMemMap.top,
g_rcMemMap.left +
uMemMapWidth / uMaxPages * (uPage + 1),
g_rcMemMap.bottom);
}
uPage++;
}
EndPaint(hwnd, &ps);
}
/////////////////////////////////////////////////////////////
BOOL CALLBACK Dlg_Proc (HWND hwnd, UINT uMsg,
WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
chHANDLE_DLGMSG(hwnd, WM_INITDIALOG, Dlg_OnInitDialog);
chHANDLE_DLGMSG(hwnd, WM_COMMAND, Dlg_OnCommand);
chHANDLE_DLGMSG(hwnd, WM_HSCROLL, Dlg_OnHScroll);
chHANDLE_DLGMSG(hwnd, WM_PAINT, Dlg_OnPaint);
chHANDLE_DLGMSG(hwnd, WM_DESTROY, Dlg_OnDestroy);
}
return(FALSE);
}
/////////////////////////////////////////////////////////////
int WINAPI _tWinMain (HINSTANCE hinstExe,
HINSTANCE hinstPrev, LPTSTR pszCmdLine, int nCmdShow) {
SYSTEM_INFO SystemInfo;
chWARNIFUNICODEUNDERWIN95();
// Get the page size used on this CPU.
GetSystemInfo(&SystemInfo);
g_uPageSize = SystemInfo.dwPageSize;
DialogBox(hinstExe, MAKEINTRESOURCE(IDD_VMALLOC),
NULL, Dlg_Proc);
return(0);
}
/////////////////////// End Of File ///////////////////////
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?