Annotation of mstools/samples/sdktools/dlgedit/file.c, revision 1.1

1.1     ! root        1: 
        !             2: /******************************************************************************\
        !             3: *       This is a part of the Microsoft Source Code Samples. 
        !             4: *       Copyright (C) 1993 Microsoft Corporation.
        !             5: *       All rights reserved. 
        !             6: *       This source code is only intended as a supplement to 
        !             7: *       Microsoft Development Tools and/or WinHelp documentation.
        !             8: *       See these sources for detailed information regarding the 
        !             9: *       Microsoft samples programs.
        !            10: \******************************************************************************/
        !            11: 
        !            12: /****************************** Module Header *******************************
        !            13: * Module Name: file.c
        !            14: *
        !            15: * This file contains the high level routines that begin opening
        !            16: * and saving files.
        !            17: *
        !            18: * Functions:
        !            19: *    Open()
        !            20: *    BuildFilterString()
        !            21: *    DoWeSave()
        !            22: *    Save()
        !            23: *    OpenCmdLineFile()
        !            24: *    FileInPath()
        !            25: *    ShowFileStatus()
        !            26: *    DifferentDirs()
        !            27: *    HasPath()
        !            28: *    WriteDWordPad()
        !            29: *    BuildDefSaveName()
        !            30: *    WriteTheFile()
        !            31: *    FormTempFileName()
        !            32: *    FileCat()
        !            33: *
        !            34: * Comments:
        !            35: *
        !            36: ****************************************************************************/
        !            37: 
        !            38: #include "dlgedit.h"
        !            39: #include "dlgfuncs.h"
        !            40: #include "dlgextrn.h"
        !            41: #include "dialogs.h"
        !            42: 
        !            43: #include <wchar.h>
        !            44: 
        !            45: #include <commdlg.h>
        !            46: 
        !            47: 
        !            48: /*
        !            49:  * File types.
        !            50:  */
        !            51: #define FILE_RES    0               // Resource (.RES) file.
        !            52: #define FILE_DLG    1               // Dialog (.DLG) file.
        !            53: #define FILE_INC    2               // Include (.H) file.
        !            54: 
        !            55: STATICFN VOID BuildDefSaveName(INT FileType, LPTSTR pszFullFileName,
        !            56:     LPTSTR pszFileName, LPTSTR pszOtherFullFileName, LPTSTR pszOtherFileName,
        !            57:     LPTSTR pszFullFileNameBuffer, INT cchBuffer);
        !            58: STATICFN BOOL WriteTheFile(LPTSTR pszFile, INT fmt);
        !            59: STATICFN VOID FormTempFileName(LPTSTR pszBaseName,  LPTSTR pszBuffer);
        !            60: STATICFN VOID FileCat(LPTSTR pchName, LPTSTR pchCat, BOOL fChop);
        !            61: 
        !            62: 
        !            63: 
        !            64: /************************************************************************
        !            65: * Open
        !            66: *
        !            67: * Handles opening of resource and include files.
        !            68: * Saves current dialog in the resource.
        !            69: * Might put up a message box.
        !            70: * Cancels moves.
        !            71: * Changes szFullResFile, pszResFile, szFullIncludeFile, pszIncludeFile
        !            72: * Puts up dialog boxes.
        !            73: * Restores dialog box from resource.
        !            74: * Sets changed flags.
        !            75: *
        !            76: * Arguments:
        !            77: *   INT FileType - FILE_RESOURCE or FILE_INCLUDE.
        !            78: *
        !            79: * Returns:
        !            80: *   TRUE if successful, FALSE if not.
        !            81: *
        !            82: ************************************************************************/
        !            83: 
        !            84: BOOL Open(
        !            85:     INT FileType)
        !            86: {
        !            87:     BOOL fSuccess;
        !            88:     BOOL fGotName;
        !            89:     OPENFILENAME ofn;
        !            90:     TCHAR szNewFileName[CCHMAXPATH];
        !            91:     TCHAR szInitialDir[CCHMAXPATH];
        !            92:     TCHAR szFilter[CCHTEXTMAX];
        !            93:     INT idPrevDlg;
        !            94: 
        !            95:     /*
        !            96:      * Cancel any outstanding selection(s).
        !            97:      */
        !            98:     CancelSelection(TRUE);
        !            99: 
        !           100:     /*
        !           101:      * Put current dialog back into the resource buffer.
        !           102:      */
        !           103:     if (!SynchDialogResource())
        !           104:         return FALSE;
        !           105: 
        !           106:     /*
        !           107:      * Begin setting up the globals and the open file dialog structure.
        !           108:      */
        !           109:     fSuccess = FALSE;
        !           110:     *szNewFileName = CHAR_NULL;
        !           111: 
        !           112:     /*
        !           113:      * Build up the filter string.
        !           114:      */
        !           115:     BuildFilterString(FileType, szFilter);
        !           116: 
        !           117:     ofn.lStructSize = sizeof(ofn);
        !           118:     ofn.hwndOwner = ghwndMain;
        !           119:     ofn.hInstance = NULL;
        !           120:     ofn.lpstrFilter = szFilter;
        !           121:     ofn.lpstrCustomFilter = NULL;
        !           122:     ofn.nMaxCustFilter = 0;
        !           123:     ofn.nFilterIndex = 1;
        !           124:     ofn.lpstrFile = szNewFileName;
        !           125:     ofn.nMaxFile = CCHMAXPATH;
        !           126:     ofn.lpstrFileTitle = NULL;
        !           127:     ofn.nMaxFileTitle = 0;
        !           128: 
        !           129:     if (FileType == FILE_INCLUDE) {
        !           130:         /*
        !           131:          * If there is a res file, set the default include file
        !           132:          * name to open to be the basename of the res file with
        !           133:          * a .H extension, if such a file exists.  We use szInitialDir
        !           134:          * here as a temporary buffer.
        !           135:          */
        !           136:         if (pszResFile) {
        !           137:             lstrcpy(szInitialDir, szFullResFile);
        !           138:             FileCat(szInitialDir, ids(IDS_DOTH), TRUE);
        !           139:             if (GetFileAttributes(szInitialDir) != -1) {
        !           140:                 lstrcpy(szNewFileName, pszResFile);
        !           141:                 FileCat(szNewFileName, ids(IDS_DOTH), TRUE);
        !           142:             }
        !           143:         }
        !           144: 
        !           145:         ofn.lpstrTitle = ids(IDS_INCOPENTITLE);
        !           146:         ofn.lpstrDefExt = ids(IDS_INCEXT);
        !           147:     }
        !           148:     else {
        !           149:         ofn.lpstrTitle = ids(IDS_RESOPENTITLE);
        !           150:         ofn.lpstrDefExt = ids(IDS_RESEXT);
        !           151:     }
        !           152: 
        !           153:     /*
        !           154:      * If they have already opened one res file, start looking for
        !           155:      * any new files to open in the same directory.  Otherwise, just
        !           156:      * default to the current directory.
        !           157:      */
        !           158:     if (pszResFile) {
        !           159:         lstrcpy(szInitialDir, szFullResFile);
        !           160:         *FileInPath(szInitialDir) = CHAR_NULL;
        !           161:         ofn.lpstrInitialDir = szInitialDir;
        !           162:     }
        !           163:     else {
        !           164:         ofn.lpstrInitialDir = NULL;
        !           165:     }
        !           166: 
        !           167:     ofn.Flags = OFN_HIDEREADONLY | OFN_SHOWHELP | OFN_FILEMUSTEXIST;
        !           168:     ofn.lCustData = 0;
        !           169:     ofn.lpfnHook = NULL;
        !           170:     ofn.lpTemplateName = NULL;
        !           171: 
        !           172:     /*
        !           173:      * Fire off the dialog box to open the file.
        !           174:      */
        !           175:     EnteringDialog((FileType == FILE_INCLUDE) ?
        !           176:             DID_COMMONFILEOPENINCLUDE : DID_COMMONFILEOPENRES,
        !           177:             &idPrevDlg, TRUE);
        !           178:     fGotName = GetOpenFileName(&ofn);
        !           179:     EnteringDialog(idPrevDlg, NULL, FALSE);
        !           180:     if (fGotName) {
        !           181:         if (FileType == FILE_INCLUDE) {
        !           182:             if (OpenIncludeFile(szNewFileName)) {
        !           183:                 /*
        !           184:                  * Since we just loaded a new include file, we mark the
        !           185:                  * resource as changed so that the .RES and .DLG files
        !           186:                  * will be written out with the proper name in the
        !           187:                  * DLGINCLUDE statement.
        !           188:                  */
        !           189:                 gfResChged = TRUE;
        !           190:                 fSuccess = TRUE;
        !           191:             }
        !           192:         }
        !           193:         else {
        !           194:             if (OpenResFile(szNewFileName))
        !           195:                 fSuccess = TRUE;
        !           196:         }
        !           197:     }
        !           198: 
        !           199:     ShowFileStatus(TRUE);
        !           200: 
        !           201:     return fSuccess;
        !           202: }
        !           203: 
        !           204: 
        !           205: 
        !           206: /************************************************************************
        !           207: * BuildFilterString
        !           208: *
        !           209: * This function creates a filter string to be passed into the
        !           210: * standard file open and save dialogs.  This will be something like:
        !           211: * "Resource (*.res)\0*.res\0\0"
        !           212: *
        !           213: * Arguments:
        !           214: *   INT FileType      - Flags for type of file, FILE_INCLUDE, FILE_RESOURCE
        !           215: *                       or FILE_DLL.
        !           216: *   LPTSTR pszFilter  - Where to return the filter string.
        !           217: *
        !           218: ************************************************************************/
        !           219: 
        !           220: VOID BuildFilterString(
        !           221:     INT FileType,
        !           222:     LPTSTR pszFilter)
        !           223: {
        !           224:     INT idsFileSpecName;
        !           225:     INT idsFileSpec;
        !           226:     LPTSTR psz;
        !           227: 
        !           228:     if (FileType & FILE_INCLUDE) {
        !           229:         idsFileSpecName = IDS_DEFINCFILESPECNAME;
        !           230:         idsFileSpec = IDS_DEFINCFILESPEC;
        !           231:     }
        !           232:     else if (FileType & FILE_RESOURCE) {
        !           233:         idsFileSpecName = IDS_DEFRESFILESPECNAME;
        !           234:         idsFileSpec = IDS_DEFRESFILESPEC;
        !           235:     }
        !           236:     else { // Must be a DLL.
        !           237:         idsFileSpecName = IDS_DEFDLLFILESPECNAME;
        !           238:         idsFileSpec = IDS_DEFDLLFILESPEC;
        !           239:     }
        !           240: 
        !           241:     /*
        !           242:      * Build up the filter string.  This will be something like:
        !           243:      * "Resource (*.res)\0*.res\0\0"
        !           244:      */
        !           245:     psz = (LPTSTR)WriteSz(pszFilter, ids(idsFileSpecName));
        !           246:     psz = (LPTSTR)WriteSz(psz, ids(idsFileSpec));
        !           247:     *psz = CHAR_NULL;
        !           248: }
        !           249: 
        !           250: 
        !           251: 
        !           252: /************************************************************************
        !           253: * OpenCmdLineFile
        !           254: *
        !           255: * Handles opening of the resource file specified on the command line.
        !           256: *
        !           257: * Arguments:
        !           258: *   LPTSTR - pointer to the file name string
        !           259: *
        !           260: ************************************************************************/
        !           261: 
        !           262: VOID OpenCmdLineFile(
        !           263:     LPTSTR pszFileName)
        !           264: {
        !           265:     TCHAR szFullPath[CCHMAXPATH];
        !           266:     LPTSTR pszOnlyFileName;
        !           267: 
        !           268:     if (SearchPath(L".", pszFileName, ids(IDS_DOTRES), CCHMAXPATH,
        !           269:             szFullPath, &pszOnlyFileName) == -1) {
        !           270:         Message(MSG_CANTOPENRES, pszFileName);
        !           271:     }
        !           272:     else {
        !           273:         OpenResFile(szFullPath);
        !           274:     }
        !           275: }
        !           276: 
        !           277: 
        !           278: 
        !           279: /************************************************************************
        !           280: * DoWeSave
        !           281: *
        !           282: * This function checks to see if the include file or the resource file
        !           283: * needs to be saved.  It first checks the changed flags and if TRUE,
        !           284: * asks the user if they want to save the file.  If they say yes, it
        !           285: * calls Save to do the actual work.
        !           286: *
        !           287: * Arguments:
        !           288: *     INT rgbFlags = FILE_RESOURCE or FILE_INCLUDE (but not both).
        !           289: *
        !           290: * Returns:
        !           291: *     IDYES    - The user wanted to save the file AND the save
        !           292: *                was successful, or the file has not been changed.
        !           293: *     IDNO     - The file had been changed but the user did not
        !           294: *                want it saved.
        !           295: *     IDCANCEL - The file had been changed, and either the user wanted
        !           296: *                it saved and the save failed, or they specified that
        !           297: *                they wanted the operation cancelled.
        !           298: *
        !           299: ************************************************************************/
        !           300: 
        !           301: INT DoWeSave(
        !           302:     INT rgbFlags)
        !           303: {
        !           304:     LPTSTR pszFile;
        !           305:     INT MsgCode;
        !           306:     BOOL fChanged;
        !           307:     INT nRet = IDYES;
        !           308: 
        !           309:     /*
        !           310:      * First set variables for current case.
        !           311:      */
        !           312:     if (rgbFlags & FILE_RESOURCE) {
        !           313:         fChanged = gfResChged;
        !           314:         MsgCode = MSG_CLOSING;
        !           315:         pszFile = pszResFile ? pszResFile : ids(IDS_UNTITLED);
        !           316:     }
        !           317:     else {
        !           318:         fChanged = gfIncChged;
        !           319:         MsgCode = MSG_INCLCLOSING;
        !           320:         pszFile = pszIncludeFile ? pszIncludeFile : ids(IDS_UNTITLED);
        !           321:     }
        !           322: 
        !           323:     if (fChanged) {
        !           324:         nRet = Message(MsgCode, pszFile);
        !           325:         if (nRet == IDYES) {
        !           326:             if (!Save(FILE_NOSHOW | rgbFlags))
        !           327:                 nRet = IDCANCEL;
        !           328:         }
        !           329:     }
        !           330: 
        !           331:     return nRet;
        !           332: }
        !           333: 
        !           334: 
        !           335: 
        !           336: /************************************************************************
        !           337: * Save
        !           338: *
        !           339: * Handles all saving of files based on menu choice.  Does a
        !           340: * CancelSelection and a SynchDialogResource.
        !           341: *
        !           342: * Arguments:
        !           343: *     INT rgbFlags - Can include FILE_SHOW, FILE_INCLUDE, FILE_SAVEAS.
        !           344: *
        !           345: * Returns:
        !           346: *     TRUE if the file was saved, FALSE if not.
        !           347: *
        !           348: ************************************************************************/
        !           349: 
        !           350: BOOL Save(
        !           351:     INT rgbFlags)
        !           352: {
        !           353:     OPENFILENAME ofn;
        !           354:     BOOL fGotName;
        !           355:     LPTSTR pszFileName;
        !           356:     LPTSTR pszFileNameDlg;
        !           357:     LPTSTR pszFullFileName;
        !           358:     BOOL fSuccess = FALSE;
        !           359:     TCHAR szInitialDir[CCHMAXPATH];
        !           360:     TCHAR szSaveFileName[CCHMAXPATH];
        !           361:     TCHAR szSaveFileNameDlg[CCHMAXPATH];
        !           362:     TCHAR szFilter[CCHTEXTMAX];
        !           363:     INT idPrevDlg;
        !           364: 
        !           365:     /*
        !           366:      * Put current dialog back into the resource buffer.
        !           367:      */
        !           368:     if (!SynchDialogResource())
        !           369:         return FALSE;
        !           370: 
        !           371:     /*
        !           372:      * If the file being saved has not been named, force a "Save As".
        !           373:      */
        !           374:     if ((rgbFlags & FILE_INCLUDE) ? !pszIncludeFile : !pszResFile)
        !           375:         rgbFlags |= FILE_SAVEAS;
        !           376: 
        !           377:     if (rgbFlags & FILE_SAVEAS) {
        !           378:         ofn.lStructSize = sizeof(ofn);
        !           379:         ofn.hwndOwner = ghwndMain;
        !           380:         ofn.hInstance = NULL;
        !           381: 
        !           382:         /*
        !           383:          * Build up the filter string.
        !           384:          */
        !           385:         BuildFilterString(rgbFlags, szFilter);
        !           386:         ofn.lpstrFilter = szFilter;
        !           387:         ofn.lpstrCustomFilter = NULL;
        !           388:         ofn.nMaxCustFilter = 0;
        !           389:         ofn.nFilterIndex = 1;
        !           390: 
        !           391:         ofn.lpstrFile = szSaveFileName;
        !           392:         ofn.nMaxFile = CCHMAXPATH;
        !           393:         ofn.lpstrFileTitle = NULL;
        !           394:         ofn.nMaxFileTitle = 0;
        !           395: 
        !           396:         if (rgbFlags & FILE_INCLUDE) {
        !           397:             ofn.lpstrTitle = ids(IDS_INCSAVETITLE);
        !           398:             ofn.lpstrDefExt = ids(IDS_INCEXT);
        !           399:             BuildDefSaveName(FILE_INCLUDE,
        !           400:                     szFullIncludeFile, pszIncludeFile,
        !           401:                     szFullResFile, pszResFile,
        !           402:                     szInitialDir, CCHMAXPATH);
        !           403:         }
        !           404:         else {
        !           405:             ofn.lpstrTitle = ids(IDS_RESSAVETITLE);
        !           406:             ofn.lpstrDefExt = ids(IDS_RESEXT);
        !           407:             BuildDefSaveName(FILE_RESOURCE,
        !           408:                     szFullResFile, pszResFile,
        !           409:                     szFullIncludeFile, pszIncludeFile,
        !           410:                     szInitialDir, CCHMAXPATH);
        !           411:         }
        !           412: 
        !           413:         /*
        !           414:          * At this point, szInitialDir contains the full path to
        !           415:          * the suggested save file name.  Find the end of the path,
        !           416:          * copy just the filename to the file name buffer and cut
        !           417:          * the filename portion off the initial directory buffer.
        !           418:          */
        !           419:         pszFileName = FileInPath(szInitialDir);
        !           420:         lstrcpy(szSaveFileName, pszFileName);
        !           421:         *pszFileName = CHAR_NULL;
        !           422:         ofn.lpstrInitialDir = szInitialDir;
        !           423: 
        !           424:         ofn.Flags = OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | OFN_SHOWHELP;
        !           425:         ofn.lCustData = 0;
        !           426:         ofn.lpfnHook = NULL;
        !           427:         ofn.lpTemplateName = NULL;
        !           428: 
        !           429:         /*
        !           430:          * Fire off the dialog box to get the file name to use.
        !           431:          */
        !           432:         EnteringDialog((rgbFlags & FILE_INCLUDE) ?
        !           433:                 DID_COMMONFILESAVEINCLUDE : DID_COMMONFILESAVERES,
        !           434:                 &idPrevDlg, TRUE);
        !           435:         fGotName = GetSaveFileName(&ofn);
        !           436:         EnteringDialog(idPrevDlg, NULL, FALSE);
        !           437:         if (fGotName) {
        !           438:             pszFullFileName = szSaveFileName;
        !           439:             pszFileName = FileInPath(szSaveFileName);
        !           440:             fSuccess = TRUE;
        !           441:         }
        !           442:     }
        !           443:     else {
        !           444:         if (rgbFlags & FILE_INCLUDE) {
        !           445:             pszFileName = pszIncludeFile;
        !           446:             pszFullFileName = szFullIncludeFile;
        !           447:         }
        !           448:         else {
        !           449:             pszFileName = pszResFile;
        !           450:             pszFullFileName = szFullResFile;
        !           451:         }
        !           452: 
        !           453:         fSuccess = TRUE;
        !           454:     }
        !           455: 
        !           456:     if (fSuccess) {
        !           457:         if (rgbFlags & FILE_INCLUDE) {
        !           458:             /*
        !           459:              * Save include file.
        !           460:              */
        !           461:             if (!WriteTheFile(pszFullFileName, FILE_INC)) {
        !           462:                 Message(MSG_CANTCREATE, pszFileName);
        !           463:                 fSuccess = FALSE;
        !           464:             }
        !           465:         }
        !           466:         else {
        !           467:             /*
        !           468:              * Form the same name as the .res file but with
        !           469:              * a .dlg extension.
        !           470:              */
        !           471:             lstrcpy(szSaveFileNameDlg, pszFullFileName);
        !           472:             pszFileNameDlg = FileInPath(szSaveFileNameDlg);
        !           473:             FileCat(pszFileNameDlg, ids(IDS_DOTDLG), TRUE);
        !           474: 
        !           475:             /*
        !           476:              * Save .RES file, then the .DLG file.  It is done
        !           477:              * in this order so that makes wil notice that the
        !           478:              * .dlg file has a newer time stamp than the .res
        !           479:              * and will cause the .res to be rebuilt.  This
        !           480:              * could be necessary to pick up other changes
        !           481:              * in the resources in a project.
        !           482:              */
        !           483:             if (!WriteTheFile(pszFullFileName, FILE_RES)) {
        !           484:                 Message(MSG_CANTCREATE, pszFileName);
        !           485:                 fSuccess = FALSE;
        !           486:             }
        !           487:             else if (!WriteTheFile(szSaveFileNameDlg, FILE_DLG)) {
        !           488:                 Message(MSG_CANTCREATE, pszFileNameDlg);
        !           489:                 fSuccess = FALSE;
        !           490:             }
        !           491:             else {
        !           492:                 /*
        !           493:                  * Successfully saved both files.  Update our
        !           494:                  * globals.
        !           495:                  */
        !           496:                 lstrcpy(szFullResFile, pszFullFileName);
        !           497:                 pszResFile = FileInPath(szFullResFile);
        !           498:                 gfResChged = FALSE;
        !           499:             }
        !           500:         }
        !           501:     }
        !           502: 
        !           503:     ShowFileStatus(TRUE);
        !           504: 
        !           505:     return fSuccess;
        !           506: }
        !           507: 
        !           508: 
        !           509: 
        !           510: /************************************************************************
        !           511: * BuildDefSaveName
        !           512: *
        !           513: * This function takes the filenames of the current resource and include
        !           514: * files and builds the default filename that will be shown in the
        !           515: * "Save As" dialog.  If the current file is still untitled, it will
        !           516: * attempt to pick a default name based on the other files name.
        !           517: *
        !           518: * To use, pass in the file type (FILE_RESOURCE or FILE_INCLUDE) and
        !           519: * give the current file name and full file name of both the current
        !           520: * file you are building, and the other type of file.  The following
        !           521: * rules will be followed, in order:
        !           522: *
        !           523: *   1. If the file name is valid (not NULL) and it is either the
        !           524: *      include file we are naming or it is the res file but there
        !           525: *      is no include file, it will copy the full file name to the
        !           526: *      output buffer.
        !           527: *
        !           528: *   2. If the other file name is valid, it will take this name, add the
        !           529: *      appropriate extension and copy it to the output buffer.
        !           530: *
        !           531: *   3. If neither of the file names are valid (they are BOTH untitled),
        !           532: *      it will assume the current directory and make a default file
        !           533: *      name with the appropriate extension.
        !           534: *
        !           535: * Rule 1 is a little complicated, but it's purpose is to make it so
        !           536: * that if a default res file name is being requested, and they changed
        !           537: * the directory and/or name for the include file that was just saved,
        !           538: * the default directory and name for the res file will be the same
        !           539: * directory and base name as the new include file directory and name.
        !           540: *
        !           541: * Arguments:
        !           542: *   INT FileType                 - Either FILE_RESOURE or FILE_INCLUDE.
        !           543: *   LPTSTR pszFullFileName       - The full file name.  This will only
        !           544: *                                  be used if pszFileName is not NULL.
        !           545: *   LPTSTR pszFileName           - File name to use, or NULL if it is
        !           546: *                                  currently untitled.
        !           547: *   LPTSTR pszOtherFullFileName  - Full file name of the other file.  Only
        !           548: *                                  considered valid if pszOtherFileName is
        !           549: *                                  not NULL.
        !           550: *   LPTSTR pszOtherFileName      - File name of the other file, or NULL if
        !           551: *                                  it is untitled.
        !           552: *   LPTSTR pszFullFileNameBuffer - Where to put the full file name.
        !           553: *   INT cchBuffer                - Size of the buffer in characters.
        !           554: *
        !           555: ************************************************************************/
        !           556: 
        !           557: STATICFN VOID BuildDefSaveName(
        !           558:     INT FileType,
        !           559:     LPTSTR pszFullFileName,
        !           560:     LPTSTR pszFileName,
        !           561:     LPTSTR pszOtherFullFileName,
        !           562:     LPTSTR pszOtherFileName,
        !           563:     LPTSTR pszFullFileNameBuffer,
        !           564:     INT cchBuffer)
        !           565: {
        !           566:     TCHAR szBuffer[CCHMAXPATH];
        !           567: 
        !           568:     if (pszFileName && (FileType == FILE_INCLUDE || !pszOtherFileName)) {
        !           569:         /*
        !           570:          * Simple case.  The file already has a title.
        !           571:          */
        !           572:         lstrcpy(pszFullFileNameBuffer, pszFullFileName);
        !           573:     }
        !           574:     else if (pszOtherFileName) {
        !           575:         /*
        !           576:          * Copy the other files name and add the proper extension.
        !           577:          */
        !           578:         lstrcpy(pszFullFileNameBuffer, pszOtherFullFileName);
        !           579:         FileCat(pszFullFileNameBuffer,
        !           580:                 (FileType == FILE_INCLUDE) ? ids(IDS_DOTH) :
        !           581:                 ids(IDS_DOTRES), TRUE);
        !           582:     }
        !           583:     else {
        !           584:         /*
        !           585:          * Pick a default name in the current directory and
        !           586:          * add the proper extension.
        !           587:          */
        !           588:         lstrcpy(szBuffer, ids(IDS_DEFSAVENAME));
        !           589:         FileCat(szBuffer,
        !           590:                 (FileType == FILE_INCLUDE) ? ids(IDS_DOTH) :
        !           591:                 ids(IDS_DOTRES), TRUE);
        !           592:         GetFullPathName(szBuffer, cchBuffer, pszFullFileNameBuffer, NULL);
        !           593:     }
        !           594: }
        !           595: 
        !           596: 
        !           597: 
        !           598: /************************************************************************
        !           599: * WriteTheFile
        !           600: *
        !           601: * This function accepts a pointer to a resource buffer and a format
        !           602: * type.  It writes the buffer out in the appropriate format.  It
        !           603: * gets the file name from pszFile, adding the appropriate extension
        !           604: * for the type of file.  The file is first written to a temporary file
        !           605: * then the old file is removed and finally the new file is renamed.
        !           606: *
        !           607: * Arguments:
        !           608: *   LPTSTR pszFile  - The name to save to.
        !           609: *   INT fmt         - format to write the buffer out in,
        !           610: *                     FILE_RES, FILE_INC or FILE_DLG.
        !           611: *
        !           612: * Returns:
        !           613: *     TRUE => File successfully written.
        !           614: *     FALSE => Failure in writing file.
        !           615: *
        !           616: ************************************************************************/
        !           617: 
        !           618: STATICFN BOOL WriteTheFile(
        !           619:     LPTSTR pszFile,
        !           620:     INT fmt)
        !           621: {
        !           622:     TCHAR szTempFile[CCHMAXPATH]; /* Used for temporary filename            */
        !           623:     TCHAR szSrcFile[CCHMAXPATH];  /* Source file with proper extension      */
        !           624:     HANDLE hfWrite;
        !           625:     HCURSOR hcurSave;
        !           626:     BOOL fSuccess = FALSE;
        !           627:     WORD idsExt;
        !           628: 
        !           629:     hcurSave = SetCursor(hcurWait);
        !           630: 
        !           631:     switch (fmt) {
        !           632:         case FILE_RES:
        !           633:             idsExt = IDS_DOTRES;
        !           634:             break;
        !           635: 
        !           636:         case FILE_DLG:
        !           637:             idsExt = IDS_DOTDLG;
        !           638:             break;
        !           639: 
        !           640:         case FILE_INC:
        !           641:             idsExt = IDS_DOTH;
        !           642:             break;
        !           643:     }
        !           644: 
        !           645:     /*
        !           646:      * Append appropriate file name extension.
        !           647:      */
        !           648:     lstrcpy(szSrcFile, pszFile);
        !           649:     FileCat(szSrcFile, ids(idsExt), fmt == FILE_DLG ? TRUE : FALSE);
        !           650: 
        !           651:     /*
        !           652:      * Generate appropriate temporary file name in the same directory.
        !           653:      * It is done in the same directory so that a simple rename can
        !           654:      * be done later.
        !           655:      */
        !           656:     FormTempFileName(szSrcFile, szTempFile);
        !           657: 
        !           658:     if ((hfWrite = CreateFile(szTempFile, GENERIC_READ | GENERIC_WRITE,
        !           659:             FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,
        !           660:             NULL)) == (HANDLE)-1)
        !           661:         goto Exit;
        !           662: 
        !           663:     switch (fmt) {
        !           664:         case FILE_RES:
        !           665:             if (!WriteRes(hfWrite, szSrcFile))
        !           666:                 goto CloseAndExit;
        !           667: 
        !           668:             break;
        !           669: 
        !           670:         case FILE_DLG:
        !           671:             if (!WriteDlg(hfWrite, szSrcFile))
        !           672:                 goto CloseAndExit;
        !           673: 
        !           674:             break;
        !           675: 
        !           676:         case FILE_INC:
        !           677:             if (!WriteInc(hfWrite))
        !           678:                 goto CloseAndExit;
        !           679: 
        !           680:             break;
        !           681:     }
        !           682: 
        !           683:     CloseHandle((HANDLE)hfWrite);
        !           684:     DeleteFile(szSrcFile);
        !           685:     if (!MoveFile(szTempFile, szSrcFile)) {
        !           686:         DeleteFile(szTempFile);
        !           687:         goto Exit;
        !           688:     }
        !           689: 
        !           690:     fSuccess = TRUE;
        !           691: 
        !           692:     /*
        !           693:      * If we just wrote to the include file, read it to get the new
        !           694:      * file offsets, etc.
        !           695:      */
        !           696:     if (fmt == FILE_INC) {
        !           697:         if (!OpenIncludeFile(szSrcFile))
        !           698:             fSuccess = FALSE;
        !           699:     }
        !           700: 
        !           701: Exit:
        !           702:     SetCursor(hcurSave);
        !           703:     return fSuccess;
        !           704: 
        !           705: CloseAndExit:
        !           706:     CloseHandle(hfWrite);
        !           707:     DeleteFile(szTempFile);
        !           708:     SetCursor(hcurSave);
        !           709:     return fSuccess;
        !           710: }
        !           711: 
        !           712: 
        !           713: 
        !           714: /************************************************************************
        !           715: * FormTempFileName
        !           716: *
        !           717: * This function forms a temporary file name in the provided string.
        !           718: * The provided string is assumed to have been filled with a filename
        !           719: * that includes a path.  The temp file will be created in the same
        !           720: * directory as the file that is currently in the string.
        !           721: *
        !           722: * Arguments:
        !           723: *   LPTSTR pszBaseName - The base name (a filename that includes a path).
        !           724: *   LPTSTR pszBuffer   - Where to return the
        !           725: *
        !           726: ************************************************************************/
        !           727: 
        !           728: STATICFN VOID FormTempFileName(
        !           729:     LPTSTR pszBaseName,
        !           730:     LPTSTR pszBuffer)
        !           731: {
        !           732:     TCHAR szBuffer[CCHMAXPATH];
        !           733:     LPTSTR psz;
        !           734: 
        !           735:     /*
        !           736:      * Cut the base file name down to just the path portion.
        !           737:      */
        !           738:     lstrcpy(szBuffer, pszBaseName);
        !           739:     psz = FileInPath(szBuffer);
        !           740:     psz--;
        !           741:     *psz = TEXT('\0');
        !           742: 
        !           743:     /*
        !           744:      * Create a temporary file in the same directory.
        !           745:      */
        !           746:     GetTempFileName(szBuffer, L"dlg", 0, pszBuffer);
        !           747: }
        !           748: 
        !           749: 
        !           750: 
        !           751: /************************************************************************
        !           752: * FileInPath
        !           753: *
        !           754: * This function takes a path and returns a pointer to the file name
        !           755: * portion of it.  For instance, it will return a pointer to
        !           756: * "abc.res" if it is given the following path: "c:\windows\abc.res".
        !           757: *
        !           758: * Arguments:
        !           759: *   LPTSTR pszPath - Path to look through.
        !           760: *
        !           761: ************************************************************************/
        !           762: 
        !           763: LPTSTR FileInPath(
        !           764:     LPTSTR pszPath)
        !           765: {
        !           766:     LPTSTR psz;
        !           767: 
        !           768:     psz = pszPath + lstrlen(pszPath);
        !           769:     while (psz > pszPath) {
        !           770:         psz--;
        !           771:         if (*psz == CHAR_BACKSLASH || *psz == CHAR_COLON) {
        !           772:             psz++;
        !           773:             break;
        !           774:         }
        !           775:     }
        !           776: 
        !           777:     return psz;
        !           778: }
        !           779: 
        !           780: 
        !           781: 
        !           782: /************************************************************************
        !           783: * FileCat
        !           784: *
        !           785: * This function puts the extension pchCat on the file spec pch.
        !           786: * If fChop, this is done regardless of whether pch has an extension
        !           787: * or not (replacing the old extension).  Otherwise, pchCat is added
        !           788: * only if there is no extension on the spec pch.
        !           789: *
        !           790: * Arguments:
        !           791: *     LPTSTR pch        - The file spec to "cat" the extension to.
        !           792: *     LPTSTR pchCat     - The extension to "cat" on to pch,
        !           793: *                         including the '.'
        !           794: *
        !           795: ************************************************************************/
        !           796: 
        !           797: STATICFN VOID FileCat(
        !           798:     LPTSTR pchName,
        !           799:     LPTSTR pchCat,
        !           800:     BOOL fChop)
        !           801: {
        !           802:     LPTSTR pch;
        !           803: 
        !           804:     pch = pchName + lstrlen(pchName);
        !           805:     pch--;
        !           806: 
        !           807:     /* back up to '.' or '\\' */
        !           808:     while (*pch != CHAR_DOT) {
        !           809:         if (*pch == CHAR_BACKSLASH || pch <= pchName) {
        !           810:             /* no extension, add one */
        !           811:             lstrcat(pchName, pchCat);
        !           812:             return;
        !           813:         }
        !           814: 
        !           815:         pch--;
        !           816:     }
        !           817: 
        !           818:     if (fChop)
        !           819:         lstrcpy(pch, pchCat);
        !           820: }
        !           821: 
        !           822: 
        !           823: 
        !           824: /************************************************************************
        !           825: * ShowFileStatus
        !           826: *
        !           827: * This function displays the title of the Dialog Editor, along with
        !           828: * the file names for the RES and H files with asterisks if they have
        !           829: * changed.  It displays this information only if one of these items
        !           830: * has changed or if fForce is TRUE.
        !           831: *
        !           832: * Arguments:
        !           833: *   BOOL fForce - TRUE if the title should be updated even if the value
        !           834: *                 of gfResChged or gfIncChged has not changed since the
        !           835: *                 last call.  This function should be called with fForce
        !           836: *                 equal to TRUE if it is known that one of the file names
        !           837: *                 has just been changed.
        !           838: *
        !           839: ************************************************************************/
        !           840: 
        !           841: VOID ShowFileStatus(
        !           842:     BOOL fForce)
        !           843: {
        !           844:     static BOOL fResChgedSave = FALSE;
        !           845:     static BOOL fIncChgedSave = FALSE;
        !           846:     TCHAR szTitle[CCHTEXTMAX];
        !           847: 
        !           848:     if (gfResChged != fResChgedSave || gfIncChged != fIncChgedSave ||
        !           849:             fForce) {
        !           850:         lstrcpy(szTitle, ids(IDS_DLGEDIT));
        !           851:         lstrcat(szTitle, L" - ");
        !           852:         lstrcat(szTitle, pszResFile ? pszResFile : ids(IDS_UNTITLED));
        !           853:         if (gfResChged)
        !           854:             lstrcat(szTitle, L"*");
        !           855: 
        !           856:         lstrcat(szTitle, L", ");
        !           857:         lstrcat(szTitle, pszIncludeFile ? pszIncludeFile : ids(IDS_UNTITLED));
        !           858:         if (gfIncChged)
        !           859:             lstrcat(szTitle, L"*");
        !           860: 
        !           861:         SetWindowText(ghwndMain, szTitle);
        !           862: 
        !           863:         fResChgedSave = gfResChged;
        !           864:         fIncChgedSave = gfIncChged;
        !           865:     }
        !           866: }
        !           867: 
        !           868: 
        !           869: 
        !           870: /************************************************************************
        !           871: * DifferentDirs
        !           872: *
        !           873: * This function returns TRUE if the given full paths are to files
        !           874: * that are in different directories.
        !           875: *
        !           876: * Arguments:
        !           877: *   LPTSTR pszPath1 - First path.
        !           878: *   LPTSTR pszPath2 - Second path.
        !           879: *
        !           880: ************************************************************************/
        !           881: 
        !           882: BOOL DifferentDirs(
        !           883:     LPTSTR pszPath1,
        !           884:     LPTSTR pszPath2)
        !           885: {
        !           886:     INT nLen1;
        !           887:     INT nLen2;
        !           888:     LPTSTR pszFile1;
        !           889:     LPTSTR pszFile2;
        !           890: 
        !           891:     pszFile1 = FileInPath(pszPath1);
        !           892:     pszFile2 = FileInPath(pszPath2);
        !           893: 
        !           894:     nLen1 = lstrlen(pszPath1) - lstrlen(pszFile1);
        !           895:     nLen2 = lstrlen(pszPath2) - lstrlen(pszFile2);
        !           896:     if (nLen1 != nLen2 || _wcsnicmp(pszPath1, pszPath2, nLen1) != 0)
        !           897:         return TRUE;
        !           898:     else
        !           899:         return FALSE;
        !           900: }
        !           901: 
        !           902: 
        !           903: 
        !           904: /************************************************************************
        !           905: * HasPath
        !           906: *
        !           907: * This function returns TRUE if the given filespec includes a path
        !           908: * specification.  It returns false if it is a filename without a
        !           909: * path.
        !           910: *
        !           911: * A filespec is considered to have a path if a backslash character (\)
        !           912: * is found in it.
        !           913: *
        !           914: * Arguments:
        !           915: *   LPTSTR pszFileSpec - File spec to check.
        !           916: *
        !           917: ************************************************************************/
        !           918: 
        !           919: BOOL HasPath(
        !           920:     LPTSTR pszFileSpec)
        !           921: {
        !           922:     LPTSTR psz;
        !           923: 
        !           924:     for (psz = pszFileSpec; *psz; psz++)
        !           925:         if (*psz == CHAR_BACKSLASH)
        !           926:             return TRUE;
        !           927: 
        !           928:     return FALSE;
        !           929: }
        !           930: 
        !           931: 
        !           932: 
        !           933: /************************************************************************
        !           934: * WriteDWordPad
        !           935: *
        !           936: * This function writes nulls to the specified file until it is
        !           937: * dword aligned.  If the file is already dword aligned, nothing
        !           938: * will be written.
        !           939: *
        !           940: * Arguments:
        !           941: *   HANDLE hf    - The file to write to.
        !           942: *   DWORD cbFile - Where the file pointer is at in the file.
        !           943: *
        !           944: * Returns:
        !           945: *   TRUE if successful, FALSE otherwise.
        !           946: *
        !           947: ************************************************************************/
        !           948: 
        !           949: BOOL WriteDWordPad(
        !           950:     HANDLE hf,
        !           951:     DWORD cbFile)
        !           952: {
        !           953:     static BYTE Buf[3] = {0, 0, 0};
        !           954:     WORD cb;
        !           955: 
        !           956:     cb = (WORD)((4 - (((WORD)cbFile) & 3)) % 4);
        !           957:     if (cb) {
        !           958:         if (_lwrite((HFILE)hf, (LPSTR)Buf, cb) == -1)
        !           959:             return FALSE;
        !           960:     }
        !           961: 
        !           962:     return TRUE;
        !           963: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.