|
|
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: rwdlg.c ! 14: * ! 15: * Does the writing of .DLG files. ! 16: * ! 17: * Functions: ! 18: * WriteDlg() ! 19: * WriteDlgInclude() ! 20: * WriteDialogHeader() ! 21: * WriteDialogHeaderLanguage() ! 22: * WriteControl() ! 23: * WriteNameOrd() ! 24: * WriteText() ! 25: * WriteIDDlg() ! 26: * GetControlKeyword() ! 27: * WriteClass() ! 28: * WriteStyles() ! 29: * WriteClassStyle() ! 30: * WriteCustomStyle() ! 31: * WriteCoords() ! 32: * WriteValue() ! 33: * WriteHexWord() ! 34: * WriteHexDWord() ! 35: * WriteString() ! 36: * WriteQuotedString() ! 37: * WriteEscapedString() ! 38: * WriteDlgChar() ! 39: * WriteDlgFlush() ! 40: * Tab() ! 41: * NewLine() ! 42: * Quote() ! 43: * Comma() ! 44: * Space() ! 45: * ORSymbol() ! 46: * ! 47: * Comments: ! 48: * ! 49: ****************************************************************************/ ! 50: ! 51: #include "dlgedit.h" ! 52: #include "dlgfuncs.h" ! 53: #include "dlgextrn.h" ! 54: ! 55: ! 56: /* ! 57: * Wrap lines before they go over this right margin. ! 58: */ ! 59: #define CCHRIGHTMARGIN 76 ! 60: ! 61: /* ! 62: * Defines for the tabs and tab indent levels. ! 63: */ ! 64: #define CCHTABWIDTH 4 // Tabs are four spaces wide. ! 65: #define TABLEVELNONE 0 // No indent (at left margin). ! 66: #define TABLEVELCONTROL 1 // Indent to start of controls. ! 67: #define TABLEVELCONTROLDESC 5 // Indent to control description. ! 68: ! 69: /* ! 70: * Macro to set the current tab level. The level is multiplied ! 71: * by the tab width. ! 72: */ ! 73: #define SetTab(t) (cTabStop = ((t)*CCHTABWIDTH)) ! 74: ! 75: /* ! 76: * Macro that determines if the current position is the first ! 77: * column for the current tab setting. ! 78: */ ! 79: #define AtFirstTabColumn() ((cColumn == cTabStop) ? TRUE : FALSE) ! 80: ! 81: STATICFN VOID WriteDlgInclude(LPTSTR pszFullDlgFile); ! 82: STATICFN PCONTROLDATA WriteDialogHeader(PRES pRes, PDIALOGBOXHEADER pdbh); ! 83: STATICFN VOID WriteDialogHeaderLanguage(WORD wLanguage); ! 84: STATICFN PCONTROLDATA WriteControl(PCONTROLDATA pcd); ! 85: STATICFN VOID WriteNameOrd(LPTSTR pszNameOrd); ! 86: STATICFN VOID WriteText(LPTSTR pszText); ! 87: STATICFN VOID WriteIDDlg(INT id, BOOL fHexOK); ! 88: STATICFN LPTSTR GetControlKeyword(INT iClass, DWORD flStyle, ! 89: DWORD *pflStylePredef, DWORD *pflStyleDefault, BOOL *pfWriteText, ! 90: BOOL *pfNotFound); ! 91: STATICFN VOID WriteClass(LPTSTR pszClass); ! 92: STATICFN BOOL WriteStyles(INT iClass, LPTSTR pszClass, DWORD flStyle, ! 93: DWORD flStylePredef, DWORD flStyleDefault, PDWORD pflStyleLeft, ! 94: BOOL fNullStyles, BOOL fCommaPrefix); ! 95: STATICFN BOOL WriteClassStyle(INT iClass, DWORD flStyle, ! 96: DWORD flStylePredef, DWORD flStyleDefault, PDWORD pflStyleLeft, ! 97: BOOL fPrevWritten, BOOL fNullStyles, BOOL fCommaPrefix); ! 98: STATICFN BOOL WriteCustomStyle(LPTSTR pszClass, DWORD flStyle, ! 99: PDWORD pflStyleLeft); ! 100: STATICFN VOID WriteCoords(INT x, INT y, INT cx, INT cy); ! 101: STATICFN VOID WriteValue(INT n); ! 102: STATICFN VOID WriteHexWord(WORD w); ! 103: STATICFN VOID WriteHexDWord(DWORD dw); ! 104: STATICFN VOID WriteString(LPTSTR psz); ! 105: STATICFN VOID WriteQuotedString(LPTSTR psz); ! 106: STATICFN VOID WriteEscapedString(LPTSTR psz); ! 107: STATICFN VOID WriteDlgChar(TCHAR ch); ! 108: STATICFN VOID WriteDlgFlush(VOID); ! 109: STATICFN VOID Tab(VOID); ! 110: STATICFN VOID NewLine(VOID); ! 111: STATICFN VOID Quote(VOID); ! 112: STATICFN VOID Comma(VOID); ! 113: STATICFN VOID Space(VOID); ! 114: STATICFN VOID ORSymbol(VOID); ! 115: ! 116: static INT cColumn; /* Current column in the line. */ ! 117: static INT cTabStop; /* Current tabstop column. */ ! 118: static HANDLE hfDlg; /* All workers write to this file. */ ! 119: static jmp_buf jbWriteDlg; /* Capture the state for longjmp. */ ! 120: ! 121: ! 122: ! 123: /************************************************************************ ! 124: * WriteDlg ! 125: * ! 126: * This function writes the dialog boxes in the given resource to the ! 127: * hfWrite file in the .DLG file RC format. ! 128: * ! 129: * Arguments: ! 130: * HANDLE - handle to the file ! 131: * LPTSTR - pointer to the resource file name ! 132: * ! 133: ************************************************************************/ ! 134: ! 135: BOOL WriteDlg( ! 136: HANDLE hfWrite, ! 137: LPTSTR pszFullDlgFile) ! 138: { ! 139: HANDLE hResLocked = NULL; ! 140: PRES pRes = NULL; ! 141: PRESLINK prl; ! 142: PDIALOGBOXHEADER pdbh; ! 143: PCONTROLDATA pcd; ! 144: INT cItems; ! 145: ! 146: /* ! 147: * Set our error trap up. The api setjmp will return a zero at first, ! 148: * then if a write error occurs later and longjmp is called, it ! 149: * will return non-zero and we will return the failure up to the ! 150: * caller. After this point, there must be no calls to allocate ! 151: * memory, open files, etc., unless this trap has a way to detect ! 152: * what happened and clean it up. See the c-runtime help file for more ! 153: * information about setjump/longjmp. ! 154: */ ! 155: if (_setjmp(jbWriteDlg)) { ! 156: /* ! 157: * If the resource is locked, unlock it. ! 158: */ ! 159: if (hResLocked) ! 160: GlobalUnlock(hResLocked); ! 161: ! 162: return FALSE; ! 163: } ! 164: ! 165: /* ! 166: * Initialize our globals. The hfDlg global is used so that hfWrite ! 167: * doesn't have to be passed on the stack over and over. ! 168: */ ! 169: hfDlg = hfWrite; ! 170: cColumn = 0; ! 171: SetTab(TABLEVELNONE); ! 172: ! 173: WriteDlgInclude(pszFullDlgFile); ! 174: ! 175: /* ! 176: * Process each resource in the list. ! 177: */ ! 178: for (prl = gprlHead; prl; prl = prl->prlNext) { ! 179: /* ! 180: * Skip if it is not a dialog resource. ! 181: */ ! 182: if (!prl->fDlgResource) ! 183: continue; ! 184: ! 185: /* ! 186: * Set up pointers to this dialog resource. ! 187: */ ! 188: pRes = (PRES)GlobalLock(prl->hRes); ! 189: hResLocked = prl->hRes; ! 190: ! 191: pdbh = (PDIALOGBOXHEADER)SkipResHeader(pRes); ! 192: ! 193: NewLine(); ! 194: pcd = WriteDialogHeader(pRes, pdbh); ! 195: ! 196: WriteString(ids(IDS_BEGIN)); ! 197: NewLine(); ! 198: ! 199: /* ! 200: * Write the controls. ! 201: */ ! 202: cItems = (INT)pdbh->NumberOfItems; ! 203: while (cItems--) ! 204: pcd = WriteControl(pcd); ! 205: ! 206: /* ! 207: * Finish up dialog template. ! 208: */ ! 209: WriteString(ids(IDS_END)); ! 210: NewLine(); ! 211: ! 212: GlobalUnlock(prl->hRes); ! 213: hResLocked = NULL; ! 214: } ! 215: ! 216: /* ! 217: * Flush any remaining characters in the write buffer. ! 218: */ ! 219: WriteDlgFlush(); ! 220: ! 221: return TRUE; ! 222: } ! 223: ! 224: ! 225: ! 226: /************************************************************************ ! 227: * WriteDlgInclude ! 228: * ! 229: * This routine writes out the "DLGINCLUDE" lines to the .DLG file. ! 230: * ! 231: * Arguments: ! 232: * LPTSTR - dialog file name ! 233: * ! 234: ************************************************************************/ ! 235: ! 236: STATICFN VOID WriteDlgInclude( ! 237: LPTSTR pszFullDlgFile) ! 238: { ! 239: if (pszIncludeFile) { ! 240: WriteValue(ORDID_DLGINCLUDE_NAME); ! 241: Space(); ! 242: WriteString(ids(IDS_DLGINCLUDE)); ! 243: Space(); ! 244: Quote(); ! 245: ! 246: /* ! 247: * If the include file is in a different directory than the resource ! 248: * file, write the full path to it. Otherwise, we just write the ! 249: * include file name. ! 250: */ ! 251: if (DifferentDirs(pszFullDlgFile, szFullIncludeFile)) ! 252: WriteEscapedString(szFullIncludeFile); ! 253: else ! 254: WriteEscapedString(pszIncludeFile); ! 255: ! 256: Quote(); ! 257: NewLine(); ! 258: } ! 259: } ! 260: ! 261: ! 262: ! 263: /************************************************************************ ! 264: * WriteDialogHeader ! 265: * ! 266: * Writes out the dialog header lines. ! 267: * ! 268: * Arguments: ! 269: * PRES - pointer to the resource ! 270: * PDIALOGBOXHEADER - pointer to the dialog box header ! 271: * ! 272: ************************************************************************/ ! 273: ! 274: STATICFN PCONTROLDATA WriteDialogHeader( ! 275: PRES pRes, ! 276: PDIALOGBOXHEADER pdbh) ! 277: { ! 278: DWORD flStyle; ! 279: DWORD flExtStyle; ! 280: DWORD flStyleLeft; ! 281: INT cdit; ! 282: INT x; ! 283: INT y; ! 284: INT cx; ! 285: INT cy; ! 286: LPTSTR pszMenuName; ! 287: LPTSTR pszClass; ! 288: LPTSTR pszCaption; ! 289: INT nPointSize; ! 290: LPTSTR pszFontName; ! 291: PCONTROLDATA pcd; ! 292: PRES2 pRes2; ! 293: BOOL fWritten; ! 294: ! 295: pRes2 = ResourcePart2(pRes); ! 296: ! 297: WriteNameOrd(ResourceName(pRes)); ! 298: Space(); ! 299: WriteString(ids(IDS_DIALOG)); ! 300: ! 301: if (pRes2->MemoryFlags & MMF_PRELOAD) { ! 302: Space(); ! 303: WriteString(ids(IDS_PRELOAD)); ! 304: } ! 305: ! 306: if (!(pRes2->MemoryFlags & MMF_MOVEABLE)) { ! 307: Space(); ! 308: WriteString(ids(IDS_FIXED)); ! 309: } ! 310: ! 311: if (!(pRes2->MemoryFlags & MMF_PURE)) { ! 312: Space(); ! 313: WriteString(ids(IDS_IMPURE)); ! 314: } ! 315: ! 316: /* ! 317: * Parse out the dialog template. ! 318: */ ! 319: pcd = ParseDialogBoxHeader(pdbh, &flStyle, &flExtStyle, &cdit, &x, &y, ! 320: &cx, &cy, &pszMenuName, &pszClass, &pszCaption, ! 321: &nPointSize, &pszFontName); ! 322: ! 323: Space(); ! 324: WriteCoords(x, y, cx, cy); ! 325: ! 326: NewLine(); ! 327: ! 328: /* ! 329: * Write the language. ! 330: */ ! 331: WriteDialogHeaderLanguage(pRes2->LanguageId); ! 332: ! 333: /* ! 334: * Print out the "STYLE" line for the dialog. ! 335: */ ! 336: WriteString(ids(IDS_STYLE)); ! 337: Space(); ! 338: SetTab(TABLEVELCONTROL); ! 339: WriteStyles(IC_DIALOG, NULL, flStyle, 0L, 0L, &flStyleLeft, TRUE, FALSE); ! 340: SetTab(TABLEVELNONE); ! 341: NewLine(); ! 342: ! 343: /* ! 344: * Print out the "EXSTYLE" line for the dialog, if necessary. ! 345: */ ! 346: if (flExtStyle) { ! 347: WriteString(ids(IDS_EXSTYLE)); ! 348: Space(); ! 349: SetTab(TABLEVELCONTROL); ! 350: ! 351: fWritten = WriteClassStyle(IC_EXSTYLE, flExtStyle, 0L, 0L, ! 352: &flStyleLeft, FALSE, TRUE, FALSE); ! 353: ! 354: /* ! 355: * If there is anything left (styles that the dialog editor ! 356: * does not know about) write it out as a hex constant. ! 357: */ ! 358: if (flStyleLeft) { ! 359: if (fWritten) ! 360: ORSymbol(); ! 361: ! 362: WriteHexDWord(flStyleLeft); ! 363: } ! 364: ! 365: SetTab(TABLEVELNONE); ! 366: NewLine(); ! 367: } ! 368: ! 369: /* ! 370: * If it has a caption, print it out. ! 371: */ ! 372: if (*pszCaption) { ! 373: WriteString(ids(IDS_CAPTION)); ! 374: Space(); ! 375: WriteText(pszCaption); ! 376: NewLine(); ! 377: } ! 378: ! 379: /* ! 380: * If it has a font specified, print it out. ! 381: */ ! 382: if (flStyle & DS_SETFONT) { ! 383: WriteString(ids(IDS_FONT)); ! 384: Space(); ! 385: ! 386: WriteValue(nPointSize); ! 387: Comma(); ! 388: WriteQuotedString(pszFontName); ! 389: NewLine(); ! 390: } ! 391: ! 392: /* ! 393: * If it has a class specified, print it out. ! 394: */ ! 395: if (*pszClass) { ! 396: WriteString(ids(IDS_CLASS)); ! 397: Space(); ! 398: WriteText(pszClass); ! 399: NewLine(); ! 400: } ! 401: ! 402: /* ! 403: * If it has a menu specified, print it out. ! 404: */ ! 405: if (*pszMenuName) { ! 406: WriteString(ids(IDS_MENU)); ! 407: Space(); ! 408: WriteNameOrd(pszMenuName); ! 409: NewLine(); ! 410: } ! 411: ! 412: if (pRes2->Version) { ! 413: WriteString(ids(IDS_VERSION)); ! 414: Space(); ! 415: WriteValue(pRes2->Version); ! 416: NewLine(); ! 417: } ! 418: ! 419: if (pRes2->Characteristics) { ! 420: WriteString(ids(IDS_CHARACTERISTICS)); ! 421: Space(); ! 422: WriteValue(pRes2->Characteristics); ! 423: NewLine(); ! 424: } ! 425: ! 426: return pcd; ! 427: } ! 428: ! 429: ! 430: ! 431: /************************************************************************ ! 432: * WriteDialogHeaderLanguage ! 433: * ! 434: * Writes out the dialog header "LANGUAGE" line. ! 435: * ! 436: * Arguments: ! 437: * WORD - language to write out ! 438: * ! 439: ************************************************************************/ ! 440: ! 441: STATICFN VOID WriteDialogHeaderLanguage( ! 442: WORD wLanguage) ! 443: { ! 444: WORD wPrimary; ! 445: WORD wSubLang; ! 446: INT i; ! 447: INT j; ! 448: INT idsLang; ! 449: INT idsSubLang; ! 450: ! 451: WriteString(ids(IDS_LANGUAGE)); ! 452: Space(); ! 453: ! 454: idsLang = 0; ! 455: idsSubLang = 0; ! 456: wPrimary = (WORD)PRIMARYLANGID(wLanguage); ! 457: wSubLang = SUBLANGID(wLanguage); ! 458: for (i = 0; i < gcLanguages; i++) { ! 459: if (gaLangTable[i].wPrimary == wPrimary) { ! 460: idsLang = gaLangTable[i].idsLang; ! 461: ! 462: for (j = 0; j < gaLangTable[i].cSubLangs; j++) { ! 463: if (gaLangTable[i].asl[j].wSubLang == wSubLang) { ! 464: idsSubLang = gaLangTable[i].asl[j].idsSubLang; ! 465: break; ! 466: } ! 467: } ! 468: ! 469: break; ! 470: } ! 471: } ! 472: ! 473: if (idsLang) ! 474: WriteString(ids(idsLang)); ! 475: else ! 476: WriteHexWord(wPrimary); ! 477: ! 478: Comma(); ! 479: ! 480: if (idsSubLang) ! 481: WriteString(ids(idsSubLang)); ! 482: else ! 483: WriteHexWord(wSubLang); ! 484: ! 485: NewLine(); ! 486: } ! 487: ! 488: ! 489: ! 490: /************************************************************************ ! 491: * WriteControl ! 492: * ! 493: * Writes out a control line. ! 494: * ! 495: * Arguments: ! 496: * PCONTROLDATA - pointer to the control data ! 497: * ! 498: ************************************************************************/ ! 499: ! 500: STATICFN PCONTROLDATA WriteControl( ! 501: PCONTROLDATA pcd) ! 502: { ! 503: INT x; ! 504: INT y; ! 505: INT cx; ! 506: INT cy; ! 507: INT id; ! 508: DWORD flStyle; ! 509: DWORD flExtStyle; ! 510: LPTSTR pszClass; ! 511: LPTSTR pszText; ! 512: INT iClass; ! 513: LPTSTR pszKeyword; ! 514: BOOL fWriteText; ! 515: BOOL fNotFound; ! 516: DWORD flStylePredef; ! 517: DWORD flStyleDefault; ! 518: DWORD flStyleLeft; ! 519: BOOL fWritten; ! 520: ! 521: pcd = ParseControlData(pcd, &flStyle, &flExtStyle, &x, &y, &cx, &cy, ! 522: &id, &pszClass, &pszText); ! 523: ! 524: /* ! 525: * Determine the class of the control. ! 526: */ ! 527: iClass = GetiClass(pszClass); ! 528: ! 529: /* ! 530: * Determine if there are any predefined RC keywords that we ! 531: * can use instead of the generic "CONTROL" keyword for this ! 532: * style of control. ! 533: */ ! 534: pszKeyword = GetControlKeyword(iClass, flStyle, &flStylePredef, ! 535: &flStyleDefault, &fWriteText, &fNotFound); ! 536: ! 537: SetTab(TABLEVELCONTROL); ! 538: Tab(); ! 539: WriteString(pszKeyword); ! 540: SetTab(TABLEVELCONTROLDESC); ! 541: Tab(); ! 542: ! 543: /* ! 544: * Write out the text field, if this type of control has one. ! 545: */ ! 546: if (fWriteText) { ! 547: WriteText(pszText); ! 548: Comma(); ! 549: } ! 550: ! 551: /* ! 552: * Write out the id for the control. ! 553: */ ! 554: WriteIDDlg(id, TRUE); ! 555: ! 556: /* ! 557: * If we did not find a predefined keyword to use instead of "CONTROL", ! 558: * we have to write out the fields in a different order, and specify ! 559: * the class as well. ! 560: */ ! 561: if (fNotFound) { ! 562: WriteClass(pszClass); ! 563: Comma(); ! 564: fWritten = WriteStyles(iClass, pszClass, flStyle, flStylePredef, ! 565: flStyleDefault, &flStyleLeft, fNotFound, FALSE); ! 566: ! 567: if (!fWritten || flStyleLeft) { ! 568: if (fWritten) ! 569: ORSymbol(); ! 570: ! 571: WriteHexWord(LOWORD(flStyleLeft)); ! 572: } ! 573: ! 574: Comma(); ! 575: WriteCoords(x, y, cx, cy); ! 576: } ! 577: else { ! 578: Comma(); ! 579: WriteCoords(x, y, cx, cy); ! 580: fWritten = WriteStyles(iClass, pszClass, flStyle, flStylePredef, ! 581: flStyleDefault, &flStyleLeft, fNotFound, TRUE); ! 582: ! 583: if (flStyleLeft) { ! 584: if (fWritten) ! 585: ORSymbol(); ! 586: else ! 587: Comma(); ! 588: ! 589: WriteHexWord(LOWORD(flStyleLeft)); ! 590: fWritten = TRUE; ! 591: } ! 592: } ! 593: ! 594: /* ! 595: * Write out the extended styles for the control, if necessary. ! 596: */ ! 597: if (flExtStyle) { ! 598: /* ! 599: * If writing a predefined keyword (not CONTROL), and there ! 600: * were no styles written out at the end of the line, write ! 601: * a style of zero. RC doesn't like consecutive comma's, ! 602: * and we need to skip the styles field to get to the ! 603: * extended styles field. ! 604: */ ! 605: if (!fNotFound && !fWritten) { ! 606: Comma(); ! 607: WriteValue(0); ! 608: } ! 609: ! 610: Comma(); ! 611: ! 612: fWritten = WriteClassStyle(IC_EXSTYLE, flExtStyle, 0L, 0L, ! 613: &flStyleLeft, FALSE, TRUE, FALSE); ! 614: ! 615: /* ! 616: * If there is anything left (styles that the dialog editor ! 617: * does not know about) write it out as a hex constant. ! 618: */ ! 619: if (flStyleLeft) { ! 620: if (fWritten) ! 621: ORSymbol(); ! 622: ! 623: WriteHexDWord(flStyleLeft); ! 624: } ! 625: } ! 626: ! 627: SetTab(TABLEVELNONE); ! 628: NewLine(); ! 629: ! 630: return pcd; ! 631: } ! 632: ! 633: ! 634: ! 635: /************************************************************************ ! 636: * WriteNameOrd ! 637: * ! 638: * Writes out the name/ordinal. Handles the case where the name ! 639: * is really an ordinal instead of a string. When it is a string, ! 640: * it will not be quoted. ! 641: * ! 642: * This routine never writes the ordinal out in hex, because the ! 643: * items that it is intended to write are not parsed properly by ! 644: * the Windows RC.EXE if they are written in hex notation. ! 645: * ! 646: * Arguments: ! 647: * LPTSTR pszNameOrd - The name/ordinal to write. ! 648: * ! 649: ************************************************************************/ ! 650: ! 651: STATICFN VOID WriteNameOrd( ! 652: LPTSTR pszNameOrd) ! 653: { ! 654: if (IsOrd(pszNameOrd)) ! 655: /* ! 656: * Write the name as a numeric ordinal. ! 657: */ ! 658: WriteIDDlg(OrdID(pszNameOrd), FALSE); ! 659: else ! 660: WriteString(pszNameOrd); ! 661: } ! 662: ! 663: ! 664: ! 665: /************************************************************************ ! 666: * WriteText ! 667: * ! 668: * Writes out the text for a control or dialog. This will either be ! 669: * an ordinal (icon's text field) or a quoted string. ! 670: * ! 671: * Arguments: ! 672: * LPTSTR pszText - text to write out ! 673: * ! 674: ************************************************************************/ ! 675: ! 676: STATICFN VOID WriteText( ! 677: LPTSTR pszText) ! 678: { ! 679: if (IsOrd(pszText)) ! 680: /* ! 681: * Write the text as an ID. Hex notation is allowed. ! 682: */ ! 683: WriteIDDlg(OrdID(pszText), TRUE); ! 684: else ! 685: WriteQuotedString(pszText); ! 686: } ! 687: ! 688: ! 689: ! 690: /************************************************************************ ! 691: * WriteIDDlg ! 692: * ! 693: * Writes out the ID. This may be written out as either a symbol ! 694: * or a numeric. ! 695: * ! 696: * Arguments: ! 697: * INT id - id to write out ! 698: * BOOL fHexOK - flag specifies whether the id is a hex numeric. ! 699: * ! 700: ************************************************************************/ ! 701: ! 702: STATICFN VOID WriteIDDlg( ! 703: INT id, ! 704: BOOL fHexOK) ! 705: { ! 706: TCHAR szID[CCHTEXTMAX]; ! 707: ! 708: IDToLabel(szID, id, fHexOK); ! 709: WriteString(szID); ! 710: } ! 711: ! 712: ! 713: ! 714: /************************************************************************ ! 715: * GetControlKeyword ! 716: * ! 717: * This routine does a lookup in the predefined RC keyword table ! 718: * associated with the given class for a keyword that can be used ! 719: * instead of "CONTROL". The match is based on the style of the control ! 720: * that is passed in. If a match is not found, it defaults all the ! 721: * returned values to use the "CONTROL" keyword. ! 722: * ! 723: * Arguments: ! 724: * INT iClass - The class of the control. ! 725: * DWORD flStyle - The style of the control. ! 726: * DWORD *pflStylePredef - Return for the bits of the predefined control ! 727: * (if found). These can be removed later from ! 728: * the style flag. ! 729: * DWORD *pflStyleDefault - Return for the default styles. ! 730: * BOOL *pfWriteText - Return for the "Write Text" flag. This will ! 731: * be TRUE if this control has a text field. ! 732: * BOOL *pfNotFound - Return for the "Not Found" flag. This will ! 733: * be TRUE if no match was found and the "CONTROL" ! 734: * keyword was defaulted to. ! 735: * ! 736: * Returns: ! 737: * A pointer to the control keyword to use. ! 738: * If a match was found, *pflStylePredef is set to the bits for the match. ! 739: * If not found, this is set to zero. ! 740: * The default style bits for this keyword will be returned. ! 741: * The "Write Text" flag will be set. ! 742: * The "Not Found" flag will be set. ! 743: * ! 744: ************************************************************************/ ! 745: ! 746: STATICFN LPTSTR GetControlKeyword( ! 747: INT iClass, ! 748: DWORD flStyle, ! 749: DWORD *pflStylePredef, ! 750: DWORD *pflStyleDefault, ! 751: BOOL *pfWriteText, ! 752: BOOL *pfNotFound) ! 753: { ! 754: register INT i; ! 755: INT iMax; ! 756: PRCKEYWORD prckwd; ! 757: ! 758: if (gfUseNewKeywords && iClass != IC_UNKNOWN) { ! 759: iMax = acsd[iClass].cKeywords; ! 760: prckwd = acsd[iClass].parckwd; ! 761: ! 762: /* ! 763: * Loop through all the keywords for this class. ! 764: */ ! 765: for (i = 0; i < iMax; i++, prckwd++) { ! 766: /* ! 767: * Does the style (masked) exactly match the keywords style? ! 768: */ ! 769: if ((flStyle & prckwd->flStyleMask) == prckwd->flStyle) { ! 770: /* ! 771: * Yes. Set the "Has Text" flag, we did find a match, ! 772: * put the found bits in the predefined style flag, ! 773: * set the default styles flag and return the found ! 774: * keyword. ! 775: */ ! 776: *pfWriteText = prckwd->fHasText; ! 777: *pfNotFound = FALSE; ! 778: *pflStylePredef = prckwd->flStyle; ! 779: *pflStyleDefault = prckwd->flStyleDefault; ! 780: return ids(prckwd->idsKeyword); ! 781: } ! 782: } ! 783: } ! 784: ! 785: /* ! 786: * A match was not found. We must write text, we didn't find a ! 787: * match, we will be using the "CONTROL" keyword and the default ! 788: * styles that this keyword implies is the "child" and "visible" ! 789: * bits (rc.exe OR's these styles in implicitly). ! 790: */ ! 791: *pfWriteText = TRUE; ! 792: *pfNotFound = TRUE; ! 793: *pflStylePredef = 0L; ! 794: *pflStyleDefault = WS_VISIBLE | WS_CHILD; ! 795: return ids(IDS_CONTROL); ! 796: } ! 797: ! 798: ! 799: ! 800: /************************************************************************ ! 801: * WriteClass ! 802: * ! 803: * Writes out the class for a control. ! 804: * ! 805: * Arguments: ! 806: * LPTSTR pszClass - pointer to the class string ! 807: * ! 808: ************************************************************************/ ! 809: ! 810: STATICFN VOID WriteClass( ! 811: LPTSTR pszClass) ! 812: { ! 813: INT i; ! 814: WORD idOrd; ! 815: ! 816: Comma(); ! 817: ! 818: /* ! 819: * Is this class a predefined type instead of a string? ! 820: */ ! 821: if (IsOrd(pszClass)) { ! 822: /* ! 823: * Figure out which type it is and get the class string to ! 824: * write. ! 825: */ ! 826: idOrd = OrdID(pszClass); ! 827: for (i = 0; i < IC_DIALOG; i++) { ! 828: if (acsd[i].idOrd == idOrd) { ! 829: pszClass = ids(acsd[i].idsClass); ! 830: break; ! 831: } ! 832: } ! 833: } ! 834: ! 835: WriteQuotedString(pszClass); ! 836: } ! 837: ! 838: ! 839: ! 840: /************************************************************************ ! 841: * WriteStyles ! 842: * ! 843: * This function writes the class and style info to the file ! 844: * for the control or dialog box in the RC format. ! 845: * ! 846: * Arguments: ! 847: * INT iClass = The class of the item. ! 848: * LPTSTR pszClass = Class name of the control. ! 849: * DWORD flStyle = The style of the item. ! 850: * DWORD flStylePredef = The styles bits implicit in the predefined ! 851: * keyword for this control. This should be ! 852: * zero if this control doesn't have a predefined ! 853: * keyword for it. ! 854: * DWORD flStyleDefault = The default styles implicit in the item. ! 855: * PDWORD pflStyleLeft = Where to return any style bits that do not ! 856: * get written out. ! 857: * BOOL fNullStyles = TRUE if we should still write the style word ! 858: * even if the style flag is zero. ! 859: * BOOL fCommaPrefix = TRUE means that a comma will be written out ! 860: * before writing any styles. If no styles ! 861: * are written, no comma will be written either. ! 862: * ! 863: * Returns: ! 864: * TRUE => Something was written out. ! 865: * FALSE => Nothing was written out. ! 866: * ! 867: ************************************************************************/ ! 868: ! 869: STATICFN BOOL WriteStyles( ! 870: INT iClass, ! 871: LPTSTR pszClass, ! 872: DWORD flStyle, ! 873: DWORD flStylePredef, ! 874: DWORD flStyleDefault, ! 875: PDWORD pflStyleLeft, ! 876: BOOL fNullStyles, ! 877: BOOL fCommaPrefix) ! 878: { ! 879: DWORD flStyleLeft; ! 880: BOOL fWritten = FALSE; ! 881: ! 882: /* ! 883: * Write the control specific styles. ! 884: */ ! 885: if (iClass == IC_CUSTOM) { ! 886: fWritten = WriteCustomStyle(pszClass, flStyle, &flStyleLeft); ! 887: } ! 888: else { ! 889: fWritten = WriteClassStyle(iClass, flStyle, flStylePredef, ! 890: flStyleDefault, &flStyleLeft, FALSE, fNullStyles, ! 891: fCommaPrefix); ! 892: } ! 893: ! 894: /* ! 895: * If we are writing styles for the dialog, remove the WS_GROUP ! 896: * and WS_TABSTOP bits from the style before proceeding. This is ! 897: * because the WS_MINIMIZEBOX and WS_MAXIMIZEBOX styles use the ! 898: * same bits, and these keywords will have already been written ! 899: * out by the preceding WriteClassStyle call if those bits are ! 900: * present. ! 901: */ ! 902: if (iClass == IC_DIALOG) ! 903: flStyle &= ~(WS_GROUP | WS_TABSTOP); ! 904: ! 905: /* ! 906: * Write the window styles that are common to the different ! 907: * controls (the high word). ! 908: */ ! 909: fWritten |= WriteClassStyle(IC_WINDOW, flStyleLeft, flStylePredef, ! 910: flStyleDefault, &flStyleLeft, fWritten, fNullStyles, fCommaPrefix); ! 911: ! 912: /* ! 913: * Pass back any styles that were not written. ! 914: */ ! 915: *pflStyleLeft = flStyleLeft; ! 916: ! 917: return fWritten; ! 918: } ! 919: ! 920: ! 921: ! 922: /************************************************************************ ! 923: * WriteClassStyle ! 924: * ! 925: * This function writes the class style symbols to the file. The styles ! 926: * to write out are passed in flStyle, and the styles that are implicitly ! 927: * set by this type of control already are passed in flStyleDefault. The ! 928: * style keywords corresponding to the bits in flStyle are written out, ! 929: * separated by " | ", and any bits in flStyleDefault that are NOT set ! 930: * are written out preceded by a "NOT" to explicitly turn them off. This ! 931: * is used in the case of the predefined RC keywords, which often have ! 932: * styles like WS_TABSTOP or WS_VISIBLE already implicit in them. There ! 933: * is no need to explicitly specify them, but if they are not present, we ! 934: * must NOT them out. The parameter flStylePredef contains the style bits ! 935: * that identified the predefined control keyword itself (if any) and ! 936: * thus are removed from the style before writing anything out. ! 937: * ! 938: * Arguments: ! 939: * INT iClass = The class of the control. See the ! 940: * IC_ constants defined in dlgedit.h. ! 941: * DWORD flStyle = The style of control. This nails ! 942: * down the exact type of control. ! 943: * DWORD flStylePredef = The styles bits implicit in the predefined ! 944: * keyword for this control. This should be ! 945: * zero if this control doesn't have a predefined ! 946: * keyword for it. ! 947: * DWORD flStyleDefault = The default styles that are implicit with ! 948: * this control. This will only be set if this ! 949: * control is using a predefined RC keyword. A ! 950: * value of zero means that there are no default ! 951: * styles implicitly specified. ! 952: * PDWORD pflStyleLeft = Where to return any style bits that do not ! 953: * get written out. ! 954: * BOOL fPrevWritten = TRUE means a previous style symbol has ! 955: * been written and to put " | " before ! 956: * the next symbol. ! 957: * BOOL fNullStyles = TRUE if we should still write the style word ! 958: * even if the style flag is zero. This is used ! 959: * to handle the case where a predefined keyword ! 960: * has been written out that implies a style that ! 961: * also happens to be zero. Without this flag ! 962: * being FALSE the style flag implicit in the ! 963: * keyword would be redundantly written out again. ! 964: * In general, if we have written out a predefined ! 965: * keyword this flag should be FALSE. ! 966: * BOOL fCommaPrefix = TRUE means that a comma will be written out ! 967: * before writing any styles. This will only ! 968: * happen if fPrevWritten is FALSE. If no styles ! 969: * are written, no comma will be written either. ! 970: * ! 971: * Returns: ! 972: * TRUE => Something was written out. ! 973: * FALSE => Nothing was written out. ! 974: * ! 975: ************************************************************************/ ! 976: ! 977: STATICFN BOOL WriteClassStyle( ! 978: INT iClass, ! 979: DWORD flStyle, ! 980: DWORD flStylePredef, ! 981: DWORD flStyleDefault, ! 982: PDWORD pflStyleLeft, ! 983: BOOL fPrevWritten, ! 984: BOOL fNullStyles, ! 985: BOOL fCommaPrefix) ! 986: { ! 987: register WORD i; ! 988: WORD iMax; ! 989: DWORD flStyleMask; ! 990: PCLASSSTYLE pcs; ! 991: ! 992: iMax = (WORD)acsd[iClass].cClassStyles; ! 993: pcs = acsd[iClass].pacs; ! 994: ! 995: /* ! 996: * Remove the bits that identified the predefined control keyword ! 997: * from the style flag before proceeding. For instance, if I already ! 998: * am going to be writing out a "PUSHBUTTON", there is no reason ! 999: * to write out the "BS_PUSHBUTTON" style. If there is no predefined ! 1000: * control keyword, flStylePredef will be zero and this will do ! 1001: * nothing. ! 1002: */ ! 1003: flStyle &= ~flStylePredef; ! 1004: ! 1005: /* ! 1006: * Go through all possible flags for this style. ! 1007: */ ! 1008: for (i = 0; i < iMax; i++, pcs++) { ! 1009: flStyleMask = pcs->flStyleMask ? pcs->flStyleMask : pcs->flStyle; ! 1010: ! 1011: /* ! 1012: * Is this styles bits set? ! 1013: */ ! 1014: if ((flStyle & flStyleMask) == pcs->flStyle) { ! 1015: /* ! 1016: * Remove these bits from the styles left. Even if ! 1017: * we do not write them out, they are still accounted ! 1018: * for and can be removed from the styles remaining. ! 1019: */ ! 1020: flStyle &= ~pcs->flStyle; ! 1021: ! 1022: /* ! 1023: * Skip this style if we don't want to write styles that are ! 1024: * zero, or if the style is already implicitly specified for ! 1025: * this control (a non-zero default style mask must be specified). ! 1026: */ ! 1027: if ((!pcs->flStyle && !fNullStyles) || ! 1028: (flStyleDefault && ! 1029: (flStyleDefault & flStyleMask) == pcs->flStyle)) ! 1030: continue; ! 1031: ! 1032: /* ! 1033: * If there is a string for this style, write it out, preceded ! 1034: * by an "|" symbol if necessary. ! 1035: */ ! 1036: if (*ids(acsd[iClass].idsStylesStart + i)) { ! 1037: if (fPrevWritten) { ! 1038: ORSymbol(); ! 1039: } ! 1040: else { ! 1041: if (fCommaPrefix) ! 1042: Comma(); ! 1043: ! 1044: fPrevWritten = TRUE; ! 1045: } ! 1046: ! 1047: /* ! 1048: * Write the string. ! 1049: */ ! 1050: WriteString(ids(acsd[iClass].idsStylesStart + i)); ! 1051: } ! 1052: } ! 1053: /* ! 1054: * No the styles bit is not set. Is it implicit in the keyword ! 1055: * being used? If so, we need to explicitly NOT it ! 1056: * out in the dialog template. ! 1057: * Note that this should not be done in the case where the style ! 1058: * is zero. ! 1059: */ ! 1060: else if (flStyleDefault && ! 1061: (flStyleDefault & flStyleMask) == pcs->flStyle && ! 1062: pcs->flStyle) { ! 1063: if (fPrevWritten) { ! 1064: ORSymbol(); ! 1065: } ! 1066: else { ! 1067: if (fCommaPrefix) ! 1068: Comma(); ! 1069: ! 1070: fPrevWritten = TRUE; ! 1071: } ! 1072: ! 1073: WriteString(ids(IDS_NOT)); ! 1074: Space(); ! 1075: WriteString(ids(acsd[iClass].idsStylesStart + i)); ! 1076: } ! 1077: } ! 1078: ! 1079: /* ! 1080: * Pass back the style bits that were not written out. ! 1081: */ ! 1082: *pflStyleLeft = flStyle; ! 1083: ! 1084: return fPrevWritten; ! 1085: } ! 1086: ! 1087: ! 1088: ! 1089: /************************************************************************ ! 1090: * WriteCustomStyle ! 1091: * ! 1092: * Writes our the custom control information ! 1093: * ! 1094: * Arguments: ! 1095: * LPTSTR - class name of the control ! 1096: * DWORD - style of the control ! 1097: * PDWORD - styles left to be written ! 1098: * ! 1099: * Returns: ! 1100: * TRUE if custom styles were written out; otherwise, FALSE. ! 1101: * ! 1102: ************************************************************************/ ! 1103: ! 1104: STATICFN BOOL WriteCustomStyle( ! 1105: LPTSTR pszClass, ! 1106: DWORD flStyle, ! 1107: PDWORD pflStyleLeft) ! 1108: { ! 1109: PCUSTLINK pcl; ! 1110: LPCCSTYLEFLAG pStyleFlags; ! 1111: DWORD flStyleMask; ! 1112: INT i; ! 1113: BOOL fWritten = FALSE; ! 1114: ! 1115: /* ! 1116: * Search the list of installed custom controls for one ! 1117: * that matches the class. ! 1118: */ ! 1119: for (pcl = gpclHead; ! 1120: pcl && lstrcmpi(pcl->pwcd->pszClass, pszClass) != 0; ! 1121: pcl = pcl->pclNext) ! 1122: ; ! 1123: ! 1124: /* ! 1125: * Was a match found and is this control from a DLL (not emulated)? ! 1126: */ ! 1127: if (pcl && !pcl->pwcd->fEmulated) { ! 1128: for (i = 0, pStyleFlags = pcl->pwcd->aStyleFlags; ! 1129: i < pcl->pwcd->cStyleFlags; ! 1130: i++, pStyleFlags++) { ! 1131: flStyleMask = pStyleFlags->flStyleMask ? ! 1132: pStyleFlags->flStyleMask : pStyleFlags->flStyle; ! 1133: ! 1134: /* ! 1135: * Is this styles bits set? ! 1136: */ ! 1137: if ((flStyle & flStyleMask) == pStyleFlags->flStyle) { ! 1138: /* ! 1139: * Remove these bits from the styles left. ! 1140: */ ! 1141: flStyle &= ~pStyleFlags->flStyle; ! 1142: ! 1143: if (fWritten) ! 1144: ORSymbol(); ! 1145: else ! 1146: fWritten = TRUE; ! 1147: ! 1148: /* ! 1149: * Write the string. ! 1150: */ ! 1151: WriteString(pStyleFlags->pszStyle); ! 1152: } ! 1153: } ! 1154: } ! 1155: ! 1156: /* ! 1157: * Return the styles that remain to be written. ! 1158: */ ! 1159: *pflStyleLeft = flStyle; ! 1160: ! 1161: return fWritten; ! 1162: } ! 1163: ! 1164: ! 1165: ! 1166: /************************************************************************ ! 1167: * WriteCoords ! 1168: * ! 1169: * This function writes the coordinates out to the file as decimal ! 1170: * ascii numbers separated by ", ". ! 1171: * ! 1172: * Arguments: ! 1173: * INT x, y, cx, cy = The coordinates. ! 1174: * ! 1175: ************************************************************************/ ! 1176: ! 1177: STATICFN VOID WriteCoords( ! 1178: INT x, ! 1179: INT y, ! 1180: INT cx, ! 1181: INT cy) ! 1182: { ! 1183: WriteValue(x); ! 1184: Comma(); ! 1185: WriteValue(y); ! 1186: Comma(); ! 1187: WriteValue(cx); ! 1188: Comma(); ! 1189: WriteValue(cy); ! 1190: } ! 1191: ! 1192: ! 1193: ! 1194: /************************************************************************ ! 1195: * WriteValue ! 1196: * ! 1197: * This function writes the value of 'n' as a decimal ascii string to ! 1198: * the file. ! 1199: * ! 1200: * Arguments: ! 1201: * INT n = The number to write. ! 1202: * ! 1203: ************************************************************************/ ! 1204: ! 1205: STATICFN VOID WriteValue( ! 1206: INT n) ! 1207: { ! 1208: TCHAR szNum[32]; ! 1209: ! 1210: itoaw(n, szNum, 10); ! 1211: WriteString(szNum); ! 1212: } ! 1213: ! 1214: ! 1215: ! 1216: /************************************************************************ ! 1217: * WriteHexWord ! 1218: * ! 1219: * This function writes the value of 'w' as a hex constant to the file. ! 1220: * ! 1221: * Arguments: ! 1222: * WORD w - The word to write. ! 1223: * ! 1224: ************************************************************************/ ! 1225: ! 1226: STATICFN VOID WriteHexWord( ! 1227: WORD w) ! 1228: { ! 1229: TCHAR szNum[17]; ! 1230: ! 1231: itoax(w, szNum); ! 1232: WriteString(szNum); ! 1233: } ! 1234: ! 1235: ! 1236: ! 1237: /************************************************************************ ! 1238: * WriteHexDWord ! 1239: * ! 1240: * This function writes the value of 'dw' as a hex constant to the file. ! 1241: * ! 1242: * Arguments: ! 1243: * DWORD dw - The dword to write. ! 1244: * ! 1245: ************************************************************************/ ! 1246: ! 1247: STATICFN VOID WriteHexDWord( ! 1248: DWORD dw) ! 1249: { ! 1250: TCHAR szNum[32]; ! 1251: ! 1252: wsprintf(szNum, L"0x%8.8X", dw); ! 1253: WriteString(szNum); ! 1254: } ! 1255: ! 1256: ! 1257: ! 1258: /************************************************************************ ! 1259: * WriteString ! 1260: * ! 1261: * This function writes the given string to the file. If the string ! 1262: * would cause it to overflow the margin, a new line, with indenting ! 1263: * to the current tab level, is forced before writing the string. ! 1264: * ! 1265: * Arguments: ! 1266: * LPTSTR psz = The string to write out. ! 1267: * ! 1268: ************************************************************************/ ! 1269: ! 1270: STATICFN VOID WriteString( ! 1271: LPTSTR psz) ! 1272: { ! 1273: register INT nLen; ! 1274: ! 1275: nLen = lstrlen(psz); ! 1276: ! 1277: if (!AtFirstTabColumn() && cColumn + nLen > CCHRIGHTMARGIN) ! 1278: NewLine(); ! 1279: ! 1280: while (nLen--) ! 1281: WriteDlgChar(*psz++); ! 1282: } ! 1283: ! 1284: ! 1285: ! 1286: /************************************************************************ ! 1287: * WriteQuotedString ! 1288: * ! 1289: * This function writes the given string to the file. If the string ! 1290: * would cause it to overflow the margin, a new line, with indenting ! 1291: * to the current tab level, is forced before writing the string. ! 1292: * This function will also enclose the given string in double-quotes, ! 1293: * and ensures that the string will not be broken when it is written. ! 1294: * If there are any escape characters (backslashes or quotes) in the ! 1295: * string, they will be escaped properly so that rc.exe can read them ! 1296: * properly. ! 1297: * ! 1298: * Arguments: ! 1299: * LPTSTR psz = The string to write out. ! 1300: * ! 1301: ************************************************************************/ ! 1302: ! 1303: STATICFN VOID WriteQuotedString( ! 1304: LPTSTR psz) ! 1305: { ! 1306: register INT nLen; ! 1307: LPTSTR pszT; ! 1308: ! 1309: /* ! 1310: * Find the actual length of the string. To do this, we must scan ! 1311: * for the characters that will be escaped later. ! 1312: */ ! 1313: nLen = lstrlen(psz); ! 1314: pszT = psz; ! 1315: while (*pszT) { ! 1316: if (*pszT == CHAR_DBLQUOTE || *pszT == CHAR_BACKSLASH) ! 1317: nLen++; ! 1318: ! 1319: pszT++; ! 1320: } ! 1321: ! 1322: /* ! 1323: * Start a new line if necessary. Add 2 for the quotes. ! 1324: */ ! 1325: if (!AtFirstTabColumn() && cColumn + nLen + 2 > CCHRIGHTMARGIN) ! 1326: NewLine(); ! 1327: ! 1328: Quote(); ! 1329: WriteEscapedString(psz); ! 1330: Quote(); ! 1331: } ! 1332: ! 1333: ! 1334: ! 1335: /************************************************************************ ! 1336: * WriteEscapedString ! 1337: * ! 1338: * This function writes the given string to the file. It is different ! 1339: * from WriteString in that it will add a '\' in front of other ! 1340: * backslashes and a second double quote in front of double quotes. ! 1341: * This is necessary when writing out a string which will be surrounded ! 1342: * by quotes, such as the Text fields in the .DLG file. ! 1343: * ! 1344: * Arguments: ! 1345: * LPTSTR psz = The string to write out. ! 1346: * ! 1347: ************************************************************************/ ! 1348: ! 1349: STATICFN VOID WriteEscapedString( ! 1350: LPTSTR psz) ! 1351: { ! 1352: while (*psz) { ! 1353: if (*psz == CHAR_DBLQUOTE) ! 1354: WriteDlgChar(CHAR_DBLQUOTE); ! 1355: else if (*psz == CHAR_BACKSLASH) ! 1356: WriteDlgChar(CHAR_BACKSLASH); ! 1357: ! 1358: WriteDlgChar(*psz++); ! 1359: } ! 1360: } ! 1361: ! 1362: ! 1363: ! 1364: /************************************************************************ ! 1365: * WriteDlgChar ! 1366: * ! 1367: * Low level function to do an actual character write to the file. ! 1368: * Some buffering is done then _lwrite is called. ! 1369: * ! 1370: * Because it is buffered, before closing the file any remaining ! 1371: * characters in the buffer must be flushed to disk using WriteDlgFlush. ! 1372: * ! 1373: * If an error occurs on the write, Throw will be called to jump back ! 1374: * up to WriteDlg and return the failure to the caller. ! 1375: * ! 1376: * The globals gachWriteBuffer and cbWritePos are updated by this routine. ! 1377: * ! 1378: * Arguments: ! 1379: * TCHAR ch - The character to write. ! 1380: * ! 1381: * Returns: ! 1382: * If an error occurs on the _lwrite, the execution will be thrown ! 1383: * back to the WriteDlg function. Otherwise, nothing is returned. ! 1384: * ! 1385: ************************************************************************/ ! 1386: ! 1387: STATICFN VOID WriteDlgChar( ! 1388: TCHAR ch) ! 1389: { ! 1390: INT cbWritten; ! 1391: ! 1392: gachWriteBuffer[cbWritePos++] = ch; ! 1393: ! 1394: /* ! 1395: * Is the buffer full? ! 1396: */ ! 1397: if (cbWritePos == CCHFILEBUFFER) { ! 1398: CHAR abWriteBuffer[CCHFILEBUFFER]; ! 1399: BOOL fDefCharUsed; ! 1400: ! 1401: WideCharToMultiByte(CP_ACP, 0, gachWriteBuffer, CCHFILEBUFFER, ! 1402: abWriteBuffer, CCHFILEBUFFER, NULL, &fDefCharUsed); ! 1403: ! 1404: cbWritten = (INT)_lwrite((HFILE)hfDlg, abWriteBuffer, cbWritePos); ! 1405: if (cbWritten != cbWritePos) ! 1406: longjmp(jbWriteDlg, 1); ! 1407: ! 1408: cbWritePos = 0; ! 1409: } ! 1410: ! 1411: /* ! 1412: * Update the current column counter. ! 1413: */ ! 1414: if (ch == CHAR_RETURN || ch == CHAR_NEWLINE) { ! 1415: /* ! 1416: * Carriage return or newline resets column position to 0. ! 1417: */ ! 1418: cColumn = 0; ! 1419: } ! 1420: else { ! 1421: cColumn++; ! 1422: } ! 1423: } ! 1424: ! 1425: ! 1426: ! 1427: /************************************************************************ ! 1428: * WriteDlgFlush ! 1429: * ! 1430: * This routine flushes the write buffer. This must be done before ! 1431: * the file is closed or data can be lost. ! 1432: * ! 1433: * The global cbWritePos is updated by this routine. ! 1434: * ! 1435: * Returns: ! 1436: * If an error occurs on the _lwrite, the execution will be thrown ! 1437: * back to the WriteDlg function. Otherwise, nothing is returned. ! 1438: * ! 1439: ************************************************************************/ ! 1440: ! 1441: STATICFN VOID WriteDlgFlush(VOID) ! 1442: { ! 1443: INT cbWritten; ! 1444: ! 1445: /* ! 1446: * Are any bytes remaining in the buffer? ! 1447: */ ! 1448: if (cbWritePos) { ! 1449: CHAR abWriteBuffer[CCHFILEBUFFER]; ! 1450: BOOL fDefCharUsed; ! 1451: ! 1452: WideCharToMultiByte(CP_ACP, 0, gachWriteBuffer, cbWritePos, ! 1453: abWriteBuffer, CCHFILEBUFFER, NULL, &fDefCharUsed); ! 1454: ! 1455: cbWritten = (INT)_lwrite((HFILE)hfDlg, abWriteBuffer, cbWritePos); ! 1456: if (cbWritten != cbWritePos) ! 1457: longjmp(jbWriteDlg, 1); ! 1458: ! 1459: cbWritePos = 0; ! 1460: } ! 1461: } ! 1462: ! 1463: ! 1464: ! 1465: /**************************************************************************** ! 1466: * Tab ! 1467: * ! 1468: * Writes spaces up to the current tab level setting. ! 1469: * ! 1470: ****************************************************************************/ ! 1471: ! 1472: STATICFN VOID Tab(VOID) ! 1473: { ! 1474: while (cColumn < cTabStop) ! 1475: WriteDlgChar(CHAR_SPACE); ! 1476: } ! 1477: ! 1478: ! 1479: ! 1480: /**************************************************************************** ! 1481: * NewLine ! 1482: * ! 1483: * Begins a new line by writing a carriage return and linefeed. Also ! 1484: * indents the following line up to the current tab level. ! 1485: * ! 1486: ****************************************************************************/ ! 1487: ! 1488: STATICFN VOID NewLine(VOID) ! 1489: { ! 1490: WriteDlgChar(CHAR_RETURN); ! 1491: WriteDlgChar(CHAR_NEWLINE); ! 1492: Tab(); ! 1493: } ! 1494: ! 1495: ! 1496: ! 1497: /**************************************************************************** ! 1498: * Quote ! 1499: * ! 1500: * Writes a double quote. ! 1501: * ! 1502: ****************************************************************************/ ! 1503: ! 1504: STATICFN VOID Quote(VOID) ! 1505: { ! 1506: WriteDlgChar(CHAR_DBLQUOTE); ! 1507: } ! 1508: ! 1509: ! 1510: ! 1511: /**************************************************************************** ! 1512: * Comma ! 1513: * ! 1514: * Writes a comma then a space. ! 1515: * ! 1516: ****************************************************************************/ ! 1517: ! 1518: STATICFN VOID Comma(VOID) ! 1519: { ! 1520: WriteDlgChar(CHAR_COMMA); ! 1521: WriteDlgChar(CHAR_SPACE); ! 1522: } ! 1523: ! 1524: ! 1525: ! 1526: /**************************************************************************** ! 1527: * Space ! 1528: * ! 1529: * Writes a space. ! 1530: * ! 1531: ****************************************************************************/ ! 1532: ! 1533: STATICFN VOID Space(VOID) ! 1534: { ! 1535: WriteDlgChar(CHAR_SPACE); ! 1536: } ! 1537: ! 1538: ! 1539: ! 1540: /**************************************************************************** ! 1541: * ORSymbol ! 1542: * ! 1543: * Writes " | ". ! 1544: * ! 1545: ****************************************************************************/ ! 1546: ! 1547: STATICFN VOID ORSymbol(VOID) ! 1548: { ! 1549: WriteDlgChar(CHAR_SPACE); ! 1550: WriteDlgChar(CHAR_ORSYMBOL); ! 1551: WriteDlgChar(CHAR_SPACE); ! 1552: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.