📄 prntfile.c
字号:
/****************************************************************************
PROGRAM: PrntFile.c
PURPOSE: Loads, saves, and edits text files
FUNCTIONS:
WinMain() - calls initialization function, processes message loop
InitApplication() - initializes window data and registers window
InitInstance() - saves instance handle and creates main window
MainWndProc() - processes messages
About() - processes messages for "About" dialog box
SaveAsDlg() - save file under different name
OpenDlg() - let user select a file, and open it.
UpdateListBox() - Update the list box of OpenDlg
ChangeDefExt() - Change the default extension
SeparateFile() - Separate filename and pathname
AddExt() - Add default extension
CheckFileName() - Check for wildcards, add extension if needed
SaveFile() - Save current file
QuerySaveFile() - Called when some action might lose current contents
SetNewBuffer() - Set new buffer for edit window
Copyright 1991 Microsoft Corporation. All rights reserved.
****************************************************************************/
#include "windows.h"
#include "prntfile.h"
#include "drivinit.h"
#include "string.h"
#include "stdio.h"
HANDLE hInst;
HANDLE hAccTable; /* handle to accelerator table */
HWND hEditWnd; /* handle to edit window */
HWND hwnd; /* handle to main window */
/* Additional includes needed for the fstat() function */
#include <sys\types.h>
#include <sys\stat.h>
char FileName[128];
char PathName[128];
char OpenName[128];
char DefPath[128];
char DefSpec[13] = "*.*";
char DefExt[] = ".txt";
char str[255];
HANDLE hEditBuffer; /* handle to editing buffer */
HANDLE hOldBuffer; /* old buffer handle */
HANDLE hHourGlass; /* handle to hourglass cursor */
HANDLE hSaveCursor; /* current cursor handle */
int hFile; /* file handle */
int count; /* number of chars read or written */
PSTR pBuffer; /* address of read/write buffer */
OFSTRUCT OfStruct; /* information from OpenFile() */
struct stat FileStatus; /* information from fstat() */
BOOL bChanges = FALSE; /* TRUE if the file is changed */
BOOL bSaveEnabled = FALSE; /* TRUE if text in the edit buffer */
PSTR pEditBuffer; /* address of the edit buffer */
RECT Rect; /* dimension of the client window */
char Untitled[] = /* default window title */
"Edit File - (untitled)";
/* Printer variables */
HDC hPr; /* handle for printer device context */
int LineSpace; /* spacing between lines */
int LinesPerPage; /* lines per page */
int CurrentLine; /* current line */
int LineLength; /* line length */
DWORD dwLines; /* number of lines to print */
DWORD dwIndex; /* index into lines to print */
char pLine[128]; /* buffer to store lines before printing */
TEXTMETRIC TextMetric; /* information about character size */
BOOL bAbort; /* FALSE if user cancels printing */
HWND hAbortDlgWnd;
FARPROC lpAbortDlg, lpAbortProc;
/****************************************************************************
FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)
PURPOSE: calls initialization function, processes message loop
****************************************************************************/
int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
HANDLE hInstance;
HANDLE hPrevInstance;
LPSTR lpCmdLine;
int nCmdShow;
{
MSG msg;
if (!hPrevInstance)
if (!InitApplication(hInstance))
return (FALSE);
if (!InitInstance(hInstance, nCmdShow))
return (FALSE);
while (GetMessage(&msg, NULL, NULL, NULL))
{
/* Only translate message if it is not an accelerator message */
if (!TranslateAccelerator(hwnd, hAccTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (msg.wParam);
}
/****************************************************************************
FUNCTION: InitApplication(HANDLE)
PURPOSE: Initializes window data and registers window class
****************************************************************************/
BOOL InitApplication(hInstance)
HANDLE hInstance;
{
WNDCLASS wc;
wc.style = NULL;
wc.lpfnWndProc = MainWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = COLOR_WINDOW + 1;
wc.lpszMenuName = "PrntFileMenu";
wc.lpszClassName = "PrntFileWClass";
return (RegisterClass(&wc));
}
/****************************************************************************
FUNCTION: InitInstance(HANDLE, int)
PURPOSE: Saves instance handle and creates main window
****************************************************************************/
BOOL InitInstance(hInstance, nCmdShow)
HANDLE hInstance;
int nCmdShow;
{
RECT Rect;
hInst = hInstance;
hAccTable = LoadAccelerators(hInst, "PrntFileAcc");
hwnd = CreateWindow(
"PrntFileWClass",
"PrntFile Sample Application",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL
);
if (!hwnd)
return (FALSE);
GetClientRect(hwnd, (LPRECT) &Rect);
/* Create a child window */
hEditWnd = CreateWindow("Edit",
NULL,
WS_CHILD | WS_VISIBLE |
ES_MULTILINE |
WS_VSCROLL | WS_HSCROLL |
ES_AUTOHSCROLL | ES_AUTOVSCROLL,
0,
0,
(Rect.right - Rect.left),
(Rect.bottom - Rect.top),
hwnd,
IDC_EDIT, /* Child control i.d. */
hInst,
NULL);
if (!hEditWnd)
{
DestroyWindow(hwnd);
return (NULL);
}
/* Get an hourglass cursor to use during file transfers */
hHourGlass = LoadCursor(NULL, IDC_WAIT);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
return (TRUE);
}
/****************************************************************************
FUNCTION: MainWndProc(HWND, unsigned, WORD, LONG)
PURPOSE: Processes messages
MESSAGES:
WM_COMMAND - application menu (About dialog box)
WM_DESTROY - destroy window
WM_SIZE - window size has changed
WM_QUERYENDSESSION - willing to end session?
WM_ENDSESSION - end Windows session
WM_CLOSE - close the window
WM_SIZE - window resized
COMMENTS:
Adds printing capability to the EDITFILE program. Printing request
is sent as an IDM_PRINT message.
Before the printing operation begins, a modeless dialog box is
created to allow the user to abort the printing operation. This
dialog box remains active until the print job is completed, or the
user cancels the print operation.
****************************************************************************/
long FAR PASCAL MainWndProc(hWnd, message, wParam, lParam)
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
FARPROC lpProcAbout, lpOpenDlg, lpSaveAsDlg;
int Success; /* return value from SaveAsDlg() */
int IOStatus; /* result of file i/o */
int nPageSize; /* vert. resolution of printer device */
switch (message)
{
case WM_COMMAND:
switch (wParam)
{
case IDM_ABOUT:
lpProcAbout = MakeProcInstance(About, hInst);
DialogBox(hInst, "AboutBox", hWnd, lpProcAbout);
FreeProcInstance(lpProcAbout);
break;
case IDM_NEW:
/* If current file has been modified, query user about
* saving it.
*/
if (!QuerySaveFile(hWnd))
return (NULL);
/* bChanges is set to FALSE to indicate there have been
* no changes since the last file save.
*/
bChanges = FALSE;
FileName[0] = 0;
/* Update the edit buffer */
SetNewBuffer(hWnd, NULL, Untitled);
break;
case IDM_OPEN:
if (!QuerySaveFile(hWnd))
return (NULL);
lpOpenDlg = MakeProcInstance((FARPROC) OpenDlg, hInst);
/* Open the file and get its handle */
hFile = DialogBox(hInst, "Open", hWnd, lpOpenDlg);
FreeProcInstance(lpOpenDlg);
if (!hFile)
return (NULL);
/* Allocate edit buffer to the size of the file + 1 */
hEditBuffer =
LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT,
(WORD)FileStatus.st_size + 1);
if (!hEditBuffer)
{
MessageBox(hWnd, "Not enough memory.", NULL,
MB_OK | MB_ICONHAND);
return (NULL);
}
hSaveCursor = SetCursor(hHourGlass);
pEditBuffer = LocalLock(hEditBuffer);
IOStatus = (int)_hread(hFile, pEditBuffer, FileStatus.st_size);
_lclose(hFile);
/* # bytes read must equal file size */
if (IOStatus != (int)FileStatus.st_size)
{
sprintf(str, "Error reading %s.", FileName);
SetCursor(hSaveCursor); /* Remove the hourglass */
MessageBox(hWnd, str, NULL, MB_OK | MB_ICONEXCLAMATION);
}
LocalUnlock(hEditBuffer);
/* Set up a new buffer and window title */
sprintf(str, "PrntFile - %s", FileName);
SetNewBuffer(hWnd, hEditBuffer, str);
SetCursor(hSaveCursor); /* restore the cursor */
break;
case IDM_SAVE:
/* If there is no filename, use the saveas command to get
* one. Otherwise, save the file using the current
* filename.
*/
if (!FileName[0])
goto saveas;
if (bChanges)
SaveFile(hWnd);
break;
case IDM_SAVEAS:
saveas:
lpSaveAsDlg = MakeProcInstance(SaveAsDlg, hInst);
/* Call the SaveAsDlg() function to get the new filename */
Success = DialogBox(hInst, "SaveAs", hWnd, lpSaveAsDlg);
FreeProcInstance(lpSaveAsDlg);
/* If successful, update the window title, save the file */
if (Success == IDOK)
{
sprintf(str, "PrntFile - %s", FileName);
SetWindowText(hWnd, str);
SaveFile(hWnd);
}
break; /* User canceled */
case IDM_PRINT:
hSaveCursor = SetCursor(hHourGlass);
hPr = GetPrinterDC();
if (!hPr)
{
sprintf(str, "Unable to get Printer DC -- cannot print %s",
FileName);
MessageBox(hWnd, str, NULL, MB_OK | MB_ICONHAND);
return (NULL);
}
lpAbortDlg = MakeProcInstance(AbortDlg, hInst);
lpAbortProc = MakeProcInstance(AbortProc, hInst);
/* Define the abort function */
Escape(hPr, SETABORTPROC, NULL, (LPSTR)(LONG)lpAbortProc,
(LPSTR)NULL);
if (Escape(hPr, STARTDOC, 4, "PrntFile text",(LPSTR)NULL) < 0)
{
MessageBox(hWnd, "Unable to start print job",
NULL, MB_OK | MB_ICONHAND);
FreeProcInstance(lpAbortDlg);
FreeProcInstance(lpAbortProc);
DeleteDC(hPr);
}
bAbort = FALSE; /* Clears the abort flag */
/* Create the Abort dialog box (modeless) */
hAbortDlgWnd = CreateDialog(hInst, "AbortDlg", hWnd, lpAbortDlg);
if (!hAbortDlgWnd)
{
SetCursor(hSaveCursor); /* Remove the hourglass */
MessageBox(hWnd, "NULL Abort window handle",
NULL, MB_OK | MB_ICONHAND);
return (FALSE);
}
/* Now show Abort dialog */
ShowWindow (hAbortDlgWnd, SW_NORMAL);
/* Disable the main window to avoid reentrancy problems */
EnableWindow(hWnd, FALSE);
SetCursor(hSaveCursor); /* Remove the hourglass */
/* Since there may be more than one line, it is necessary to
* compute the spacing between lines. This can be done by
* retrieving the height of the characters printed
* and advancing by that height plus the recommended external
* leading height.
*/
GetTextMetrics(hPr, &TextMetric);
LineSpace = TextMetric.tmHeight + TextMetric.tmExternalLeading;
/* Since there may be more lines than can fit on one
* page, it is necessary to compute the number of lines to
* print per page. This can be done by retrieving the
* dimensions of the page and dividing the height
* by the line spacing.
*/
nPageSize = GetDeviceCaps (hPr, VERTRES);
LinesPerPage = nPageSize / LineSpace - 1;
/* Since only one line can be printed at a time, a count of
* lines to print is needed. This is available by sending the
* EM_GETLINECOUNT message to the edit control.
*/
dwLines = SendMessage(hEditWnd, EM_GETLINECOUNT, 0, 0L);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -