home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 1998 May
/
Pcwk5b98.iso
/
Borland
/
Cplus45
/
BC45
/
OWL1.PAK
/
FILEWND.CPP
< prev
next >
Wrap
Text File
|
1995-08-29
|
10KB
|
393 lines
// ObjectWindows - (C) Copyright 1992 by Borland International
/* --------------------------------------------------------
FILEWND.CPP
Defines type TFileWindow, a text editor which can read
and write to a file.
-------------------------------------------------------- */
#include <string.h>
#include <stdio.h>
#include <alloc.h>
#include "filewnd.h"
#define Min(a, b) ((a) < (b) ? (a) : (b))
/* Constructor for a TFileWindow. Initializes its data members using
passed parameters and default values. */
TFileWindow::TFileWindow(PTWindowsObject AParent,LPSTR ATitle,
LPSTR AFileName, PTModule AModule)
: TEditWindow(AParent, ATitle, AModule)
{
IsNewFile = TRUE;
FileName = _fstrdup(AFileName ? AFileName : "");
}
/* Dispose of the file name. */
TFileWindow::~TFileWindow()
{
if ( FileName )
farfree(FileName);
}
/* Performs setup for a TFileWindow, appending 'Untitled' to its caption */
void TFileWindow::SetupWindow()
{
TEditWindow::SetupWindow();
SetFileName(FileName);
if ( FileName[0] != '\0')
if ( !Read() )
SetFileName("");
}
/* Sets the file name of the window and updates the caption. */
void TFileWindow::SetFileName(LPSTR AFileName)
{
char NewCaption[81];
LPSTR P[2];
if ( FileName != AFileName )
{
farfree(FileName);
FileName = _fstrdup(AFileName ? AFileName : "");
}
P[0] = Title;
if ( FileName[0] == '\0' )
P[1] = "(Untitled)";
else
P[1] = AFileName;
if ( Title == NULL || Title[0] == '\0' )
SetWindowText(HWindow, P[1]);
else
{
wvsprintf(NewCaption, "%s - %s", (LPSTR)P);
SetWindowText(HWindow, NewCaption);
}
}
/* Begins the edit of a new file, after determining that it is Ok to
clear the TEdit's text. */
void TFileWindow::NewFile()
{
if ( CanClear() )
{
Editor->Clear();
InvalidateRect(Editor->HWindow, NULL, FALSE);
Editor->ClearModify();
IsNewFile = TRUE;
SetFileName(NULL);
}
}
/* Replaces the current file with the given file. */
void TFileWindow::ReplaceWith(LPSTR AFileName)
{
char OldName[MAXPATH];
_fstrcpy(OldName, FileName);
SetFileName(AFileName);
if ( Read() )
InvalidateRect(Editor->HWindow, NULL, FALSE);
else
SetFileName(OldName);
}
/* Brings up a dialog allowing the user to open a file into this
window. Same as selecting File|Open from the menus. */
void TFileWindow::Open()
{
char TmpName[MAXPATH];
if ( CanClear() && (GetModule()->ExecDialog(
new TFileDialog(this, SD_FILEOPEN,
_fstrcpy(TmpName, "*.*"), GetModule())) == IDOK) )
ReplaceWith(TmpName);
}
static HANDLE LocalReAllocDS(HANDLE hMem, WORD wBytes, WORD wFlags,
WORD TheDS)
{
WORD SavedDS;
HANDLE ReturnValue;
SavedDS = _DS;
_DS = TheDS;
ReturnValue = LocalReAlloc(hMem, wBytes, wFlags);
_DS = SavedDS;
return ReturnValue;
}
static LPSTR LocalLockDS(HANDLE hMem, WORD TheDS)
{
WORD SavedDS;
LPSTR ReturnValue;
SavedDS = _DS;
_DS = TheDS;
ReturnValue = (LPSTR)LocalLock(hMem);
_DS = SavedDS;
return ReturnValue;
}
static BOOL LocalUnlockDS(HANDLE hMem, WORD TheDS)
{
WORD SavedDS;
BOOL ReturnValue;
SavedDS = _DS;
_DS = TheDS;
ReturnValue = LocalUnlock(hMem);
_DS = SavedDS;
return ReturnValue;
}
/* Reads the contents of a previously-specified file into the TEdit
child control. */
BOOL TFileWindow::Read()
{
long CharsToRead;
UINT HEditorBuffer;
LPSTR EditorBuffer;
WORD EditorsDS;
char S[MAXPATH + 33];
int AFile;
BOOL Success = FALSE;
AFile = _lopen(FileName, OF_READ);
if ( AFile != -1 )
{
CharsToRead = _llseek(AFile, 0L, 2);
_llseek(AFile, 0L, 0);
if ( CharsToRead < MaxInt && CharsToRead > 0 )
{
Editor->Clear();
// attempt to reallocate Editor's buffer to the size of the file
HEditorBuffer = SendMessage(Editor->HWindow, EM_GETHANDLE, 0, 0L);
EditorsDS = FP_SEG(GlobalLock((Editor->GetModule())->hInstance));
if ( LocalReAllocDS((HANDLE)HEditorBuffer, (WORD)(CharsToRead+1),
LHND, EditorsDS) != NULL )
{
// read the file into EditorBuffer
EditorBuffer = (LPSTR)LocalLockDS((HANDLE)HEditorBuffer, EditorsDS);
if ( _lread(AFile, EditorBuffer, (WORD)CharsToRead) == CharsToRead )
{
// NULL terminate Editor's buffer
EditorBuffer[(WORD)CharsToRead] = '\0';
LocalUnlockDS((HANDLE)HEditorBuffer, EditorsDS);
SendMessage(Editor->HWindow, EM_SETHANDLE, HEditorBuffer, 0L);
Success = TRUE;
IsNewFile = FALSE;
Editor->ClearModify();
Editor->SetSelection(0,0);
}
}
GlobalUnlock((Editor->GetModule())->hInstance);
}
_lclose(AFile);
}
if ( !Success )
{
wsprintf(S, "Unable to read file \"%s\" from disk", FileName);
MessageBox(HWindow, S, GetModule()->Name, MB_ICONEXCLAMATION | MB_OK);
}
return Success;
}
/* Saves the contents of the TEdit child control into the file currently
being editted. Returns true if the file was saved or
Editor->IsModified returns FALSE (contents already saved). */
BOOL TFileWindow::Save()
{
if ( Editor->IsModified() )
{
if ( IsNewFile )
return SaveAs();
else
{
if ( Write() )
return TRUE;
else
return FALSE;
}
}
else // Editor's contents haven't been changed. No need to write.
return TRUE;
}
/* Saves the contents of the TEdit child control into a file whose name
is retrieved from the user, through execution of a "Save" file
dialog. Returns true if the file was saved. */
BOOL TFileWindow::SaveAs()
{
char TmpName[MAXPATH];
char OldName[MAXPATH];
OFSTRUCT TmpOfStruct;
char S[MAXPATH+20];
_fstrcpy(OldName, FileName);
if ( FileName )
_fstrcpy(TmpName, FileName);
else
TmpName[0] = '\0';
if ( GetModule()->ExecDialog( new TFileDialog
(this, SD_FILESAVE, TmpName, GetModule())) == IDOK )
{
if ( OpenFile(TmpName, &TmpOfStruct, OF_EXIST) != -1 )
{
wsprintf(S, "Replace Current \"%s\"?", (LPSTR)TmpName);
if ( MessageBox(HWindow, S, "File Changed",
MB_YESNO | MB_ICONQUESTION) == IDNO )
{
SetFileName(OldName);
return FALSE;
}
}
SetFileName(TmpName);
if ( Write() )
return TRUE;
else
{
SetFileName(OldName);
return FALSE;
}
}
return FALSE;
}
/* Writes the contents of the TEdit child control to a
previously-specified file. */
BOOL TFileWindow::Write()
{
const BufferSize = 1024;
long CharsToWrite, CharsWritten = 0;
int BlockSize;
Pchar ABuffer;
char S[MAXPATH + 33];
int NumLines;
int AFile;
AFile = _lcreat(FileName, 0);
if ( AFile == -1 )
{
wsprintf(S, "Unable to write file \"%s\" to disk", FileName);
MessageBox(HWindow, S, GetModule()->Name, MB_ICONEXCLAMATION | MB_OK);
return FALSE;
}
else
{
NumLines = Editor->GetNumLines();
CharsToWrite = Editor->GetLineIndex(NumLines-1) +
Editor->GetLineLength(NumLines-1);
ABuffer = new char[BufferSize+1 + 2*NumLines];
if ( !ABuffer )
return FALSE;
else
{
while ( CharsWritten < CharsToWrite )
{
BlockSize = (int)Min((CharsToWrite - CharsWritten), BufferSize);
Editor->GetSubText(ABuffer, (int)CharsWritten,
(int)(CharsWritten + BlockSize));
if (_lwrite(AFile, ABuffer, strlen(ABuffer)) == (WORD)-1)
{
delete ABuffer;
_lclose(AFile);
return FALSE;
}
CharsWritten += BlockSize;
}
IsNewFile = FALSE;
Editor->ClearModify();
delete ABuffer;
}
_lclose(AFile);
}
return TRUE;
}
/* Returns a BOOL value indicating whether or not it is Ok to clear
the TEdit's text. Returns TRUE if the text has not been changed, or
if the user Oks the clearing of the text. */
BOOL TFileWindow::CanClear()
{
char S[MAXPATH+28];
int Rslt;
if ( Editor->IsModified() )
{
if ( !FileName || (FileName[0]=='\0'))
_fstrcpy(S, "Untitled file has changed. Save?");
else
wsprintf(S, "File \"%s\" has changed. Save?", FileName);
Rslt = MessageBox(HWindow, S, "File Changed",
MB_YESNOCANCEL | MB_ICONQUESTION);
if ( Rslt == IDYES )
return Save();
else
return Rslt != IDCANCEL;
}
return TRUE;
}
/* Returns a BOOL value indicating whether or not it is Ok to close
the TEdit's text. Returns the result of a call to CanClear. */
BOOL TFileWindow::CanClose()
{
return CanClear();
}
/* Responds to an incoming "New" command (with a CM_FILENEW command
identifier) by calling NewFile. */
void TFileWindow::CMFileNew(TMessage&)
{
NewFile();
}
/* Responds to an incoming "Open" command (with a CM_FILEOPEN command
identifier) by calling Open(). */
void TFileWindow::CMFileOpen(TMessage&)
{
Open();
}
/* Responds to an incoming "Save" command (with a CM_FILESAVE
command identifier) by calling Save. */
void TFileWindow::CMFileSave(TMessage&)
{
Save();
}
/* Responds to an incoming "SaveAs" command (with a CM_FILESAVEAS
command identifier) by calling SaveAs. */
void TFileWindow::CMFileSaveAs(TMessage&)
{
SaveAs();
}
/* Reads an instance of TFileWindow from the passed ipstream. */
void *TFileWindow::read(ipstream& is)
{
TEditWindow::read(is);
FileName = is.freadString();
IsNewFile = ( FileName[0] == '\0' );
return this;
}
/* Writes the TFileWindow to the passed opstream. */
void TFileWindow::write(opstream& os)
{
TEditWindow::write(os);
os.fwriteString(FileName);
}
TStreamable *TFileWindow::build()
{
return new TFileWindow(streamableInit);
}
TStreamableClass RegFileWindow("TFileWindow", TFileWindow::build,
__DELTA(TFileWindow));