|
|
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: menu.c ! 14: * ! 15: * Contains the main menu switching functions and the clipboard functions. ! 16: * ! 17: * Functions: ! 18: * DialogMenu() ! 19: * LoadMenuBitmaps() ! 20: * FreeMenuBitmaps() ! 21: * InitMenu() ! 22: * MsgFilterHookFunc() ! 23: * ShowHelp() ! 24: * CopyToClipboard() ! 25: * DlgInClipboard() ! 26: * PasteFromClipboard() ! 27: * GetHelpContext() ! 28: * ! 29: * Comments: ! 30: * ! 31: ****************************************************************************/ ! 32: ! 33: #include "dlgedit.h" ! 34: #include "dlgfuncs.h" ! 35: #include "dlgextrn.h" ! 36: #include "dialogs.h" ! 37: ! 38: #include <string.h> ! 39: ! 40: ! 41: #define MM10PERINCH 254 // Tenths of a millimeter per inch. ! 42: ! 43: typedef struct { ! 44: WORD idm; ! 45: INT idbm; ! 46: HBITMAP hbm; ! 47: } BITMAPMENU; ! 48: ! 49: ! 50: STATICFN VOID CopyToClipboard(VOID); ! 51: STATICFN BOOL DlgInClipboard(VOID); ! 52: STATICFN VOID PasteFromClipboard(VOID); ! 53: STATICFN INT GetHelpContext(INT idSubject, PHELPMAP phmap); ! 54: ! 55: ! 56: static BITMAPMENU bmpmenuTable[] = { ! 57: {MENU_ALIGNLEFT, IDBM_ALEFT, NULL }, ! 58: {MENU_ALIGNVERT, IDBM_AVERT, NULL }, ! 59: {MENU_ALIGNRIGHT, IDBM_ARIGHT, NULL }, ! 60: {MENU_ALIGNTOP, IDBM_ATOP, NULL }, ! 61: {MENU_ALIGNHORZ, IDBM_AHORZ, NULL }, ! 62: {MENU_ALIGNBOTTOM, IDBM_ABOTTOM, NULL }, ! 63: {MENU_SPACEVERT, IDBM_ASPCVERT, NULL }, ! 64: {MENU_SPACEHORZ, IDBM_ASPCHORZ, NULL }, ! 65: {MENU_ARRSIZEWIDTH, IDBM_ASZWIDTH, NULL }, ! 66: {MENU_ARRSIZEHEIGHT, IDBM_ASZHGHT, NULL }, ! 67: {MENU_ARRPUSHBOTTOM, IDBM_APBBOTTM, NULL }, ! 68: {MENU_ARRPUSHRIGHT, IDBM_APBRIGHT, NULL } ! 69: }; ! 70: ! 71: ! 72: ! 73: /************************************************************************ ! 74: * DialogMenu ! 75: * ! 76: * This is the main switching function to send menu commands to the ! 77: * appropriate function. ! 78: * ! 79: * Arguments: ! 80: * INT - the menu command ! 81: * ! 82: ************************************************************************/ ! 83: ! 84: VOID DialogMenu( ! 85: INT cmd) ! 86: { ! 87: /* ! 88: * Be sure any outstanding changes get applied without errors. ! 89: */ ! 90: if (!StatusApplyChanges()) ! 91: return; ! 92: ! 93: switch (cmd) { ! 94: ! 95: /* ! 96: * File menu ---------------------------------------------------- ! 97: */ ! 98: ! 99: case MENU_NEWRES: ! 100: if (DoWeSave(FILE_INCLUDE) == IDCANCEL || ! 101: DoWeSave(FILE_RESOURCE) == IDCANCEL) ! 102: break; ! 103: ! 104: FreeInclude(); ! 105: FreeRes(); ! 106: AddNewDialog(); ! 107: ShowFileStatus(TRUE); ! 108: break; ! 109: ! 110: case MENU_OPEN: ! 111: if (DoWeSave(FILE_INCLUDE) == IDCANCEL || ! 112: DoWeSave(FILE_RESOURCE) == IDCANCEL) ! 113: break; ! 114: ! 115: Open(FILE_RESOURCE); ! 116: ! 117: break; ! 118: ! 119: case MENU_SAVE: ! 120: if (gfIncChged) { ! 121: if (!Save(FILE_NOSHOW | FILE_INCLUDE)) ! 122: break; ! 123: } ! 124: ! 125: if (gfResChged) ! 126: Save(FILE_NOSHOW | FILE_RESOURCE); ! 127: ! 128: break; ! 129: ! 130: case MENU_SAVEAS: ! 131: /* ! 132: * Save the include file, but only if there is one. ! 133: */ ! 134: if (pszIncludeFile || plInclude) { ! 135: if (!Save(FILE_NOSHOW | FILE_INCLUDE | FILE_SAVEAS)) ! 136: break; ! 137: } ! 138: ! 139: /* ! 140: * Save the resource file. ! 141: */ ! 142: Save(FILE_NOSHOW | FILE_RESOURCE | FILE_SAVEAS); ! 143: ! 144: break; ! 145: ! 146: case MENU_NEWCUST: ! 147: DlgBox(DID_NEWCUST, (WNDPROC)NewCustDlgProc); ! 148: break; ! 149: ! 150: case MENU_OPENCUST: ! 151: OpenCustomDialog(); ! 152: break; ! 153: ! 154: case MENU_REMCUST: ! 155: DlgBox(DID_REMCUST, (WNDPROC)RemCustDlgProc); ! 156: break; ! 157: ! 158: case MENU_SETINCLUDE: ! 159: if (DoWeSave(FILE_INCLUDE) != IDCANCEL) ! 160: Open(FILE_INCLUDE); ! 161: ! 162: break; ! 163: ! 164: case MENU_EXIT: ! 165: PostMessage(ghwndMain, WM_CLOSE, 0, 0L); ! 166: break; ! 167: ! 168: /* ! 169: * Edit menu ---------------------------------------------------- ! 170: */ ! 171: ! 172: case MENU_RESTOREDIALOG: ! 173: RestoreDialog(); ! 174: break; ! 175: ! 176: case MENU_CUT: ! 177: case MENU_COPY: ! 178: if (gfEditingDlg) { ! 179: /* ! 180: * Save current stuff in clipboard. ! 181: */ ! 182: CopyToClipboard(); ! 183: ! 184: /* ! 185: * Clear the selection if they did a "cut" instead of ! 186: * a "copy". ! 187: */ ! 188: if (cmd == MENU_CUT) ! 189: DeleteControl(); ! 190: } ! 191: ! 192: break; ! 193: ! 194: case MENU_PASTE: ! 195: PasteFromClipboard(); ! 196: break; ! 197: ! 198: case MENU_DELETE: ! 199: DeleteControl(); ! 200: break; ! 201: ! 202: case MENU_DUPLICATE: ! 203: Duplicate(); ! 204: break; ! 205: ! 206: case MENU_SYMBOLS: ! 207: ViewInclude(); ! 208: break; ! 209: ! 210: case MENU_STYLES: ! 211: StylesDialog(); ! 212: break; ! 213: ! 214: case MENU_SIZETOTEXT: ! 215: SizeToText(); ! 216: break; ! 217: ! 218: case MENU_NEWDIALOG: ! 219: AddNewDialog(); ! 220: break; ! 221: ! 222: case MENU_SELECTDIALOG: ! 223: SelectDialogDialog(); ! 224: break; ! 225: ! 226: /* ! 227: * Arrange menu ------------------------------------------------- ! 228: */ ! 229: ! 230: case MENU_ALIGNLEFT: ! 231: case MENU_ALIGNVERT: ! 232: case MENU_ALIGNRIGHT: ! 233: case MENU_ALIGNTOP: ! 234: case MENU_ALIGNHORZ: ! 235: case MENU_ALIGNBOTTOM: ! 236: AlignControls(cmd); ! 237: break; ! 238: ! 239: case MENU_SPACEVERT: ! 240: case MENU_SPACEHORZ: ! 241: ArrangeSpacing(cmd); ! 242: break; ! 243: ! 244: case MENU_ARRSIZEWIDTH: ! 245: case MENU_ARRSIZEHEIGHT: ! 246: ArrangeSize(cmd); ! 247: break; ! 248: ! 249: case MENU_ARRPUSHBOTTOM: ! 250: case MENU_ARRPUSHRIGHT: ! 251: ArrangePushButtons(cmd); ! 252: break; ! 253: ! 254: case MENU_ORDERGROUP: ! 255: OrderGroupDialog(); ! 256: break; ! 257: ! 258: case MENU_ARRSETTINGS: ! 259: ArrangeSettingsDialog(); ! 260: break; ! 261: ! 262: /* ! 263: * Options menu ------------------------------------------------- ! 264: */ ! 265: ! 266: case MENU_TESTMODE: ! 267: if (gfTestMode) ! 268: DestroyTestDialog(); ! 269: else ! 270: CreateTestDialog(); ! 271: ! 272: break; ! 273: ! 274: case MENU_HEXMODE: ! 275: /* ! 276: * Flip the flag, and update the status display so that ! 277: * the id value will be displayed in the new format. ! 278: */ ! 279: gfHexMode = gfHexMode ? FALSE : TRUE; ! 280: StatusUpdate(); ! 281: break; ! 282: ! 283: case MENU_TRANSLATE: ! 284: /* ! 285: * Flip the flag, and set the enable state of the fields ! 286: * in the status window. Changing the translate mode can ! 287: * effect whether they are allowed to change ids of controls. ! 288: */ ! 289: gfTranslateMode = gfTranslateMode ? FALSE : TRUE; ! 290: ! 291: /* ! 292: * If they turned on Translate mode, reset the tool and ! 293: * hide the Toolbox. Otherwise, show the toolbox if they ! 294: * want it shown. ! 295: */ ! 296: if (gfTranslateMode) { ! 297: ToolboxShow(FALSE); ! 298: ToolboxSelectTool(W_NOTHING, FALSE); ! 299: } ! 300: else if (gfShowToolbox) { ! 301: ToolboxShow(TRUE); ! 302: } ! 303: ! 304: StatusSetEnable(); ! 305: break; ! 306: ! 307: case MENU_USENEWKEYWORDS: ! 308: /* ! 309: * Flip the flag. ! 310: */ ! 311: gfUseNewKeywords = gfUseNewKeywords ? FALSE : TRUE; ! 312: break; ! 313: ! 314: case MENU_SHOWTOOLBOX: ! 315: /* ! 316: * Toggle the state of the Toolbox. ! 317: */ ! 318: gfShowToolbox = gfShowToolbox ? FALSE : TRUE; ! 319: ToolboxShow(gfShowToolbox); ! 320: ! 321: break; ! 322: ! 323: /* ! 324: * Help menu ---------------------------------------------------- ! 325: */ ! 326: ! 327: case MENU_CONTENTS: ! 328: WinHelp(ghwndMain, gszHelpFile, HELP_CONTENTS, 0L); ! 329: break; ! 330: ! 331: case MENU_SEARCH: ! 332: /* ! 333: * Tell winhelp to be sure this app's help file is current, ! 334: * then invoke a search with an empty starting key. ! 335: */ ! 336: WinHelp(ghwndMain, gszHelpFile, HELP_FORCEFILE, 0); ! 337: WinHelp(ghwndMain, gszHelpFile, HELP_PARTIALKEY, (DWORD)szEmpty); ! 338: break; ! 339: ! 340: case MENU_ABOUT: ! 341: DlgBox(DID_ABOUT, (WNDPROC)AboutDlgProc); ! 342: break; ! 343: ! 344: /* ! 345: * Hidden menu commands (accessed by accelerators) -------------- ! 346: */ ! 347: ! 348: case MENU_HIDDEN_TOTOOLBOX: ! 349: if (ghwndToolbox && IsWindowVisible(ghwndToolbox)) ! 350: SetFocus(ghwndToolbox); ! 351: ! 352: break; ! 353: ! 354: case MENU_HIDDEN_TOPROPBAR: ! 355: SetFocus(hwndStatus); ! 356: break; ! 357: } ! 358: } ! 359: ! 360: ! 361: ! 362: /************************************************************************ ! 363: * LoadMenuBitmaps ! 364: * ! 365: * This function loads and inserts the menu items that are bitmaps. ! 366: * This has to be done at runtime because windows does not have a ! 367: * way to specify bitmap menu items in the rc file. ! 368: * ! 369: * Arguments: ! 370: * HMENU hMenu - The menu handle. ! 371: * ! 372: ************************************************************************/ ! 373: ! 374: VOID LoadMenuBitmaps( ! 375: HMENU hMenu) ! 376: { ! 377: INT i; ! 378: ! 379: for (i = 0; i < sizeof(bmpmenuTable) / sizeof(BITMAPMENU); i++) { ! 380: bmpmenuTable[i].hbm = ! 381: LoadBitmap(ghInst, MAKEINTRESOURCE(bmpmenuTable[i].idbm)); ! 382: ! 383: ModifyMenu(hMenu, bmpmenuTable[i].idm, ! 384: MF_BYCOMMAND | MF_BITMAP, bmpmenuTable[i].idm, ! 385: (LPTSTR)(DWORD)bmpmenuTable[i].hbm); ! 386: } ! 387: } ! 388: ! 389: ! 390: ! 391: /************************************************************************ ! 392: * FreeMenuBitmaps ! 393: * ! 394: * This function frees the menu bitmaps that were loaded by ! 395: * LoadMenuBitmaps. This function should be called only when ! 396: * the application is exiting, because it frees the bitmaps ! 397: * without removing them from the menu first. ! 398: * ! 399: ************************************************************************/ ! 400: ! 401: VOID FreeMenuBitmaps(VOID) ! 402: { ! 403: INT i; ! 404: ! 405: for (i = 0; i < sizeof(bmpmenuTable) / sizeof(BITMAPMENU); i++) ! 406: if (bmpmenuTable[i].hbm) ! 407: DeleteObject(bmpmenuTable[i].hbm); ! 408: } ! 409: ! 410: ! 411: ! 412: /************************************************************************ ! 413: * InitMenu ! 414: * ! 415: * This function grays/enables and checks/unchecks the menu items ! 416: * appropriately for the given state. ! 417: * ! 418: * Arguments: ! 419: * HMENU hMenu - The menu handle. ! 420: * ! 421: ************************************************************************/ ! 422: ! 423: VOID InitMenu( ! 424: HMENU hMenu) ! 425: { ! 426: register INT i; ! 427: BOOL fEnable; ! 428: NPCTYPE npc; ! 429: HMENU hMenuArrange; ! 430: ! 431: MyEnableMenuItem(hMenu, MENU_NEWRES, !gfTranslateMode); ! 432: ! 433: MyEnableMenuItem(hMenu, MENU_SAVE, ! 434: (gfEditingDlg || gprlHead) && (gfResChged || gfIncChged)); ! 435: ! 436: MyEnableMenuItem(hMenu, MENU_SAVEAS, gfEditingDlg || gprlHead); ! 437: ! 438: MyEnableMenuItem(hMenu, MENU_SETINCLUDE, ! 439: (gfEditingDlg || gprlHead) && !gfTranslateMode); ! 440: ! 441: MyEnableMenuItem(hMenu, MENU_REMCUST, gpclHead); ! 442: ! 443: MyEnableMenuItem(hMenu, MENU_RESTOREDIALOG, gfDlgChanged && gcd.prl); ! 444: ! 445: MyEnableMenuItem(hMenu, MENU_CUT, ! 446: gnpcSel && gfEditingDlg && !gfTranslateMode); ! 447: ! 448: MyEnableMenuItem(hMenu, MENU_COPY, gnpcSel && gfEditingDlg); ! 449: ! 450: MyEnableMenuItem(hMenu, MENU_PASTE, !gfTranslateMode && ! 451: IsClipboardFormatAvailable(fmtDlg) && ! 452: (gfEditingDlg || DlgInClipboard())); ! 453: ! 454: MyEnableMenuItem(hMenu, MENU_DELETE, gnpcSel && !gfTranslateMode); ! 455: ! 456: MyEnableMenuItem(hMenu, MENU_DUPLICATE, gnpcSel && !gfTranslateMode); ! 457: ! 458: MyEnableMenuItem(hMenu, MENU_SYMBOLS, ! 459: (gfEditingDlg || gprlHead) && !gfTranslateMode); ! 460: ! 461: MyEnableMenuItem(hMenu, MENU_STYLES, gnpcSel && !gfTranslateMode); ! 462: ! 463: /* ! 464: * For the "Size to text" menu command to be enabled, there ! 465: * must be at least one control selected, and one of the ! 466: * controls selected has to be able to be sized to its text. ! 467: */ ! 468: fEnable = FALSE; ! 469: if (gcSelected) { ! 470: for (npc = npcHead; npc; npc = npc->npcNext) { ! 471: if (npc->fSelected && npc->pwcd->fSizeToText) { ! 472: fEnable = TRUE; ! 473: break; ! 474: } ! 475: } ! 476: } ! 477: ! 478: MyEnableMenuItem(hMenu, MENU_SIZETOTEXT, fEnable); ! 479: ! 480: MyEnableMenuItem(hMenu, MENU_NEWDIALOG, !gfTranslateMode); ! 481: ! 482: MyEnableMenuItem(hMenu, MENU_SELECTDIALOG, gfEditingDlg || gprlHead); ! 483: ! 484: hMenuArrange = GetSubMenu(hMenu, MENUPOS_ARRANGE); ! 485: ! 486: MyEnableMenuItemByPos(hMenuArrange, MENUPOS_ARRANGEALIGN, gcSelected > 1); ! 487: ! 488: MyEnableMenuItemByPos(hMenuArrange, MENUPOS_ARRANGESPACE, gcSelected > 1); ! 489: ! 490: /* ! 491: * For the "Same size" menu option to be enabled, there ! 492: * must be more than one control selected, and they ! 493: * must be sizeable controls. ! 494: */ ! 495: fEnable = FALSE; ! 496: if (gcSelected > 1) { ! 497: for (i = 0, npc = npcHead; npc; npc = npc->npcNext) { ! 498: if (npc->fSelected && npc->pwcd->fSizeable) { ! 499: i++; ! 500: ! 501: if (i > 1) { ! 502: fEnable = TRUE; ! 503: break; ! 504: } ! 505: } ! 506: } ! 507: } ! 508: ! 509: MyEnableMenuItemByPos(hMenuArrange, MENUPOS_ARRANGESIZE, fEnable); ! 510: ! 511: /* ! 512: * For the Arrange/Push buttons menu item to be enabled, ! 513: * there must be a dialog up and it must have at least one ! 514: * push button. In addition, if there are control(s) other ! 515: * than the dialog selected, at least one of the selected ! 516: * controls must be a push button. ! 517: */ ! 518: fEnable = FALSE; ! 519: if (gfEditingDlg || gprlHead) { ! 520: if (!gcSelected || gfDlgSelected) { ! 521: for (npc = npcHead; npc; npc = npc->npcNext) { ! 522: if (npc->pwcd->iType == W_PUSHBUTTON) { ! 523: fEnable = TRUE; ! 524: break; ! 525: } ! 526: } ! 527: } ! 528: else { ! 529: for (npc = npcHead; npc; npc = npc->npcNext) { ! 530: if (npc->pwcd->iType == W_PUSHBUTTON && npc->fSelected) { ! 531: fEnable = TRUE; ! 532: break; ! 533: } ! 534: } ! 535: } ! 536: } ! 537: ! 538: MyEnableMenuItemByPos(hMenuArrange, MENUPOS_ARRANGEPUSH, fEnable); ! 539: ! 540: MyEnableMenuItem(hMenu, MENU_ORDERGROUP, ! 541: npcHead && !gfTranslateMode && !gfTestMode && cWindows > 1); ! 542: ! 543: MyEnableMenuItem(hMenu, MENU_TESTMODE, gfEditingDlg); ! 544: MyCheckMenuItem(hMenu, MENU_TESTMODE, gfTestMode); ! 545: ! 546: MyEnableMenuItem(hMenu, MENU_HEXMODE, !gfTestMode); ! 547: MyCheckMenuItem(hMenu, MENU_HEXMODE, gfHexMode); ! 548: ! 549: MyEnableMenuItem(hMenu, MENU_TRANSLATE, !gfTestMode); ! 550: MyCheckMenuItem(hMenu, MENU_TRANSLATE, gfTranslateMode); ! 551: ! 552: MyEnableMenuItem(hMenu, MENU_USENEWKEYWORDS, !gfTestMode); ! 553: MyCheckMenuItem(hMenu, MENU_USENEWKEYWORDS, gfUseNewKeywords); ! 554: ! 555: MyEnableMenuItem(hMenu, MENU_SHOWTOOLBOX, !gfTestMode && !gfTranslateMode); ! 556: MyCheckMenuItem(hMenu, MENU_SHOWTOOLBOX, gfShowToolbox); ! 557: } ! 558: ! 559: ! 560: ! 561: /************************************************************************ ! 562: * CopyToClipboard ! 563: * ! 564: * Puts the current dialog and a bitmap image of it into the clipboard. ! 565: * Gives a dialog box resource to the Clipboard. ! 566: * Gives a bit map to the clipboard. ! 567: * Clears everything else out of clipboard. ! 568: * ! 569: ************************************************************************/ ! 570: ! 571: STATICFN VOID CopyToClipboard(VOID) ! 572: { ! 573: INT cbRes; ! 574: HANDLE hResClip; ! 575: PRES lpRes; ! 576: PRES pRes; ! 577: HDC hdcSrc; ! 578: HDC hdcDst; ! 579: RECT rc; ! 580: HBITMAP hbm; ! 581: ! 582: /* ! 583: * Store the current selection in a dialog resource. ! 584: */ ! 585: if (!(pRes = AllocDialogResource(FALSE, TRUE))) ! 586: return; ! 587: ! 588: /* ! 589: * Allocate global memory for it. ! 590: */ ! 591: cbRes = ResourceSize(pRes); ! 592: if (!cbRes || !(hResClip = GlobalAlloc(GHND | GMEM_DDESHARE, cbRes))) { ! 593: MyFree(pRes); ! 594: Message(MSG_OUTOFMEMORY); ! 595: return; ! 596: } ! 597: ! 598: /* ! 599: * Copy it to the global memory. ! 600: */ ! 601: lpRes = (PRES)GlobalLock(hResClip); ! 602: memcpy(lpRes, pRes, cbRes); ! 603: GlobalUnlock(hResClip); ! 604: MyFree(pRes); ! 605: ! 606: /* ! 607: * Now place it in the clipboard. ! 608: */ ! 609: if (OpenClipboard(ghwndMain)) { ! 610: EmptyClipboard(); ! 611: SetClipboardData(fmtDlg, hResClip); ! 612: ! 613: /* ! 614: * If the dialog is selected, place a bitmap image of it ! 615: * in the clipboard also. The drag handles will be removed ! 616: * first and the dialog will be activated so that the ! 617: * image looks proper. ! 618: */ ! 619: if (gfDlgSelected) { ! 620: CancelSelection(FALSE); ! 621: SetActiveWindow(gcd.npc->hwnd); ! 622: UpdateWindow(gcd.npc->hwnd); ! 623: ! 624: if (hdcSrc = GetDC(NULL)) { ! 625: GetWindowRect(gcd.npc->hwnd, &rc); ! 626: if (hbm = CreateCompatibleBitmap(hdcSrc, ! 627: rc.right - rc.left, rc.bottom - rc.top)) { ! 628: if (hdcDst = CreateCompatibleDC(hdcSrc)) { ! 629: /* ! 630: * Calculate the dimensions of the bitmap and ! 631: * convert them to tenths of a millimeter for ! 632: * setting the size with the SetBitmapDimensionEx ! 633: * call. This allows programs like WinWord to ! 634: * retrieve the bitmap and know what size to ! 635: * display it as. ! 636: */ ! 637: SetBitmapDimensionEx(hbm, ! 638: ((rc.right - rc.left) * MM10PERINCH) / ! 639: GetDeviceCaps(hdcSrc, LOGPIXELSX), ! 640: ((rc.bottom - rc.top) * MM10PERINCH) / ! 641: GetDeviceCaps(hdcSrc, LOGPIXELSY), ! 642: NULL); ! 643: ! 644: SelectObject(hdcDst, hbm); ! 645: BitBlt(hdcDst, 0, 0, ! 646: rc.right - rc.left, rc.bottom - rc.top, ! 647: hdcSrc, rc.left, rc.top, SRCCOPY); ! 648: DeleteDC(hdcDst); ! 649: SetClipboardData(CF_BITMAP, hbm); ! 650: } ! 651: else { ! 652: DeleteObject(hbm); ! 653: } ! 654: } ! 655: ! 656: ReleaseDC(NULL, hdcSrc); ! 657: } ! 658: ! 659: SetActiveWindow(ghwndMain); ! 660: SelectControl(gcd.npc, FALSE); ! 661: } ! 662: ! 663: CloseClipboard(); ! 664: } ! 665: else { ! 666: Message(MSG_NOCLIP); ! 667: } ! 668: } ! 669: ! 670: ! 671: ! 672: /************************************************************************ ! 673: * DlgInClipboard ! 674: * ! 675: * This function returns TRUE if there is data in the clipboard in the ! 676: * dialog format, and this data is for a complete dialog, not just for ! 677: * a group of controls. ! 678: * ! 679: ************************************************************************/ ! 680: ! 681: STATICFN BOOL DlgInClipboard(VOID) ! 682: { ! 683: HANDLE hClip; ! 684: PRES pRes; ! 685: PDIALOGBOXHEADER pdbh; ! 686: BOOL fDlgResFound = FALSE; ! 687: ! 688: if (!OpenClipboard(ghwndMain)) ! 689: return FALSE; ! 690: ! 691: if (hClip = GetClipboardData(fmtDlg)) { ! 692: pRes = (PRES)GlobalLock(hClip); ! 693: ! 694: /* ! 695: * If cx is CONTROLS_ONLY, then we know that we only ! 696: * want to copy the controls in the template, not the ! 697: * entire dialog plus controls. ! 698: */ ! 699: pdbh = (PDIALOGBOXHEADER)SkipResHeader(pRes); ! 700: if (pdbh->cx != CONTROLS_ONLY) ! 701: fDlgResFound = TRUE; ! 702: ! 703: GlobalUnlock(hClip); ! 704: } ! 705: ! 706: CloseClipboard(); ! 707: ! 708: return fDlgResFound; ! 709: } ! 710: ! 711: ! 712: ! 713: /************************************************************************ ! 714: * PasteFromClipboard ! 715: * ! 716: * This routine pastes any data from the clipboard into the current ! 717: * resource file. If the data represents a complete dialog, a new dialog ! 718: * is added. If it represents some controls, the operation to drop them ! 719: * into the current dialog is begun. ! 720: * ! 721: ************************************************************************/ ! 722: ! 723: STATICFN VOID PasteFromClipboard(VOID) ! 724: { ! 725: HANDLE hClip; ! 726: PRES pResClip; ! 727: PRES pResCopy; ! 728: INT cbRes; ! 729: ! 730: if (!OpenClipboard(ghwndMain)) { ! 731: Message(MSG_NOCLIP); ! 732: return; ! 733: } ! 734: ! 735: if (hClip = GetClipboardData(fmtDlg)) { ! 736: pResClip = (PRES)GlobalLock(hClip); ! 737: cbRes = ResourceSize(pResClip); ! 738: ! 739: /* ! 740: * Make a copy of the clipboard data. This needs to be done ! 741: * because we may need to drag the new controls for a while, ! 742: * and it is rude to leave the clipboard open that long. ! 743: */ ! 744: if (pResCopy = (PRES)MyAlloc(cbRes)) { ! 745: memcpy((PBYTE)pResCopy, (PBYTE)pResClip, cbRes); ! 746: ! 747: /* ! 748: * Now duplicate the dialog or controls in the clipboard. ! 749: * The pResCopy buffer does NOT need to be freed here, because ! 750: * it will be freed after the drag operation is complete. ! 751: */ ! 752: MakeCopyFromRes(pResCopy); ! 753: } ! 754: ! 755: GlobalUnlock(hClip); ! 756: } ! 757: ! 758: CloseClipboard(); ! 759: } ! 760: ! 761: ! 762: ! 763: /************************************************************************ ! 764: * MsgFilterHookFunc ! 765: * ! 766: * This is the exported message filter function that is hooked into ! 767: * the message stream for detecting the pressing of the F1 key, at ! 768: * which time it calls up the appropriate help. ! 769: * ! 770: ************************************************************************/ ! 771: ! 772: BOOL APIENTRY MsgFilterHookFunc( ! 773: INT nCode, ! 774: WPARAM wParam, ! 775: LPMSG lpMsg) ! 776: { ! 777: if ((nCode == MSGF_MENU || nCode == MSGF_DIALOGBOX) && ! 778: (lpMsg->message == WM_KEYDOWN && lpMsg->wParam == VK_F1)) { ! 779: /* ! 780: * Display help. ! 781: */ ! 782: ShowHelp((nCode == MSGF_MENU) ? TRUE : FALSE); ! 783: ! 784: /* ! 785: * Tell Windows to swallow this message. ! 786: */ ! 787: return 1; ! 788: } ! 789: ! 790: return CallNextHookEx(ghhkMsgFilter, nCode, wParam, (LONG)lpMsg); ! 791: } ! 792: ! 793: ! 794: ! 795: /************************************************************************ ! 796: * ShowHelp ! 797: * ! 798: * This function is called when the user has requested help. It will ! 799: * look at the menu state (if fMenuHelp is TRUE) or which dialog ! 800: * is currently up to determine the help topic, then it calls WinHelp. ! 801: * ! 802: * Arguments: ! 803: * BOOL fMenuHelp - TRUE if this help is for a menu (help was requested ! 804: * in the menu modal loop). If FALSE, general help ! 805: * or help for a dialog is assumed. ! 806: * ! 807: ************************************************************************/ ! 808: ! 809: VOID ShowHelp( ! 810: BOOL fMenuHelp) ! 811: { ! 812: INT nHelpContext = 0; ! 813: HWND hwndFocus; ! 814: ! 815: if (fMenuHelp) { ! 816: nHelpContext = GetHelpContext(gMenuSelected, gahmapMenu); ! 817: } ! 818: else { ! 819: /* ! 820: * Look for help for the current dialog. ! 821: */ ! 822: if (gidCurrentDlg) { ! 823: nHelpContext = GetHelpContext(gidCurrentDlg, gahmapDialog); ! 824: } ! 825: else { ! 826: /* ! 827: * There is no current dialog. Is the window with the ! 828: * focus a control on the Properties Bar? ! 829: */ ! 830: if ((hwndFocus = GetFocus()) && IsChild(hwndStatus, hwndFocus)) ! 831: nHelpContext = GetHelpContext(DID_STATUS, gahmapDialog); ! 832: } ! 833: } ! 834: ! 835: /* ! 836: * If there is help context, display it. Otherwise display ! 837: * the Contents screen. ! 838: */ ! 839: if (nHelpContext) ! 840: WinHelp(ghwndMain, gszHelpFile, HELP_CONTEXT, nHelpContext); ! 841: else ! 842: WinHelp(ghwndMain, gszHelpFile, HELP_CONTENTS, 0L); ! 843: } ! 844: ! 845: ! 846: ! 847: /************************************************************************ ! 848: * GetHelpContext ! 849: * ! 850: * This function takes a subject and returns its matching help ! 851: * context id from the given HELPMAP table. ! 852: * ! 853: * Arguments: ! 854: * INT idSubject - ID of the subject to find the help context for. ! 855: * PHELPMAP phmap - The help map table. It is assumed that the ! 856: * last entry in the table has a NULL subject id. ! 857: * ! 858: ************************************************************************/ ! 859: ! 860: STATICFN INT GetHelpContext( ! 861: INT idSubject, ! 862: PHELPMAP phmap) ! 863: { ! 864: while (phmap->idSubject) { ! 865: if (phmap->idSubject == idSubject) ! 866: return phmap->HelpContext; ! 867: ! 868: phmap++; ! 869: } ! 870: ! 871: return 0; ! 872: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.