⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 filedlg.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
    break;
    /* Filetype combo box */
  case IDC_FILETYPE:
    FILEDLG95_FILETYPE_OnCommand(hwnd,wNotifyCode);
    break;
    /* LookIn combo box */
  case IDC_LOOKIN:
    FILEDLG95_LOOKIN_OnCommand(hwnd,wNotifyCode);
    break;

  /* --- toolbar --- */
    /* Up folder button */
  case FCIDM_TB_UPFOLDER:
    FILEDLG95_SHELL_UpFolder(hwnd);
    break;
    /* New folder button */
  case FCIDM_TB_NEWFOLDER:
    FILEDLG95_SHELL_ExecuteCommand(hwnd,CMDSTR_NEWFOLDERA);
    break;
    /* List option button */
  case FCIDM_TB_SMALLICON:
    FILEDLG95_SHELL_ExecuteCommand(hwnd,CMDSTR_VIEWLISTA);
    break;
    /* Details option button */
  case FCIDM_TB_REPORTVIEW:
    FILEDLG95_SHELL_ExecuteCommand(hwnd,CMDSTR_VIEWDETAILSA);
    break;
    /* Details option button */
  case FCIDM_TB_DESKTOP:
    FILEDLG95_SHELL_BrowseToDesktop(hwnd);
    break;

  case IDC_FILENAME:
    break;

  }
  /* Do not use the listview selection anymore */
  fodInfos->DlgInfos.dwDlgProp &= ~FODPROP_USEVIEW;
  return 0;
}

/***********************************************************************
 *      FILEDLG95_OnWMGetIShellBrowser
 *
 * WM_GETISHELLBROWSER message handler
 */
static LRESULT FILEDLG95_OnWMGetIShellBrowser(HWND hwnd)
{

  FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);

  TRACE("\n");

  SetWindowLongPtrW(hwnd,DWLP_MSGRESULT,(LONG_PTR)fodInfos->Shell.FOIShellBrowser);

  return TRUE;
}


/***********************************************************************
 *      FILEDLG95_SendFileOK
 *
 * Sends the CDN_FILEOK notification if required
 *
 * RETURNS
 *  TRUE if the dialog should close
 *  FALSE if the dialog should not be closed
 */
static BOOL FILEDLG95_SendFileOK( HWND hwnd, FileOpenDlgInfos *fodInfos )
{
    /* ask the hook if we can close */
    if(IsHooked(fodInfos))
    {
        LRESULT retval;

        TRACE("---\n");
        /* First send CDN_FILEOK as MSDN doc says */
        retval = SendCustomDlgNotificationMessage(hwnd,CDN_FILEOK);
        if (GetWindowLongPtrW(fodInfos->DlgInfos.hwndCustomDlg, DWLP_MSGRESULT))
        {
            TRACE("canceled\n");
            return (retval == 0);
        }

        /* fodInfos->ofnInfos points to an ASCII or UNICODE structure as appropriate */
        retval = SendMessageW(fodInfos->DlgInfos.hwndCustomDlg,
                              fodInfos->HookMsg.fileokstring, 0, (LPARAM)fodInfos->ofnInfos);
        if (GetWindowLongPtrW(fodInfos->DlgInfos.hwndCustomDlg, DWLP_MSGRESULT))
        {
            TRACE("canceled\n");
            return (retval == 0);
        }
    }
    return TRUE;
}

/***********************************************************************
 *      FILEDLG95_OnOpenMultipleFiles
 *
 * Handles the opening of multiple files.
 *
 * FIXME
 *  check destination buffer size
 */
BOOL FILEDLG95_OnOpenMultipleFiles(HWND hwnd, LPWSTR lpstrFileList, UINT nFileCount, UINT sizeUsed)
{
  WCHAR   lpstrPathSpec[MAX_PATH] = {0};
  UINT   nCount, nSizePath;
  FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);

  TRACE("\n");

  if(fodInfos->unicode)
  {
     LPOPENFILENAMEW ofn = fodInfos->ofnInfos;
     ofn->lpstrFile[0] = '\0';
  }
  else
  {
     LPOPENFILENAMEA ofn = (LPOPENFILENAMEA) fodInfos->ofnInfos;
     ofn->lpstrFile[0] = '\0';
  }

  COMDLG32_GetDisplayNameOf( fodInfos->ShellInfos.pidlAbsCurrent, lpstrPathSpec );

  if ( !(fodInfos->ofnInfos->Flags & OFN_NOVALIDATE) &&
      ( fodInfos->ofnInfos->Flags & OFN_FILEMUSTEXIST) &&
       ! ( fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG ) )
  {
    LPWSTR lpstrTemp = lpstrFileList;

    for ( nCount = 0; nCount < nFileCount; nCount++ )
    {
      LPITEMIDLIST pidl;

      pidl = GetPidlFromName(fodInfos->Shell.FOIShellFolder, lpstrTemp);
      if (!pidl)
      {
        WCHAR lpstrNotFound[100];
        WCHAR lpstrMsg[100];
        WCHAR tmp[400];
        static const WCHAR nl[] = {'\n',0};

        LoadStringW(COMDLG32_hInstance, IDS_FILENOTFOUND, lpstrNotFound, 100);
        LoadStringW(COMDLG32_hInstance, IDS_VERIFYFILE, lpstrMsg, 100);

        lstrcpyW(tmp, lpstrTemp);
        lstrcatW(tmp, nl);
        lstrcatW(tmp, lpstrNotFound);
        lstrcatW(tmp, nl);
        lstrcatW(tmp, lpstrMsg);

        MessageBoxW(hwnd, tmp, fodInfos->title, MB_OK | MB_ICONEXCLAMATION);
        return FALSE;
      }

      /* move to the next file in the list of files */
      lpstrTemp += lstrlenW(lpstrTemp) + 1;
      COMDLG32_SHFree(pidl);
    }
  }

  nSizePath = lstrlenW(lpstrPathSpec) + 1;
  if ( !(fodInfos->ofnInfos->Flags & OFN_EXPLORER) )
  {
    /* For "oldstyle" dialog the components have to
       be separated by blanks (not '\0'!) and short
       filenames have to be used! */
    FIXME("Components have to be separated by blanks\n");
  }
  if(fodInfos->unicode)
  {
    LPOPENFILENAMEW ofn = fodInfos->ofnInfos;
    lstrcpyW( ofn->lpstrFile, lpstrPathSpec);
    memcpy( ofn->lpstrFile + nSizePath, lpstrFileList, sizeUsed*sizeof(WCHAR) );
  }
  else
  {
    LPOPENFILENAMEA ofn = (LPOPENFILENAMEA)fodInfos->ofnInfos;

    if (ofn->lpstrFile != NULL)
    {
      nSizePath = WideCharToMultiByte(CP_ACP, 0, lpstrPathSpec, -1,
			  ofn->lpstrFile, ofn->nMaxFile, NULL, NULL);
      if (ofn->nMaxFile > nSizePath)
      {
	WideCharToMultiByte(CP_ACP, 0, lpstrFileList, sizeUsed,
			    ofn->lpstrFile + nSizePath,
			    ofn->nMaxFile - nSizePath, NULL, NULL);
      }
    }
  }

  fodInfos->ofnInfos->nFileOffset = nSizePath;
  fodInfos->ofnInfos->nFileExtension = 0;

  if ( !FILEDLG95_SendFileOK(hwnd, fodInfos) )
    return FALSE;

  /* clean and exit */
  FILEDLG95_Clean(hwnd);
  return EndDialog(hwnd,TRUE);
}

/***********************************************************************
 *      FILEDLG95_OnOpen
 *
 * Ok button WM_COMMAND message handler
 *
 * If the function succeeds, the return value is nonzero.
 */
#define ONOPEN_BROWSE 1
#define ONOPEN_OPEN   2
#define ONOPEN_SEARCH 3
static void FILEDLG95_OnOpenMessage(HWND hwnd, int idCaption, int idText)
{
  WCHAR strMsgTitle[MAX_PATH];
  WCHAR strMsgText [MAX_PATH];
  if (idCaption)
    LoadStringW(COMDLG32_hInstance, idCaption, strMsgTitle, sizeof(strMsgTitle)/sizeof(WCHAR));
  else
    strMsgTitle[0] = '\0';
  LoadStringW(COMDLG32_hInstance, idText, strMsgText, sizeof(strMsgText)/sizeof(WCHAR));
  MessageBoxW(hwnd,strMsgText, strMsgTitle, MB_OK | MB_ICONHAND);
}

BOOL FILEDLG95_OnOpen(HWND hwnd)
{
  LPWSTR lpstrFileList;
  UINT nFileCount = 0;
  UINT sizeUsed = 0;
  BOOL ret = TRUE;
  WCHAR lpstrPathAndFile[MAX_PATH];
  WCHAR lpstrTemp[MAX_PATH];
  LPSHELLFOLDER lpsf = NULL;
  int nOpenAction;
  FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);

  TRACE("hwnd=%p\n", hwnd);

  /* get the files from the edit control */
  nFileCount = FILEDLG95_FILENAME_GetFileNames(hwnd, &lpstrFileList, &sizeUsed, '\0');

  /* try if the user selected a folder in the shellview */
  if(nFileCount == 0)
  {
      BrowseSelectedFolder(hwnd);
      return FALSE;
  }

  if(nFileCount > 1)
  {
      ret = FILEDLG95_OnOpenMultipleFiles(hwnd, lpstrFileList, nFileCount, sizeUsed);
      goto ret;
  }

  TRACE("count=%u len=%u file=%s\n", nFileCount, sizeUsed, debugstr_w(lpstrFileList));

/*
  Step 1:  Build a complete path name from the current folder and
  the filename or path in the edit box.
  Special cases:
  - the path in the edit box is a root path
    (with or without drive letter)
  - the edit box contains ".." (or a path with ".." in it)
*/

  /* Get the current directory name */
  if (!COMDLG32_GetDisplayNameOf(fodInfos->ShellInfos.pidlAbsCurrent, lpstrPathAndFile))
  {
    /* last fallback */
    GetCurrentDirectoryW(MAX_PATH, lpstrPathAndFile);
  }
  PathAddBackslashW(lpstrPathAndFile);

  TRACE("current directory=%s\n", debugstr_w(lpstrPathAndFile));

  /* if the user specifyed a fully qualified path use it */
  if(PathIsRelativeW(lpstrFileList))
  {
    lstrcatW(lpstrPathAndFile, lpstrFileList);
  }
  else
  {
    /* does the path have a drive letter? */
    if (PathGetDriveNumberW(lpstrFileList) == -1)
      lstrcpyW(lpstrPathAndFile+2, lpstrFileList);
    else
      lstrcpyW(lpstrPathAndFile, lpstrFileList);
  }

  /* resolve "." and ".." */
  PathCanonicalizeW(lpstrTemp, lpstrPathAndFile );
  lstrcpyW(lpstrPathAndFile, lpstrTemp);
  TRACE("canon=%s\n", debugstr_w(lpstrPathAndFile));

  MemFree(lpstrFileList);

/*
  Step 2: here we have a cleaned up path

  We have to parse the path step by step to see if we have to browse
  to a folder if the path points to a directory or the last
  valid element is a directory.

  valid variables:
    lpstrPathAndFile: cleaned up path
 */

  if (nFileCount &&
      (fodInfos->ofnInfos->Flags & OFN_NOVALIDATE) &&
      !(fodInfos->ofnInfos->Flags & OFN_FILEMUSTEXIST))
    nOpenAction = ONOPEN_OPEN;
  else
    nOpenAction = ONOPEN_BROWSE;

  /* don't apply any checks with OFN_NOVALIDATE */
  {
    LPWSTR lpszTemp, lpszTemp1;
    LPITEMIDLIST pidl = NULL;
    static const WCHAR szwInvalid[] = { '/',':','<','>','|', 0};

    /* check for invalid chars */
    if((strpbrkW(lpstrPathAndFile+3, szwInvalid) != NULL) && !(fodInfos->ofnInfos->Flags & OFN_NOVALIDATE))
    {
      FILEDLG95_OnOpenMessage(hwnd, IDS_INVALID_FILENAME_TITLE, IDS_INVALID_FILENAME);
      ret = FALSE;
      goto ret;
    }

    if (FAILED (SHGetDesktopFolder(&lpsf))) return FALSE;

    lpszTemp1 = lpszTemp = lpstrPathAndFile;
    while (lpszTemp1)
    {
      LPSHELLFOLDER lpsfChild;
      WCHAR lpwstrTemp[MAX_PATH];
      DWORD dwEaten, dwAttributes;
      LPWSTR p;

      lstrcpyW(lpwstrTemp, lpszTemp);
      p = PathFindNextComponentW(lpwstrTemp);

      if (!p) break; /* end of path */

      *p = 0;
      lpszTemp = lpszTemp + lstrlenW(lpwstrTemp);

      /* There are no wildcards when OFN_NOVALIDATE is set */
      if(*lpszTemp==0 && !(fodInfos->ofnInfos->Flags & OFN_NOVALIDATE))
      {
        static const WCHAR wszWild[] = { '*', '?', 0 };
	/* if the last element is a wildcard do a search */
        if(strpbrkW(lpszTemp1, wszWild) != NULL)
        {
	  nOpenAction = ONOPEN_SEARCH;
	  break;
	}
      }
      lpszTemp1 = lpszTemp;

      TRACE("parse now=%s next=%s sf=%p\n",debugstr_w(lpwstrTemp), debugstr_w(lpszTemp), lpsf);

      /* append a backslash to drive letters */
      if(lstrlenW(lpwstrTemp)==2 && lpwstrTemp[1] == ':' && 
	 ((lpwstrTemp[0] >= 'a' && lpwstrTemp[0] <= 'z') ||
	  (lpwstrTemp[0] >= 'A' && lpwstrTemp[0] <= 'Z'))) 
      {
        PathAddBackslashW(lpwstrTemp);
      }

      dwAttributes = SFGAO_FOLDER;
      if(SUCCEEDED(IShellFolder_ParseDisplayName(lpsf, hwnd, NULL, lpwstrTemp, &dwEaten, &pidl, &dwAttributes)))
      {
        /* the path component is valid, we have a pidl of the next path component */
        TRACE("parse OK attr=0x%08x pidl=%p\n", dwAttributes, pidl);
        if(dwAttributes & SFGAO_FOLDER)
        {
          if(FAILED(IShellFolder_BindToObject(lpsf, pidl, 0, &IID_IShellFolder, (LPVOID*)&lpsfChild)))
          {
            ERR("bind to failed\n"); /* should not fail */
            break;
          }
          IShellFolder_Release(lpsf);
          lpsf = lpsfChild;
          lpsfChild = NULL;
        }
        else
        {
          TRACE

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -