|
|
1.1 ! root 1: /************************************************************************ ! 2: ! 3: File: open.c ! 4: ! 5: Purpose: ! 6: ! 7: This file contains the routines to control the CDTEST.EXE "Open" dialog ! 8: box. The "Open" dialog box allows the user to enter values into an ! 9: OPENFILENAME structure and then create GetOpenFileName() dialog boxes ! 10: on the fly. ! 11: ! 12: Functions: ! 13: ! 14: DoOpenDialog() -- starts off the main dialog for "open" ! 15: ! 16: OpenFunc() -- Callback function for main dialog ! 17: ! 18: InitOpenStruct() -- Fills initial OPENFILENAME structure. ! 19: ! 20: FillOpenDlg() -- Fills the dialog with the values from ! 21: the OPENFILENAME structure. ! 22: ! 23: GetOpenDlg() -- Retrieves the users entries from the ! 24: main dialog and puts them in the ! 25: OPENFILENAME structure. ! 26: ! 27: InitFilterString() -- Creates filter string ! 28: ! 29: InitCustFiltString() -- Creates custom filter string ! 30: ! 31: InterpretCustomFilterString() -- Parses custom filter string returned ! 32: from GetOpenFileName() ! 33: ! 34: GetCorrectResourceHandle() -- Loads custom templates from file ! 35: as resource handles ! 36: ! 37: OpenSaveHookProc() -- The hook function that will be ! 38: called if GetOpen/Save is called ! 39: with the OFN_ENABLEHOOK flag set. ! 40: ! 41: MultiThreadOpenSave() -- Creates two Open/Save dialogs that ! 42: the user can simultaneously access ! 43: ! 44: OpenSaveThread1Proc() -- The starting address of thread 1 ! 45: ! 46: OpenSaveThread2Proc() -- The starting address of thread 2 ! 47: ! 48: DoOpenSaveStuff() -- Does the actuall calling of ! 49: GetOpen/SaveFileName() ! 50: ! 51: OpenMultiThreadEnableButtons() -- Enables and disables buttons in ! 52: main dialog. Needed when multi- ! 53: threading. ! 54: ! 55: ************************************************************************/ ! 56: ! 57: #include <windows.h> ! 58: #include <commdlg.h> ! 59: #include <stdlib.h> ! 60: #include <winnls.h> ! 61: #include "cdtest.h" ! 62: #include "open.h" ! 63: #include "save.h" ! 64: #include "dlgs.h" //include file that contains all #defines for the ! 65: //commdlg dialog templates. ! 66: ! 67: ! 68: /* All functions defined in this file + 1 external function ! 69: and one external variable */ ! 70: ! 71: extern UINT uMode ; //see cdtest.c ! 72: extern LONG MyAtol(LPTSTR, BOOL, LPBOOL) ; ! 73: void InterpretCustomFilterString(void) ; ! 74: HANDLE GetCorrectResourceHandle(void) ; ! 75: void DoOpenSaveStuff(LPOPENFILENAME) ; ! 76: UINT APIENTRY OpenSaveHookProc(HWND hwnd, UINT msg, UINT wParam, LONG lParam) ; ! 77: DWORD OpenSaveThread1Proc(LPDWORD) ; ! 78: DWORD OpenSaveThread2Proc(LPDWORD) ; ! 79: void MultiThreadOpenSave(void) ; ! 80: void OpenMultiThreadEnableButtons(BOOL, HWND) ; ! 81: ! 82: ! 83: /* All global variables defined in this file */ ! 84: ! 85: HWND hwndMainDialog ; //global handle for open dialog. ! 86: ! 87: HANDLE hRes ; //handles to the resource and dialog for ! 88: HANDLE hDialog ; //ofn_enabletemplatehandle ! 89: ! 90: HBRUSH hBrushDlg ; ! 91: HBRUSH hBrushEdit ; //brush handles for new colors done with hook proc ! 92: HBRUSH hBrushButton ; ! 93: ! 94: HANDLE hOpenSaveThread1, hOpenSaveThread2 ; //variables for the ! 95: DWORD dwThreadID1, dwThreadID2 ; //multithreading part ! 96: DWORD dwThreadParm1, dwThreadParm2 ; ! 97: OPENFILENAME ofnThread1, ofnThread2 ; ! 98: int nOpenDialogCount ; ! 99: ! 100: ! 101: ! 102: ! 103: ! 104: /************************************************************************ ! 105: ! 106: Function: DoOpenDialog(HWND) ! 107: ! 108: Purpose: To create the GetOpenFileName() and GetSaveFileName() ! 109: creation dialog. ! 110: ! 111: Returns: Nothing. ! 112: ! 113: Comments: ! 114: ! 115: GetOpenFileName() and GetSaveFileName() are similiar enough so that ! 116: the same dialog can be used to edit their creation structure elements, ! 117: so a global variable "bDoOpenDlg" keeps track of which one to create ! 118: when the user clicks the OK or Multithread buttons... ! 119: ! 120: ************************************************************************/ ! 121: ! 122: ! 123: void DoOpenDialog(HWND hwnd) ! 124: { ! 125: ! 126: bDoOpenDlg = TRUE ; ! 127: ! 128: ! 129: DialogBox(hInst, MAKEINTRESOURCE(ID_OPENDIALOG), hwnd, OpenFunc) ; ! 130: ! 131: } ! 132: ! 133: ! 134: ! 135: ! 136: ! 137: ! 138: /************************************************************************ ! 139: ! 140: ! 141: Function: OpenFunc(HWND, UINT, UINT, LONG) ! 142: ! 143: Purpose: ! 144: ! 145: This is the callback function for the dialog box containing the ! 146: GetOpenFileName() and the GetSaveFileName() creation options. ! 147: ! 148: This function will handle the messages for this dialog and create ! 149: either a GetOpenFileName() dialog or a GetSaveFileName() dialog ! 150: depending on the state of the bDoOpenDlg variable. ! 151: ! 152: Returns: TRUE or FALSE depending on the situation. ! 153: ! 154: Comments: ! 155: ! 156: ! 157: ************************************************************************/ ! 158: ! 159: ! 160: BOOL APIENTRY OpenFunc(HWND hwnd, UINT msg, UINT wParam, LONG lParam) ! 161: { ! 162: switch (msg) ! 163: { ! 164: ! 165: case WM_INITDIALOG: ! 166: ! 167: if (bDoOpenDlg) ! 168: SetWindowText(hwnd, TEXT("GetOpenFileName()")) ; ! 169: else ! 170: SetWindowText(hwnd, TEXT("GetSaveFileName()")) ; ! 171: ! 172: ! 173: /* initialize the OPENFILENAME structure members */ ! 174: ! 175: InitOpenStruct(hwnd, &ofn) ; ! 176: ! 177: ! 178: /* Fill these values into the creation dialog */ ! 179: ! 180: FillOpenDlg(hwnd, &ofn) ; ! 181: ! 182: ! 183: /* There are three separate OPENFILENAME structures. One for ! 184: the main Open/Save dialog and one for each multithreaded dialog. ! 185: Set them equal to begin with */ ! 186: ! 187: *(&ofnThread1) = *(&ofnThread2) = *(&ofn) ; ! 188: ! 189: hwndMainDialog = hwnd ; ! 190: ! 191: SetFocus(GetDlgItem(hwnd, ID_STRUCTSIZEO)) ; ! 192: ! 193: break ; ! 194: ! 195: ! 196: ! 197: case UMSG_DECREMENTDLGCOUNT: //user defined message indicating ! 198: //the closure of a multithreaded dialog ! 199: ! 200: /* When we are multithreading, there is nothing to prevent the ! 201: user from interacting with the creation dialog once the first ! 202: GetOpen(Save) file name dialog has returned. So, in order ! 203: to prevent the Multithread" button from being pressed again ! 204: before the previous two multithreaded dialogs have been canceled, ! 205: disable the controls until we get a message from each thread ! 206: that the dialog has ended */ ! 207: ! 208: ! 209: nOpenDialogCount-- ; ! 210: ! 211: if (nOpenDialogCount == 0) ! 212: OpenMultiThreadEnableButtons(TRUE, hwnd) ; ! 213: ! 214: break ; ! 215: ! 216: ! 217: case WM_COMMAND: ! 218: { ! 219: switch (LOWORD(wParam)) ! 220: { ! 221: ! 222: case IDOK: ! 223: GetOpenDlg(hwnd, &ofn) ; //get the user's input ! 224: DoOpenSaveStuff(&ofn) ; //do the dialog ! 225: break ; ! 226: ! 227: ! 228: case IDCANCEL: ! 229: EndDialog(hwnd, FALSE) ; ! 230: break ; ! 231: ! 232: ! 233: case ID_RESETOPEN: ! 234: ! 235: SendDlgItemMessage(hwnd, ID_FILTERO, CB_RESETCONTENT, ! 236: (WPARAM) 0, (LPARAM) 0) ; ! 237: ! 238: InitOpenStruct(hwnd, &ofn) ; ! 239: ! 240: FillOpenDlg(hwnd, &ofn) ; ! 241: ! 242: SendDlgItemMessage(hwnd, ID_NULLSTRUCTO, BM_SETCHECK, (WPARAM)0, (LPARAM)0) ; ! 243: SendDlgItemMessage(hwnd, ID_USEHINSTO, BM_SETCHECK, (WPARAM)0, (LPARAM)0) ; ! 244: ! 245: *(&ofnThread1) = *(&ofnThread2) = *(&ofn) ; ! 246: ! 247: SetFocus(GetDlgItem(hwnd, ID_STRUCTSIZEO)) ; ! 248: ! 249: break ; ! 250: ! 251: ! 252: case ID_ADD1O: ! 253: ! 254: GetDlgItemText(hwnd, ID_FILTERO, szTemp, 100) ; ! 255: ! 256: if (*szTemp) ! 257: { ! 258: SendDlgItemMessage(hwnd, ID_FILTERO, CB_ADDSTRING, (WPARAM) 0, ! 259: (LPARAM) (LPTSTR) szTemp) ; ! 260: SetWindowText(GetDlgItem(hwnd, ID_FILTERO), TEXT("")) ; ! 261: } ! 262: break ; ! 263: ! 264: ! 265: case ID_ADD2O: ! 266: ! 267: GetDlgItemText(hwnd, ID_CUSTFILTO, szTemp, 100) ; ! 268: ! 269: if (*szTemp) ! 270: { ! 271: SendDlgItemMessage(hwnd, ID_CUSTFILTO, CB_ADDSTRING, (WPARAM) 0, ! 272: (LPARAM) (LPTSTR) szTemp) ; ! 273: SetWindowText(GetDlgItem(hwnd, ID_CUSTFILTO), TEXT("")) ; ! 274: } ! 275: break ; ! 276: ! 277: ! 278: case ID_CLEAR1O: ! 279: SendDlgItemMessage(hwnd, ID_FILTERO, CB_RESETCONTENT, ! 280: (WPARAM) 0, (LPARAM) 0) ; ! 281: break ; ! 282: ! 283: case ID_CLEAR2O: ! 284: SendDlgItemMessage(hwnd, ID_CUSTFILTO, CB_RESETCONTENT, ! 285: (WPARAM) 0, (LPARAM) 0) ; ! 286: break ; ! 287: ! 288: case ID_MULTIOPEN: ! 289: ! 290: /* First, disable the OK, Cancel, and MultiThread buttons */ ! 291: ! 292: OpenMultiThreadEnableButtons(FALSE, hwnd) ; ! 293: ! 294: ! 295: /* Then multithread the dialogs */ ! 296: ! 297: nOpenDialogCount = 2 ; ! 298: ! 299: MultiThreadOpenSave() ; ! 300: ! 301: break ; ! 302: ! 303: ! 304: default: //end WM_COMMAND case ! 305: break ; ! 306: } ! 307: } ! 308: ! 309: default: ! 310: ! 311: /* If the help button is pressed in the GetOpen/SaveFileName() ! 312: dialogs, it will send a message Registered with RegisterWindowMessage() ! 313: to the parent window. The message nHelpMessage was registered ! 314: at application startup */ ! 315: ! 316: if (msg == nHelpMessage) ! 317: MessageBox(GetForegroundWindow(), ! 318: TEXT("Hello from the help button"), ! 319: TEXT("Open Help Button"), MB_OK | MB_APPLMODAL) ; ! 320: ! 321: break ; ! 322: ! 323: } ! 324: ! 325: return FALSE ; ! 326: } ! 327: ! 328: ! 329: ! 330: ! 331: ! 332: ! 333: ! 334: /************************************************************************ ! 335: ! 336: ! 337: Function: InitOpenStruct(HWND, LPOPENFILENAME) ! 338: ! 339: Purpose: ! 340: ! 341: Initializes the OPENFILENAME structure. The structure is referenced ! 342: via a pointer passed in as the second parameter so that we can pass ! 343: any of the three OPENFILENAME structures into this function and ! 344: Initialize them. ! 345: ! 346: Returns: Nothing. ! 347: ! 348: Comments: ! 349: ! 350: The szFilterInits and szCustFiltInits arrays are initialized to ! 351: contain some default strings. Eventually the strings in ! 352: these arrays must be arranged one after the other with a null ! 353: character between them and two null characters at the end: ! 354: ! 355: "Text files\0*.txt\0All files\0*.*\0\0" ! 356: ! 357: ************************************************************************/ ! 358: ! 359: ! 360: void InitOpenStruct(HWND hwnd, LPOPENFILENAME po) ! 361: { ! 362: int i = 0 ; ! 363: szFileName[0] = 0 ; ! 364: szFileTitle[0] = 0 ; ! 365: ! 366: dwFlags = OFN_READONLY | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_SHOWHELP ; ! 367: ! 368: if (bDoOpenDlg) ! 369: lstrcpy(szDlgTitle, TEXT("Open Dialog Title")) ; ! 370: else ! 371: lstrcpy(szDlgTitle, TEXT("Save Dialog Title")) ; ! 372: ! 373: lstrcpy(szDefExt, TEXT("rat")) ; ! 374: lstrcpy(szInitialDir, TEXT("c:\\")) ; ! 375: lstrcpy(szTempName, TEXT("opentemp1")) ; ! 376: ! 377: lstrcpy(&szFilterInits[0][0], TEXT("All Files (*.*)")) ; ! 378: lstrcpy(&szFilterInits[1][0], TEXT("*.*")) ; ! 379: lstrcpy(&szFilterInits[2][0], TEXT("Fat Files (*.fat)")) ; ! 380: lstrcpy(&szFilterInits[3][0], TEXT("*.fat")) ; ! 381: szFilterInits[4][0] = (TCHAR) 0 ; ! 382: ! 383: lstrcpy(&szCustFiltInits[0][0], TEXT("Last Filter Used")) ; ! 384: lstrcpy(&szCustFiltInits[1][0], TEXT("*.lst")) ; ! 385: szCustFiltInits[2][0] = (TCHAR) 0 ; ! 386: ! 387: ! 388: /* ! 389: ! 390: These two functions will create "strings" in the applications ! 391: data area that are in the form ! 392: ! 393: "Filter Description"\0 ! 394: "Filter"\0 ! 395: "Filter Description"\0 ! 396: "Filter"\0 ! 397: .. ! 398: .. ! 399: \0\0 ! 400: ! 401: The filters must be in this form in order that the common dialogs ! 402: interpret it correctly... ! 403: */ ! 404: ! 405: InitFilterString() ; ! 406: ! 407: InitCustFilterString() ; ! 408: ! 409: po->lStructSize = sizeof(OPENFILENAME) ; ! 410: po->hwndOwner = hwnd ; ! 411: po->hInstance = hInst ; ! 412: (LPTSTR) po->lpstrFilter = lpszFilterString ; ! 413: po->lpstrCustomFilter = lpszCustFilterString ; ! 414: po->nMaxCustFilter = MAXCUSTFILTER ; ! 415: po->nFilterIndex = 1L ; ! 416: po->lpstrFile = szFileName ; ! 417: po->nMaxFile = FILENAMESIZE ; ! 418: po->lpstrFileTitle = szFileTitle ; ! 419: po->nMaxFileTitle = FILETITLESIZE ; ! 420: po->lpstrInitialDir = szInitialDir ; ! 421: (LPTSTR) po->lpstrTitle = szDlgTitle ; ! 422: po->Flags = dwFlags ; ! 423: po->nFileOffset = 0 ; ! 424: po->nFileExtension = 0 ; ! 425: (LPTSTR) po->lpstrDefExt = szDefExt; ! 426: po->lCustData = 0L ; ! 427: po->lpfnHook = OpenSaveHookProc ; ! 428: (LPTSTR) po->lpTemplateName = szTempName ; ! 429: ! 430: return ; ! 431: } ! 432: ! 433: ! 434: ! 435: ! 436: ! 437: ! 438: ! 439: /************************************************************************ ! 440: ! 441: ! 442: Function: FillOpenDlg(HWND, LPOPENFILENAME) ! 443: ! 444: Purpose: ! 445: ! 446: - This function will fill in the edit boxes that correspond to each ! 447: of the fields in the OPENFILENAME structure. The user can accept ! 448: these values to create the common dialog or edit them. ! 449: ! 450: Returns: Nothing. ! 451: ! 452: Comments: ! 453: ! 454: The contents of the strings "szShortFilter" and "szLongFilter" ! 455: determine how a WORD or a DWORD value is represented in the edit boxes ! 456: ! 457: ************************************************************************/ ! 458: ! 459: void FillOpenDlg(HWND hwnd, LPOPENFILENAME po) ! 460: { ! 461: int i = 0 ; ! 462: ! 463: wsprintf(szTemp, szShortFilter, (int) po->lStructSize) ; ! 464: SetDlgItemText(hwnd, ID_STRUCTSIZEO, szTemp) ; ! 465: ! 466: wsprintf(szTemp, szLongFilter, (LONG) po->hwndOwner) ; ! 467: SetDlgItemText(hwnd, ID_HWNDOWNERO, szTemp) ; ! 468: ! 469: wsprintf(szTemp, szLongFilter, (LONG) po->hInstance) ; ! 470: SetDlgItemText(hwnd, ID_HINSTANCEO, szTemp) ; ! 471: ! 472: ! 473: SendDlgItemMessage(hwnd, ID_FILTERO, CB_RESETCONTENT, ! 474: (WPARAM) 0, (LPARAM) 0) ; ! 475: ! 476: while (szFilterInits[i][0] != (TCHAR) 0) ! 477: { ! 478: SendDlgItemMessage(hwnd, ID_FILTERO, CB_ADDSTRING, (WPARAM) 0, ! 479: (LPARAM) (LPTSTR) &szFilterInits[i][0]) ; ! 480: i++ ; ! 481: } ! 482: ! 483: SendDlgItemMessage(hwnd, ID_FILTERO, CB_SETCURSEL, ! 484: (WPARAM) 0, (LPARAM) 0 ) ; ! 485: ! 486: ! 487: ! 488: SendDlgItemMessage(hwnd, ID_CUSTFILTO, CB_RESETCONTENT, ! 489: (WPARAM) 0, (LPARAM) 0) ; ! 490: ! 491: for (i=0; i<2; i++) ! 492: SendDlgItemMessage(hwnd, ID_CUSTFILTO, CB_ADDSTRING, (WPARAM) 0, ! 493: (LPARAM) (LPTSTR) &szCustFiltInits[i][0]) ; ! 494: ! 495: SendDlgItemMessage(hwnd, ID_CUSTFILTO, CB_SETCURSEL, ! 496: (WPARAM) 0, (LPARAM) 0) ; ! 497: ! 498: ! 499: wsprintf(szTemp, szShortFilter, (int) po->nMaxCustFilter) ; ! 500: SetDlgItemText(hwnd, ID_MAXCUSTFILTO, szTemp) ; ! 501: ! 502: wsprintf(szTemp, szShortFilter, (int) po->nFilterIndex) ; ! 503: SetDlgItemText(hwnd, ID_FILTINDEXO, szTemp) ; ! 504: ! 505: SetDlgItemText(hwnd, ID_SZFILEO, po->lpstrFile) ; ! 506: ! 507: wsprintf(szTemp, szShortFilter, (int) po->nMaxFile) ; ! 508: SetDlgItemText(hwnd, ID_MAXSZFILEO, szTemp) ; ! 509: ! 510: SetDlgItemText(hwnd, ID_SZFILETITLEO, po->lpstrFileTitle) ; ! 511: ! 512: wsprintf(szTemp, szShortFilter, (int) po->nMaxFileTitle) ; ! 513: SetDlgItemText(hwnd, ID_MAXSZFILETITLEO, szTemp) ; ! 514: ! 515: SetDlgItemText(hwnd, ID_SZINITDIRO, po->lpstrInitialDir) ; ! 516: ! 517: SetDlgItemText(hwnd, ID_SZTITLEO, po->lpstrTitle) ; ! 518: ! 519: wsprintf(szTemp, szLongFilter, po->Flags) ; ! 520: SetDlgItemText(hwnd, ID_FLAGSO, szTemp) ; ! 521: ! 522: wsprintf(szTemp, szShortFilter, po->nFileOffset) ; ! 523: SetDlgItemText(hwnd, ID_FILEOFFO, szTemp) ; ! 524: ! 525: wsprintf(szTemp, szShortFilter, po->nFileExtension) ; ! 526: SetDlgItemText(hwnd, ID_FILEEXTO, szTemp) ; ! 527: ! 528: SetDlgItemText(hwnd, ID_SZDEFEXTO, po->lpstrDefExt) ; ! 529: ! 530: wsprintf(szTemp, szLongFilter, po->lCustData) ; ! 531: SetDlgItemText(hwnd, ID_CUSTDATAO, szTemp) ; ! 532: ! 533: wsprintf(szTemp, szLongFilter, po->lpfnHook) ; ! 534: SetDlgItemText(hwnd, ID_HOOKO, szTemp) ; ! 535: ! 536: SetDlgItemText(hwnd, ID_TEMPLATEO, po->lpTemplateName) ; ! 537: ! 538: return ; ! 539: } ! 540: ! 541: ! 542: ! 543: ! 544: ! 545: ! 546: ! 547: ! 548: /************************************************************************ ! 549: ! 550: ! 551: Function: GetOpenDlg(HWND, LPOPENFILENAME) ! 552: ! 553: ! 554: Purpose: ! 555: ! 556: This function will retrieve the contents of each edit box corresponding ! 557: with each field in the OPENFILENAME structure, and fill in the ! 558: OPENFILENAME structure with these values. ! 559: ! 560: Returns: Nothing. ! 561: ! 562: Comments: ! 563: ! 564: if (uMode == IDM_HEXMODE), then the numbers should be interpreted as ! 565: hexidecimal and the MyAtol() function is called with its "bHex" ! 566: parameter set to true. ! 567: ! 568: ************************************************************************/ ! 569: ! 570: void GetOpenDlg(HWND hwnd, LPOPENFILENAME po) ! 571: { ! 572: int i ; ! 573: BOOL b ; ! 574: TCHAR szNum[20] ; ! 575: ! 576: GetDlgItemText(hwnd, ID_STRUCTSIZEO, szNum, 20) ; ! 577: po->lStructSize = MyAtol(szNum, uMode==IDM_HEXMODE, &b) ; ! 578: ! 579: GetDlgItemText(hwnd, ID_HWNDOWNERO, szNum, 20) ; ! 580: po->hwndOwner = (HWND) MyAtol(szNum, uMode==IDM_HEXMODE, &b) ; ! 581: ! 582: GetDlgItemText(hwnd, ID_HINSTANCEO, szNum, 20) ; ! 583: po->hInstance = (HANDLE) MyAtol(szNum, uMode==IDM_HEXMODE, &b) ; ! 584: ! 585: ! 586: /* these are just strings, no conversion necessary */ ! 587: ! 588: i = 0 ; ! 589: while (SendDlgItemMessage(hwnd, ID_FILTERO, CB_GETLBTEXT, (WPARAM) i, ! 590: (LPARAM) (LPTSTR) szFilterInits[i]) != CB_ERR) ! 591: { i++ ; } ! 592: ! 593: ! 594: /* create the filter string */ ! 595: ! 596: InitFilterString() ; ! 597: ! 598: ! 599: i = 0 ; ! 600: ! 601: while (SendDlgItemMessage(hwnd, ID_CUSTFILTO, CB_GETLBTEXT, (WPARAM) i, ! 602: (LPARAM) (LPTSTR) szCustFiltInits[i]) != CB_ERR) ! 603: { i++ ; } ! 604: ! 605: ! 606: InitCustFilterString() ; ! 607: ! 608: ! 609: GetDlgItemText(hwnd, ID_MAXCUSTFILTO, szNum, 20) ; ! 610: po->nMaxCustFilter = MyAtol(szNum, uMode==IDM_HEXMODE, &b) ; ! 611: ! 612: GetDlgItemText(hwnd, ID_FILTINDEXO, szNum, 20) ; ! 613: po->nFilterIndex = MyAtol(szNum, uMode==IDM_HEXMODE, &b) ; ! 614: ! 615: GetDlgItemText(hwnd, ID_SZFILEO, po->lpstrFile, MAXBUF) ; ! 616: ! 617: GetDlgItemText(hwnd, ID_MAXSZFILEO, szNum, 20) ; ! 618: po->nMaxFile = MyAtol(szNum, uMode==IDM_HEXMODE, &b) ; ! 619: ! 620: GetDlgItemText(hwnd, ID_SZFILETITLEO, po->lpstrFileTitle, MAXBUF) ; ! 621: ! 622: GetDlgItemText(hwnd, ID_MAXSZFILETITLEO, szNum, MAXBUF) ; ! 623: po->nMaxFileTitle = MyAtol(szNum, uMode==IDM_HEXMODE, &b) ; ! 624: ! 625: GetDlgItemText(hwnd, ID_SZINITDIRO, (LPTSTR) po->lpstrInitialDir, MAXBUF) ; ! 626: ! 627: GetDlgItemText(hwnd, ID_SZTITLEO, (LPTSTR) po->lpstrTitle, MAXBUF) ; ! 628: ! 629: GetDlgItemText(hwnd, ID_FLAGSO, szNum, 20) ; ! 630: po->Flags = MyAtol(szNum, uMode==IDM_HEXMODE, &b) ; ! 631: ! 632: GetDlgItemText(hwnd, ID_FILEOFFO, szNum, 20) ; ! 633: po->nFileOffset = (WORD) MyAtol(szNum, uMode==IDM_HEXMODE, &b) ; ! 634: ! 635: GetDlgItemText(hwnd, ID_FILEEXTO, szNum, 20) ; ! 636: po->nFileExtension = (WORD) MyAtol(szNum, uMode==IDM_HEXMODE, &b) ; ! 637: ! 638: GetDlgItemText(hwnd, ID_SZDEFEXTO, (LPTSTR) po->lpstrDefExt, DEFEXTSIZE) ; ! 639: ! 640: GetDlgItemText(hwnd, ID_CUSTDATAO, szNum, 20) ; ! 641: po->lCustData = MyAtol(szNum, uMode==IDM_HEXMODE, &b) ; ! 642: ! 643: GetDlgItemText(hwnd, ID_HOOKO, szNum, 20) ; ! 644: po->lpfnHook = (LPOFNHOOKPROC) MyAtol(szNum, uMode==IDM_HEXMODE, &b) ; ! 645: ! 646: GetDlgItemText(hwnd, ID_TEMPLATEO, (LPTSTR) po->lpTemplateName, TEMPNAMESIZE) ; ! 647: ! 648: ! 649: /* if we are supposed to use a preloaded resource handle, load it and put it in ! 650: OPENFILENAME.hInstance... */ ! 651: ! 652: if (IsDlgButtonChecked(hwnd, ID_USEHINSTO) == 1) ! 653: po->hInstance = GetCorrectResourceHandle() ; ! 654: ! 655: return ; ! 656: } ! 657: ! 658: ! 659: ! 660: ! 661: ! 662: ! 663: ! 664: /************************************************************************ ! 665: ! 666: ! 667: Function: InitFilterString(void) ! 668: ! 669: ! 670: Purpose: ! 671: ! 672: This function will create a "string" in memory in the form that the ! 673: GetOpenFileName() function will expect for the filters it fills into ! 674: the "List Files of Type" combo box. ! 675: ! 676: Returns: Nothing. ! 677: ! 678: Comments: ! 679: ! 680: The szFilterInits and szCustFiltInits arrays are initialized to ! 681: contain some default strings. Eventually the strings in ! 682: these arrays must be arranged one after the other with a null ! 683: character between them and two null characters at the end: ! 684: ! 685: "Text files\0*.txt\0All files\0*.*\0\0" ! 686: ! 687: ************************************************************************/ ! 688: ! 689: ! 690: void InitFilterString(void) ! 691: { ! 692: int i ; ! 693: int nInc = 0 ; ! 694: LPTSTR lpStr = szFilterString ; ! 695: ! 696: ! 697: /* First, zero out this memory just for the sake of sanity */ ! 698: ! 699: for (i=0; i<MAXBUF; i++) ! 700: szFilterString[i] = 0 ; ! 701: ! 702: ! 703: /* Now, for each string in the szFilterInits array, concatenate it to ! 704: the last one right after the last one's null terminator */ ! 705: ! 706: i = 0 ; ! 707: ! 708: while (szFilterInits[i][0] != (TCHAR) 0) ! 709: { ! 710: lstrcpy(lpStr, &szFilterInits[i][0]) ; ! 711: nInc+=lstrlen(&szFilterInits[i][0]) + 1 ; //1 past null term... ! 712: lpStr = &szFilterString[nInc] ; ! 713: i++ ; ! 714: } ! 715: ! 716: szFilterString[nInc] = (TCHAR) 0 ; //double terminator ! 717: ! 718: ! 719: /* Set the lpszFilterString to point to the memory we just filled in ! 720: with the filters because lpszFilterString is what is in ! 721: OPENFILENAME->lpstrFilter */ ! 722: ! 723: lpszFilterString = szFilterString ; ! 724: ! 725: return ; ! 726: } ! 727: ! 728: ! 729: ! 730: ! 731: ! 732: ! 733: ! 734: ! 735: ! 736: /************************************************************************ ! 737: ! 738: ! 739: Function: InitCustFiltString(void) ! 740: ! 741: ! 742: Purpose: ! 743: ! 744: This function will create a "string" in memory in the form that the ! 745: GetOpenFileName() function will expect for a custom filter. ! 746: ! 747: Returns: Nothing. ! 748: ! 749: Comments: ! 750: ! 751: The szFilterInits and szCustFiltInits arrays are initialized to ! 752: contain some default strings. Eventually the strings in ! 753: these arrays must be arranged one after the other with a null ! 754: character between them and two null characters at the end: ! 755: ! 756: "Text files\0*.txt\0All files\0*.*\0\0" ! 757: ! 758: This program initializes these strings, but they do not need to be ! 759: initialized. The GetOpenFileName() functiion will write a filter ! 760: into this memory area if the user types a new filter into the ! 761: "FileName" box and returns by clicking the OK button (indicating that ! 762: a file matching that filter was found). ! 763: ! 764: ************************************************************************/ ! 765: ! 766: ! 767: void InitCustFilterString(void) ! 768: { ! 769: int i ; ! 770: LPTSTR lpStr = szCustFilterString ; ! 771: int nInc = 0 ; ! 772: ! 773: for (i=0; i<MAXBUF; i++) ! 774: szCustFilterString[i] = 0 ; ! 775: ! 776: i = 0 ; ! 777: ! 778: for(i=0; i<2; i++) //only two for the custom filter ! 779: { ! 780: lstrcpy(lpStr, &szCustFiltInits[i][0]) ; ! 781: nInc+=lstrlen(&szCustFiltInits[i][0]) + 1 ; ! 782: lpStr = &szCustFilterString[nInc] ; ! 783: } ! 784: ! 785: szCustFilterString[nInc] = (TCHAR) 0 ; ! 786: ! 787: lpszCustFilterString = szCustFilterString ; ! 788: ! 789: return ; ! 790: } ! 791: ! 792: ! 793: ! 794: ! 795: ! 796: ! 797: ! 798: ! 799: ! 800: /************************************************************************ ! 801: ! 802: Function: InterpretCustomFilterString(void) ! 803: ! 804: ! 805: Purpose: ! 806: ! 807: This function will parse the memory that is being used for the ! 808: custom filter string. If the user returned TRUE after entering ! 809: their own filter, the new filter will be here and so we need to ! 810: add it to our custom filter init array... ! 811: ! 812: Returns: Nothing. ! 813: ! 814: Comments: ! 815: ! 816: ************************************************************************/ ! 817: ! 818: void InterpretCustomFilterString(void) ! 819: { ! 820: LPTSTR pNext ; ! 821: ! 822: int nCount = lstrlen(ofn.lpstrCustomFilter) ; ! 823: ! 824: pNext = ofn.lpstrCustomFilter + nCount + 1 ; //one past the NULL ! 825: ! 826: ! 827: /* add it to the filter inits array */ ! 828: ! 829: lstrcpy(&szCustFiltInits[0][0], ofn.lpstrCustomFilter) ; ! 830: lstrcpy(&szCustFiltInits[1][0], pNext) ; ! 831: ! 832: } ! 833: ! 834: ! 835: ! 836: ! 837: ! 838: ! 839: ! 840: ! 841: ! 842: /************************************************************************ ! 843: ! 844: Function: GetCorrectResourceHandle(void) ! 845: ! 846: Purpose: ! 847: ! 848: This function will use FindResource() to find the correct custom ! 849: template resource, use LoadResource() to get a handle to it. ! 850: ! 851: Returns: A handle to a custom template resource. ! 852: ! 853: Comments: ! 854: ! 855: The names for the custom template for GetOpenFileName() are ! 856: ! 857: "opentemp1" -- normal ! 858: "opentemp2" -- contains a multi-select list box for the file names ! 859: ! 860: If the user has marked the "Preloaded Template" box and specified ! 861: OFN_ENABLETEMPLATEHANDLE in the "Flags" edit box, this handle ! 862: will be used to create the GetOpenFileName() dialog box. ! 863: ! 864: ************************************************************************/ ! 865: ! 866: ! 867: HANDLE GetCorrectResourceHandle(void) ! 868: { ! 869: if (ofn.Flags & OFN_ALLOWMULTISELECT) ! 870: { ! 871: hRes = FindResource(hInst, TEXT("opentemp2"), RT_DIALOG) ; ! 872: hDialog = LoadResource(hInst, hRes) ; ! 873: } ! 874: ! 875: else ! 876: { ! 877: hRes = FindResource(hInst, TEXT("opentemp1"), RT_DIALOG) ; ! 878: hDialog = LoadResource(hInst, hRes) ; ! 879: } ! 880: ! 881: return hDialog ; ! 882: } ! 883: ! 884: ! 885: ! 886: ! 887: ! 888: ! 889: ! 890: /************************************************************************ ! 891: ! 892: Function: OpenSaveHookProc(HWND, UINT, UINT, LONG) ; ! 893: ! 894: Purpose: ! 895: ! 896: This function is the hook function for the GetOpenFileName() function. ! 897: If GetOpenFileName() is called with the OFN_ENABLEHOOK flag, this ! 898: function will be called before the normal GetOpenFileName() dialog ! 899: function is called. ! 900: ! 901: Returns: FALSE to pass the message on to the normal GetOpenFileName() ! 902: logic, TRUE to discard the message. ! 903: ! 904: Comments: ! 905: ! 906: To enable this function in this program, enter the value for ! 907: OFN_ENABLEHOOK in the "Flags" edit box. ! 908: ! 909: ************************************************************************/ ! 910: ! 911: ! 912: UINT APIENTRY OpenSaveHookProc(HWND hwnd, UINT msg, UINT wParam, LONG lParam) ! 913: { ! 914: LPOPENFILENAME pOfn ; ! 915: TCHAR szMsg[50] ; ! 916: ! 917: switch(msg) ! 918: { ! 919: case WM_INITDIALOG: ! 920: ! 921: pOfn = (LPOPENFILENAME) lParam ; ! 922: ! 923: ! 924: /* During initialization, if there is a hook proc, the getopen() ! 925: code will send pointer to the OPENFILENAME strucure in the ! 926: lParam. To demonstrate this, pop up a message box if this ! 927: structure has a non zero value in the lCustData structure member */ ! 928: ! 929: ! 930: if (pOfn->lCustData != 0L) ! 931: { ! 932: wsprintf(szMsg, TEXT("OPENFILENAME->lCustData is: %ld"), pOfn->lCustData) ; ! 933: ! 934: MessageBox(hwnd, szMsg, TEXT("lCustData Sent!"), MB_OK) ; ! 935: } ! 936: ! 937: SetWindowText(hwnd, TEXT("Open Hook Proc Dialog")) ; ! 938: ! 939: break ; ! 940: ! 941: ! 942: /* use the WM_CTLCOLOR* messages to change the color of the Open ! 943: dialog */ ! 944: ! 945: case WM_CTLCOLORDLG: ! 946: ! 947: if (!hBrushDlg) ! 948: hBrushDlg = GetStockObject(LTGRAY_BRUSH) ; ! 949: ! 950: return (UINT) hBrushDlg ; ! 951: ! 952: break ; ! 953: ! 954: ! 955: case WM_CTLCOLORBTN: ! 956: ! 957: SetBkMode((HDC) wParam, TRANSPARENT) ; //sets background color ! 958: //for push and check box ! 959: //buttons... ! 960: ! 961: if (!hBrushButton) ! 962: hBrushButton = GetStockObject(LTGRAY_BRUSH) ; ! 963: ! 964: return (UINT) hBrushButton ; ! 965: ! 966: break ; ! 967: ! 968: ! 969: case WM_CTLCOLORSTATIC: ! 970: ! 971: SetTextColor((HDC) wParam, RGB(0x00, 0xff, 0x00)) ; //green ! 972: SetBkMode((HDC) wParam, TRANSPARENT) ; //transparent text ! 973: ! 974: if (!hBrushDlg) ! 975: hBrushDlg = GetStockObject(LTGRAY_BRUSH) ; ! 976: ! 977: return (UINT) hBrushDlg ; ! 978: ! 979: break ; ! 980: ! 981: ! 982: case WM_COMMAND: ! 983: switch (LOWORD(wParam)) ! 984: { ! 985: case chx1: ! 986: MessageBox(hwnd, TEXT("Read-Only button clicked..."), ! 987: TEXT("Open"), MB_OK | MB_APPLMODAL) ; ! 988: break ; ! 989: ! 990: case ID_FILEPREVIEW: ! 991: MessageBox(hwnd, TEXT("File Preview Button Clicked"), ! 992: TEXT("Open"), MB_OK | MB_APPLMODAL) ; ! 993: break ; ! 994: ! 995: default: break ; ! 996: } ! 997: break ; ! 998: ! 999: default: ! 1000: ! 1001: if (msg == nOpenShareVMsg) ! 1002: { ! 1003: MessageBox(hwnd, TEXT("The SHAREVSTRING message is here!"), ! 1004: TEXT("Open"), ! 1005: MB_ICONEXCLAMATION | MB_OK | MB_APPLMODAL) ; ! 1006: ! 1007: return OFN_SHAREWARN ; ! 1008: } ! 1009: break ; ! 1010: } ! 1011: ! 1012: return FALSE ; //send msg to the common dialog code ! 1013: } ! 1014: ! 1015: ! 1016: ! 1017: ! 1018: ! 1019: ! 1020: ! 1021: ! 1022: ! 1023: /************************************************************************ ! 1024: ! 1025: Function: MultiThreadOpenSave(void) ! 1026: ! 1027: Purpose: ! 1028: ! 1029: This function will start two threads and then return. The two ! 1030: threads will create GetOpenFileName() dialogs, and the user ! 1031: can interact with two Open dialogs at once. ! 1032: ! 1033: Returns: Nothing. ! 1034: ! 1035: Comments: ! 1036: ! 1037: This will create two Open dialogs, but they will be created in the ! 1038: same location on the screen. The only way to change that would be ! 1039: to call the function with a hookproc and move one of the windows. ! 1040: ! 1041: But that would mean that if the user did not enter OFN_ENABLEHOOK ! 1042: in the "Flags" edit box, we would be no better off than before. So, ! 1043: in order to see both dialogs, you just have to move the top one out ! 1044: of the way a little. ! 1045: ! 1046: Multithreading note: ! 1047: ! 1048: This function will return before the common dialog functions return. ! 1049: Therefore, do not pass any parameters to this function that will be ! 1050: referenced by the common dialogs because as soon as this function ! 1051: ends those parameters will be gone. ! 1052: ! 1053: ************************************************************************/ ! 1054: ! 1055: void MultiThreadOpenSave(void) ! 1056: { ! 1057: ! 1058: if (!(hOpenSaveThread1 = CreateThread((LPSECURITY_ATTRIBUTES) NULL, 0, ! 1059: (LPTHREAD_START_ROUTINE) OpenSaveThread1Proc, ! 1060: &dwThreadParm1, CREATE_SUSPENDED, &dwThreadID1))) ! 1061: ! 1062: { ! 1063: MessageBox(GetForegroundWindow(), TEXT("Cannot create thread 1"), NULL, MB_OK | MB_ICONEXCLAMATION) ; ! 1064: OpenMultiThreadEnableButtons(TRUE, hwndMainDialog) ; ! 1065: nOpenDialogCount = 0 ; ! 1066: return ; ! 1067: } ! 1068: ! 1069: ! 1070: ! 1071: if (!(hOpenSaveThread2 = CreateThread((LPSECURITY_ATTRIBUTES) NULL, 0, ! 1072: (LPTHREAD_START_ROUTINE) OpenSaveThread2Proc, ! 1073: &dwThreadParm2, CREATE_SUSPENDED, &dwThreadID2))) ! 1074: { ! 1075: MessageBox(GetForegroundWindow(), TEXT("Cannot create thread 2"), NULL, MB_OK | MB_ICONEXCLAMATION) ; ! 1076: OpenMultiThreadEnableButtons(TRUE, hwndMainDialog) ; ! 1077: nOpenDialogCount = 0 ; ! 1078: return ; ! 1079: } ! 1080: ! 1081: ! 1082: ResumeThread(hOpenSaveThread1) ; ! 1083: ResumeThread(hOpenSaveThread2) ; ! 1084: ! 1085: } ! 1086: ! 1087: ! 1088: ! 1089: ! 1090: ! 1091: ! 1092: ! 1093: /************************************************************************ ! 1094: ! 1095: Function: OpenSaveThreadProc1(LPDWORD) ! 1096: ! 1097: Purpose: ! 1098: ! 1099: This is the address where the first thread starts executing. ! 1100: ! 1101: Returns: Any DWORD value. ! 1102: ! 1103: Comments: ! 1104: ! 1105: ************************************************************************/ ! 1106: ! 1107: ! 1108: DWORD OpenSaveThread1Proc(LPDWORD pDw) ! 1109: { ! 1110: ! 1111: /* Get the user's input */ ! 1112: ! 1113: GetOpenDlg(hwndMainDialog, &ofnThread1) ; ! 1114: ! 1115: ! 1116: /* Do the dialog */ ! 1117: ! 1118: DoOpenSaveStuff(&ofnThread1) ; ! 1119: ! 1120: ! 1121: /* send a message to the parent telling it to decrement the dialog count. ! 1122: When the dialog count reaches zero, all the buttons are enabled again. */ ! 1123: ! 1124: SendMessage(hwndMainDialog, UMSG_DECREMENTDLGCOUNT, 0, 0L) ; ! 1125: ! 1126: return 0L ; ! 1127: } ! 1128: ! 1129: ! 1130: ! 1131: ! 1132: ! 1133: ! 1134: ! 1135: /************************************************************************ ! 1136: ! 1137: Function: OpenSaveThreadProc2(LPDWORD) ! 1138: ! 1139: Purpose: ! 1140: ! 1141: This is the address where the second thread starts executing. ! 1142: ! 1143: Returns: Any DWORD value. ! 1144: ! 1145: Comments: ! 1146: ! 1147: ************************************************************************/ ! 1148: ! 1149: DWORD OpenSaveThread2Proc(LPDWORD pDw) ! 1150: { ! 1151: GetOpenDlg(hwndMainDialog, &ofnThread2) ; ! 1152: ! 1153: DoOpenSaveStuff(&ofnThread2) ; ! 1154: ! 1155: SendMessage(hwndMainDialog, UMSG_DECREMENTDLGCOUNT, 0, 0L) ; ! 1156: ! 1157: return 0L ; ! 1158: } ! 1159: ! 1160: ! 1161: ! 1162: ! 1163: ! 1164: ! 1165: ! 1166: /************************************************************************ ! 1167: ! 1168: Function: DoOpenSaveStuff(LPOPENFILENAME) ! 1169: ! 1170: Purpose: ! 1171: ! 1172: This is the function that actually calls GetOpenFileName() or ! 1173: GetSaveFileName(). It receives a pointer to the structure to ! 1174: use as its only parameter. ! 1175: ! 1176: Returns: Nothing. ! 1177: ! 1178: Comments: ! 1179: ! 1180: ************************************************************************/ ! 1181: ! 1182: void DoOpenSaveStuff(LPOPENFILENAME po) ! 1183: { ! 1184: BOOL bRet = TRUE ; ! 1185: ! 1186: ! 1187: /* If bOpenDlg is TRUE, do GetOpenFileName(), else do GetSave(). ! 1188: If the "NULL Structure" button is checked, send in a NULL pointer ! 1189: to the function */ ! 1190: ! 1191: if (bDoOpenDlg) ! 1192: { ! 1193: if (IsDlgButtonChecked(hwndMainDialog, ID_NULLSTRUCTO) == 1) ! 1194: bRet = GetOpenFileName((LPOPENFILENAME) NULL) ; ! 1195: else ! 1196: bRet = GetOpenFileName(po) ; ! 1197: } ! 1198: ! 1199: else ! 1200: { ! 1201: if (IsDlgButtonChecked(hwndMainDialog, ID_NULLSTRUCTO)) ! 1202: bRet = GetSaveFileName((LPOPENFILENAME) NULL) ; ! 1203: else ! 1204: bRet = GetSaveFileName(po) ; ! 1205: } ! 1206: ! 1207: ! 1208: /* Record the results */ ! 1209: ! 1210: wsprintf(szTemp, szLongFilter, CommDlgExtendedError()) ; ! 1211: SetDlgItemText(hwndMainDialog, ID_ERRORO, szTemp) ; ! 1212: ! 1213: wsprintf(szTemp, szShortFilter, (int) bRet) ; ! 1214: SetDlgItemText(hwndMainDialog, ID_RETURNO, szTemp) ; ! 1215: ! 1216: InterpretCustomFilterString() ; ! 1217: ! 1218: FillOpenDlg(hwndMainDialog, po) ; ! 1219: ! 1220: if (hDialog) ! 1221: { ! 1222: FreeResource(hDialog) ; //free ofn.hInstance ! 1223: hDialog = (HANDLE) 0 ; ! 1224: hRes = (HANDLE) 0 ; ! 1225: } ! 1226: } ! 1227: ! 1228: ! 1229: ! 1230: ! 1231: ! 1232: ! 1233: ! 1234: /************************************************************************ ! 1235: ! 1236: Function: OpenMultiThreadEnableButtons(BOOL, HWND) ! 1237: ! 1238: Purpose: ! 1239: ! 1240: Enable or disable the buttons that might affect the state of the ! 1241: OPENFILENAME structures. This is necessary because during a ! 1242: multithreading session, these buttons may be accessible even though ! 1243: there are Open dialogs still working and we don't want to change ! 1244: the OPENFILENAME structure out from under them. ! 1245: ! 1246: ! 1247: Returns: Nothing. ! 1248: ! 1249: Comments: ! 1250: ! 1251: ************************************************************************/ ! 1252: ! 1253: void OpenMultiThreadEnableButtons(BOOL bEnable, HWND hwnd) ! 1254: { ! 1255: EnableWindow(GetDlgItem(hwnd, IDOK), bEnable) ; ! 1256: EnableWindow(GetDlgItem(hwnd, IDCANCEL), bEnable) ; ! 1257: EnableWindow(GetDlgItem(hwnd, ID_RESETOPEN), bEnable) ; ! 1258: EnableWindow(GetDlgItem(hwnd, ID_MULTIOPEN), bEnable) ; ! 1259: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.