809 lines
16 KiB
C++
809 lines
16 KiB
C++
// Filename: generic_stuff.cpp
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "includes.h"
|
|
#include "MainFrm.h"
|
|
//
|
|
#include "generic_stuff.h"
|
|
|
|
|
|
#define BASEDIRNAME "base"
|
|
#define BASEDIRNAME_XMEN "development"
|
|
|
|
// kept as non-hungarian labels purely because these 2 are so common in our projects...
|
|
//
|
|
char qdir[1024]={0}; // "S:\"
|
|
char gamedir[1024]={0}; // "S:\\baseq3\\"
|
|
|
|
// unlike "normal" SetQdirFromPath() functions, I need to see if qdir has changed
|
|
// (ie by loading an EF model over an SOF model) which could mean that we're in a different dir, and so
|
|
// should lose all cached textures etc...
|
|
//
|
|
bool bXMenPathHack = false;
|
|
bool bQ3RulesApply = true;
|
|
static bool SetQdirFromPath2( const char *path, const char *psBaseDir );
|
|
void SetQdirFromPath( const char *path )
|
|
{
|
|
char prevQdir[1024];
|
|
strcpy(prevQdir,qdir);
|
|
|
|
bXMenPathHack = false; // MUST be here
|
|
|
|
if (SetQdirFromPath2(path,BASEDIRNAME))
|
|
{
|
|
bQ3RulesApply = true;
|
|
}
|
|
else
|
|
{
|
|
if (SetQdirFromPath2(path,BASEDIRNAME_XMEN))
|
|
{
|
|
bQ3RulesApply = false;
|
|
bXMenPathHack = true;
|
|
}
|
|
}
|
|
|
|
if (stricmp(prevQdir,qdir))
|
|
{
|
|
extern void Media_Delete(void);
|
|
Media_Delete();
|
|
}
|
|
}
|
|
|
|
static bool SetQdirFromPath2( const char *path, const char *psBaseDir )
|
|
{
|
|
// static bool bDone = false;
|
|
|
|
// if (!bDone)
|
|
{
|
|
// bDone = true;
|
|
|
|
char temp[1024];
|
|
strcpy(temp,path);
|
|
path = temp;
|
|
const char *c;
|
|
const char *sep;
|
|
int len, count;
|
|
|
|
// if (!(path[0] == '/' || path[0] == '\\' || path[1] == ':'))
|
|
// { // path is partial
|
|
// Q_getwd (temp);
|
|
// strcat (temp, path);
|
|
// path = temp;
|
|
// }
|
|
|
|
_strlwr((char*)path);
|
|
|
|
// search for "base" in path from the RIGHT hand side (and must have a [back]slash just before it)
|
|
|
|
len = strlen(psBaseDir);
|
|
for (c=path+strlen(path)-1 ; c != path ; c--)
|
|
{
|
|
int i;
|
|
|
|
if (!strnicmp (c, psBaseDir, len)
|
|
&&
|
|
(*(c-1) == '/' || *(c-1) == '\\') // would be more efficient to do this first, but only checking after a strncasecmp ok ensures no invalid pointer-1 access
|
|
)
|
|
{
|
|
sep = c + len;
|
|
count = 1;
|
|
while (*sep && *sep != '/' && *sep != '\\')
|
|
{
|
|
sep++;
|
|
count++;
|
|
}
|
|
strncpy (gamedir, path, c+len+count-path);
|
|
gamedir[c+len+count-path]='\0';
|
|
for ( i = 0; i < (int)strlen( gamedir ); i++ )
|
|
{
|
|
if ( gamedir[i] == '\\' )
|
|
gamedir[i] = '/';
|
|
}
|
|
// qprintf ("gamedir: %s\n", gamedir);
|
|
|
|
strncpy (qdir, path, c-path);
|
|
qdir[c-path] = 0;
|
|
for ( i = 0; i < (int)strlen( qdir ); i++ )
|
|
{
|
|
if ( qdir[i] == '\\' )
|
|
qdir[i] = '/';
|
|
}
|
|
// qprintf ("qdir: %s\n", qdir);
|
|
|
|
return true;
|
|
}
|
|
}
|
|
// Error ("SetQdirFromPath: no '%s' in %s", BASEDIRNAME, path);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// takes (eg) "q:\quake\baseq3\textures\borg\name.tga"
|
|
//
|
|
// and produces "textures/borg/name.tga"
|
|
//
|
|
void Filename_RemoveQUAKEBASE(CString &string)
|
|
{
|
|
string.Replace("\\","/");
|
|
string.MakeLower();
|
|
|
|
/*
|
|
int loc = string.Find("/quake");
|
|
if (loc >=0 )
|
|
{
|
|
loc = string.Find("/",loc+1);
|
|
if (loc >=0)
|
|
{
|
|
// now pointing at "baseq3", "demoq3", whatever...
|
|
loc = string.Find("/", loc+1);
|
|
|
|
if (loc >= 0)
|
|
{
|
|
// now pointing at local filename...
|
|
//
|
|
string = string.Mid(loc+1);
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
|
|
// SetQdirFromPath( string );
|
|
string.Replace( gamedir, "" );
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool FileExists (LPCSTR psFilename)
|
|
{
|
|
FILE *handle = fopen(psFilename, "r");
|
|
if (!handle)
|
|
{
|
|
return false;
|
|
}
|
|
fclose (handle);
|
|
return true;
|
|
}
|
|
|
|
long FileLen( LPCSTR psFilename)
|
|
{
|
|
FILE *handle = fopen(psFilename, "r");
|
|
if (!handle)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
long l = filesize(handle);
|
|
|
|
fclose (handle);
|
|
return l;
|
|
}
|
|
|
|
|
|
|
|
|
|
// returns actual filename only, no path
|
|
//
|
|
char *Filename_WithoutPath(LPCSTR psFilename)
|
|
{
|
|
static char sString[MAX_PATH];
|
|
/*
|
|
LPCSTR p = strrchr(psFilename,'\\');
|
|
|
|
if (!p++)
|
|
{
|
|
p = strrchr(psFilename,'/');
|
|
if (!p++)
|
|
p=psFilename;
|
|
}
|
|
|
|
strcpy(sString,p);
|
|
*/
|
|
|
|
LPCSTR psCopyPos = psFilename;
|
|
|
|
while (*psFilename)
|
|
{
|
|
if (*psFilename == '/' || *psFilename == '\\')
|
|
psCopyPos = psFilename+1;
|
|
psFilename++;
|
|
}
|
|
|
|
strcpy(sString,psCopyPos);
|
|
|
|
return sString;
|
|
|
|
}
|
|
|
|
|
|
// returns (eg) "\dir\name" for "\dir\name.bmp"
|
|
//
|
|
char *Filename_WithoutExt(LPCSTR psFilename)
|
|
{
|
|
static char sString[MAX_PATH];
|
|
|
|
strcpy(sString,psFilename);
|
|
|
|
char *p = strrchr(sString,'.');
|
|
char *p2= strrchr(sString,'\\');
|
|
char *p3= strrchr(sString,'/');
|
|
|
|
// special check, make sure the first suffix we found from the end wasn't just a directory suffix (eg on a path'd filename with no extension anyway)
|
|
//
|
|
if (p &&
|
|
(p2==0 || (p2 && p>p2)) &&
|
|
(p3==0 || (p3 && p>p3))
|
|
)
|
|
*p=0;
|
|
|
|
return sString;
|
|
|
|
}
|
|
|
|
|
|
// loses anything after the path (if any), (eg) "\dir\name.bmp" becomes "\dir"
|
|
//
|
|
char *Filename_PathOnly(LPCSTR psFilename)
|
|
{
|
|
static char sString[MAX_PATH];
|
|
|
|
strcpy(sString,psFilename);
|
|
|
|
// for (int i=0; i<strlen(sString); i++)
|
|
// {
|
|
// if (sString[i] == '/')
|
|
// sString[i] = '\\';
|
|
// }
|
|
|
|
char *p1= strrchr(sString,'\\');
|
|
char *p2= strrchr(sString,'/');
|
|
char *p = (p1>p2)?p1:p2;
|
|
if (p)
|
|
*p=0;
|
|
|
|
return sString;
|
|
|
|
}
|
|
|
|
|
|
// returns filename's extension only (including '.'), else returns original string if no '.' in it...
|
|
//
|
|
char *Filename_ExtOnly(LPCSTR psFilename)
|
|
{
|
|
static char sString[MAX_PATH];
|
|
LPCSTR p = strrchr(psFilename,'.');
|
|
|
|
if (!p)
|
|
p=psFilename;
|
|
|
|
strcpy(sString,p);
|
|
|
|
return sString;
|
|
|
|
}
|
|
|
|
|
|
// used when sending output to a text file etc, keeps columns nice and neat...
|
|
//
|
|
char *String_EnsureMinLength(LPCSTR psString, int iMinLength)
|
|
{
|
|
static char sString[8][1024];
|
|
static int i=0;
|
|
|
|
i=(i+1)&7;
|
|
|
|
strcpy(sString[i],psString);
|
|
|
|
// a bit slow and lazy, but who cares?...
|
|
//
|
|
while (strlen(sString[i])<(UINT)iMinLength)
|
|
strcat(sString[i]," ");
|
|
|
|
return sString[i];
|
|
|
|
}
|
|
|
|
|
|
// similar to strlwr, but (crucially) doesn't touch original...
|
|
//
|
|
char *String_ToLower(LPCSTR psString)
|
|
{
|
|
static char sString[MAX_PATH];
|
|
|
|
strcpy(sString,psString);
|
|
return strlwr(sString);
|
|
|
|
}
|
|
|
|
// similar to strupr, but (crucially) doesn't touch original...
|
|
//
|
|
char *String_ToUpper(LPCSTR psString)
|
|
{
|
|
static char sString[MAX_PATH];
|
|
|
|
strcpy(sString,psString);
|
|
return strupr(sString);
|
|
|
|
}
|
|
|
|
char *String_ForwardSlash(LPCSTR psString)
|
|
{
|
|
static char sString[MAX_PATH];
|
|
|
|
strcpy(sString,psString);
|
|
|
|
char *p;
|
|
while ( (p=strchr(sString,'\\')) != NULL)
|
|
{
|
|
*p = '/';
|
|
}
|
|
|
|
return strlwr(sString);
|
|
}
|
|
|
|
|
|
char *String_RemoveOccurences(LPCSTR psString, LPCSTR psSubStr)
|
|
{
|
|
static CString str;
|
|
str = psString;
|
|
|
|
str.Replace(psSubStr,"");
|
|
|
|
return const_cast < char * > ((LPCSTR) str); // :-)
|
|
}
|
|
|
|
|
|
char *va(char *format, ...)
|
|
{
|
|
va_list argptr;
|
|
static char string[16][16384]; // important to have a good depth to this. 16 is nice
|
|
static index = 0;
|
|
|
|
index = (++index)&15;
|
|
|
|
va_start (argptr, format);
|
|
// vsprintf (string[index], format,argptr);
|
|
_vsnprintf(string[index], sizeof(string[0]), format, argptr);
|
|
va_end (argptr);
|
|
string[index][sizeof(string[0])-1] = '\0';
|
|
|
|
return string[index];
|
|
}
|
|
|
|
|
|
// returns a path to somewhere writeable, without trailing backslash...
|
|
//
|
|
// (for extra speed now, only evaluates it on the first call, change this if you like)
|
|
//
|
|
char *scGetTempPath(void)
|
|
{
|
|
static char sBuffer[MAX_PATH];
|
|
DWORD dwReturnedSize;
|
|
static int i=0;
|
|
|
|
if (!i++)
|
|
{
|
|
dwReturnedSize = GetTempPath(sizeof(sBuffer),sBuffer);
|
|
|
|
if (dwReturnedSize>sizeof(sBuffer))
|
|
{
|
|
// temp path too long to return, so forget it...
|
|
//
|
|
strcpy(sBuffer,"c:"); // "c:\\"); // should be writeable
|
|
}
|
|
|
|
// strip any trailing backslash...
|
|
//
|
|
if (sBuffer[strlen(sBuffer)-1]=='\\')
|
|
sBuffer[strlen(sBuffer)-1]='\0';
|
|
}// if (!i++)
|
|
|
|
return sBuffer;
|
|
|
|
}
|
|
|
|
|
|
// psInitialSaveName can be "" if not bothered
|
|
LPCSTR InputSaveFileName(LPCSTR psInitialSaveName, LPCSTR psCaption, LPCSTR psInitialPath, LPCSTR psFilter, LPCSTR psExtension)
|
|
{
|
|
CFileStatus Filestatus;
|
|
CFile File;
|
|
static char name[MAX_PATH];
|
|
|
|
CString strInitialSaveName(psInitialSaveName);
|
|
strInitialSaveName.Replace("/","\\"); // or windows immediately cancels the dialog
|
|
|
|
CFileDialog FileDlg(FALSE, psExtension,
|
|
strInitialSaveName,
|
|
OFN_OVERWRITEPROMPT|OFN_CREATEPROMPT,
|
|
psFilter, //TEXT("Map Project Files (*.mpj)|*.lit|Other Map Files (*.smd/*.sc2)|*.sc2;*.smd|FastMap Files (*.fmf)|*.fmf|All Files(*.*)|*.*||"), //Map Object Files|*.sms||"),
|
|
AfxGetMainWnd()
|
|
);
|
|
|
|
// FileDlg.m_ofn.lpstrInitialDir=psInitialPath;
|
|
// FileDlg.m_ofn.lpstrTitle=psCaption;
|
|
// strcpy(name,psInitialSaveName);
|
|
// FileDlg.m_ofn.lpstrFile=name;
|
|
|
|
if (FileDlg.DoModal() == IDOK)
|
|
{
|
|
static CString strName;
|
|
strName = FileDlg.GetPathName();
|
|
return strName;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
// "psInitialLoadName" param can be "" if not bothered, "psInitialDir" can be NULL to open to last browse-dir
|
|
//
|
|
// psFilter example: TEXT("Model files (*.glm)|*.glm|All Files(*.*)|*.*||") // LPCSTR psFilter
|
|
//
|
|
// there is too much crap in here, and some needless code, fix it sometime... (yeah, right)
|
|
//
|
|
LPCSTR InputLoadFileName(LPCSTR psInitialLoadName, LPCSTR psCaption, LPCSTR psInitialDir, LPCSTR psFilter)
|
|
{
|
|
CFileStatus Filestatus;
|
|
CFile File;
|
|
static char name[MAX_PATH];
|
|
|
|
CFileDialog FileDlg(TRUE, NULL, NULL,
|
|
OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST,
|
|
//TEXT("Map Project Files (*.mpj)|*.lit|Other Map Files (*.smd/*.sc2)|*.sc2;*.smd|FastMap Files (*.fmf)|*.fmf|All Files(*.*)|*.*||"), //Map Object Files|*.sms||"),
|
|
psFilter, //Map Object Files|*.sms||"),
|
|
AfxGetMainWnd());
|
|
|
|
static CString strInitialDir;
|
|
if (psInitialDir)
|
|
strInitialDir = psInitialDir;
|
|
strInitialDir.Replace("/","\\");
|
|
|
|
FileDlg.m_ofn.lpstrInitialDir = (LPCSTR) strInitialDir;
|
|
FileDlg.m_ofn.lpstrTitle=psCaption; // Load Editor Model";
|
|
|
|
CString strInitialLoadName(psInitialLoadName);
|
|
strInitialLoadName.Replace("/","\\");
|
|
strcpy(name,(LPCSTR)strInitialLoadName);
|
|
FileDlg.m_ofn.lpstrFile=name;
|
|
|
|
if (FileDlg.DoModal() == IDOK)
|
|
{
|
|
return name;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
|
|
// these MUST all be MB_TASKMODAL boxes now!!
|
|
//
|
|
bool gbErrorBox_Inhibit = false; // Keith wanted to be able to remote-deactivate these...
|
|
string strLastError;
|
|
LPCSTR ModView_GetLastError() // function for him to be able to interrogate if he's disabled the error boxes
|
|
{
|
|
return strLastError.c_str();
|
|
}
|
|
|
|
|
|
extern bool Gallery_Active();
|
|
extern void Gallery_AddError (LPCSTR psText);
|
|
extern void Gallery_AddInfo (LPCSTR psText);
|
|
extern void Gallery_AddWarning (LPCSTR psText);
|
|
|
|
void ErrorBox(const char *sString)
|
|
{
|
|
if (Gallery_Active())
|
|
{
|
|
Gallery_AddError(sString);
|
|
Gallery_AddError("\n");
|
|
return;
|
|
}
|
|
|
|
if (!gbErrorBox_Inhibit)
|
|
{
|
|
MessageBox( NULL, sString, "Error", MB_OK|MB_ICONERROR|MB_TASKMODAL );
|
|
}
|
|
|
|
strLastError = sString;
|
|
}
|
|
void InfoBox(const char *sString)
|
|
{
|
|
if (Gallery_Active())
|
|
{
|
|
Gallery_AddInfo(sString);
|
|
Gallery_AddInfo("\n");
|
|
return;
|
|
}
|
|
|
|
MessageBox( NULL, sString, "Info", MB_OK|MB_ICONINFORMATION|MB_TASKMODAL );
|
|
}
|
|
void WarningBox(const char *sString)
|
|
{
|
|
if (Gallery_Active())
|
|
{
|
|
Gallery_AddWarning(sString);
|
|
Gallery_AddWarning("\n");
|
|
return;
|
|
}
|
|
|
|
MessageBox( NULL, sString, "Warning", MB_OK|MB_ICONWARNING|MB_TASKMODAL );
|
|
}
|
|
|
|
|
|
|
|
bool GetYesNo(const char *psQuery)
|
|
{
|
|
if (Gallery_Active())
|
|
{
|
|
Gallery_AddWarning("GetYesNo call (... to which I guessed 'NO' ) using this query...\n\n");
|
|
Gallery_AddWarning(psQuery);
|
|
Gallery_AddWarning("\n");
|
|
return false;
|
|
}
|
|
|
|
//#define GetYesNo(psQuery) (!!(MessageBox(AppVars.hWnd,psQuery,"Query",MB_YESNO|MB_ICONWARNING|MB_TASKMODAL)==IDYES))
|
|
#define _GetYesNo(psQuery) (!!(AfxMessageBox(psQuery, MB_YESNO|MB_ICONWARNING|MB_TASKMODAL)==IDYES))
|
|
return _GetYesNo(psQuery);
|
|
}
|
|
|
|
void StatusMessage(LPCSTR psString) // param can be NULL to indicate fallback to "ready" or whatever you want
|
|
{
|
|
CMainFrame* pMainFrame = (CMainFrame*) AfxGetMainWnd();
|
|
if (pMainFrame)
|
|
{
|
|
pMainFrame->StatusMessage(psString);
|
|
}
|
|
}
|
|
|
|
|
|
/* this piece copied out of on-line examples, it basically works as a
|
|
similar function to Ffilelength(int handle), but it works with streams */
|
|
long filesize(FILE *handle)
|
|
{
|
|
long curpos, length;
|
|
|
|
curpos = ftell(handle);
|
|
fseek(handle, 0L, SEEK_END);
|
|
length = ftell(handle);
|
|
fseek(handle, curpos, SEEK_SET);
|
|
|
|
return length;
|
|
}
|
|
|
|
|
|
// returns -1 for error
|
|
int LoadFile (LPCSTR psPathedFilename, void **bufferptr, int bReportErrors)
|
|
{
|
|
FILE *f;
|
|
int length;
|
|
void *buffer;
|
|
|
|
f = fopen(psPathedFilename,"rb");
|
|
if (f)
|
|
{
|
|
length = filesize(f);
|
|
buffer = malloc (length+1);
|
|
((char *)buffer)[length] = 0;
|
|
int lread = fread (buffer,1,length, f);
|
|
fclose (f);
|
|
|
|
if (lread==length)
|
|
{
|
|
*bufferptr = buffer;
|
|
return length;
|
|
}
|
|
free(buffer);
|
|
}
|
|
|
|
extern bool gbInImageLoader; // tacky, but keeps quieter errors
|
|
if (bReportErrors && !gbInImageLoader)
|
|
{
|
|
ErrorBox(va("Error reading file %s!",psPathedFilename));
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
|
|
// returns -1 for error
|
|
int SaveFile (LPCSTR psPathedFilename, const void *pBuffer, int iSize)
|
|
{
|
|
extern void CreatePath (const char *path);
|
|
CreatePath(psPathedFilename);
|
|
FILE *f = fopen(psPathedFilename,"wb");
|
|
if (f)
|
|
{
|
|
int iLength = fwrite(pBuffer, 1, iSize, f);
|
|
fclose (f);
|
|
|
|
if (iLength == iSize)
|
|
{
|
|
return iLength;
|
|
}
|
|
|
|
ErrorBox(va("Error writing file \"%s\" (length %d), only %d bytes written!",psPathedFilename,iSize,iLength));
|
|
return -1;
|
|
}
|
|
|
|
ErrorBox(va("Error opening file \"%s\" for writing!",psPathedFilename));
|
|
|
|
return -1;
|
|
}
|
|
|
|
|
|
|
|
// this'll return a string of up to the first 4095 chars of a system error message...
|
|
//
|
|
LPCSTR SystemErrorString(DWORD dwError)
|
|
{
|
|
static char sString[4096];
|
|
|
|
LPVOID lpMsgBuf=0;
|
|
|
|
FormatMessage(
|
|
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
|
|
NULL,
|
|
dwError,
|
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
|
(LPTSTR) &lpMsgBuf,
|
|
0,
|
|
NULL
|
|
);
|
|
|
|
ZEROMEM(sString);
|
|
strncpy(sString,(LPCSTR) lpMsgBuf,sizeof(sString)-1);
|
|
|
|
LocalFree( lpMsgBuf );
|
|
|
|
return sString;
|
|
}
|
|
|
|
|
|
void SystemErrorBox(DWORD dwError)
|
|
{
|
|
ErrorBox( SystemErrorString(dwError) );
|
|
}
|
|
|
|
|
|
|
|
LPCSTR scGetComputerName(void)
|
|
{
|
|
static char cTempBuffer[128]; // well ott for laziness
|
|
DWORD dwTempBufferSize;
|
|
static int i=0;
|
|
|
|
if (!i++)
|
|
{
|
|
dwTempBufferSize = (sizeof (cTempBuffer))-1;
|
|
strcpy(cTempBuffer,"");
|
|
if (!GetComputerName(cTempBuffer, &dwTempBufferSize))
|
|
strcpy(cTempBuffer,"Unknown"); // error retrieving host computer name
|
|
}
|
|
|
|
return &cTempBuffer[0];
|
|
}
|
|
|
|
LPCSTR scGetUserName(void)
|
|
{
|
|
static char cTempBuffer[128];
|
|
DWORD dwTempBufferSize;
|
|
static int i=0;
|
|
|
|
if (!i++)
|
|
{
|
|
dwTempBufferSize = (sizeof (cTempBuffer))-1;
|
|
strcpy(cTempBuffer,"");
|
|
if (!GetUserName(cTempBuffer, &dwTempBufferSize))
|
|
strcpy(cTempBuffer,"Unknown"); // error retrieving host computer name
|
|
}
|
|
|
|
return &cTempBuffer[0];
|
|
}
|
|
|
|
|
|
|
|
|
|
bool TextFile_Read(CString &strFile, LPCSTR psFullPathedFilename, bool bLoseSlashSlashREMs /* = true */, bool bLoseBlankLines /* = true */)
|
|
{
|
|
FILE *fhTextFile = fopen(psFullPathedFilename,"rt");
|
|
if (fhTextFile)
|
|
{
|
|
char sLine[32768]; // sod it, should be enough for one line.
|
|
char *psLine;
|
|
|
|
strFile.Empty();
|
|
|
|
while ((psLine = fgets( sLine, sizeof(sLine), fhTextFile ))!=NULL)
|
|
{
|
|
if (bLoseSlashSlashREMs && !strncmp(psLine,"//",2))
|
|
{
|
|
// do nothing
|
|
}
|
|
else
|
|
{
|
|
// lose any whitespace to either side
|
|
CString strTemp(psLine);
|
|
strTemp.TrimLeft();
|
|
strTemp.TrimRight();
|
|
strTemp+="\n"; // restore the CR that got trimmed off by TrimRight()
|
|
|
|
if (bLoseBlankLines && (strTemp.IsEmpty() || strTemp.GetAt(0)=='\n'))
|
|
{
|
|
// do nothing
|
|
}
|
|
else
|
|
{
|
|
strFile += strTemp;
|
|
}
|
|
}
|
|
}
|
|
fclose(fhTextFile);
|
|
}
|
|
|
|
return !!fhTextFile;
|
|
}
|
|
|
|
|
|
|
|
bool SendFileToNotepad(LPCSTR psFilename)
|
|
{
|
|
bool bReturn = false;
|
|
|
|
char sExecString[MAX_PATH];
|
|
|
|
sprintf(sExecString,"notepad %s",psFilename);
|
|
|
|
if (WinExec(sExecString, // LPCSTR lpCmdLine, // address of command line
|
|
SW_SHOWNORMAL // UINT uCmdShow // window style for new application
|
|
)
|
|
>31 // don't ask me, Windoze just uses >31 as OK in this call.
|
|
)
|
|
{
|
|
// ok...
|
|
//
|
|
bReturn = true;
|
|
}
|
|
else
|
|
{
|
|
ErrorBox("Unable to locate/run NOTEPAD on this machine!\n\n(let me know about this -Ste)");
|
|
}
|
|
|
|
return bReturn;
|
|
}
|
|
|
|
// creates as temp file, then spawns notepad with it...
|
|
//
|
|
bool SendStringToNotepad(LPCSTR psWhatever, LPCSTR psLocalFileName)
|
|
{
|
|
bool bReturn = false;
|
|
|
|
LPCSTR psOutputFileName = va("%s\\%s",scGetTempPath(),psLocalFileName);
|
|
|
|
FILE *handle = fopen(psOutputFileName,"wt");
|
|
if (handle)
|
|
{
|
|
fprintf(handle,psWhatever);
|
|
fclose(handle);
|
|
|
|
bReturn = SendFileToNotepad(psOutputFileName);
|
|
}
|
|
else
|
|
{
|
|
ErrorBox(va("Unable to create file \"%s\" for notepad to use!",psOutputFileName));
|
|
}
|
|
|
|
return bReturn;
|
|
}
|
|
|
|
|
|
|
|
////////////////////////// eof ///////////////////////////
|