home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
magazine
/
pcmagazi
/
1992
/
15
/
sysmon.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-06-20
|
31KB
|
837 lines
// SysMon - System Monitor for Windows 3.1
// Copyright (C) 1992 Ray Duncan
// PC Magazine * Ziff Davis Publishing
#define dim(x) (sizeof(x) / sizeof(x[0])) // returns no. of elements
#define MAXLINES 4096 // max lines to display
#include "stdlib.h"
#include "windows.h"
#include "toolhelp.h"
#include "dos.h"
#include "sysmon.h"
HANDLE hInst; // module instance handle
HWND hFrame; // handle for frame window
HFONT hFont; // handle for nonprop. font
int CharX, CharY; // character dimensions
int LinesPerPage; // lines per page
int CurLine = 0; // first line, current page
int TotLines = 0; // total lines to display
int TopLine = 0; // first line of last page
int DisplayType = IDM_MODULE; // type of info to display
char *LinePtr[MAXLINES]; // holds pointers to lines
char szFrameClass[] = "SysMon"; // classname for frame window
char szAppName[] = "System Monitor"; // long application name
char szMenuName[] = "SysMonMenu"; // name of menu resource
char szIcon[] = "SysMonIcon"; // name of icon resource
char szIni[] = "sysmon.ini"; // name of private INI file
WNDPROC lpTimerProc; // timer callback thunk
//
// Table of window messages supported by FrameWndProc()
// and the functions which correspond to each message.
//
struct decodeMsg frameMsgs[] = {
WM_PAINT, DoPaint,
WM_SIZE, DoSize,
WM_COMMAND, DoCommand,
WM_SETFOCUS, DoSetFocus,
WM_CLOSE, DoClose,
WM_DESTROY, DoDestroy,
WM_VSCROLL, DoVScroll, } ;
//
// Table of menubar item IDs and their corresponding functions.
//
struct decodeMsg menuitems[] = {
IDM_EXIT, DoMenuExit,
IDM_ABOUT, DoMenuAbout,
IDM_MODULE, DoDisplayType,
IDM_CLASS, DoDisplayType,
IDM_TASK, DoDisplayType,
IDM_GLOBHEAP, DoDisplayType,
IDM_SYSHEAP, DoDisplayType,
IDM_MEMMAN, DoDisplayType,
IDM_DISK, DoDisplayType,
IDM_REFRESH, DoRefresh, } ;
//
// Table of memory block types and descriptive strings
//
struct decodeUINT memType[] = {
GT_UNKNOWN, "Unknown",
GT_DGROUP, "DGROUP",
GT_DATA, "Program Data",
GT_CODE, "Program Code",
GT_TASK, "Task Database",
GT_RESOURCE, "Resource",
GT_MODULE, "Module Database",
GT_FREE, "Available",
GT_INTERNAL, "Internal",
GT_SENTINEL, "Sentinel",
GT_BURGERMASTER, "Arena Map", } ;
//
// WinMain -- entry point for this application from Windows.
//
int APIENTRY WinMain(HANDLE hInstance,
HANDLE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg; // scratch message storage
hInst = hInstance; // save this instance handle
if(!hPrevInstance) // if first instance,
if(!InitApp(hInstance)) // register window class
{
MessageBox(hFrame, "Can't initialize SysMon!", szAppName,
MB_ICONSTOP | MB_OK);
return(FALSE);
}
if(!InitInstance(hInstance, nCmdShow)) // create this instance's window
{
MessageBox(hFrame, "Can't initialize SysMon!", szAppName,
MB_ICONSTOP | MB_OK);
return(FALSE);
}
while(GetMessage(&msg, NULL, 0, 0)) // while message != WM_QUIT
{
TranslateMessage(&msg); // translate virtual key codes
DispatchMessage(&msg); // dispatch message to window
}
TermInstance(hInstance); // clean up for this instance
return(msg.wParam); // return code = WM_QUIT value
}
//
// InitApp --- global initialization code for this application.
//
BOOL InitApp(HANDLE hInstance)
{
WNDCLASS wc; // window class info
// set parameters for frame window class
wc.style = CS_HREDRAW|CS_VREDRAW; // class style
wc.lpfnWndProc = FrameWndProc; // class callback function
wc.cbClsExtra = 0; // extra per-class data
wc.cbWndExtra = 0; // extra per-window data
wc.hInstance = hInstance; // handle of class owner
wc.hIcon = LoadIcon(hInst, szIcon); // application icon
wc.hCursor = LoadCursor(NULL, IDC_ARROW); // default cursor
wc.hbrBackground = GetStockObject(WHITE_BRUSH); // background color
wc.lpszMenuName = szMenuName; // name of menu resource
wc.lpszClassName = szFrameClass; // name of window class
return(RegisterClass(&wc)); // register frame window class
}
//
// InitInstance --- instance initialization code for this application.
//
BOOL InitInstance(HANDLE hInstance, int nCmdShow)
{
HDC hdc; // handle for device context
TEXTMETRIC tm; // info about font
RECT rect; // window position & size
int i; // scratch variable
for(i = 0; i < MAXLINES; i++) // initialize all line
LinePtr[i] = NULL; // pointers
hFrame = CreateWindow( // create frame window
szFrameClass, // window class name
szAppName, // text for title bar
WS_OVERLAPPEDWINDOW | WS_VSCROLL, // window style
CW_USEDEFAULT, CW_USEDEFAULT, // default position
CW_USEDEFAULT, CW_USEDEFAULT, // default size
NULL, // no parent window
NULL, // use class default menu
hInstance, // window owner
NULL); // unused pointer
if(!hFrame) return(FALSE); // error, can't create window
hdc = GetDC(hFrame); // get device context
hFont = GetStockObject(SYSTEM_FIXED_FONT); // handle for nonprop. font
SelectObject(hdc, hFont); // realize the font and get
GetTextMetrics(hdc, &tm); // the character dimensions
CharX = tm.tmAveCharWidth;
CharY = tm.tmHeight + tm.tmExternalLeading;
ReleaseDC(hFrame, hdc); // release device context
GetWindowRect(hFrame, &rect); // current window pos & size
// read profile for frame window from previous invocation, if any
rect.left = GetPrivateProfileInt("Frame", "xul", rect.left, szIni);
rect.top = GetPrivateProfileInt("Frame", "yul", rect.top, szIni);
rect.right = GetPrivateProfileInt("Frame", "xlr", rect.right, szIni);
rect.bottom = GetPrivateProfileInt("Frame", "ylr", rect.bottom, szIni);
MoveWindow(hFrame, rect.left, rect.top, // force window size & position
rect.right-rect.left, rect.bottom-rect.top, TRUE);
// get display type from previous invocation, default to module list
DisplayType = GetPrivateProfileInt("Frame", "type", IDM_MODULE, szIni);
ShowWindow(hFrame, nCmdShow); // make frame window visible
UpdateWindow(hFrame); // force WM_PAINT message
// allocate thunk for timer callback routine
lpTimerProc = MakeProcInstance((WNDPROC) TimerProc, hInst);
// set up our 10 sec. (10,000 msec) timer callback
if (!SetTimer(hFrame, 1, 10000, lpTimerProc))
return(FALSE);
return(TRUE); // return success flag
}
//
// TermInstance -- instance termination code for this application.
// Does nothing in this case, included for symmetry with InitInstance.
//
BOOL TermInstance(HANDLE hinstance)
{
return(TRUE); // return success flag
}
//
// FrameWndProc --- callback function for application frame window.
// Searches frameMsgs[] for message match, runs corresponding function.
//
LONG FAR APIENTRY FrameWndProc(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam)
{
int i; // scratch variable
for(i = 0; i < dim(frameMsgs); i++) // decode window message and
{ // run corresponding function
if(wMsg == frameMsgs[i].Code)
return((*frameMsgs[i].Fxn)(hWnd, wMsg, wParam, lParam));
}
return(DefWindowProc(hWnd, wMsg, wParam, lParam));
}
//
// DoCommand -- process WM_COMMAND message for frame window by
// decoding the menubar item with the menuitems[] array, then
// running the corresponding function to process the command.
//
LONG DoCommand(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam)
{
int i; // scratch variable
for(i = 0; i < dim(menuitems); i++) // decode menu command and
{ // run corresponding function
if(wParam == menuitems[i].Code)
return((*menuitems[i].Fxn)(hWnd, wMsg, wParam, lParam));
}
return(DefWindowProc(hWnd, wMsg, wParam, lParam));
}
//
// DoDestroy -- process WM_DESTROY message for frame window.
//
LONG DoDestroy(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam)
{
PostQuitMessage(0); // force WM_QUIT message to
return(0); // terminate the event loop
}
//
// DoClose -- process WM_CLOSE message for frame window.
//
LONG DoClose(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam)
{
UpdateProfile(); // save window size & position
DestroyWindow(hWnd); // then close down app
return(FALSE);
}
//
// DoVScroll -- process WM_VSCROLL message for frame window.
//
LONG DoVScroll(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam)
{
RECT rect;
switch(LOWORD(wParam)) // LOWORD vital for Win32
{
case SB_TOP: // go to top of output if
if(CurLine) // we aren't there already
{
SetCurLine(0);
Repaint();
}
break;
case SB_BOTTOM: // go to bottom of output if
if(CurLine < TopLine) // we aren't there already
{
SetCurLine(TopLine);
Repaint();
}
break;
case SB_LINEUP: // scroll up by one line if
if(CurLine) // we aren't already at top
{
SetCurLine(CurLine - 1);
ScrollWindow(hWnd, 0, CharY, NULL, NULL);
UpdateWindow(hWnd);
}
break;
case SB_LINEDOWN: // scroll down by one line if
if(CurLine < TopLine) // we aren't already at bottom
{
SetCurLine(CurLine + 1);
ScrollWindow(hWnd, 0, -CharY, NULL, NULL);
GetClientRect(hWnd, &rect);
rect.top = max(0, (LinesPerPage-1) * CharY);
InvalidateRect(hWnd, &rect, TRUE);
UpdateWindow(hWnd);
}
break;
case SB_PAGEUP: // scroll up by one page
SetCurLine(CurLine - LinesPerPage);
Repaint();
break;
case SB_PAGEDOWN: // scroll down by one page
SetCurLine(CurLine + LinesPerPage);
Repaint();
break;
case SB_THUMBPOSITION: // scroll display according
SetCurLine(THUMBPOS); // to new thumb position
Repaint();
break;
}
return(FALSE);
}
//
// DoPaint -- process WM_PAINT message for frame window.
//
LONG DoPaint(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam)
{
HDC hdc;
PAINTSTRUCT ps;
int i;
hdc = BeginPaint(hWnd, &ps); // get device context
SelectObject(hdc, hFont); // select non-prop. font
for(i = 0; i < LinesPerPage; i++) // paint lines of text
PaintLine(hdc, i); // in the window
EndPaint(hWnd, &ps); // release device context
return(FALSE);
}
//
// DoSize -- process WM_SIZE message for frame window. Recalculate
// lines per page, if window has grown and at end of file may need to
// change first line in window and refresh it.
//
LONG DoSize(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam)
{
LinesPerPage = HIWORD(lParam) / CharY; // window height / char height
ConfigWindow(); // calc display parameters
if(CurLine > TopLine) // make sure window refilled
SetCurLine(TopLine); // if window got bigger
return(FALSE);
}
//
// DoSetFocus -- process WM_SETFOCUS message for frame window.
// Refresh display in case something has changed since last timer event.
// This also gets called when app is launched after window is created.
//
LONG DoSetFocus(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam)
{
SendMessage(hFrame, WM_COMMAND, IDM_REFRESH, 0);
return(FALSE);
}
//
// DoMenuExit -- process File-Exit command from menu bar.
//
LONG DoMenuExit(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam)
{
SendMessage (hWnd, WM_CLOSE, 0, 0L); // send window close message
return(FALSE); // to shut down the app
}
//
// DoDisplayType -- process items on Display popup to select
// the type of information to display, then force window update
//
LONG DoDisplayType(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam)
{
HMENU hMenu; // scratch menu handle
hMenu = GetMenu(hWnd); // update popup checkmark
CheckMenuItem(hMenu, DisplayType, MF_UNCHECKED);
DisplayType = wParam;
CheckMenuItem(hMenu, DisplayType, MF_CHECKED);
SendMessage(hWnd, WM_COMMAND, IDM_REFRESH, 0); // update window
return(FALSE);
}
//
// DoRefresh -- rebuild the information for display according to
// the currently selected display type, then refresh the window.
//
LONG DoRefresh(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam)
{
EmptyLines(); // discard previous output
switch(DisplayType) // call the appropriate
{ // list walking routine
case IDM_MODULE: // according to display type
WalkModuleList();
SetWindowCaption("Modules");
break;
case IDM_CLASS:
WalkClassList();
SetWindowCaption("Window Classes");
break;
case IDM_TASK:
WalkTaskList();
SetWindowCaption("Active Tasks");
break;
case IDM_GLOBHEAP:
WalkGlobalHeap();
SetWindowCaption("Global Heap");
break;
case IDM_SYSHEAP:
ShowSystemHeap();
SetWindowCaption("System Heap");
break;
case IDM_MEMMAN:
ShowMemManInfo();
SetWindowCaption("Memory Available");
break;
case IDM_DISK:
ShowDiskSpace();
SetWindowCaption("Disk Space Available");
break;
}
ConfigWindow(); // configure scroll bar etc.
Repaint(); // refresh the window
return(FALSE);
}
//
// DoMenuAbout -- process File-About command from menu bar.
//
LONG DoMenuAbout(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam)
{
WNDPROC lpAboutProc; // scratch far pointer
// allocate a thunk for the dialog callback, then display dialog
lpAboutProc = MakeProcInstance((WNDPROC)AboutDlgProc, hInst);
DialogBox(hInst, "AboutBox", hWnd, lpAboutProc);
FreeProcInstance(lpAboutProc);
return(FALSE);
}
//
// AboutDlgProc -- callback routine for About... dialog. Basically
// ignores all messages except for the OK button, which dismisses dialog.
//
BOOL FAR APIENTRY AboutDlgProc (HWND hwnd, UINT msg, UINT wParam, LONG lParam)
{
if((msg == WM_COMMAND) && (wParam == IDOK))
EndDialog(hwnd, 0); // if OK button, destroy dialog
else return(FALSE); // otherwise ignore message
}
//
// WalkModuleList -- uses ToolHelp functions to walk through
// module list and build formatted output in LinePtr[] array.
//
VOID WalkModuleList(VOID)
{
MODULEENTRY me; // receives module info
char temp[256]; // scratch formatting buffer
memset(&me, 0, sizeof(MODULEENTRY)); // initialize structure for
me.dwSize = sizeof(MODULEENTRY); // return of module data
AddLine("Handle Usage Module Pathname"); // format title
ModuleFirst(&me); // initialize to 1st module
do { // format module information
wsprintf(temp, "%04Xh %4d %-8.8s %s", me.hModule, me.wcUsage,
(LPSTR) me.szModule, (LPSTR) me.szExePath);
AddLine(temp); // add to array for output
} while(ModuleNext(&me)); // get next module name
}
//
// WalkClassList -- uses ToolHelp functions to walk through
// window class list and build formatted output in LinePtr[] array.
//
VOID WalkClassList(VOID)
{
CLASSENTRY ce; // receives window class info
MODULEENTRY me; // receives module info
char temp[256]; // scratch formatting buffer
memset(&ce, 0, sizeof(CLASSENTRY)); // initialize structure for
ce.dwSize = sizeof(CLASSENTRY); // return of window class data
memset(&me, 0, sizeof(MODULEENTRY)); // initialize structure for
me.dwSize = sizeof(MODULEENTRY); // return of module data
AddLine("Class Name Owner Module"); // format title
ClassFirst(&ce); // initialize to 1st class
do { // format classname & owner
ModuleFindHandle(&me, ce.hInst); // get module name
wsprintf(temp, "%-16.16s %04Xh %s", (LPSTR) ce.szClassName,
ce.hInst, (LPSTR) me.szModule);
AddLine(temp); // add to array for output
} while(ClassNext(&ce)); // get next class name
}
//
// WalkTaskList -- uses ToolHelp functions to walk through
// task list and build formatted output in LinePtr[] array.
//
VOID WalkTaskList(VOID)
{
TASKENTRY te; // receives task info
MODULEENTRY me; // receives module info
char temp[256]; // scratch formatting buffer
memset(&te, 0, sizeof(TASKENTRY)); // initialize structure for
te.dwSize = sizeof(TASKENTRY); // return of task info
memset(&me, 0, sizeof(MODULEENTRY)); // initialize structure for
me.dwSize = sizeof(MODULEENTRY); // return of module data
AddLine("Task Parent Instance Module Module Module");
AddLine("Handle Task Handle Handle Name Pathname");
TaskFirst(&te); // initialize to 1st task
do { // format task information
ModuleFindHandle(&me, te.hModule); // get modulename & pathname
wsprintf(temp, "%04Xh %04Xh %04Xh %04Xh %-8.8s %s",
te.hTask, te.hTaskParent, te.hInst, te.hModule,
(LPSTR) me.szModule, (LPSTR) me.szExePath);
AddLine(temp); // add to array for output
} while(TaskNext(&te)); // get next task
}
//
// WalkGlobalHeap -- uses ToolHelp functions to walk through
// global heap and build formatted output in LinePtr[] array.
//
VOID WalkGlobalHeap(VOID)
{
GLOBALENTRY ge; // receives heap block info
TASKENTRY te; // receives task info
MODULEENTRY me; // receives module info
int i; // scratch variable
char *p; // scratch string pointer
char temp[256]; // scratch formatting buffer
memset(&ge, 0, sizeof(GLOBALENTRY)); // initialize structure for
ge.dwSize = sizeof(GLOBALENTRY); // return of heap block info
memset(&me, 0, sizeof(MODULEENTRY)); // initialize structure for
me.dwSize = sizeof(MODULEENTRY); // return of module data
memset(&te, 0, sizeof(TASKENTRY)); // initialize structure for
te.dwSize = sizeof(TASKENTRY); // return of task info
AddLine("Handle Linear Addr Size Type Owner");
GlobalFirst(&ge, GLOBAL_ALL); // initialize to 1st block
do {
if(TaskFindHandle(&te, ge.hOwner)) // get block owner's name
ModuleFindHandle(&me, te.hModule);
else if(!ModuleFindHandle(&me, ge.hOwner))
me.szModule[0] = '\0';
p = "Unknown"; // decode memory block type
for(i = 0; i < dim(memType); i++)
if(ge.wType == memType[i].Code)
p = memType[i].Name;
// format heap block info
wsprintf(temp, "%04Xh %08lXh %08lXh %-16.16s %04Xh %s",
ge.hBlock, ge.dwAddress, ge.dwBlockSize, (LPSTR) p, ge.hOwner,
(LPSTR) me.szModule);
AddLine(temp); // add to array for output
} while(GlobalNext(&ge, GLOBAL_ALL)); // get next class name
}
//
// ShowMemManInfo -- uses ToolHelp function to display various
// memory manager information.
//
VOID ShowMemManInfo(VOID)
{
MEMMANINFO mmi; // receives memory info
char temp[256]; // scratch formatting buffer
memset(&mmi, 0, sizeof(MEMMANINFO)); // initialize structure for
mmi.dwSize = sizeof(MEMMANINFO); // return of memory info
MemManInfo(&mmi); // now retrieve info
wsprintf(temp, "Page size: %d bytes",
mmi.wPageSize);
AddLine(temp);
wsprintf(temp, "Total pages: %ld",
mmi.dwTotalPages);
AddLine(temp);
wsprintf(temp, "Swap file pages: %ld",
mmi.dwSwapFilePages);
AddLine(temp);
wsprintf(temp, "Maximum pages available: %ld",
mmi.dwMaxPagesAvailable);
AddLine(temp);
wsprintf(temp, "Maximum pages lockable: %ld",
mmi.dwMaxPagesLockable);
AddLine(temp);
wsprintf(temp, "Total unlocked pages: %ld",
mmi.dwTotalUnlockedPages);
AddLine(temp);
wsprintf(temp, "Pages not in use: %ld",
mmi.dwFreePages);
AddLine(temp);
wsprintf(temp, "Total linear address space: %ld bytes",
mmi.dwTotalLinearSpace*mmi.wPageSize);
AddLine(temp);
wsprintf(temp, "Free linear address space: %ld bytes",
mmi.dwFreeLinearSpace * mmi.wPageSize);
AddLine(temp);
wsprintf(temp, "Largest free block: %ld bytes",
mmi.dwLargestFreeBlock);
AddLine(temp);
}
//
// ShowSystemHeap -- uses ToolHelp function to display various
// system heap information.
//
VOID ShowSystemHeap(VOID)
{
SYSHEAPINFO si; // receives system heap info
char temp[256]; // scratch formatting buffer
memset(&si, 0, sizeof(SYSHEAPINFO)); // initialize structure for
si.dwSize = sizeof(SYSHEAPINFO); // return of system heap info
SystemHeapInfo(&si); // now retrieve info
wsprintf(temp, "User Heap Space Free: %d%%", si.wUserFreePercent);
AddLine(temp);
wsprintf(temp, "GDI Heap Space Free: %d%%", si.wGDIFreePercent);
AddLine(temp);
AddLine(" ");
wsprintf(temp, "User Heap Handle: %04Xh", si.hUserSegment);
AddLine(temp);
wsprintf(temp, "GDI Heap Handle: %04Xh", si.hGDISegment);
AddLine(temp);
}
//
// ShowDiskSpace -- uses DOS Int 21H function to get & display free
// disk space for each valid drive.
//
VOID ShowDiskSpace(VOID)
{
union REGS regs; // int 21h register contents
int status; // receives int86 status
int drive = 3; // start with C drive
char temp[256]; // scratch formatting buffer
AddLine("Drive Total Bytes Free Bytes"); // format titles
while(TRUE)
{
regs.h.ah = 0x36; // function number
regs.h.dl = drive; // drive code (1=A, etc.)
status = intdos(®s, ®s); // perform int 21h
if(status == -1) break; // quit if this drive invalid
wsprintf(temp, " %c %10ld %10ld", // format drive info
drive + 'A' - 1,
(LONG) regs.x.ax * (LONG) regs.x.cx * (LONG) regs.x.dx,
(LONG) regs.x.ax * (LONG) regs.x.cx * (LONG) regs.x.bx);
AddLine(temp);
drive++; // go to next drive
}
}
//
// SetCurLine - called to set CurLine to valid value, clamped to
// the range (0...TopLine), and redraw thumb on scroll bar.
//
VOID SetCurLine(int NewLine)
{
CurLine = min(max(NewLine, 0), TopLine);
SetScrollPos(hFrame, SB_VERT, CurLine, TRUE);
}
//
// ConfigWindow -- Configures various display parameters and scrollbar
// according to total lines of output, current window size, and the
// number of lines that will fit into the window.
//
VOID ConfigWindow(VOID)
{
// calc line number of first line of last page
TopLine = max(TotLines - LinesPerPage,0);
// update scroll bar range and thumb position
SetScrollRange(hFrame, SB_VERT, 0, TopLine, FALSE);
SetScrollPos(hFrame, SB_VERT, CurLine, TRUE);
}
//
// AddLine -- called with a pointer to an ASCIIZ string, allocates
// memory from the heap to hold the string, puts the pointer
// to the heap block into the next position in the LinePtr[] array,
// and updates the total line count.
//
VOID AddLine(char * p)
{
char * q; // scratch pointer
if(TotLines == MAXLINES) // bail out if line pointer
return; // array is already full
q = malloc(strlen(p)+1); // allocate memory for line
if(q == 0) // bail out out if no
return; // heap space available
strcpy(q, p); // copy string to heap
LinePtr[TotLines] = q; // put heap pointer into array
TotLines++; // count lines of output
}
//
// EmptyLines - releases all heap blocks in LinePtr[] array,
// then zeros out the line pointers and the total line count
//
VOID EmptyLines(VOID)
{
int i; // scratch variable
for(i = 0; i < MAXLINES; i++)
{
if(LinePtr[i]) // if this position in
{ // the LinePtr array is
free(LinePtr[i]); // nonzero, release the
LinePtr[i] = NULL; // heap block, then zero
} // out the LinePtr slot
}
CurLine = 0; // initialize various
TotLines = 0; // other global variables
TopLine = 0;
}
//
// PaintLine -- paint a single line of text in the window.
// The passed line number is relative to the window, NOT to the
// total array of formatted output available to be painted.
//
VOID PaintLine(HDC hdc, INT RelLine)
{
int Line = RelLine + CurLine;
if(LinePtr[Line])
TextOut(hdc, CharX, RelLine*CharY, LinePtr[Line], strlen(LinePtr[Line]));
}
//
// Repaint - force repaint of all formatted output in main window
//
VOID Repaint(VOID)
{
InvalidateRect(hFrame, NULL, TRUE); // force repaint entire window
}
//
// SetWindowCaption -- concatenate the application name with the
// display type, then update the frame window's title bar.
//
VOID SetWindowCaption(char * szDisplayType)
{
char szTemp[256]; // scratch buffer
strcpy(szTemp, szAppName); // get application name
strcat(szTemp, " - "); // add separator
strcat(szTemp, szDisplayType); // add information type
SetWindowText(hFrame, szTemp); // put result into title bar
}
//
// UpdateProfile() -- saves the current window size and position
// and display type in the application's private INI file.
//
VOID UpdateProfile(VOID)
{
RECT rect;
char temp[20];
if(IsIconic(hFrame) || IsZoomed(hFrame)) return;
GetWindowRect(hFrame, &rect);
wsprintf(temp,"%d", rect.left);
WritePrivateProfileString("Frame", "xul", temp, szIni);
wsprintf(temp,"%d", rect.top);
WritePrivateProfileString("Frame", "yul", temp, szIni);
wsprintf(temp,"%d", rect.right);
WritePrivateProfileString("Frame", "xlr", temp, szIni);
wsprintf(temp,"%d", rect.bottom);
WritePrivateProfileString("Frame", "ylr", temp, szIni);
wsprintf(temp,"%d", DisplayType);
WritePrivateProfileString("Frame", "type", temp, szIni);
}
//
// TimerProc() -- Callback for 10 second timer. Refresh display
// if window is not minimized and does not have the focus.
//
WORD FAR APIENTRY TimerProc(HWND hwnd, WORD message, WORD wParam, LONG lParam)
{
if((!IsIconic(hFrame)) && (hFrame != GetFocus()))
SendMessage(hFrame, WM_COMMAND, IDM_REFRESH, 0);
return(FALSE);
}