📄 dlapi.c
字号:
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 + -