📄 vcmon.c
字号:
sprintf( msgbuf, "%d", CurStats.rephits );
SetDlgItemText( hDlg, IDC_VCREPHIT, msgbuf );
}
// reports misses
if( CurStats.repmisses != LastStats.repmisses || init ) {
sprintf( msgbuf, "%d", CurStats.repmisses );
SetDlgItemText( hDlg, IDC_VCREPMISS, msgbuf );
}
}
//----------------------------------------------------------------------
//
// StatsLoop
//
// Thread routine that sits looping waiting for performance statistics
// that are being passed to us by the VxD.
//
//----------------------------------------------------------------------
VOID StatsLoop( VOID *dummy )
{
int i;
DWORD cbRet;
static initialized = FALSE;
for(;;) {
// wait for event to be signalled
GetOverlappedResult( VxDHandle, &Ovrlp, &cbRet, TRUE);
// get a snapshot of the current stats
CurStats = *Stats_p;
// update the text items
UpdateInfoDialog( hMainDlg, FALSE );
// update graphs
WaitForSingleObject( DrawCrit, INFINITE );
for( i=0; i< NUMGRAPHS; i++ ) {
if( Graph[i].graphstat ) {
switch( i ) {
case SIZEINDEX: {
PlotPoints( &Graph[i],
(double) CurStats.size,
(double) CurStats.free );
break;
}
case HITINDEX: {
PlotPoints( &Graph[i],
(double) (CurStats.hits - LastStats.hits ),
(double) (CurStats.misses - LastStats.misses) );
break;
}
case HOLDINDEX: {
PlotPoints( &Graph[i],
(double) (CurStats.holds - LastStats.holds ), 0 );
break;
}
case NEWINDEX: {
PlotPoints( &Graph[i],
(double) (CurStats.new - LastStats.new), 0 );
break;
}
case PGFLTINDEX: {
PlotPoints( &Graph[i],
(double) (CurStats.pagereads - LastStats.pagereads),
(double) (CurStats.pagewrites - LastStats.pagewrites) );
break;
}
case REPINDEX: {
PlotPoints( &Graph[i],
(double) (CurStats.rephits - LastStats.rephits),
(double) (CurStats.repmisses - LastStats.repmisses) );
break;
}
}
}
}
ReleaseSemaphore( DrawCrit, 1, NULL );
// update last stats
LastStats = CurStats;
}
// end thread implied
}
//----------------------------------------------------------------------
//
// Reset
//
// Resets statistics and has graphs start drawing fresh.
//
//----------------------------------------------------------------------
void Reset( HWND hDlg )
{
HDC hdcMem, hDC;
HBITMAP oldbitmap;
HBRUSH hbrBkGnd;
RECT rc;
int index, j;
// get drawing critical section
WaitForSingleObject( DrawCrit, INFINITE );
// zero the data structure
LastStats.rephits = Stats_p->rephits = 0;
LastStats.repmisses = Stats_p->repmisses = 0;
LastStats.holds = Stats_p->holds = 0;
LastStats.misses = Stats_p->misses = 0;
LastStats.hits = Stats_p->hits = 0;
LastStats.pagereads = Stats_p->pagereads = 0;
LastStats.pagewrites= Stats_p->pagewrites = 0;
LastStats.new = Stats_p->new = 0;
CurStats = LastStats;
// grab device context
hDC = GetDC( hDlg );
// clear the graphs and restart them
for( index = 0; index < NUMGRAPHS; index++ ) {
if( Graph[ index ].graphstat ) {
Graph[index].xval = 0;
// redraw the graph image as cleared
hdcMem = CreateCompatibleDC (hDC) ;
oldbitmap = SelectObject( hdcMem, Graph[index].hgraphbmp ) ;
hbrBkGnd = GRAPHBKGRND;
rc.top = rc.left = 0;
rc.right = Graph[index].graphwidth;
rc.bottom = Graph[index].graphheight;
FillRect( hdcMem, &rc, hbrBkGnd );
DeleteObject(hbrBkGnd);
// draw the graph seperator and set bitmap
if( Graph[index].numplots == 2) {
Graph[index].halfheight[0] = (Graph[index].graphheight - 2)/2 - 1;
Graph[index].halfheight[1] = Graph[index].graphheight -
Graph[index].halfheight[0] - 4;
DrawSeperator( hdcMem, Graph[index].halfheight[0] + 1,
Graph[index].graphwidth );
} else
Graph[index].halfheight[0] = Graph[index].graphheight - 1;
Graph[index].hgraphbmp = SelectObject( hdcMem, oldbitmap );
DeleteDC (hdcMem) ;
for(j=0; j < Graph[index].graphwidth; j++ ) {
Graph[index].yval[0][j] = -1.0;
if( Graph[index].numplots == 2 )
Graph[index].yval[1][j] = -1.0;
}
}
}
ReleaseDC( hDlg, hDC );
UpdateInfoDialog( hDlg, TRUE );
// release critical section
ReleaseSemaphore( DrawCrit, 1, NULL );
}
//----------------------------------------------------------------------
//
// VxDConnect
//
// Initializes connection with the VxD. This includes passing it our
// event handle and obtaining the address of the statistics data structure.
//
//----------------------------------------------------------------------
BOOL VxDConnect( HWND hDlg )
{
DWORD cbRet;
// connect with VxD
VxDHandle = CreateFile( VXD_NAME, 0, 0, NULL,
0, FILE_FLAG_OVERLAPPED|
FILE_FLAG_DELETE_ON_CLOSE,
NULL );
if ( VxDHandle == INVALID_HANDLE_VALUE ) {
wsprintf( msgbuf, "%s is not loaded properly.", VXD_NAME );
Abort( hDlg, msgbuf );
return FALSE;
}
// Create event which will be used by VxD to indicate operation is
// complete
if ( !(Ovrlp.hEvent = CreateEvent( 0, FALSE, 0, NULL )) ) {
wsprintf( msgbuf, "Windows is out of resources." );
Abort( hDlg, msgbuf);
return FALSE;
}
// get the address of the stats structure
if ( ! DeviceIoControl( VxDHandle, VCMON_STATUS,
NULL, 0, &Stats_p, sizeof( &Stats_p ),
&cbRet, &Ovrlp ) ) {
wsprintf( msgbuf, "Can't get %s status.", VXD_NAME );
Abort( hDlg, msgbuf );
return FALSE;
}
// fire-off the statistics handling thread
_beginthread( StatsLoop, 0, NULL );
return TRUE;
}
//----------------------------------------------------------------------
//
// MainDialog
//
// This is the main window. It presents the statistics to the user
// about VCache.
//
//----------------------------------------------------------------------
LONG APIENTRY MainDialog( HWND hDlg, UINT message, UINT wParam,
LONG lParam ) {
static HDC hDC;
static RECT FrameRect;
static HBITMAP hBitmap, hSMBitmap, hBmp;
static HWND hFrame;
switch (message) {
case WM_INITDIALOG :
// get control information
hFrame = GetDlgItem ( hDlg, IDC_FRAME );
GetClientRect( hFrame, &FrameRect );
hBitmap = LoadBitmap( hInst, MAKEINTRESOURCE(IDB_LOGO));
hSMBitmap = LoadBitmap( hInst, MAKEINTRESOURCE(IDB_SMLOGO));
// create a semaphore for multi-threading
DrawCrit = CreateSemaphore( NULL, 1, 1, NULL );
// establish connection with the VxD
if( !VxDConnect( hDlg ))
return TRUE;
// set-up graph data structures and font
hDC = GetDC( hDlg );
InitializeGraphs( hDC );
ReleaseDC( hDlg, hDC );
// center the dialog
centerWindow( hDlg );
// intialize text fields
CurStats = *Stats_p;
UpdateInfoDialog( hDlg, TRUE );
LastStats = CurStats;
break;
case WM_PAINT: {
PAINTSTRUCT Paint;
POINT frametop, windowpt;
// get location where picture will be drawn
windowpt.x = windowpt.y = 0;
frametop.x = frametop.y = 0;
ClientToScreen( hDlg, &windowpt );
ClientToScreen( hFrame, &frametop );
// draws the cool bitmap logo onto the dialog box
hDC = BeginPaint( hDlg, &Paint );
if( FrameRect.bottom < 140 )
hBmp = hSMBitmap;
else
hBmp = hBitmap;
DrawBitmap( hDC, hBmp, (short) (frametop.x - windowpt.x),
(short) (frametop.y - windowpt.y),
FrameRect.right,
FrameRect.bottom, 1 );
EndPaint( hDlg, &Paint );
break;
}
case WM_COMMAND :
switch (LOWORD( wParam )) {
// monitoring graph check boxes
case IDC_GRSIZE:
ToggleGraph( hDlg, IDC_GRSIZE, SIZEINDEX );
break;
case IDC_GRHITS:
ToggleGraph( hDlg, IDC_GRHITS, HITINDEX );
break;
case IDC_GRHOLD:
ToggleGraph( hDlg, IDC_GRHOLD, HOLDINDEX );
break;
case IDC_GRNEW:
ToggleGraph( hDlg, IDC_GRNEW, NEWINDEX );
break;
case IDC_GRPGFLT:
ToggleGraph( hDlg, IDC_GRPGFLT, PGFLTINDEX );
break;
case IDC_GRREP:
ToggleGraph( hDlg, IDC_GRREP, REPINDEX );
break;
case IDRESET:
Reset( hDlg );
break;
case IDOK :
CloseGraphs( hDlg );
EndDialog (hDlg, 0) ;
PostQuitMessage (0) ;
break ;
case IDABOUT:
DialogBox( hInst, "ABOUT", hDlg, AboutDlgProc );
break;
case IDRATE:
DialogBox( hInst, "SLIDER", hDlg, SliderDlgProc );
break;
}
break;
case WM_DESTROY:
DeleteObject( RedPen );
DeleteObject( BluePen );
DeleteObject( BlackPen );
DeleteObject( WhitePen );
DeleteObject( GrayPen );
if( hFont ) DeleteObject( hFont );
break;
case WM_CLOSE:
CloseGraphs( hDlg );
EndDialog (hDlg, 0);
PostQuitMessage( 0 );
break;
}
return DefWindowProc ( hDlg, message, wParam, lParam);
}
//----------------------------------------------------------------------
//
// WinMain
//
// Registers a class. The reason I did this is because the application
// doesn't get cleaned up properly upon exit if winmain just calls
// dialogbox. This was manifested by all the system icons disappearing
// after the program exited. See Petzold's hexcalc example for the base
// of this.
//
//----------------------------------------------------------------------
int CALLBACK WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow )
{
static char szAppName [] = "VCMON" ;
MSG msg ;
WNDCLASSEX wndclass ;
hInst = hInstance;
if (!hPrevInstance) {
// create the main window class
wndclass.cbSize = sizeof( WNDCLASSEX );
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = (WNDPROC) MainDialog ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = DLGWINDOWEXTRA ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (hInstance, "AVCICON") ;
wndclass.hIconSm = LoadIcon (hInstance, "AVCICON");
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) (COLOR_BTNFACE+1);
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
RegisterClassEx (&wndclass) ;
// create the graph window class
wndclass.lpfnWndProc = (WNDPROC) GraphProc ;
wndclass.cbWndExtra = sizeof( graphdata * ) ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon( hInstance, "GRAPHICON" );
wndclass.hIconSm = LoadIcon( hInstance, "GRAPHICON" );
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = NULL;
wndclass.lpszClassName = "Graph" ;
RegisterClassEx( &wndclass ) ;
}
// init common controls
InitCommonControls();
// create the dialog
hMainDlg = CreateDialog( hInstance, "VCMON", NULL, (DLGPROC)MainDialog) ;
ShowWindow( hMainDlg, nCmdShow) ;
while (GetMessage (&msg, NULL, 0, 0)) {
if( !IsDialogMessage( hMainDlg, &msg )) {
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
}
return msg.wParam ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -