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

📄 dlapi.c

📁 C语言编程中算法数据结构中的树行代码
💻 C
📖 第 1 页 / 共 3 页
字号:
        else
          return(FALSE);
      }
    }
  }

  // No matching
  return(pdlf->bExcludeFilter)?TRUE:FALSE;

}



//==== DriveBox ===============================================================

//=============================================================================
//
//  Internal Itemdata Structure
//
typedef struct tagDC_ITEMDATA
{

  LPITEMIDLIST  pidl;
  LPSHELLFOLDER lpsf;

} DC_ITEMDATA, *LPDC_ITEMDATA;


//=============================================================================
//
//  DriveBox_Init()
//
//  Initializes the drive box
//
BOOL DriveBox_Init(HWND hwnd)
{

  HIMAGELIST hil;
  SHFILEINFO shfi;

  hil = (HIMAGELIST)SHGetFileInfo("C:\\",0,&shfi,sizeof(SHFILEINFO),
                                  SHGFI_SMALLICON | SHGFI_SYSICONINDEX);
  SendMessage(hwnd,CBEM_SETIMAGELIST,0,(LPARAM)hil);
  SendMessage(hwnd,CBEM_SETEXTENDEDSTYLE,CBES_EX_NOSIZELIMIT,CBES_EX_NOSIZELIMIT);

  return TRUE;

}


//=============================================================================
//
//  DriveBox_Fill
//

int DriveBox_Fill(HWND hwnd)
{

  //LPMALLOC lpMalloc;

  LPSHELLFOLDER lpsfDesktop;
  LPSHELLFOLDER lpsf; // Workspace == CSIDL_DRIVES

  LPITEMIDLIST  pidl;
  LPITEMIDLIST  pidlEntry;

  LPENUMIDLIST  lpe;

  COMBOBOXEXITEM  cbei;
  LPDC_ITEMDATA   lpdcid;

  ULONG dwAttributes = 0;

  DWORD grfFlags = SHCONTF_FOLDERS;


  // Init ComboBox
  SendMessage(hwnd,WM_SETREDRAW,0,0);
  SendMessage(hwnd,CB_RESETCONTENT,0,0);

  ZeroMemory(&cbei,sizeof(COMBOBOXEXITEM));
  cbei.mask = CBEIF_TEXT | CBEIF_IMAGE | CBEIF_SELECTEDIMAGE | CBEIF_LPARAM;
  cbei.pszText = LPSTR_TEXTCALLBACK;
  cbei.cchTextMax = MAX_PATH;
  cbei.iImage = I_IMAGECALLBACK;
  cbei.iSelectedImage = I_IMAGECALLBACK;

  // Get Shell's IMalloc Interface
  //if (NOERROR == SHGetMalloc(&lpMalloc))
  //{

    // Get pidl to [My Computer]
    if (NOERROR == SHGetSpecialFolderLocation(hwnd,
                                              CSIDL_DRIVES,
                                              &pidl))
    {

      // Get Desktop Folder
      if (NOERROR == SHGetDesktopFolder(&lpsfDesktop))
      {

        // Bind pidl to IShellFolder
        if (NOERROR == lpsfDesktop->lpVtbl->BindToObject(
                                              lpsfDesktop,
                                              pidl,
                                              NULL,
                                              &IID_IShellFolder,
                                              &lpsf))

        {

          // Create an Enumeration object for lpsf
          if (NOERROR == lpsf->lpVtbl->EnumObjects(
                                         lpsf,
                                         hwnd,
                                         grfFlags,
                                         &lpe))

          {

            // Enumerate the contents of [My Computer]
            while (NOERROR == lpe->lpVtbl->Next(
                                             lpe,
                                             1,
                                             &pidlEntry,
                                             NULL))

            {

              // Add item to the List if it is part of the
              // Filesystem
              dwAttributes = SFGAO_FILESYSTEM;

              lpsf->lpVtbl->GetAttributesOf(
                              lpsf,
                              1,
                              &pidlEntry,
                              &dwAttributes);

              if (dwAttributes & SFGAO_FILESYSTEM)
              {

                // Windows XP: check if pidlEntry is a drive
                SHDESCRIPTIONID di;
                HRESULT hr;
                hr = SHGetDataFromIDList(lpsf,pidlEntry,SHGDFIL_DESCRIPTIONID,
                                         &di,sizeof(SHDESCRIPTIONID));
                if (hr != NOERROR || (di.dwDescriptionId >= SHDID_COMPUTER_DRIVE35 &&
                                      di.dwDescriptionId <= SHDID_COMPUTER_OTHER))
                {

                  lpdcid = g_lpMalloc->lpVtbl->Alloc(
                                                g_lpMalloc,
                                                sizeof(DC_ITEMDATA));

                  //lpdcid->pidl = IL_Copy(lpMalloc,pidlEntry);
                  lpdcid->pidl = pidlEntry;
                  lpdcid->lpsf = lpsf;

                  lpsf->lpVtbl->AddRef(lpsf);

                  // Insert sorted ...
                  {
                    COMBOBOXEXITEM cbei2;
                    LPDC_ITEMDATA lpdcid2;
                    HRESULT hr;
                    cbei2.mask = CBEIF_LPARAM;
                    cbei2.iItem = 0;

                    while ((SendMessage(hwnd,CBEM_GETITEM,0,(LPARAM)&cbei2)))
                    {
                      lpdcid2 = (LPDC_ITEMDATA)cbei2.lParam;
                      hr = (lpdcid->lpsf->lpVtbl->CompareIDs(
                                 lpdcid->lpsf,
                                 0,
                                 lpdcid->pidl,
                                 lpdcid2->pidl));

                      if ((short)(SCODE_CODE(GetScode(hr))) < 0)
                        break;
                      else
                        cbei2.iItem++;
                    }

                    cbei.iItem = cbei2.iItem;
                    cbei.lParam = (LPARAM)lpdcid;
                    SendMessage(hwnd,CBEM_INSERTITEM,0,(LPARAM)&cbei);

                  }

                }

              }

              //lpMalloc->lpVtbl->Free(lpMalloc,pidlEntry);

            } // IEnumIDList::Next()

            lpe->lpVtbl->Release(lpe);

          } // IShellFolder::EnumObjects()

          lpsf->lpVtbl->Release(lpsf);

        } // IShellFolder::BindToObject()

        g_lpMalloc->lpVtbl->Free(g_lpMalloc,pidl);

      } // SHGetSpecialFolderLocation()

      lpsfDesktop->lpVtbl->Release(lpsfDesktop);

    } // SHGetDesktopFolder()

    //lpMalloc->lpVtbl->Release(lpMalloc);

  //} // SHGetMalloc()


  SendMessage(hwnd,WM_SETREDRAW,1,0);
  // Return number of items added to combo box
  return (SendMessage(hwnd,CB_GETCOUNT,0,0));

}


//=============================================================================
//
//  DriveBox_GetSelDrive
//
BOOL DriveBox_GetSelDrive(HWND hwnd,LPSTR lpszDrive,int nDrive,BOOL fNoSlash)
{

  COMBOBOXEXITEM cbei;
  LPDC_ITEMDATA lpdcid;
  int i = SendMessage(hwnd,CB_GETCURSEL,0,0);

  // CB_ERR means no Selection
  if (i == CB_ERR)
    return FALSE;

  // Get DC_ITEMDATA* of selected Item
  cbei.mask = CBEIF_LPARAM;
  cbei.iItem = i;
  SendMessage(hwnd,CBEM_GETITEM,0,(LPARAM)&cbei);
  lpdcid = (LPDC_ITEMDATA)cbei.lParam;

  // Get File System Path for Drive
  IL_GetDisplayName(lpdcid->lpsf,lpdcid->pidl,SHGDN_FORPARSING,lpszDrive,nDrive);

  // Remove Backslash if required (makes Drive relative!!!)
  if (fNoSlash)
    PathRemoveBackslash(lpszDrive);

  return TRUE;

}


//=============================================================================
//
//  DriveBox_SelectDrive
//
BOOL DriveBox_SelectDrive(HWND hwnd,LPCSTR lpszPath)
{

  COMBOBOXEXITEM cbei;
  LPDC_ITEMDATA lpdcid;
  char szRoot[64];

  int i;
  int cbItems = SendMessage(hwnd,CB_GETCOUNT,0,0);

  // No Drives in Combo Box
  if (!cbItems)
    return FALSE;

  cbei.mask = CBEIF_LPARAM;

  for (i = 0; i < cbItems; i++)
  {
    // Get DC_ITEMDATA* of Item i
    cbei.iItem = i;
    SendMessage(hwnd,CBEM_GETITEM,0,(LPARAM)&cbei);
    lpdcid = (LPDC_ITEMDATA)cbei.lParam;

    // Get File System Path for Drive
    IL_GetDisplayName(lpdcid->lpsf,lpdcid->pidl,SHGDN_FORPARSING,szRoot,64);

    // Compare Root Directory with Path
    if (PathIsSameRoot(lpszPath,szRoot))
    {
      // Select matching Drive
      SendMessage(hwnd,CB_SETCURSEL,i,0);
      return TRUE;
    }
  }

  // Don't select anything
  SendMessage(hwnd,CB_SETCURSEL,(WPARAM)-1,0);
  return FALSE;

}


//=============================================================================
//
//  DriveBox_PropertyDlg()
//
//  Shows standard Win95 Property Dlg for selected Drive
//
BOOL DriveBox_PropertyDlg(HWND hwnd)
{

  COMBOBOXEXITEM cbei;
  LPDC_ITEMDATA lpdcid;
  int iItem;
  LPCONTEXTMENU lpcm;
  CMINVOKECOMMANDINFO cmi;
  BOOL bSuccess = TRUE;

  static const char *lpVerb = "properties";

  iItem = SendMessage(hwnd,CB_GETCURSEL,0,0);

  if (iItem == CB_ERR)
    return FALSE;

  cbei.mask = CBEIF_LPARAM;
  cbei.iItem = iItem;
  SendMessage(hwnd,CBEM_GETITEM,0,(LPARAM)&cbei);
  lpdcid = (LPDC_ITEMDATA)cbei.lParam;

  if (NOERROR == lpdcid->lpsf->lpVtbl->GetUIObjectOf(
                                         lpdcid->lpsf,
                                         GetParent(hwnd),  // Owner
                                         1,                // Number of objects
                                         &lpdcid->pidl,    // pidl
                                         &IID_IContextMenu,
                                         NULL,
                                         &lpcm))
  {

    cmi.cbSize = sizeof(CMINVOKECOMMANDINFO);
    cmi.fMask = 0;
    cmi.hwnd = GetParent(hwnd);
    cmi.lpVerb = lpVerb;
    cmi.lpParameters = NULL;
    cmi.lpDirectory = NULL;
    cmi.nShow = SW_SHOWNORMAL;
    cmi.dwHotKey = 0;
    cmi.hIcon = NULL;

    if (NOERROR != lpcm->lpVtbl->InvokeCommand(lpcm,&cmi))
      bSuccess = FALSE;

    lpcm->lpVtbl->Release(lpcm);

  }

  else
    bSuccess = FALSE;

  return(bSuccess);

}


//=============================================================================
//
//  DriveBox_DeleteItem
//
LRESULT DriveBox_DeleteItem(HWND hwnd,LPARAM lParam)
{

  //LPMALLOC lpMalloc;
  NMCOMBOBOXEX *lpnmcbe;
  COMBOBOXEXITEM cbei;
  LPDC_ITEMDATA lpdcid;

  lpnmcbe = (LPVOID)lParam;
  cbei.iItem = lpnmcbe->ceItem.iItem;

  cbei.mask = CBEIF_LPARAM;
  SendMessage(hwnd,CBEM_GETITEM,0,(LPARAM)&cbei);
  lpdcid = (LPDC_ITEMDATA)cbei.lParam;

  //SHGetMalloc(&lpMalloc);

  // Free pidl
  g_lpMalloc->lpVtbl->Free(g_lpMalloc,lpdcid->pidl);
  // Release lpsf
  lpdcid->lpsf->lpVtbl->Release(lpdcid->lpsf);

  // Free lpdcid itself
  g_lpMalloc->lpVtbl->Free(g_lpMalloc,lpdcid);

  // Release lpMalloc
  //lpMalloc->lpVtbl->Release(lpMalloc);

  return TRUE;

}


//=============================================================================
//
//  DriveBox_GetDispInfo
//
LRESULT DriveBox_GetDispInfo(HWND hwnd,LPARAM lParam)
{

  NMCOMBOBOXEX *lpnmcbe;
  LPDC_ITEMDATA lpdcid;
  SHFILEINFO shfi;
  char szTemp[256];

  lpnmcbe = (LPVOID)lParam;
  lpdcid = (LPDC_ITEMDATA)lpnmcbe->ceItem.lParam;

  if (!lpdcid)
    return FALSE;

  // Get Display Name
  if (lpnmcbe->ceItem.mask & CBEIF_TEXT)
    IL_GetDisplayName(lpdcid->lpsf,lpdcid->pidl,SHGDN_NORMAL,lpnmcbe->ceItem.pszText,lpnmcbe->ceItem.cchTextMax);

  // Get Icon Index
  if (lpnmcbe->ceItem.mask & (CBEIF_IMAGE | CBEIF_SELECTEDIMAGE))
  {
    IL_GetDisplayName(lpdcid->lpsf,lpdcid->pidl,SHGDN_FORPARSING,szTemp,256);
    SHGetFileInfo(szTemp,0,&shfi,sizeof(SHFILEINFO),SHGFI_SYSICONINDEX | SHGFI_SMALLICON);
    lpnmcbe->ceItem.iImage = shfi.iIcon;
    lpnmcbe->ceItem.iSelectedImage = shfi.iIcon;
  }

  // Set values
  lpnmcbe->ceItem.mask |= CBEIF_DI_SETITEM;

  return TRUE;

}



//==== ItemID =================================================================

//=============================================================================
//
//  IL_Create()
//
// Creates an ITEMIDLIST by concatenating pidl1 and pidl2
// cb1 and cb2 indicate the sizes of the pidls, where cb1
// can be zero and pidl1 can be NULL
//
// If cb2 is zero, the size of pidl2 is retrieved using
// IL_GetSize(pidl2)
//
LPITEMIDLIST IL_Create(LPMALLOC lpMalloc,
                       LPCITEMIDLIST pidl1,UINT cb1,
                       LPCITEMIDLIST pidl2,UINT cb2)
{

  LPITEMIDLIST pidl;

  if (!pidl2)
    return NULL;

  if (!cb2)
    cb2 = IL_GetSize(pidl2) + 2; // Space for terminating Bytes

  if (!cb1)
    cb1 = IL_GetSize(pidl1);

  // Allocate Memory
  pidl = lpMalloc->lpVtbl->Alloc(lpMalloc,cb1 + cb2);

  // Init new ITEMIDLIST
  if (pidl1)
    CopyMemory(pidl,pidl1,cb1);

  // pidl2 can't be NULL here
  CopyMemory((LPBYTE)pidl + cb1,pidl2,cb2);

  return pidl;

}


//=============================================================================
//
// IL_GetSize()
//
// Retrieves the number of bytes in a pidl
// Does not add space for zero terminators !!
//
UINT IL_GetSize(LPCITEMIDLIST pidl)
{

  LPITEMIDLIST pidlTmp;
  UINT cb = 0;

  if (!pidl)
    return 0;

  for (pidlTmp = (LPITEMIDLIST)pidl;
       pidlTmp->mkid.cb;
       pidlTmp = _IL_Next(pidlTmp))

    cb += pidlTmp->mkid.cb;


  return cb;

}


//=============================================================================
//
// IL_GetDisplayName()
//
// Gets the Display Name of a pidl. lpsf is the parent IShellFolder Interface
// dwFlags specify a SHGDN_xx value
//
BOOL IL_GetDisplayName(LPSHELLFOLDER lpsf,
                       LPCITEMIDLIST pidl,
                       DWORD dwFlags,
                       LPSTR lpszDisplayName,
                       int nDisplayName)
{

  STRRET str;

  if (NOERROR == lpsf->lpVtbl->GetDisplayNameOf(lpsf,
                                                pidl,
                                                dwFlags,
                                                &str))
  {

    // Shlwapi.dll provides new function:
    // StrRetToBuf(&str,pidl,lpszDisplayName,nDisplayName);
    // ...but I suppose my version is faster ;-)
    switch (str.uType)
    {

      case STRRET_WSTR:
        WideCharToMultiByte(CP_ACP,
                            0,
                            str.pOleStr,
                            -1,
                            lpszDisplayName,
                            nDisplayName,
                            NULL,
                            NULL);
        g_lpMalloc->lpVtbl->Free(g_lpMalloc,str.pOleStr);
        break;

      case STRRET_OFFSET:
        lstrcpyn(lpszDisplayName,
                 ((char *)(pidl)) + str.uOffset,
                 nDisplayName);
        break;

      case STRRET_CSTR:
        lstrcpyn(lpszDisplayName,str.cStr,nDisplayName);
        break;

    }

    return TRUE;
  }

  return FALSE;
}



///   End of Dlapi.c   \\\

⌨️ 快捷键说明

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