453 lines
18 KiB
C
453 lines
18 KiB
C
|
/*----------------------------------------------------------------------------*\
|
||
|
| edit.c - routines for dealing with multi-line edit controls |
|
||
|
| |
|
||
|
| |
|
||
|
| History: |
|
||
|
| 01/01/88 toddla Created |
|
||
|
| 11/04/90 w-dougb Commented & formatted the code to look pretty |
|
||
|
| |
|
||
|
\*----------------------------------------------------------------------------*/
|
||
|
|
||
|
/*----------------------------------------------------------------------------*\
|
||
|
| |
|
||
|
| i n c l u d e f i l e s |
|
||
|
| |
|
||
|
\*----------------------------------------------------------------------------*/
|
||
|
|
||
|
#include <windows.h>
|
||
|
#include "gmem.h"
|
||
|
#include "edit.h"
|
||
|
#include "mcitest.h"
|
||
|
|
||
|
/*----------------------------------------------------------------------------*\
|
||
|
| |
|
||
|
| c o n s t a n t a n d m a c r o d e f i n i t i o n s |
|
||
|
| |
|
||
|
\*----------------------------------------------------------------------------*/
|
||
|
|
||
|
#define ISSPACE(c) ((c) == ' ' || (c) == '\t')
|
||
|
#define ISEOL(c) ((c) == '\n'|| (c) == '\r')
|
||
|
#define ISWHITE(c) (ISSPACE(c) || ISEOL(c))
|
||
|
|
||
|
|
||
|
/*----------------------------------------------------------------------------*\
|
||
|
| EditOpenFile(hwndEdit, lszFile) |
|
||
|
| |
|
||
|
| Description: |
|
||
|
| This function opens the file <lszFile>, copies the contents of the |
|
||
|
| file into the edit control with the handle <hwndEdit>, and then closes |
|
||
|
| the file. |
|
||
|
| |
|
||
|
| Arguments: |
|
||
|
| hwndEdit window handle of the edit box control |
|
||
|
| lszFile filename of the file to be opened |
|
||
|
| |
|
||
|
| Returns: |
|
||
|
| TRUE if the operation was successful, else FALSE |
|
||
|
| |
|
||
|
\*----------------------------------------------------------------------------*/
|
||
|
|
||
|
BOOL EditOpenFile(
|
||
|
HWND hwndEdit,
|
||
|
LPTSTR lszFile)
|
||
|
{
|
||
|
#ifdef UNICODE
|
||
|
HANDLE fh; /* DOS file handle returned by OpenFile */
|
||
|
#else
|
||
|
HFILE fh; /* DOS file handle returned by OpenFile */
|
||
|
OFSTRUCT of; /* structure used by the OpenFile routine */
|
||
|
#endif
|
||
|
LPTSTR lszText; /* pointer to the opened file's text */
|
||
|
UINT nFileLen; /* length, in bytes, of the opened file */
|
||
|
HCURSOR hcur; /* handle to the pre-hourglass cursor */
|
||
|
|
||
|
/* If a valid window handle or a filename was not specified, then exit.
|
||
|
*/
|
||
|
if (!hwndEdit || !lszFile) {
|
||
|
dprintf1((TEXT("EditOpenFile: Invalid window or filename")));
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
/* Open the file for reading */
|
||
|
|
||
|
#ifdef UNICODE
|
||
|
fh = CreateFile(lszFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
|
||
|
if (fh == INVALID_HANDLE_VALUE) {
|
||
|
dprintf1((TEXT("Failed to open: %s"), lszFile));
|
||
|
return FALSE;
|
||
|
}
|
||
|
#else
|
||
|
fh = OpenFile(lszFile, &of, OF_READ);
|
||
|
if (fh == HFILE_ERROR) {
|
||
|
dprintf1((TEXT("Failed to open: %s"), lszFile));
|
||
|
return FALSE;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
nFileLen = (UINT)GetFileSize((HANDLE)fh, NULL);
|
||
|
if (HFILE_ERROR == nFileLen) {
|
||
|
dprintf1((TEXT("Failed to find file size: %s"), lszFile));
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Create a pointer to a region of memory large enough to hold the entire
|
||
|
* contents of the file. If this was successful, then read the file into
|
||
|
* this region, and use this region as the text for the edit control.
|
||
|
* Finally, free up the region and its pointer, and close the file.
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
lszText = (LPTSTR)GAllocPtr(nFileLen+1); // Note: no *sizeof(TCHAR)
|
||
|
if (NULL != lszText) {
|
||
|
|
||
|
BOOL fReturn;
|
||
|
/* This could take a while - show the hourglass cursor */
|
||
|
|
||
|
hcur = SetCursor(LoadCursor(NULL, IDC_WAIT));
|
||
|
|
||
|
/* Read the file and copy the contents into the edit control */
|
||
|
|
||
|
dprintf3((TEXT("reading file...")));
|
||
|
|
||
|
#ifdef UNICODE
|
||
|
{
|
||
|
DWORD bytesRead;
|
||
|
|
||
|
if (ReadFile(fh, lszText, nFileLen, &bytesRead, NULL)) {
|
||
|
lszText[bytesRead]=0;
|
||
|
dprintf2((TEXT("File loaded ok")));
|
||
|
SetWindowTextA(hwndEdit, (LPSTR)lszText); // Until we have UNICODE files
|
||
|
fReturn = TRUE;
|
||
|
} else {
|
||
|
dprintf2((TEXT("Error loading file")));
|
||
|
fReturn = FALSE;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
/* Free up the memory, close the file, and restore the cursor */
|
||
|
|
||
|
GFreePtr(lszText);
|
||
|
CloseHandle(fh);
|
||
|
#else
|
||
|
if ((_lread((HFILE)fh, lszText, nFileLen)) == nFileLen) {
|
||
|
lszText[nFileLen/sizeof(TCHAR)]=0;
|
||
|
dprintf2((TEXT("File loaded ok")));
|
||
|
SetWindowText(hwndEdit, lszText);
|
||
|
fReturn = TRUE;
|
||
|
} else {
|
||
|
dprintf2((TEXT("Error loading file")));
|
||
|
fReturn = FALSE;
|
||
|
}
|
||
|
|
||
|
/* Free up the memory, close the file, and restore the cursor */
|
||
|
|
||
|
GFreePtr(lszText);
|
||
|
_lclose((HFILE)fh);
|
||
|
#endif
|
||
|
SetCursor(hcur);
|
||
|
|
||
|
return fReturn;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* We couldn't allocate the required memory, so close the file and
|
||
|
* return FALSE.
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
dprintf1((TEXT("Failed memory allocation for file")));
|
||
|
#ifdef UNICODE
|
||
|
CloseHandle(fh);
|
||
|
#else
|
||
|
_lclose((HFILE)fh);
|
||
|
#endif
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*----------------------------------------------------------------------------*\
|
||
|
| EditSaveFile(hwndEdit, lszFile) |
|
||
|
| |
|
||
|
| Description: |
|
||
|
| This function saves the contents of the edit control with the handle |
|
||
|
| <hwndEdit> into the file <lszFile>, creating the file if required. |
|
||
|
| |
|
||
|
| Arguments: |
|
||
|
| hwndEdit window handle of the edit box control |
|
||
|
| lszFile filename of the file to be saved |
|
||
|
| |
|
||
|
| Returns: |
|
||
|
| TRUE if the operation was successful, else FALSE |
|
||
|
| |
|
||
|
\*----------------------------------------------------------------------------*/
|
||
|
|
||
|
BOOL EditSaveFile(
|
||
|
HWND hwndEdit,
|
||
|
LPTSTR lszFile)
|
||
|
{
|
||
|
#ifdef UNICODE
|
||
|
HANDLE fh; /* DOS file handle returned by OpenFile */
|
||
|
DWORD dwBytesWritten;
|
||
|
#else
|
||
|
OFSTRUCT of; /* structure used by the OpenFile routine */
|
||
|
HFILE fh; /* DOS file handle returned by OpenFile */
|
||
|
#endif
|
||
|
LPTSTR lszText; /* pointer to the saved file's text */
|
||
|
int nFileLen; /* length, in bytes, of the saved file */
|
||
|
HCURSOR hcur; /* handle to the pre-hourglass cursor */
|
||
|
|
||
|
/* If a valid window handle or a filename was not specified, then exit */
|
||
|
dprintf2((TEXT("EditSaveFile: Saving %s"), lszFile));
|
||
|
|
||
|
if (!hwndEdit || !lszFile) {
|
||
|
dprintf1((TEXT("EditSaveFile: Invalid window or filename")));
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
/* Create (or overwrite) the save file */
|
||
|
|
||
|
#ifdef UNICODE
|
||
|
fh = CreateFile(lszFile, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, 0);
|
||
|
if (fh == INVALID_HANDLE_VALUE) {
|
||
|
dprintf1((TEXT("EditSaveFile: Error opening file")));
|
||
|
return FALSE;
|
||
|
}
|
||
|
#else
|
||
|
fh = OpenFile(lszFile, &of, OF_CREATE);
|
||
|
if (fh == HFILE_ERROR) {
|
||
|
dprintf1((TEXT("EditSaveFile: Error opening file")));
|
||
|
return FALSE;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
/* Find out how big the contents of the edit box are */
|
||
|
|
||
|
nFileLen = GetWindowTextLength(hwndEdit);
|
||
|
// nFileLen = nFileLen*sizeof(TCHAR); We write ASCII
|
||
|
|
||
|
/*
|
||
|
* Create a pointer to a region of memory large enough to hold the entire
|
||
|
* contents of the edit box. If this was successful, then read the contents
|
||
|
* of the edit box into this region, and write the contents of this region
|
||
|
* into the save file. Finally, free up the region and its pointer, and
|
||
|
* close the file.
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
lszText = (LPTSTR)GAllocPtr(nFileLen);
|
||
|
if (NULL != lszText) {
|
||
|
|
||
|
/* This could take a while - show the hourglass cursor */
|
||
|
|
||
|
hcur = SetCursor(LoadCursor(NULL, IDC_WAIT));
|
||
|
|
||
|
/* Read the contents of the edit box, and write it to the save file */
|
||
|
|
||
|
GetWindowTextA(hwndEdit, (LPSTR)lszText, nFileLen); // Save ASCII file
|
||
|
|
||
|
#ifdef UNICODE
|
||
|
WriteFile(fh, lszText, nFileLen, &dwBytesWritten, NULL);
|
||
|
#else
|
||
|
_lwrite(fh, lszText, nFileLen);
|
||
|
#endif
|
||
|
|
||
|
|
||
|
/* Free up the memory, close the file, and restore the cursor */
|
||
|
|
||
|
GFreePtr(lszText);
|
||
|
#ifdef UNICODE
|
||
|
CloseHandle(fh);
|
||
|
#else
|
||
|
_lclose(fh);
|
||
|
#endif
|
||
|
SetCursor(hcur);
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* We couldn't allocate the required memory, so close the file and
|
||
|
* return FALSE.
|
||
|
*/
|
||
|
|
||
|
_lclose((HFILE)fh);
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*----------------------------------------------------------------------------*\
|
||
|
| EditGetLineCount(hwndEdit) |
|
||
|
| |
|
||
|
| Description: |
|
||
|
| This function finds out how many lines of text are in the edit box and |
|
||
|
| returns this value. |
|
||
|
| |
|
||
|
| Arguments: |
|
||
|
| hwndEdit window handle of the edit box control |
|
||
|
| |
|
||
|
| Returns: |
|
||
|
| The number of lines of text in the edit control. |
|
||
|
| |
|
||
|
\*----------------------------------------------------------------------------*/
|
||
|
|
||
|
DWORD EditGetLineCount(
|
||
|
HWND hwndEdit)
|
||
|
{
|
||
|
return SendMessage(hwndEdit, EM_GETLINECOUNT, 0, 0L);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*----------------------------------------------------------------------------*\
|
||
|
| EditGetLine(hwndEdit, iLine, lszLineBuffer, cch) |
|
||
|
| |
|
||
|
| Description: |
|
||
|
| This function retrieves the contents of line # <iLine> from the edit |
|
||
|
| box control with handle <hwndEdit>. If <iLine> is out of range (that |
|
||
|
| number line does not exist in the multi line edit field) then FALSE is |
|
||
|
| returned. Otherwise the line is copied into the buffer pointed to by |
|
||
|
| <lszLineBuffer> with white space removed. |
|
||
|
| The string is also null terminated even if it means truncation. |
|
||
|
| |
|
||
|
| Arguments: |
|
||
|
| hwndEdit window handle of the edit box control |
|
||
|
| iLine line # to get the contents of |
|
||
|
| lszLineBuffer pointer to the buffer to copy the line to |
|
||
|
| cch max # of characters to copy (MIN value on entry==2) |
|
||
|
| |
|
||
|
| Returns: |
|
||
|
| TRUE. |
|
||
|
| |
|
||
|
\*----------------------------------------------------------------------------*/
|
||
|
|
||
|
BOOL EditGetLine(
|
||
|
HWND hwndEdit,
|
||
|
int iLine,
|
||
|
LPTSTR lszLineBuffer,
|
||
|
int cch)
|
||
|
{
|
||
|
int nLines; /* total number of lines in the edit box */
|
||
|
|
||
|
/*
|
||
|
* Find out how many lines are in the edit control. If the requested line
|
||
|
* is out of range, then return.
|
||
|
*/
|
||
|
|
||
|
nLines = (int)EditGetLineCount(hwndEdit);
|
||
|
if (iLine < 0 || iLine >= nLines) {
|
||
|
if (iLine!= nLines) { // Probably because the user pressed Enter
|
||
|
// and the line number is beyond the end
|
||
|
dprintf1((TEXT("Requested line count %d is out of range (%d)"), iLine, nLines));
|
||
|
}
|
||
|
return *lszLineBuffer = 0;
|
||
|
/* This sets the buffer to null and returns FALSE */
|
||
|
}
|
||
|
|
||
|
/* Read the requested line into the string pointed to by <lszLineBuffer> */
|
||
|
/* NOTE: This routine is always called with cch at least TWO */
|
||
|
|
||
|
*((LPWORD)lszLineBuffer) = (WORD)cch;
|
||
|
cch = (int)SendMessage(hwndEdit, EM_GETLINE, iLine, (LONG)(LPTSTR)lszLineBuffer);
|
||
|
/* The returned string is NOT null terminated */
|
||
|
|
||
|
/* Strip trailing white spaces from the string, and null-terminate it */
|
||
|
while(cch > 0 && ISWHITE(lszLineBuffer[cch-1])) {
|
||
|
cch--;
|
||
|
}
|
||
|
lszLineBuffer[cch] = 0;
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*----------------------------------------------------------------------------*\
|
||
|
| EditGetCurLine(hwndEdit) |
|
||
|
| |
|
||
|
| Description: |
|
||
|
| This function retrieves the line number of the current line in the |
|
||
|
| edit box control with handle <hwndEdit>. It returns this line number. |
|
||
|
| |
|
||
|
| Arguments: |
|
||
|
| hwndEdit window handle of the edit box control |
|
||
|
| |
|
||
|
| Returns: |
|
||
|
| The line number of the current line. |
|
||
|
| |
|
||
|
\*----------------------------------------------------------------------------*/
|
||
|
|
||
|
int EditGetCurLine(
|
||
|
HWND hwndEdit)
|
||
|
{
|
||
|
int iLine; /* Line number of the currently active line */
|
||
|
|
||
|
iLine = (int)SendMessage(hwndEdit, EM_LINEFROMCHAR, (WPARAM)-1, 0L);
|
||
|
|
||
|
if (iLine < 0) {
|
||
|
iLine = 0;
|
||
|
}
|
||
|
|
||
|
return iLine;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*----------------------------------------------------------------------------*\
|
||
|
| EditSetCurLine(hwndEdit, iLine) |
|
||
|
| |
|
||
|
| Description: |
|
||
|
| This function sets the current line in the edit box control with |
|
||
|
| handle <hwndEdit> to the number given in <iLine>. |
|
||
|
| |
|
||
|
| Arguments: |
|
||
|
| hwndEdit window handle of the edit box control |
|
||
|
| iLine the line number to be made the current line |
|
||
|
| |
|
||
|
| Returns: |
|
||
|
| void |
|
||
|
| |
|
||
|
\*----------------------------------------------------------------------------*/
|
||
|
|
||
|
void EditSetCurLine(
|
||
|
HWND hwndEdit,
|
||
|
int iLine)
|
||
|
{
|
||
|
int off;
|
||
|
|
||
|
off = (int)SendMessage(hwndEdit, EM_LINEINDEX, iLine, 0L);
|
||
|
SendMessage(hwndEdit, EM_SETSEL, off, off);
|
||
|
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------*\
|
||
|
| EditSelectLine(hwndEdit, iLine) |
|
||
|
| |
|
||
|
| Description: |
|
||
|
| This function selects line # <iLine> in the edit box control with |
|
||
|
| handle <hwndEdit>. |
|
||
|
| |
|
||
|
| Arguments: |
|
||
|
| hwndEdit window handle of the edit box control |
|
||
|
| iLine the line number to be selected |
|
||
|
| |
|
||
|
| Returns: |
|
||
|
| void |
|
||
|
| |
|
||
|
\*----------------------------------------------------------------------------*/
|
||
|
|
||
|
void EditSelectLine(
|
||
|
HWND hwndEdit,
|
||
|
int iLine)
|
||
|
{
|
||
|
int offS;
|
||
|
int offE;
|
||
|
|
||
|
offS = (int)SendMessage(hwndEdit, EM_LINEINDEX, iLine, 0L);
|
||
|
offE = (int)SendMessage(hwndEdit, EM_LINEINDEX, iLine+1, 0L);
|
||
|
|
||
|
|
||
|
if (offE < offS) { /* Select to the end */
|
||
|
offE = -1;
|
||
|
}
|
||
|
|
||
|
SendMessage(hwndEdit, EM_SETSEL, offS, offE);
|
||
|
}
|