DLGOPEN.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:22k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /******************************************************************************
  2. *       This is a part of the Microsoft Source Code Samples. 
  3. *       Copyright (C) 1993-1997 Microsoft Corporation.
  4. *       All rights reserved. 
  5. *       This source code is only intended as a supplement to 
  6. *       Microsoft Development Tools and/or WinHelp documentation.
  7. *       See these sources for detailed information regarding the 
  8. *       Microsoft samples programs.
  9. ******************************************************************************/
  10. /*******************************************************************************
  11.  *                                                                             *
  12.  *  MODULE      : DLGOPEN.C                                                    *
  13.  *                                                                             *
  14.  *  DESCRIPTION : Routines to display a standard File/Open and File/Save       *
  15.  *                dialog boxes.                                                *
  16.  *                                                                             *
  17.  *  FUNCTIONS   : DlgOpenFile() - Displays a dialog box for opening or saving a*
  18.  *                                file.                                        *
  19.  *                                                                             *
  20.  *                DlgfnOpen()   - Dialog function for the above dialog.        *
  21.  *                                                                             *
  22.  *                AddExt()      - Adds an extension to a filename if not       *
  23.  *                                already present.                             *
  24.  *                                                                             *
  25.  *                FSearchSpec() - Checks if given string contains a wildcard   *
  26.  *                                character.                                   *
  27.  *                                                                             *
  28.  *                FillListBox() - Fills listbox with files that match specs.   *
  29.  *                                                                             *
  30.  *                DlgCheckOkEnable() - Enables <OK> button iff there's text in *
  31.  *                                     the edit control.                       *
  32.  *                                                                             *
  33.  *                NOTE : These routines require that the app. be running       *
  34.  *                       SS = DS since they use near pointers into the stack.  *
  35.  *                                                                             *
  36.  *******************************************************************************/
  37. #include <windows.h>
  38. #include <string.h>
  39. #include "showdib.h"
  40. static PSTR         szExt;
  41. static PSTR         szFileName;
  42. static PSTR         szTitle;
  43. static DWORD        flags;
  44. static WORD         fOpt;
  45. /* Forward declarations of helper functions */
  46. static VOID  NEAR DlgCheckOkEnable(HWND hwnd, INT idEdit, UINT message);
  47. static CHAR *NEAR FillListBox (HWND,CHAR*, UINT);
  48. static BOOL  NEAR FSearchSpec (CHAR*);
  49. static VOID  NEAR AddExt (CHAR*,CHAR*);
  50. #define DLGOPEN_UNUSED   0
  51. /* Mask to eliminate bogus style and bitcount combinations ...
  52.  * RLE formats, if chosen should be matched with the bitcounts:
  53.  *   RLE4 scheme should be used only for 4 bitcount DIBs.
  54.  *   RLE8   "      "     "   "   "    "  8   "       "
  55.  *
  56.  * BITCOUNTMASK is indexed by DLGOPEN_RLE4 >> 4, DLGOPEN_RLE8 >> 4
  57.  * and DLGOPEN_RLE8 >> 4
  58.  */
  59. static WORD BITCOUNTMASK[] = { DLGOPEN_UNUSED,
  60.                                DLGOPEN_1BPP | DLGOPEN_8BPP | DLGOPEN_24BPP,
  61.                                DLGOPEN_1BPP | DLGOPEN_4BPP | DLGOPEN_24BPP,
  62.                                DLGOPEN_UNUSED,
  63.                                0 };
  64. /*******************************************************************************
  65.  *                                                                             *
  66.  *  FUNCTION   :DlgOpen(LPSTR szFile)                                          *
  67.  *                                                                             *
  68.  *  PURPOSE    :Display dialog box for opening files. Allow user to interact   *
  69.  *              with dialogbox, change directories as necessary, and try to    *
  70.  *              open file if user selects one. Automatically append            *
  71.  *              extension to filename if necessary.                            *
  72.  *              This routine correctly parses filenames containing KANJI       *
  73.  *              characters.                                                    *
  74.  *                                                                             *
  75.  *  RETURNS    :  - Handle to the opened file if legal filename.               *
  76.  *                - 0 if user presses <cancel>                                 *
  77.  *                - 1 if filename entered is illegal                           *
  78.  *                                                                             *
  79.  *******************************************************************************/
  80. HFILE APIENTRY DlgOpenFile (
  81.     HWND          hwndParent,
  82.     CHAR          *szTitleIn,
  83.     DWORD         flagsIn,
  84.     CHAR          *szExtIn,
  85.     CHAR          *szFileNameIn,
  86.     WORD          *pfOpt)
  87. {
  88.     INT      fh;
  89.     FARPROC  lpProc;
  90.     CHAR     achFile[128];
  91.     CHAR     achExt[128];
  92.     HANDLE   hInstance;
  93.     WORD     w;
  94.     if (pfOpt == NULL)
  95.         pfOpt = &w;
  96.     flags    = flagsIn;
  97.     fOpt     = *pfOpt;
  98.     lstrcpy (szFileName = achFile, szFileNameIn);
  99.     lstrcpy (szExt = achExt, szExtIn);
  100.     szTitle = szTitleIn;
  101.     hInstance = (HANDLE)GetWindowLong (hwndParent, GWL_HINSTANCE);
  102.     /* Show the dialog box */
  103.     lpProc = MakeProcInstance ((FARPROC)DlgfnOpen, hInstance);
  104.     fh = DialogBox (hInstance, "DlgOpenBox", hwndParent, (DLGPROC)lpProc);
  105.     FreeProcInstance (lpProc);
  106.     if (fh != 0){
  107.         lstrcpy (szFileNameIn, szFileName);
  108.         *pfOpt = fOpt;
  109.     }
  110.     return fh;
  111. }
  112. /****************************************************************************
  113.  *                                                                          *
  114.  *  FUNCTION   :DlgfnOpen (hwnd, msg, wParam, lParam)                       *
  115.  *                                                                          *
  116.  *  PURPOSE    :Dialog function for File/Open dialog.                       *
  117.  *                                                                          *
  118.  ****************************************************************************/
  119. LONG APIENTRY DlgfnOpen (
  120.     HWND hwnd,
  121.     UINT msg,
  122.     UINT wParam,
  123.     LONG lParam)
  124. {
  125.     INT      result = -1;    /* Assume illegal filename initially */
  126.     int      w;
  127.     LPSTR    lpsz;
  128.     WORD     f;
  129.     OFSTRUCT of;
  130.     RECT     rc, rcCtl;
  131.     HWND     hwndT;
  132.     BOOL     fEnable;
  133.     CHAR     lpBuffer[128];
  134.     switch (msg) {
  135.         case WM_INITDIALOG:
  136.             if (szTitle && *szTitle)
  137.                 SetWindowText (hwnd, szTitle);
  138.             /* Set text on <OK> button according to mode (File/Open or File/Save) */
  139.             if (flags & OF_SAVE) {
  140.                 LoadString(hInst, IDS_SAVESTR, lpBuffer, sizeof(lpBuffer));
  141.                 SetDlgItemText(hwnd, IDOK, lpBuffer);
  142.             }
  143.             if (flags & OF_OPEN) {
  144.                 LoadString(hInst, IDS_OPENSTR, lpBuffer, sizeof(lpBuffer));
  145.                 SetDlgItemText(hwnd, IDOK, lpBuffer);
  146.             }
  147.             if ((flags & OF_NOOPTIONS) &&
  148.                 (hwndT = GetDlgItem(hwnd,DLGOPEN_FOLDOUT)))
  149.                 EnableWindow (hwndT,FALSE);
  150.             if (hwndT = GetDlgItem (hwnd, DLGOPEN_SMALL)) {
  151.                 GetWindowRect (hwnd,&rc);
  152.                 GetWindowRect (GetDlgItem(hwnd,DLGOPEN_SMALL),&rcCtl);
  153.                 SetWindowPos (hwnd,
  154.                               NULL,
  155.                               0,
  156.                               0,
  157.                               rcCtl.left - rc.left,
  158.                               rc.bottom - rc.top,
  159.                               SWP_NOZORDER | SWP_NOMOVE);
  160.             }
  161.             /* fill list box with filenames that match specifications, and
  162.              * fill static field with path name.
  163.              */
  164.             FillListBox(hwnd,szExt, WM_INITDIALOG);
  165.             /* If in Save mode, set the edit control with default (current)
  166.              * file name,and select the corresponding entry in the listbox.
  167.              */
  168.             if ((flags & OF_SAVE) && *szFileName) {
  169.                         SetDlgItemText (hwnd, DLGOPEN_EDIT, szFileName);
  170.                         SendDlgItemMessage (hwnd,
  171.                                     DLGOPEN_FILE_LISTBOX,
  172.                                     LB_SELECTSTRING,
  173.                                     0,
  174.                                     (LONG)(LPSTR)szFileName);
  175.             }
  176.             else {
  177.                 /*  Set the edit field with the default extensions... */
  178.                 if (flags & OF_NOSHOWSPEC)
  179.                     SetDlgItemText (hwnd, DLGOPEN_EDIT, "");
  180.                 else
  181.                     SetDlgItemText (hwnd, DLGOPEN_EDIT, szExt);
  182.             }
  183.             /*  ...and select all text in the edit field */
  184.                 /* JAP added HWND cast*/
  185.             SendMessage((HWND)GetDlgItem(hwnd, DLGOPEN_EDIT), EM_SETSEL, GET_EM_SETSEL_MPS(0, 0x7fff));
  186.             /*  check all options that are set */
  187.             for ( f = DLGOPEN_1BPP; f; f<<=1)
  188.                 CheckDlgButton(hwnd, (INT)FID(f), (WORD) (fOpt & f));
  189.             break;
  190.         case WM_COMMAND:
  191.     switch (LOWORD(wParam)) {
  192.                 case IDOK:
  193.                     if (IsWindowEnabled (GetDlgItem(hwnd, IDOK))) {
  194.                         /* Get contents of edit field and add search spec. if it
  195.                          * does not contain one.
  196.                          */
  197.                         GetDlgItemText (hwnd, DLGOPEN_EDIT, (LPSTR)szFileName, 128);
  198.              lpsz = CharPrev(szFileName, szFileName + lstrlen(szFileName));
  199.              switch (*lpsz) {
  200.                             case '\':
  201.                             case '/':
  202.                                 *lpsz = 0;
  203.                             break;
  204.                         }
  205.                         if (SetCurrentDirectory ((LPSTR)szFileName))
  206.                             lstrcpy (szFileName,szExt);
  207.                         /*  Try to open path.  If successful, fill listbox with
  208.                          *  contents of new directory.  Otherwise, open datafile.
  209.                          */
  210.                         if (FSearchSpec(szFileName)) {
  211.                             lstrcpy (szExt, FillListBox (hwnd, szFileName, WM_COMMAND));
  212.                             if (flags & OF_NOSHOWSPEC) {
  213.                                 SetDlgItemText (hwnd, DLGOPEN_EDIT, "");
  214.                             } else {
  215.                                 SetDlgItemText (hwnd, DLGOPEN_EDIT, szExt);
  216.                             }
  217.                             break;
  218.                         }
  219.                         /*  Make filename upper case and if it's a legal DOS
  220.                          *  name, try to open the file.
  221.                          */
  222.                         CharUpper(szFileName);
  223.                         AddExt(szFileName,szExt);
  224.                         result = (INT)OpenFile(szFileName, &of, (WORD)flags);
  225.                         if (result != -1) {
  226.                             lstrcpy(szFileName,of.szPathName);
  227.                         }
  228.                         else if (flags & OF_MUSTEXIST) {
  229.                             MessageBeep(0);
  230.                             return 0L;
  231.                         }
  232.                         /*  Get the state of all checked options */
  233.                         for (f = DLGOPEN_1BPP; f; f <<= 1){
  234.                             if (IsDlgButtonChecked (hwnd, FID (f)))
  235.                                 fOpt |= f;
  236.                             else
  237.                                 fOpt &= ~f;
  238.                         }
  239.                         EndDialog (hwnd, result);
  240.                     }
  241.                     break;
  242.                 case DLGOPEN_OPTION + DLGOPEN_RLE4:
  243.                 case DLGOPEN_OPTION + DLGOPEN_RLE8:
  244.                 case DLGOPEN_OPTION + DLGOPEN_RGB:
  245.                     /* Mask out incompatible bitcount options and gray the
  246.                      * appropriate radiobuttons.
  247.                      */
  248.                     for (f = DLGOPEN_1BPP; f <= DLGOPEN_24BPP; f <<= 1){
  249.                         fEnable = !(f & BITCOUNTMASK [IDF(w) >> 4 ]);
  250.                         EnableWindow (GetDlgItem (hwnd, FID(f)), fEnable);
  251.                         /* If the radiobutton is being grayed, uncheck it and
  252.                          * and check an "allowed" option so the bitcount group
  253.                          * is still accessible via the keyboard
  254.                          */
  255.                         if (!fEnable && IsDlgButtonChecked (hwnd, FID (f))){
  256.                             CheckDlgButton(hwnd, FID(f), FALSE);
  257.                             CheckDlgButton(hwnd, FID(IDF(w) >> 3), TRUE);
  258.                         }
  259.                     }
  260.                     break;
  261.                 case IDCANCEL:
  262.                     /* User pressed cancel.  Just take down dialog box. */
  263.                     EndDialog (hwnd, 0);
  264.                     break;
  265.                 /*  User single clicked or doubled clicked in listbox -
  266.                  *  Single click means fill edit box with selection.
  267.                  *  Double click means go ahead and open the selection.
  268.                  */
  269.                 case DLGOPEN_FILE_LISTBOX:
  270.                 case DLGOPEN_DIR_LISTBOX:
  271.                     switch (GET_WM_COMMAND_CMD(wParam, lParam)) {
  272.                         /* Single click case */
  273.                         case LBN_SELCHANGE:
  274.                             /* Get selection, which may be either a prefix to a
  275.                              * new search path or a filename. DlgDirSelectEx parses
  276.                              * selection, and appends a backslash if selection
  277.                              * is a prefix
  278.                              */
  279.                             DlgDirSelectEx(hwnd, szFileName, 128, LOWORD(wParam));
  280.              lpsz = CharPrev(szFileName, szFileName + lstrlen(szFileName));
  281.                  switch (*lpsz) {
  282.                                 case ':':
  283.                                     lstrcat (szFileName,".");
  284.                                     break;
  285.                                 case '\':
  286.                                 case '/':
  287.                                     *lpsz = 0;
  288.                                     break;
  289.                             }
  290.                             SetDlgItemText(hwnd, DLGOPEN_EDIT, szFileName);
  291.                             break;
  292.                         /* Double click case - first click has already been
  293.                          * processed as single click
  294.                          */
  295.                         case LBN_DBLCLK:
  296.                             PostMessage (hwnd,WM_COMMAND,IDOK,0L);
  297.                             break;
  298.                     }
  299.                     break;
  300.                 case DLGOPEN_EDIT:
  301.                     DlgCheckOkEnable(hwnd, DLGOPEN_EDIT, HIWORD(lParam));
  302.                     break;
  303.                 case DLGOPEN_FOLDOUT:
  304.                     GetWindowRect(hwnd,&rc);
  305.                     GetWindowRect(GetDlgItem(hwnd,DLGOPEN_BIG),&rcCtl);
  306.                     if ((rcCtl.left <= rc.right) && (rcCtl.top <= rc.bottom))
  307.                          GetWindowRect (GetDlgItem (hwnd, DLGOPEN_SMALL), &rcCtl);
  308.                     SetWindowPos (hwnd,
  309.                                   NULL,
  310.                                   0,
  311.                                   0,
  312.                                   rcCtl.left - rc.left,
  313.                                   rc.bottom - rc.top,
  314.                                   SWP_NOZORDER | SWP_NOMOVE);
  315.                     break;
  316.             }
  317.         default:
  318.             return FALSE;
  319.     }
  320.     return TRUE;
  321. }
  322. /****************************************************************************
  323.  *                                                                          *
  324.  *  FUNCTION   : static void NEAR DlgCheckOkEnable(hwnd, idEdit, message)   *
  325.  *                                                                          *
  326.  *  PURPOSE    : Enables the <OK> button in a dialog box iff the edit item  *
  327.  *               contains text.                                             *
  328.  *                                                                          *
  329.  ****************************************************************************/
  330. static VOID NEAR DlgCheckOkEnable(
  331.     HWND        hwnd,
  332.     INT idEdit,
  333.     UINT message)
  334. {
  335.     if (message == EN_CHANGE) {
  336.         EnableWindow ( GetDlgItem (hwnd, IDOK),
  337.                        (BOOL)SendMessage (GetDlgItem (hwnd, idEdit),
  338.                                           WM_GETTEXTLENGTH,
  339.                                           0, 0L));
  340.     }
  341. }
  342. /****************************************************************************
  343.  *                                                                          *
  344.  *  FUNCTION   : AddExt (pch, ext)                                          *
  345.  *                                                                          *
  346.  *  PURPOSE    : Add an extension to a filename if none is already specified*
  347.  *                                                                          *
  348.  ****************************************************************************/
  349. static VOID NEAR AddExt (
  350.     CHAR *pch,    /* File name    */
  351.     CHAR *ext)    /* Extension to add */
  352. {
  353.     CHAR acExt[20];
  354.     CHAR *pext = acExt;
  355.     while (*ext && *ext != '.') {
  356.         ext = CharNext(ext);
  357.     }
  358.     while (*ext && *ext != ';') {
  359.         if (IsDBCSLeadByte(*ext)) {
  360.             *pext++ = *ext++;
  361.         }
  362.         *pext++ = *ext++;
  363.     }
  364.     *pext = 0;
  365.     pext = acExt;
  366.     while (*pch == '.') {
  367.         pch++;
  368.         if ((*pch == '.') && pch[1] == '\')
  369.             pch += 2;                       /* .. */
  370.         if (*pch == '\')
  371.             pch++;                         /* . */
  372.     }
  373.     while (*pch != '') {
  374. if (*pch == '.')
  375.     return;
  376. pch = CharNext(pch);
  377.     }
  378.     // *pch++ = '.';
  379.     do
  380.         *pch++ = *pext;
  381.     while (*pext++ != '');
  382. }
  383. /****************************************************************************
  384.  *                                                                          *
  385.  *  FUNCTION   : FSearchSpec (sz)                                           *
  386.  *                                                                          *
  387.  *  PURPOSE    : Checks to see if NULL-terminated strings contains a "*" or *
  388.  *               a "?".                                                     *
  389.  *                                                                          *
  390.  *  RETURNS    : TRUE  - if the above characters are found in the string    *
  391.  *               FALSE - otherwise.                                         *
  392.  *                                                                          *
  393.  ****************************************************************************/
  394. static BOOL NEAR FSearchSpec(CHAR       *sz)
  395. {
  396.     for (; *sz ;sz = CharNext(sz)) {
  397.         if (*sz == '*' || *sz == '?')
  398.             return TRUE;
  399.     }
  400.     return FALSE;
  401. }
  402. /****************************************************************************
  403.  *                                                                          *
  404.  *  FUNCTION   : static char * NEAR FillListBox (hDlg,pFile, cmd)                   *
  405.  *                                                                          *
  406.  *  PURPOSE    : Fill list box with filenames that match specifications, and*
  407.  *               fills the static field with the path name.                 *
  408.  *                                                                          *
  409.  *  RETURNS    : A pointer to the pathname.                                                           *
  410.  *                                                                          *
  411.  ****************************************************************************/
  412. static CHAR * NEAR FillListBox (
  413.     HWND  hDlg,
  414.     CHAR  *pFile,  /* [path]{list of file wild cards, separated by ';'} */
  415.     UINT cmd)    /* if initdialog, or WM_COMMAND*/
  416. {
  417.     CHAR  ach[128];
  418.     CHAR  *pch;
  419.     CHAR  *pDir;   /* Directory name or path */
  420.     CHAR  pCurDir[256];
  421.     pch  = pFile;
  422.     pDir = ach;
  423.     if(cmd == WM_INITDIALOG){
  424.     while (*pch && *pch != ';')
  425.         pch = CharNext(pch);
  426.     while ((pch > pFile) && (*pch != '/') && (*pch != '\'))
  427.         pch = CharPrev(pFile, pch);
  428.     if (pch > pFile) {
  429.        *pch = 0;
  430.        lstrcpy (pDir, pFile);
  431.        pFile = pch + 1;
  432.     }
  433.     else {
  434.        lstrcpy (pDir,".");
  435.     }
  436.     }
  437.     else{
  438.         /* since SetCurrentDirectory was called already, I'll use GetCurrentDirectory*/
  439.         /* to get pDir*/
  440.         GetCurrentDirectory(256, pCurDir);
  441.         strcpy(pDir, pCurDir);
  442.     }
  443.     DlgDirList (hDlg, pDir, (INT)DLGOPEN_DIR_LISTBOX, (INT)DLGOPEN_PATH,(WORD)ATTRDIRLIST);
  444.     SendDlgItemMessage (hDlg, DLGOPEN_FILE_LISTBOX, LB_RESETCONTENT, 0, 0L);
  445.     SendDlgItemMessage (hDlg, DLGOPEN_FILE_LISTBOX, WM_SETREDRAW, FALSE, 0L);
  446.     pDir = pFile;            /* save pFile to return */
  447.     while (*pFile) {
  448.         pch = ach;
  449.         while (*pFile==' ')
  450.             pFile++;
  451.         while (*pFile && *pFile != ';') {
  452.         if (IsDBCSLeadByte(*pFile)) {
  453.         *pch++ = *pFile++;
  454.         }
  455.         *pch++ = *pFile++;
  456.     }
  457.         *pch = 0;
  458.         if (*pFile)
  459.             pFile++;
  460.         SendDlgItemMessage (hDlg,
  461.                             DLGOPEN_FILE_LISTBOX,
  462.                             LB_DIR,ATTRFILELIST,
  463.                             (LONG)(LPSTR)ach);
  464.     }
  465.     SendDlgItemMessage (hDlg, DLGOPEN_FILE_LISTBOX, WM_SETREDRAW, TRUE, 0L);
  466.     InvalidateRect (GetDlgItem (hDlg, DLGOPEN_FILE_LISTBOX), NULL, TRUE);
  467.     return pDir;
  468. }