home *** CD-ROM | disk | FTP | other *** search
/ Computer Select (Limited Edition) / Computer Select.iso / dobbs / v17n02 / sfedit.exe / SFILEDLG.C < prev    next >
Encoding:
C/C++ Source or Header  |  1991-11-27  |  20.1 KB  |  728 lines

  1. #define NOCOMM
  2. #include <windows.h>
  3. #include <dos.h>
  4. #include <direct.h>
  5. #include <memory.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include "sfiledlg.h"
  9. #include "getdrvx.h"
  10.  
  11. #define FATTR_DIRS  (0x0010|0x4000|0x8000)
  12. #define FATTR_FILES (0)
  13.  
  14. #define WM_SFDLG_REDRAW  (WM_USER+1)
  15.  
  16. #define PATHSIZE        (128)
  17. #define NDRIVETYPES     (7)
  18.  
  19. /* Function Prototypes */
  20. int  FAR PASCAL _export SFileDlgProc(HWND hDlg, WORD wMsg, WORD wParam,
  21.     LONG lParam);
  22. void FNameSplit(LPSTR lpszSrcFName, LPSTR lpszDstPath, LPSTR lpszDstFName);
  23. int  DriveNo(LPSTR str);
  24. BOOL GetVolumeLabel(int nDrive, LPSTR lpszLabel);
  25. BOOL GetCurDir(int nDrive, LPSTR lpszCurDir);
  26. BOOL IsDir(LPSTR str);
  27. BOOL IsWild(LPSTR str);
  28. BOOL DoWmInitDialog(HWND hDlg, WORD wMsg, WORD wParam, LONG lParam);
  29. BOOL DoWmDestroy(HWND hDlg, WORD wMsg, WORD wParam, LONG lParam);
  30. BOOL DoWmSFDlgRedraw(HWND hDlg, WORD wMsg, WORD wParam, LONG lParam);
  31. BOOL DoWmDrawItem(HWND hDlg, WORD wMsg, WORD wParam, LONG lParam);
  32. BOOL DoWmMeasureItem(HWND hDlg, WORD wMsg, WORD wParam, LONG lParam);
  33. BOOL DoCmdOk(HWND hDlg, WORD wParam, LONG lParam);
  34. BOOL DoCmdCancel(HWND hDlg, WORD wParam, LONG lParam);
  35. BOOL DoCmdFileName(HWND hDlg, WORD wParam, LONG lParam);
  36. BOOL DoCmdDirs(HWND hDlg, WORD wParam, LONG lParam);
  37. BOOL DoCmdTypes(HWND hDlg, WORD wParam, LONG lParam);
  38.  
  39. /* Types */
  40. typedef struct {
  41.     HANDLE      hImage;
  42.     HANDLE      hMask;
  43. } DrivesBmp;
  44.  
  45. typedef struct {
  46.     int         idImage;
  47.     int         idMask;
  48. } DrivesId;
  49.  
  50. /* Global variables that remain for the life of the DLL */
  51. DrivesBmp _dr_bmp[NDRIVETYPES];
  52. DrivesId  _dr_id[NDRIVETYPES] = {
  53.     {BMP_FOLDER, BMP_FOLDERM},
  54.     {BMP_REMOVE, BMP_REMOVEM},
  55.     {BMP_FIXED,  BMP_FIXEDM },
  56.     {BMP_REMOTE, BMP_REMOTEM},
  57.     {BMP_CDROM,  BMP_CDROMM },
  58.     {BMP_RAM,    BMP_RAMM   },
  59.     {BMP_SUBST,  BMP_SUBSTM }
  60. };
  61.  
  62. /*
  63.     For drives A: to Z:, _pdr_bmp[1] to _pdr_bmp[26] contain pointers into
  64.     the drive types bitmap array _dr_bmp (_pdr_bmp[0] points to the
  65.     folder bitmap).
  66. */
  67. DrivesBmp* _pdr_bmp[27];
  68. char       _dr_path[27][PATHSIZE];
  69.  
  70. short   _nBmWidth;
  71. short   _nBmHeight;
  72. HDC     _hBitmapDC;
  73. HBRUSH  _hBrSelect;
  74.  
  75. HANDLE  _hLibInstance;
  76. LPSTR   _lpszProperty = "STRUCT_SFDLG";
  77.  
  78. /* Global variables used as scratch buffers */
  79. char    _szDir[PATHSIZE];
  80. char    _szName[PATHSIZE];
  81.  
  82. int FAR PASCAL LibMain(HANDLE hLibInstance, WORD wDataSeg, WORD wHeapSize,
  83.     LPSTR lpszCmdLine)
  84. {
  85.     int     i;
  86.     BITMAP  bm;
  87.  
  88.     if (wHeapSize > 0)
  89.         UnlockData(0);
  90.  
  91.     _hLibInstance = hLibInstance;
  92.  
  93.     // Load bitmaps
  94.     for (i=0; i<NDRIVETYPES; ++i)
  95.     {
  96.         _dr_bmp[i].hImage =
  97.             LoadBitmap(_hLibInstance, MAKEINTRESOURCE(_dr_id[i].idImage));
  98.         _dr_bmp[i].hMask =
  99.             LoadBitmap(_hLibInstance, MAKEINTRESOURCE(_dr_id[i].idMask));
  100.  
  101.         if (!_dr_bmp[i].hImage || !_dr_bmp[i].hMask)
  102.         {
  103.             MessageBeep(0);
  104.             return  0;
  105.         }
  106.     }
  107.  
  108.     // Load other resources
  109.     _hBitmapDC = CreateCompatibleDC(NULL);
  110.     _hBrSelect = CreateSolidBrush( GetSysColor(COLOR_HIGHLIGHT) );
  111.  
  112.     // Set all bitmaps to the folder
  113.     for (i=0; i<=26; ++i)
  114.         _pdr_bmp[i] = &_dr_bmp[0];
  115.  
  116.     // Initialize drive array
  117.     for (i=1; i<=26; ++i)
  118.     {
  119.         int idBmp;
  120.         int j;
  121.         char ch;
  122.         static char pathbuf[PATHSIZE];
  123.  
  124.         switch (GetDriveTypeX(i-1))
  125.         {
  126.           case DRIVE_REMOVE: idBmp = BMP_REMOVE; break;
  127.           case DRIVE_FIXED:  idBmp = BMP_FIXED;  break;
  128.           case DRIVE_REMOTE: idBmp = BMP_REMOTE; break;
  129.           case DRIVE_CDROM:  idBmp = BMP_CDROM;  break;
  130.           case DRIVE_RAM:    idBmp = BMP_RAM;    break;
  131.           case DRIVE_SUBST:  idBmp = BMP_SUBST;  break;
  132.           default:           idBmp = BMP_FIXED;
  133.         }
  134.  
  135.         for (j=0; j<NDRIVETYPES; ++j)
  136.             if (idBmp == _dr_id[j].idImage)
  137.             {
  138.                 _pdr_bmp[i] = &_dr_bmp[j];
  139.                 break;
  140.             }
  141.  
  142.         ch = 'a' + (char)i - 1;
  143.  
  144.         wsprintf(_dr_path[i], "%c:", ch);
  145.  
  146.         if (idBmp == BMP_REMOTE || idBmp == BMP_SUBST)
  147.         {
  148.             wsprintf(pathbuf, "%c:.", ch);
  149.             if (GetCanonicalPath(pathbuf, pathbuf))
  150.                 wsprintf(_dr_path[i], "%c: %s", ch, (LPSTR) AnsiLower(pathbuf));
  151.         }
  152.         else
  153.         if (idBmp == BMP_FIXED || idBmp == BMP_RAM)
  154.         {
  155.             if (GetVolumeLabel(i, pathbuf))
  156.                wsprintf(_dr_path[i], "%c: %s", ch, (LPSTR) pathbuf);
  157.         }
  158.  
  159.     }
  160.  
  161.     GetObject(_dr_bmp[0].hImage, sizeof (BITMAP), (LPSTR) &bm);
  162.     _nBmWidth  = bm.bmWidth;
  163.     _nBmHeight = bm.bmHeight;
  164.  
  165.     return  1;
  166. }
  167.  
  168. int FAR PASCAL _export WEP(int nParameter)
  169. {
  170.     int i;
  171.  
  172.     DeleteObject(_hBrSelect);
  173.     DeleteDC(_hBitmapDC);
  174.  
  175.     for (i=0; i<NDRIVETYPES; ++i)
  176.     {
  177.         DeleteObject(_dr_bmp[i].hImage);
  178.         DeleteObject(_dr_bmp[i].hMask);
  179.     }
  180.  
  181.     return  1;
  182. }
  183.  
  184.  
  185. /****************************************************************************
  186.     int FAR PASCAL SFileDlg(SFDlg FAR* sfdlg)
  187.  
  188.     PURPOSE: Interface routine to the File dialog box
  189.  
  190.     PARAMETERS: struct SFDlg FAR* sfdlg  (see SFILEDLG.H)
  191.  
  192.     RETURNS: 1  File selected, 0  No file selected
  193.  
  194.     NOTES: On return, sfdlg->FileSpec contains the selected filename.
  195. ****************************************************************************/
  196. int FAR PASCAL _export SFileDlg(SFDlg FAR* sfdlg)
  197. {
  198.     FARPROC     lpfnSFileDlgProc;
  199.     BOOL        nReturn;
  200.     HANDLE      hSFDlg;
  201.     SFDlg FAR*  lpSFDlg;
  202.  
  203.     if (sfdlg->lpszTitle == NULL || *sfdlg->lpszTitle == '\0')
  204.         sfdlg->lpszTitle = "Get File";
  205.  
  206.     FNameSplit(sfdlg->lpszFileSpec, _szDir, _szName);
  207.  
  208.     // If no filename is given, use default type name
  209.     if (*_szName == '\0')
  210.     {
  211.         lstrcpy(_szName, sfdlg->lpTypes[sfdlg->nType].szFile);
  212.         lstrcpy(sfdlg->lpszFileSpec, _szName);
  213.     }
  214.  
  215.     // If no path is given, use current directory as path
  216.     if (*_szDir == '\0')
  217.     {
  218.         GetCurDir(0, sfdlg->lpszFileSpec);
  219.         lstrcat(sfdlg->lpszFileSpec, _szName);
  220.     }
  221.  
  222.     // Create a structure accessible to the dialog box
  223.     hSFDlg  = GlobalAlloc(GHND, sizeof (SFDlg));
  224.     if ((lpSFDlg = (SFDlg FAR*) GlobalLock(hSFDlg)) == NULL)
  225.     {
  226.         MessageBeep(0);
  227.         return 0;
  228.     }
  229.     *lpSFDlg = *sfdlg;
  230.  
  231.     // Call the dialog box, initializing it with the structure handle
  232.     lpfnSFileDlgProc = MakeProcInstance((FARPROC) SFileDlgProc, _hLibInstance);
  233.     nReturn = DialogBoxParam(_hLibInstance, "DLG_SFILEDLG", sfdlg->hWnd,
  234.         lpfnSFileDlgProc, hSFDlg);
  235.     FreeProcInstance(lpfnSFileDlgProc);
  236.  
  237.     *sfdlg = *lpSFDlg;
  238.  
  239.     GlobalUnlock(hSFDlg);
  240.     GlobalFree(hSFDlg);
  241.  
  242.     return  nReturn;
  243. }
  244.  
  245.  
  246. /****************************************************************************
  247.     int FAR PASCAL SFileDlgProc(HWND hDlg, WORD wMsg, WORD wParam,
  248.         LONG lParam)
  249.  
  250.     PURPOSE: File dialog box Windows callback function
  251.  
  252.     RETURNS: TRUE if message was processed
  253. ****************************************************************************/
  254. int FAR PASCAL _export SFileDlgProc(HWND hDlg, WORD wMsg, WORD wParam,
  255.     LONG lParam)
  256. {
  257.     switch(wMsg)
  258.     {
  259.       case WM_INITDIALOG :
  260.         return  DoWmInitDialog(hDlg, wMsg, wParam, lParam);
  261.  
  262.       case WM_DESTROY:
  263.         return DoWmDestroy(hDlg, wMsg, wParam, lParam);
  264.  
  265.       case WM_MEASUREITEM:
  266.         return  DoWmMeasureItem(hDlg, wMsg, wParam, lParam);
  267.  
  268.       case WM_DRAWITEM:
  269.         return  DoWmDrawItem(hDlg, wMsg, wParam, lParam);
  270.  
  271.       case WM_SFDLG_REDRAW:
  272.         return  DoWmSFDlgRedraw(hDlg, wMsg, wParam, lParam);
  273.  
  274.       case WM_COMMAND :
  275.         switch(wParam)
  276.         {
  277.           case IDOK :
  278.             return  DoCmdOk(hDlg, wParam, lParam);
  279.  
  280.           case IDCANCEL :
  281.             return  DoCmdCancel(hDlg, wParam, lParam);
  282.  
  283.           case IDD_FILENAME:
  284.             return  DoCmdFileName(hDlg, wParam, lParam);
  285.  
  286.           case IDD_DIRS:
  287.             return  DoCmdDirs(hDlg, wParam, lParam);
  288.  
  289.           case IDD_TYPES:
  290.             return  DoCmdTypes(hDlg, wParam, lParam);
  291.         }
  292.     }
  293.  
  294.     return  FALSE;
  295. }
  296.  
  297. ////////////////////////////////////////////////////////////////////////
  298. // SFileDlgProc message handlers
  299. ////////////////////////////////////////////////////////////////////////
  300. BOOL DoWmInitDialog(HWND hDlg, WORD wMsg, WORD wParam, LONG lParam)
  301. {
  302.     int         i;
  303.     SFDlg FAR*  lpSFDlg;
  304.  
  305.     // Attach the data handle to a property
  306.     SetProp(hDlg, _lpszProperty, (WORD) lParam);
  307.     lpSFDlg = (SFDlg FAR*) GlobalLock((HANDLE) lParam);
  308.  
  309.     // Set window title
  310.     SetWindowText(hDlg, lpSFDlg->lpszTitle);
  311.  
  312.     // Add file type descriptions to TYPES listbox
  313.     for (i=0; *lpSFDlg->lpTypes[i].szFile; ++i)
  314.     {
  315.         SendDlgItemMessage(hDlg, IDD_TYPES, CB_ADDSTRING,
  316.             NULL, (LONG) (LPSTR) lpSFDlg->lpTypes[i].szDesc);
  317.     }
  318.  
  319.     GlobalUnlock((HANDLE) lParam);
  320.  
  321.     // Update list box
  322.     SendMessage(hDlg, WM_SFDLG_REDRAW, 0, 0L);
  323.  
  324.     SetFocus(GetDlgItem(hDlg, IDD_FILENAME));
  325.     return  TRUE;
  326. }
  327.  
  328. BOOL DoWmDestroy(HWND hDlg, WORD wMsg, WORD wParam, LONG lParam)
  329. {
  330.     RemoveProp(hDlg, _lpszProperty);
  331.     return  TRUE;
  332. }
  333.  
  334. BOOL DoWmSFDlgRedraw(HWND hDlg, WORD wMsg, WORD wParam, LONG lParam)
  335. {
  336.     HANDLE            hSFDlg;
  337.     SFDlg FAR*  lpSFDlg;
  338.  
  339.     hSFDlg  = GetProp(hDlg, _lpszProperty);
  340.     lpSFDlg = (SFDlg FAR*) GlobalLock(hSFDlg);
  341.  
  342.     FNameSplit(lpSFDlg->lpszFileSpec, _szDir, _szName);
  343.  
  344.     // Fill DIRECTORIES listbox
  345.     if (!DlgDirList(hDlg, _szDir, IDD_DIRS, IDD_PATH, FATTR_DIRS))
  346.     {
  347.         MessageBeep(0);
  348.  
  349.         // Invalid directory, try again using root
  350.         lstrcpy(_szDir, "\\");
  351.         DlgDirList(hDlg, _szDir, IDD_DIRS, IDD_PATH, FATTR_DIRS);
  352.     }
  353.  
  354.     // Fill FILES list combo box
  355.     DlgDirListComboBox(hDlg, _szName, IDD_FILENAME, 0, FATTR_FILES);
  356.  
  357.     // Set string in FILES edit combo box
  358.     SendDlgItemMessage(hDlg, IDD_FILENAME, EM_LIMITTEXT, PATHSIZE, 0L);
  359.     SetDlgItemText(hDlg, IDD_FILENAME, _szName);
  360.  
  361.     // Make selection in TYPES listbox
  362.     SendDlgItemMessage(hDlg, IDD_TYPES, LB_SELECTSTRING, -1,
  363.         (LONG) (LPSTR) lpSFDlg->lpTypes[lpSFDlg->nType].szDesc);
  364.  
  365.     GlobalUnlock(hSFDlg);
  366.     return  TRUE;
  367. }
  368.  
  369. void DrawDirItem(HWND hDlg, LPDRAWITEMSTRUCT ds)
  370. {
  371.     int         nOldBkMode;
  372.     DWORD       dwOldColor;
  373.     int         nDriveNo;
  374.     HBITMAP     hOldBitmap;
  375.  
  376.     SendDlgItemMessage(hDlg, IDD_DIRS, LB_GETTEXT, ds->itemID,
  377.         (LONG) (LPSTR) _szDir);
  378.     nDriveNo = DriveNo(_szDir);
  379.  
  380.     // Draw the bitmap mask
  381.     hOldBitmap = SelectObject(_hBitmapDC, _pdr_bmp[nDriveNo]->hMask);
  382.     BitBlt(ds->hDC, 1, ds->rcItem.top, _nBmWidth, _nBmHeight, _hBitmapDC,
  383.         0, 0, SRCAND);
  384.  
  385.     // Draw the bitmap image
  386.     SelectObject(_hBitmapDC, _pdr_bmp[nDriveNo]->hImage);
  387.     BitBlt(ds->hDC, 1, ds->rcItem.top, _nBmWidth, _nBmHeight, _hBitmapDC,
  388.         0, 0, SRCPAINT);
  389.  
  390.     SelectObject(_hBitmapDC, hOldBitmap);
  391.  
  392.     nOldBkMode = SetBkMode(ds->hDC, TRANSPARENT);
  393.     dwOldColor = GetTextColor(ds->hDC);
  394.  
  395.     // Draw text for item
  396.     SetTextColor(ds->hDC, GetSysColor( (ds->itemState & ODS_SELECTED) ?
  397.         COLOR_HIGHLIGHTTEXT: COLOR_WINDOWTEXT));
  398.     if (nDriveNo == 0)
  399.         TextOut(ds->hDC, _nBmWidth+5, ds->rcItem.top, _szDir, lstrlen(_szDir));
  400.     else
  401.         TextOut(ds->hDC, _nBmWidth+5, ds->rcItem.top, _dr_path[nDriveNo],
  402.             lstrlen(_dr_path[nDriveNo]));
  403.  
  404.     SetTextColor(ds->hDC, dwOldColor);
  405.     SetBkMode(ds->hDC, nOldBkMode);
  406. }
  407.  
  408. BOOL DoWmDrawItem(HWND hDlg, WORD wMsg, WORD wParam, LONG lParam)
  409. {
  410.     LPDRAWITEMSTRUCT ds = (LPDRAWITEMSTRUCT) lParam;
  411.  
  412.     if (ds->CtlID == IDD_DIRS)
  413.     {
  414.         switch (ds->itemAction)
  415.         {
  416.           case ODA_SELECT:
  417.           case ODA_DRAWENTIRE:
  418.             // Draw or erase selection bar
  419.             FillRect(ds->hDC, &(ds->rcItem), (ds->itemState & ODS_SELECTED) ?
  420.                 _hBrSelect: GetStockObject(WHITE_BRUSH));
  421.             DrawDirItem(hDlg, ds);
  422.             return  TRUE;
  423.  
  424.           case ODA_FOCUS:
  425.             if ((ds->itemState & ODS_FOCUS) == ODS_FOCUS)
  426.                 DrawFocusRect(ds->hDC, &(ds->rcItem));
  427.             else
  428.             {
  429.                // Erase selection bar and focus rect
  430.                FillRect(ds->hDC, &(ds->rcItem), GetStockObject(WHITE_BRUSH));
  431.                DrawDirItem(hDlg, ds);
  432.             }
  433.             return TRUE;
  434.         }
  435.     }
  436.  
  437.     return  FALSE;
  438. }
  439.  
  440. BOOL DoWmMeasureItem(HWND hDlg, WORD wMsg, WORD wParam, LONG lParam)
  441. {
  442.     LPMEASUREITEMSTRUCT ms = (LPMEASUREITEMSTRUCT) lParam;
  443.  
  444.     if (ms->CtlID == IDD_DIRS)
  445.     {
  446.         HWND    hWndDir;
  447.         RECT    rcDir;
  448.  
  449.         // Width of an item is the width of the directory listbox
  450.         hWndDir = GetDlgItem(hDlg, IDD_DIRS);
  451.         GetWindowRect(hWndDir, &rcDir);
  452.         ms->itemWidth = rcDir.right;
  453.  
  454.         // Height of an item is the height of the first bitmap
  455.         ms->itemHeight = _nBmHeight;
  456.  
  457.         return  TRUE;
  458.     }
  459.     return  FALSE;
  460. }
  461.  
  462. BOOL DoCmdOk(HWND hDlg, WORD wParam, LONG lParam)
  463. {
  464.     BOOL        bEnd = TRUE;        // assume that the file name is OK
  465.     HANDLE      hSFDlg;
  466.     SFDlg FAR*  lpSFDlg;
  467.  
  468.     hSFDlg  = GetProp(hDlg, _lpszProperty);
  469.     lpSFDlg = (SFDlg FAR*) GlobalLock(hSFDlg);
  470.  
  471.     GetDlgItemText(hDlg, IDD_FILENAME, lpSFDlg->lpszFileSpec,
  472.         lpSFDlg->nMaxFileSpec);
  473.  
  474.     // If the name is a directory, append the default file name
  475.     if (IsDir(lpSFDlg->lpszFileSpec))
  476.         lstrcat(lpSFDlg->lpszFileSpec, lpSFDlg->lpTypes[lpSFDlg->nType].szFile);
  477.  
  478.     // Check for wildcards
  479.     if (IsWild(lpSFDlg->lpszFileSpec))
  480.         bEnd = FALSE;
  481.  
  482.     // Add path if necessary
  483.     FNameSplit(lpSFDlg->lpszFileSpec, _szDir, _szName);
  484.     if (*_szDir == '\0')
  485.     {
  486.         GetCurDir(0, _szDir);
  487.         lstrcat(lstrcpy(lpSFDlg->lpszFileSpec, _szDir), _szName);
  488.     }
  489.  
  490.     GlobalUnlock(hSFDlg);
  491.  
  492.     if (bEnd)
  493.         EndDialog(hDlg, IDOK);
  494.     else
  495.         SendMessage(hDlg, WM_SFDLG_REDRAW, 0, 0L);
  496.  
  497.     return  TRUE;
  498. }
  499.  
  500. BOOL DoCmdCancel(HWND hDlg, WORD wParam, LONG lParam)
  501. {
  502.     EndDialog(hDlg, IDCANCEL);
  503.     return  TRUE;
  504. }
  505.  
  506. BOOL DoCmdFileName(HWND hDlg, WORD wParam, LONG lParam)
  507. {
  508.     switch (HIWORD(lParam))
  509.     {
  510.       case LBN_DBLCLK:
  511.         // Fake click on the OK button
  512.         SendMessage(hDlg, WM_COMMAND, IDOK, 0L);
  513.         return  TRUE;
  514.     }
  515.     return  FALSE;
  516. }
  517.  
  518. BOOL DoCmdDirs(HWND hDlg, WORD wParam, LONG lParam)
  519. {
  520.     HANDLE      hSFDlg;
  521.     SFDlg FAR*  lpSFDlg;
  522.  
  523.     switch (HIWORD(lParam))
  524.     {
  525.       case LBN_SELCHANGE:
  526.         // Put directory selection in FILES edit combo box
  527.         DlgDirSelect(hDlg, _szDir, IDD_DIRS);
  528.         SetDlgItemText(hDlg, IDD_FILENAME, _szDir);
  529.         return  TRUE;
  530.  
  531.       case LBN_DBLCLK:
  532.         hSFDlg  = GetProp(hDlg, _lpszProperty);
  533.         lpSFDlg = (SFDlg FAR*) GlobalLock(hSFDlg);
  534.  
  535.         FNameSplit(lpSFDlg->lpszFileSpec, _szDir, _szName);
  536.  
  537.         // Get new directory
  538.         if (DlgDirSelect(hDlg, _szDir, IDD_DIRS))
  539.             lstrcpy(lpSFDlg->lpszFileSpec, _szDir);
  540.         else
  541.             *(lpSFDlg->lpszFileSpec) = '\0';
  542.  
  543.         // Append current file selection
  544.         lstrcat(lpSFDlg->lpszFileSpec, _szName);
  545.  
  546.         GlobalUnlock(hSFDlg);
  547.  
  548.         // Update list box
  549.         SendMessage(hDlg, WM_SFDLG_REDRAW, 0, 0L);
  550.         return  TRUE;
  551.     }
  552.  
  553.     return  FALSE;
  554. }
  555.  
  556. BOOL DoCmdTypes(HWND hDlg, WORD wParam, LONG lParam)
  557. {
  558.     HANDLE      hSFDlg;
  559.     SFDlg FAR*  lpSFDlg;
  560.  
  561.     switch (HIWORD(lParam))
  562.     {
  563.       int   nType;
  564.  
  565.       case LBN_SELCHANGE:
  566.         hSFDlg  = GetProp(hDlg, _lpszProperty);
  567.         lpSFDlg = (SFDlg FAR*) GlobalLock(hSFDlg);
  568.  
  569.         // Get new file type
  570.         nType = (int) SendDlgItemMessage(hDlg,IDD_TYPES,CB_GETCURSEL,0,0L);
  571.         if (nType != LB_ERR)
  572.         {
  573.             // Use the file type as file name
  574.             lstrcpy(lpSFDlg->lpszFileSpec, lpSFDlg->lpTypes[nType].szFile);
  575.             lpSFDlg->nType = nType;
  576.  
  577.             // Update edit combo box
  578.             SetDlgItemText(hDlg, IDD_FILENAME, lpSFDlg->lpszFileSpec);
  579.  
  580.             // Fake a click on the OK button
  581.             SendMessage(hDlg, WM_COMMAND, IDOK, 0L);
  582.         }
  583.  
  584.         GlobalUnlock(hSFDlg);
  585.         return  TRUE;
  586.      }
  587.      return  FALSE;
  588. }
  589.  
  590. ////////////////////////////////////////////////////////////////////////
  591. // End SFileDlgProc handlers
  592. ////////////////////////////////////////////////////////////////////////
  593.  
  594. void FNameSplit(LPSTR lpszSrcFName, LPSTR lpszDstPath, LPSTR lpszDstFName)
  595. {
  596.     LPSTR    lpStr;
  597.  
  598.     lpStr = lpszSrcFName + lstrlen(lpszSrcFName);
  599.  
  600.     // Search for the last occurrance of ':' or '\'
  601.     while (lpStr > lpszSrcFName && *lpStr != ':' && *lpStr != '\\')
  602.         --lpStr;
  603.  
  604.     if (lpStr == lpszSrcFName && *lpStr != '\\') // No path was given
  605.     {
  606.         lstrcpy(lpszDstFName, lpszSrcFName);
  607.         *lpszDstPath = 0;
  608.     }
  609.     else
  610.     {
  611.         lstrcpy(lpszDstFName, lpStr+1);
  612.         _fmemcpy(lpszDstPath, lpszSrcFName, lpStr-lpszSrcFName+1);
  613.         lpszDstPath[lpStr-lpszSrcFName+1] = '\0';
  614.     }
  615. }
  616.  
  617. /****************************************************************************
  618.     BOOL GetVolumeLabel(int nDrive, LPSTR lpszLabel)
  619.  
  620.     PURPOSE: Get the drive volume label.
  621.  
  622.     PARAMETERS: int   nDrive        drive number
  623.                 LPSTR lpszLabel     buffer to hold the drive label
  624.  
  625.     RETURNS: TRUE on success
  626. *****************************************************************************/
  627. BOOL GetVolumeLabel(int nDrive, LPSTR lpszLabel)
  628. {
  629.     static struct find_t ftBuf;
  630.     static char     buf[10];
  631.     static char     file[_MAX_FNAME];
  632.     static char     ext[_MAX_EXT];
  633.  
  634.     wsprintf(buf, "%c:\\*.*", 'a'+nDrive-1);
  635.  
  636.     if (_dos_findfirst(buf, _A_VOLID, &ftBuf) != 0)
  637.         return FALSE;
  638.  
  639.     _splitpath(ftBuf.name, NULL, NULL, file, ext);
  640.  
  641.     lstrcpy(lpszLabel, file);
  642.     if (*ext)
  643.        lstrcat(lpszLabel, ext+1);   // copy extension w/o the "."
  644.  
  645.     return  TRUE;
  646. }
  647.  
  648. /****************************************************************************
  649.     BOOL GetCurDir(int nDrive, LPSTR CurDir)
  650.  
  651.     PURPOSE: Get the current directory.
  652.  
  653.     PARAMETERS: int   nDrive        drive number
  654.                 LPSTR lpszCurDir    buffer to hold the directory name
  655.  
  656.     RETURNS: TRUE on success
  657. *****************************************************************************/
  658. BOOL GetCurDir(int nDrive, LPSTR lpszCurDir)
  659. {
  660.     static BYTE     d;
  661.     LPSTR           lpszDir;
  662.  
  663.     lpszDir = lpszCurDir;
  664.  
  665.     if ((d = (BYTE)nDrive)== 0)
  666.     {
  667.         // get current drive
  668.         _asm mov ah, 0x19;
  669.         _asm int 0x21;
  670.         _asm mov d, al;         // 0=A:,1=B:,2=C:...
  671.     }
  672.  
  673.     *lpszDir++ = d + 'a';
  674.     *lpszDir++ = ':';
  675.     *lpszDir++ = '\\';
  676.  
  677.     ++d;                        // 0=default,1=A:,2=B:,...
  678.     _asm push ds;
  679.     _asm mov ah, 0x47;
  680.     _asm mov dl, d;
  681.     _asm lds si, lpszDir;
  682.     _asm int 0x021;
  683.     _asm pop ds;
  684.     _asm jc gcw1;               // error
  685.  
  686.     if (*(lpszDir+lstrlen(lpszDir)-1) != '\\')
  687.         lstrcat(lpszDir, "\\");
  688.     return  TRUE;
  689.  
  690. gcw1:
  691.     *lpszCurDir = '\0';
  692.     return  FALSE;
  693. }
  694.  
  695. /****************************************************************************
  696.     int DriveNo(LPSTR lpStr)
  697.  
  698.     PURPOSE: Get a number representing a drive.
  699.  
  700.     PARAMETERS: LPSTR lpDriveStr        A string in the format "[-x-]"
  701.                                         where x is a drive letter a-z.
  702.  
  703.     RETURNS: An integer from 1 to 26 for valide drive strings, or 0 on error
  704. *****************************************************************************/
  705. int DriveNo(LPSTR lpDriveStr)
  706. {
  707.     LPSTR   lpStr;
  708.  
  709.     return  (*(lpStr = AnsiNext(lpDriveStr)) == '-') ?
  710.         (*AnsiNext(AnsiLower(lpStr))) - 'a' + 1 : 0;
  711. }
  712.  
  713. BOOL IsDir(LPSTR lpStr)
  714. {
  715.     char    last_char;
  716.  
  717.     // if the name ends with a ':' or '\' then it is a directory
  718.     last_char = *AnsiPrev(lpStr, lpStr+lstrlen(lpStr));
  719.     return  (last_char == ':' || last_char == '\\') ? TRUE: FALSE;
  720. }
  721.  
  722. BOOL IsWild(LPSTR lpStr)
  723. {
  724.     return  (_fstrpbrk(lpStr, "*?") != 0) ? TRUE: FALSE;
  725. }
  726.  
  727.  
  728.