Back to index

lightning-sunbird  0.9+nobinonly
Defines | Functions | Variables
dirpick.cpp File Reference
#include <windows.h>
#include <windowsx.h>
#include <direct.h>
#include <stdio.h>
#include "resource.h"

Go to the source code of this file.

Defines

#define ITEM_BITMAPWIDTH   16
#define ITEM_BITMAPHEIGHT   16
#define ITEM_LEFTMARGIN   4
#define ITEM_GAP   4

Functions

UINT DriveType (UINT iType)
static void fillComboBox (HWND hWnd)
static void fillTempLBWithDirs (HWND hWndTempLB, LPSTR lpszDir)
static void fillListBox (HWND hWnd, LPSTR lpszDir)
static void onDrawItem (LPDRAWITEMSTRUCT lpdis, BOOL bDrive)
static void fillUNCRootArray (LPSTR lpsz)
static void onInitDialog (HWND hWnd, LPSTR lpsz)
static void shutDialog (HWND hWnd)
static void onCommand (HWND hWnd, int id, HWND hWndCtl, UINT codeNotify)
static BOOL CALLBACK DirPickDlgProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
BOOL PickupDirectory (HWND hWndOwner, LPSTR lpszString)

Variables

HINSTANCE hInst
static HWND hWndDirPicker
static HICON hIconDrives [5]
static HICON hIconFolders [3]
static LPSTR lpszStringToReturn
static char szUNCRoot [256] = ""

Define Documentation

Definition at line 48 of file dirpick.cpp.

Definition at line 47 of file dirpick.cpp.

#define ITEM_GAP   4

Definition at line 50 of file dirpick.cpp.

Definition at line 49 of file dirpick.cpp.


Function Documentation

static BOOL CALLBACK DirPickDlgProc ( HWND  hWnd,
UINT  msg,
WPARAM  wParam,
LPARAM  lParam 
) [static]

Definition at line 518 of file dirpick.cpp.

{
  switch(msg) {
    case WM_INITDIALOG:
      onInitDialog(hWnd, (LPSTR)lParam);
      break;
    case WM_COMMAND:
      HANDLE_WM_COMMAND(hWnd, wParam, lParam, onCommand);
      break;
    case WM_MEASUREITEM: 
    {
      static int cyItem = -1;      //Height of a listbox item
      LPMEASUREITEMSTRUCT lpmis = (LPMEASUREITEMSTRUCT)lParam;
      if(cyItem == -1) 
      {
        HFONT hFont = (HFONT)SendMessage(hWnd, WM_GETFONT, 0, 0L);
        if(hFont == NULL)
          hFont = GetStockFont(SYSTEM_FONT);
        HDC hDC = GetDC(hWnd);
        HFONT hFontOld = SelectFont(hDC, hFont);
        TEXTMETRIC tm;
        GetTextMetrics(hDC, &tm);
        cyItem = max(ITEM_BITMAPHEIGHT, tm.tmHeight);
        SelectFont(hDC, hFontOld);
        ReleaseDC(hWnd, hDC);
      }

      lpmis->itemHeight = cyItem;
    }
      break;
    case WM_DRAWITEM:
      onDrawItem((LPDRAWITEMSTRUCT)lParam, ((UINT)wParam == ID_COMBO_DIR));
      return TRUE; // to prevent default action in listbox (drawing focus)
    default:
      return FALSE;
  }
  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

UINT DriveType ( UINT  iType)

Definition at line 578 of file dirpick.cpp.

{
  //Validate possible drive indices
  if((0 > iDrive)  || (25 < iDrive))
    return (UINT)-1;

  static char path[] = "d:\\";
  path[0] = 'a' + iDrive;
  int iType = GetDriveType(path);  

  /*
   * Under Windows NT, GetDriveType returns complete information
   * not provided under Windows 3.x which we now get through other
   * means.
   */

  return iType;
}

Here is the caller graph for this function:

static void fillComboBox ( HWND  hWnd) [static]

Definition at line 60 of file dirpick.cpp.

{
  HWND hWndCB = GetDlgItem(hWnd, ID_COMBO_DIR);
  HWND hWndTempLB = GetDlgItem(hWnd, ID_LISTTEMP_DIR);
  if(hWndCB == NULL)
    return;
  ComboBox_ResetContent(hWndCB);
  ListBox_ResetContent(hWndTempLB);
  ListBox_Dir(hWndTempLB, DDL_DRIVES|DDL_EXCLUSIVE, (LPSTR)"*");

  int iDriveCount = ListBox_GetCount(hWndTempLB);
  int iCurDrive=_getdrive() - 1;

  char szDrive[16];
  char szItem[80];

  for (int i = 0; i < iDriveCount;  i++) 
  {
    ListBox_GetText(hWndTempLB, i, szDrive);
    CharLower(szDrive);
    int iDrive = szDrive[2] - 'a';
    char szRoot[16];
    sprintf(szRoot, "%c:\\", szDrive[2]);

    int iType = DriveType(iDrive);

    if(iType < 2)
      continue;

    //Start the item string with the drive letter, colon, and two spaces
    sprintf(szItem, "%c%s", szDrive[2], ": ");

    if((iType == DRIVE_FIXED) || (iType == DRIVE_RAMDISK)) 
    { // get volume ID
      char szVolumeID[80];
      DWORD dwMaxLength;
      DWORD dwSysFlags;
      GetVolumeInformation(szRoot,             // address of root directory of the file system 
                           szVolumeID,         // address of name of the volume 
                           sizeof(szVolumeID), // length of lpVolumeNameBuffer 
                           NULL,               // address of volume serial number 
                           &dwMaxLength,       // address of system's maximum filename length
                           &dwSysFlags,        // address of file system flags 
                           NULL,               // address of name of file system 
                           NULL);              // length of lpFileSystemNameBuffer 

      CharLower(szVolumeID);
      lstrcat(szItem, szVolumeID);
    }

    //For network drives, go grab the \\server\share for it.
    if(DRIVE_REMOTE == iType) 
    {
      char szNet[64];
      szNet[0] = '\0';
      DWORD dwSizeOfszNet = sizeof(szNet);

      sprintf(szDrive, "%c:", szDrive[2]);
      CharUpper(szDrive);
      WNetGetConnection(szDrive, szNet, &dwSizeOfszNet);
      CharLower(szNet);
      lstrcat(szItem, szNet);
    }

    int index = ComboBox_AddString(hWndCB, szItem);
    ComboBox_SetItemData(hWndCB, index, MAKELONG(iDrive, iType));
    if(iDrive == iCurDrive)
      ComboBox_SetCurSel(hWndCB, index);
    if(szUNCRoot[0] != '\0')
      ComboBox_SetCurSel(hWndCB, -1);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void fillListBox ( HWND  hWnd,
LPSTR  lpszDir 
) [static]

Definition at line 170 of file dirpick.cpp.

{
  HWND hWndLB = GetDlgItem(hWnd, ID_LIST_DIR);
  HWND hWndTempLB = GetDlgItem(hWnd, ID_LISTTEMP_DIR);
  HWND hWndEdit = GetDlgItem(hWnd, ID_EDIT_DIR);
  if((hWndLB == NULL) || (lpszDir == NULL))
    return;
  
  int iLastChar = lstrlen(lpszDir);
  if(lpszDir[iLastChar - 1] == '\\')
    lpszDir[iLastChar - 1] = '\0';

  SetWindowRedraw(hWndLB, FALSE);
  ListBox_ResetContent(hWndLB);
  ListBox_ResetContent(hWndTempLB);

  LPSTR lpszLast;
  lpszLast = CharLower(lpszDir);

  SetWindowText(hWndLB, lpszDir);

  char szDir[_MAX_DIR];
  char szFullDir[_MAX_DIR];
  sprintf(szFullDir, "%s", lpszDir);
  sprintf(szDir, "%s\\*.*", lpszDir);

  BOOL bFirst = TRUE;
  char ch;
  int index;
  while (TRUE) 
  {
    LPSTR lpsz;
    if((lpszDir[0] == '\\') && (lpszDir[1] == '\\') && bFirst)
      lpsz = strchr(lpszLast + lstrlen(szUNCRoot), '\\');
    else
      lpsz = strchr(lpszLast, '\\');
    if(lpsz != NULL) {
      if (bFirst)
        ch = *(++lpsz);
      else
        ch = *lpsz;
      *lpsz = 0;
    } 
    else 
    {
      //If we're looking at a drive only, then append a backslash
      if (lpszLast == lpszDir && bFirst)
        lstrcat(lpszLast, "\\");
    }
    //Add the drive string--includes the last one where lpsz == NULL
    index = ListBox_AddString(hWndLB, lpszLast);

    UINT i = (NULL != lpsz) ? ID_ICON_FOLDEROPEN : ID_ICON_OPENSELECT;
    ListBox_SetItemData(hWndLB, index, MAKELONG(index, i));

    if(NULL == lpsz)
      break;

      //Restore last character.
    *lpsz = ch;
    lpsz += (bFirst) ? 0 : 1;

    bFirst=FALSE;
    lpszLast = lpsz;
  }
  int indent = index + 1;

  //Get available directories
  fillTempLBWithDirs(hWndTempLB, lpszDir);

  int itemCount = ListBox_GetCount(hWndTempLB);

  for (int i = 0; i < itemCount; i++) {
    index = ListBox_GetText(hWndTempLB, i, lpszDir);
    //Skip directories beginning with . (skipping . and ..)
    if(lpszDir[1] == '.')
      continue;
    //Remove the ending ']'
    iLastChar = lstrlen(lpszDir);
    lpszDir[iLastChar - 1] = '\0';
    //Add the string to the real directory list.
    index = ListBox_AddString(hWndLB, lpszDir + 1);
    ListBox_SetItemData(hWndLB, index, MAKELONG(indent, ID_ICON_FOLDERCLOSED));
  }
  //Force a listbox repaint.
  SetWindowRedraw(hWndLB, TRUE);
  InvalidateRect(hWndLB, NULL, TRUE);

  if(szFullDir[lstrlen(szFullDir) - 1] == ':')
    lstrcat(szFullDir, "\\");
  Edit_SetText(hWndEdit, szFullDir);

  GetScrollRange(hWndLB, SB_VERT, (LPINT)&i, (LPINT)&index);

  if(!(i == 0 && index == 0))
    ListBox_SetTopIndex(hWndLB, max((int)(index - 2), 0));

  ListBox_SetCurSel(hWndLB, indent - 1);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void fillTempLBWithDirs ( HWND  hWndTempLB,
LPSTR  lpszDir 
) [static]

Definition at line 133 of file dirpick.cpp.

{
  BOOL bDone = FALSE;
  WIN32_FIND_DATA ffdataStruct;

  char szPath[_MAX_PATH];
  char szFileName[_MAX_PATH];
  lstrcpy(szPath, lpszDir);
  if(szPath[lstrlen(szPath) - 1] == '\\')
    szPath[lstrlen(szPath) - 1] = '\0';
  lstrcpy(szFileName, szPath);
  lstrcat(szFileName, "\\*");
  HANDLE handle = FindFirstFile(szFileName, &ffdataStruct);
  if(handle == INVALID_HANDLE_VALUE) 
  {
    FindClose(handle);
    return;
  }
  while(!bDone) 
  {
    lstrcpy(szFileName, szPath);
    lstrcat(szFileName, "\\");
    lstrcat(szFileName, ffdataStruct.cFileName);
    if(ffdataStruct. dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) 
    {
      char szStringToAdd[_MAX_PATH + 2];
      lstrcpy(szStringToAdd, "[");
      lstrcat(szStringToAdd, ffdataStruct.cFileName);
      lstrcat(szStringToAdd, "]");
      CharLower(szStringToAdd);
      ListBox_AddString(hWndTempLB, szStringToAdd);
    }
    bDone = !FindNextFile(handle, &ffdataStruct);
  }
  FindClose(handle);
}

Here is the caller graph for this function:

static void fillUNCRootArray ( LPSTR  lpsz) [static]

Definition at line 365 of file dirpick.cpp.

{
  char szCurDir[_MAX_PATH];
  _getcwd(szCurDir, sizeof(szCurDir));
  lstrcpy(szUNCRoot, lpsz);
  if(szUNCRoot[lstrlen(szUNCRoot) - 1] == '\\')
    szUNCRoot[lstrlen(szUNCRoot) - 1] = '\0';
  for(;;) 
  {
    LPSTR lptemp = strrchr(szUNCRoot, '\\');
    if(lptemp == NULL)
      break;
    *lptemp = '\0';
    if(_chdir(szUNCRoot) == -1) 
    {
      *lptemp = '\\';
      break;
    }
  }
  _chdir(szCurDir);
}

Here is the caller graph for this function:

static void onCommand ( HWND  hWnd,
int  id,
HWND  hWndCtl,
UINT  codeNotify 
) [static]

Definition at line 426 of file dirpick.cpp.

{
  char szCurDir[_MAX_PATH];
  switch(id) 
  {
    case ID_LIST_DIR:
      if(codeNotify == LBN_DBLCLK) 
      {
        int index = ListBox_GetCurSel(hWndCtl);
        DWORD dwItemData = ListBox_GetItemData(hWndCtl, index);

        if(HIWORD(dwItemData) == ID_ICON_OPENSELECT) 
        {
          shutDialog(hWnd);
          char szString[_MAX_PATH];
          Edit_GetText(GetDlgItem(hWndDirPicker, ID_EDIT_DIR), szString, sizeof(szString));
          lstrcpy(lpszStringToReturn, szString);
          EndDialog(hWnd, IDOK);
          break;
        }

        ListBox_GetText(hWndCtl, index, szCurDir);

        char szDir[_MAX_DIR];
        LPSTR lpsz;
        if((HIWORD(dwItemData) == ID_ICON_FOLDEROPEN) && (index != 0)) 
        {
          GetWindowText(hWndCtl, szDir, sizeof(szDir));
          lpsz=_fstrstr(szDir, szCurDir);
          *(lpsz + lstrlen(szCurDir)) = '\0';
          lstrcpy(szCurDir, szDir);
        }
        if (_chdir(szCurDir) == 0) 
        {
          _getcwd(szCurDir, _MAX_PATH);
          fillListBox(hWndDirPicker, szCurDir);
        }
      }
      break;
    case ID_COMBO_DIR:
      if(codeNotify == CBN_SELCHANGE) 
      {
        char szDrive[80];
        int index = ComboBox_GetCurSel(hWndCtl);
        if(index == CB_ERR)
          break;
        ComboBox_GetLBText(hWndCtl, index, szDrive);

        int iCurDrive = _getdrive();
Retry:
        HCURSOR hCursorOld = SetCursor(LoadCursor(NULL, IDC_WAIT));
        SetCapture(hWndDirPicker);
        if((0 == _chdrive((int)(szDrive[0] - 'a' + 1))) && (NULL != _getcwd(szCurDir, _MAX_PATH))) 
        {
          fillListBox(hWndDirPicker, szCurDir);
          ListBox_SetTopIndex(GetDlgItem(hWndDirPicker, ID_LIST_DIR), 0);
          SetCursor(hCursorOld);
          ReleaseCapture();
          break;
        }
        SetCursor(hCursorOld);
        ReleaseCapture();

        char szText[80];        
        sprintf(szText, "Cannot read drive %c:", szDrive[0]);
        if(IDRETRY == MessageBox(hWndDirPicker, szText, "Choose Directory", MB_ICONEXCLAMATION|MB_RETRYCANCEL))
          goto Retry;
        
        //Changing drives failed so restore drive and selection
        _chdrive(iCurDrive);

        sprintf(szDrive, "%c:", (char)(iCurDrive + 'a' - 1));
        index = ComboBox_SelectString(hWndCtl, -1, szDrive);
      }
      break;
    case IDOK:
      shutDialog(hWnd);
      char szString[_MAX_PATH];
      Edit_GetText(GetDlgItem(hWndDirPicker, ID_EDIT_DIR), szString, sizeof(szString));
      lstrcpy(lpszStringToReturn, szString);
      EndDialog(hWnd, IDOK);
      break;
    case IDCANCEL:
      shutDialog(hWnd);
      lpszStringToReturn[0] = '\0';
      EndDialog(hWnd, IDCANCEL);
      break;
    default:
      break;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void onDrawItem ( LPDRAWITEMSTRUCT  lpdis,
BOOL  bDrive 
) [static]

Definition at line 270 of file dirpick.cpp.

{
  if((int)lpdis->itemID < 0)
    return;

  char szItem[_MAX_DIR];
  DWORD dwItemData;

  if(bDrive) 
  {
    dwItemData = ComboBox_GetItemData(lpdis->hwndItem, lpdis->itemID);
    ComboBox_GetLBText(lpdis->hwndItem, lpdis->itemID, szItem);
  } 
  else 
  {
    dwItemData = ListBox_GetItemData(lpdis->hwndItem, lpdis->itemID);
    ListBox_GetText(lpdis->hwndItem, lpdis->itemID, szItem);
  }

  if(lpdis->itemAction & (ODA_DRAWENTIRE | ODA_SELECT)) 
  {
    COLORREF colorText;
    COLORREF colorBack;
    if(lpdis->itemState & ODS_SELECTED) 
    {
      colorText = SetTextColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
      colorBack = SetBkColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHT));
    }
    HICON hIcon;
    int indent = 0;
    if(bDrive) 
    {
      int iType=(int)HIWORD(dwItemData);
      switch (iType) 
      {
        case DRIVE_REMOVABLE:
          hIcon = hIconDrives[0];
          break; 
        case DRIVE_FIXED:
          hIcon = hIconDrives[1];
          break;
        case DRIVE_REMOTE:
          hIcon = hIconDrives[2];
          break; 
        case DRIVE_CDROM:
          hIcon = hIconDrives[3];
          break; 
        case DRIVE_RAMDISK:
          hIcon = hIconDrives[4];
          break; 
      }

    } 
    else 
    {
      int iconID = (int)HIWORD(lpdis->itemData);
      switch (iconID) 
      {
        case ID_ICON_FOLDERCLOSED:
          hIcon = hIconFolders[0];
          break;
        case ID_ICON_FOLDEROPEN:
          hIcon = hIconFolders[1];
          break;
        case ID_ICON_OPENSELECT:
          hIcon = hIconFolders[2];
          break;
      }
      indent = 4 * (1 + LOWORD(lpdis->itemData));
    }

    ExtTextOut(lpdis->hDC, 
               lpdis->rcItem.left + ITEM_LEFTMARGIN + ITEM_BITMAPWIDTH + ITEM_GAP + indent,
               lpdis->rcItem.top,
               ETO_OPAQUE | ETO_CLIPPED,
               &lpdis->rcItem,
               szItem,
               lstrlen(szItem),
               NULL);

    BOOL res = DrawIcon(lpdis->hDC, 
                        lpdis->rcItem.left + ITEM_LEFTMARGIN + indent,
                        lpdis->rcItem.top, 
                        hIcon);

    if(lpdis->itemState & ODS_SELECTED) 
    {
      SetTextColor(lpdis->hDC, colorText);
      SetBkColor(lpdis->hDC, colorBack);
    }
  }
  if((lpdis->itemAction & ODA_FOCUS) || (lpdis->itemState & ODS_FOCUS))
    DrawFocusRect(lpdis->hDC, &lpdis->rcItem);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void onInitDialog ( HWND  hWnd,
LPSTR  lpsz 
) [static]

Definition at line 387 of file dirpick.cpp.

{
  hWndDirPicker = hWnd;
  lpszStringToReturn = lpsz;
  
  hIconDrives[0] = LoadIcon(hInst, MAKEINTRESOURCE(ID_ICON_DRIVEFLOPPY));
  hIconDrives[1] = LoadIcon(hInst, MAKEINTRESOURCE(ID_ICON_DRIVEHARD));
  hIconDrives[2] = LoadIcon(hInst, MAKEINTRESOURCE(ID_ICON_DRIVENETWORK));
  hIconDrives[3] = LoadIcon(hInst, MAKEINTRESOURCE(ID_ICON_DRIVECDROM));
  hIconDrives[4] = LoadIcon(hInst, MAKEINTRESOURCE(ID_ICON_DRIVERAM));

  hIconFolders[0] = LoadIcon(hInst, MAKEINTRESOURCE(ID_ICON_FOLDERCLOSED));
  hIconFolders[1] = LoadIcon(hInst, MAKEINTRESOURCE(ID_ICON_FOLDEROPEN));
  hIconFolders[2] = LoadIcon(hInst, MAKEINTRESOURCE(ID_ICON_OPENSELECT));
  
  if(lpsz[0] == '\0') 
    _getcwd(lpsz, _MAX_PATH);
  else if(lpsz[lstrlen(lpsz) - 1] == ':')
    lstrcat(lpsz, "\\");

  int ret = _chdir(lpsz);
  if(ret == -1) 
  {
    char szText[_MAX_PATH + 80];
    sprintf(szText, "The specified directory %s\ncannot be found", lpsz);
    MessageBox(GetParent(hWnd), szText, "Choose Directory", MB_ICONEXCLAMATION|MB_OK);
    _getcwd(lpsz, _MAX_PATH);
  }
  if((lpsz[0] == '\\') && (lpsz[1] == '\\'))
    fillUNCRootArray(lpsz);
  fillListBox(hWnd, lpsz);
  fillComboBox(hWnd);
}

Here is the call graph for this function:

Here is the caller graph for this function:

BOOL PickupDirectory ( HWND  hWndOwner,
LPSTR  lpszString 
)

Definition at line 597 of file dirpick.cpp.

{
  if(hWndOwner == NULL)
    hWndOwner = GetDesktopWindow();
  int ret = DialogBoxParam(hInst, MAKEINTRESOURCE(ID_DIALOG_CHOOSEDIR), hWndOwner, DirPickDlgProc, (LPARAM)lpszString);
  return (ret == IDOK);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void shutDialog ( HWND  hWnd) [static]

Definition at line 421 of file dirpick.cpp.

{
  szUNCRoot[0] = '\0';
}

Here is the caller graph for this function:


Variable Documentation

HICON hIconDrives[5] [static]

Definition at line 53 of file dirpick.cpp.

HICON hIconFolders[3] [static]

Definition at line 54 of file dirpick.cpp.

Definition at line 65 of file main.cpp.

HWND hWndDirPicker [static]

Definition at line 52 of file dirpick.cpp.

Definition at line 55 of file dirpick.cpp.

char szUNCRoot[256] = "" [static]

Definition at line 56 of file dirpick.cpp.