Annotation of mstools/samples/sdktools/dlgedit/file.c, revision 1.1.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.