📄 shellctrls.h
字号:
if( dwAttribs & SFGAO_LINK ) {
item.mask |= LVIF_STATE;
item.stateMask |= LVIS_OVERLAYMASK;
item.state |= INDEXTOOVERLAYMASK(2);
}
return InsertItem(&item);
}
// NOTE: Sorting added by Anatoly Ivasyuk.
static int CALLBACK _SortFunc(LPARAM lParam1, LPARAM lParam2, LPARAM /*lParamSort*/)
{
PSHELLITEMINFO pItem1 = reinterpret_cast<PSHELLITEMINFO>(lParam1);
PSHELLITEMINFO pItem2 = reinterpret_cast<PSHELLITEMINFO>(lParam2);
HRESULT Hr = pItem1->spFolder->CompareIDs(0, pItem1->pidlNode, pItem2->pidlNode);
if( SUCCEEDED(Hr) ) return (SHORT) (Hr & SHCIDS_COLUMNMASK);
return 0;
}
// Message Handlers
LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
{
LRESULT lRes = DefWindowProc(uMsg, wParam, lParam);
_Init();
return lRes;
}
LRESULT OnDeleteItem(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/)
{
LPNMLISTVIEW pnmlv = (LPNMLISTVIEW) pnmh;
PSHELLITEMINFO pItem = reinterpret_cast<PSHELLITEMINFO>(pnmlv->lParam);
ATLASSERT(pItem);
ATLTRY(delete pItem);
return 0;
}
LRESULT OnGetDispInfo(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/)
{
NMLVDISPINFO* lpdi = (NMLVDISPINFO*) pnmh;
PSHELLITEMINFO pItem = reinterpret_cast<PSHELLITEMINFO>(lpdi->item.lParam);
SHFILEINFO sfi;
if( lpdi->item.mask & LVIF_TEXT ) {
if( ::SHGetFileInfo((LPCTSTR)(LPCITEMIDLIST)pItem->pidlFull,
0, &sfi, sizeof(sfi),
SHGFI_PIDL | SHGFI_DISPLAYNAME) ) {
::lstrcpy(lpdi->item.pszText, sfi.szDisplayName);
}
}
if( lpdi->item.mask & LVIF_IMAGE ) {
if( ::SHGetFileInfo((LPCTSTR)(LPCITEMIDLIST)pItem->pidlFull,
0, &sfi, sizeof(sfi),
SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_LINKOVERLAY) ) {
lpdi->item.iImage = sfi.iIcon;
}
}
return 0;
}
};
/////////////////////////////////////////////////////////////////////////////
// CShellComboCtrl
class CShellComboCtrl :
public CWindowImpl< CShellComboCtrl, CComboBoxEx, CControlWinTraits >,
public CShellBaseCtrl< CShellComboCtrl >
{
public:
typedef CWindowImpl< CShellComboCtrl, CComboBoxEx, CControlWinTraits > parentClass;
BEGIN_MSG_MAP(CShellComboCtrl)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
REFLECTED_NOTIFY_CODE_HANDLER(CBEN_GETDISPINFO, OnGetDispInfo)
REFLECTED_NOTIFY_CODE_HANDLER(CBEN_DELETEITEM, OnDeleteItem)
DEFAULT_REFLECTION_HANDLER()
END_MSG_MAP()
// Operations
BOOL SubclassWindow(HWND hWnd)
{
ATLASSERT(m_hWnd==NULL);
ATLASSERT(::IsWindow(hWnd));
BOOL bRet = parentClass::SubclassWindow(hWnd);
if( bRet ) _Init();
return bRet;
}
// Implementation
BOOL _Init()
{
// Extract the System Imagelist
SHFILEINFO sfi;
CImageList images = (HIMAGELIST) ::SHGetFileInfo( _T("C:\\"), 0, &sfi, sizeof(sfi), SHGFI_SYSICONINDEX | SHGFI_SMALLICON);
SetImageList(images.Detach());
return TRUE;
}
BOOL _Populate(IShellFolder* pFolder, LPCITEMIDLIST pidlParent, DWORD dwAttribs)
{
ATLASSERT(::IsWindow(m_hWnd));
ATLASSERT(pFolder);
ATLASSERT(pidlParent);
ResetContent();
int iIndent = 0;
if( (m_dwShellStyle & SCT_EX_NOROOT) == 0 ) {
_InsertItem(pFolder, pidlParent, NULL, dwAttribs, iIndent++);
}
CComPtr<IEnumIDList> spEnum;
DWORD dwEnumFlags = SHCONTF_FOLDERS | SHCONTF_NONFOLDERS;
if( m_dwShellStyle & SCT_EX_SHOWHIDDEN ) dwEnumFlags |= SHCONTF_INCLUDEHIDDEN;
if( SUCCEEDED(pFolder->EnumObjects(NULL, dwEnumFlags, &spEnum)) ) {
CPidl pidl;
DWORD dwFetched;
while( (spEnum->Next(1, &pidl, &dwFetched) == S_OK) && (dwFetched > 0) ) {
// Get attributes and filter some items
DWORD dwAttribs = 0;
if( !_FilterItem(pFolder, pidl, dwAttribs) ) {
_InsertItem(pFolder, pidlParent, pidl, dwAttribs, iIndent);
}
pidl.Delete();
}
}
SetCurSel(0);
return TRUE;
}
int _InsertItem(IShellFolder* pFolder, LPCITEMIDLIST pidlPath, LPCITEMIDLIST pidlNode,
DWORD dwAttribs, int iIndent)
{
ATLASSERT(pFolder);
ATLASSERT(pidlPath);
// Create PARAM data
PSHELLITEMINFO pItem;
ATLTRY(pItem = new SHELLITEMINFO);
ATLASSERT(pItem);
pItem->pidlFull.Copy( pidlPath );
pItem->pidlFull.Concatenate( pidlNode );
pItem->pidlNode.Copy( pidlNode );
pItem->spFolder = pFolder;
pItem->dwAttribs = dwAttribs;
// Insert combobox item
COMBOBOXEXITEM item = { 0 };
item.iItem = -1;
item.mask = CBEIF_TEXT | CBEIF_IMAGE | CBEIF_SELECTEDIMAGE | CBEIF_INDENT | CBEIF_LPARAM;
item.pszText = LPSTR_TEXTCALLBACK;
item.iImage = item.iSelectedImage = I_IMAGECALLBACK;
item.iIndent = iIndent;
item.lParam = (LPARAM) pItem;
return InsertItem(&item);
}
// Message Handlers
LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
{
LRESULT lRes = DefWindowProc(uMsg, wParam, lParam);
_Init();
return lRes;
}
LRESULT OnDeleteItem(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/)
{
NMCOMBOBOXEX* pnmlv = (NMCOMBOBOXEX*) pnmh;
PSHELLITEMINFO pItem = reinterpret_cast<PSHELLITEMINFO>(pnmlv->ceItem.lParam);
ATLASSERT(pItem);
ATLTRY(delete pItem);
return 0;
}
LRESULT OnGetDispInfo(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/)
{
PNMCOMBOBOXEX lpdi = (PNMCOMBOBOXEX) pnmh;
PSHELLITEMINFO pItem = reinterpret_cast<PSHELLITEMINFO>(lpdi->ceItem.lParam);
SHFILEINFO sfi;
if( lpdi->ceItem.mask & CBEIF_TEXT ) {
if( ::SHGetFileInfo((LPCTSTR)(LPCITEMIDLIST)pItem->pidlFull,
0, &sfi, sizeof(sfi),
SHGFI_PIDL | SHGFI_DISPLAYNAME) ) {
::lstrcpy(lpdi->ceItem.pszText, sfi.szDisplayName);
}
}
if( lpdi->ceItem.mask & CBEIF_IMAGE ) {
if( ::SHGetFileInfo((LPCTSTR)(LPCITEMIDLIST)pItem->pidlFull,
0, &sfi, sizeof(sfi),
SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_LINKOVERLAY) ) {
lpdi->ceItem.iImage = sfi.iIcon;
}
}
if( lpdi->ceItem.mask & CBEIF_SELECTEDIMAGE ) {
if( ::SHGetFileInfo((LPCTSTR)(LPCITEMIDLIST)pItem->pidlFull,
0, &sfi, sizeof(sfi),
SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_OPENICON) ) {
lpdi->ceItem.iSelectedImage = sfi.iIcon;
}
}
return 0;
}
};
/////////////////////////////////////////////////////////////////////////////
// CExplorerMenu
// NOTE: You need to call OleInitialize() first on anything above Win98 to
// successfully execute menu commands.
class CExplorerMenu
{
public:
CComQIPtr<IContextMenu2, &IID_IContextMenu2> m_spCtxMenu2;
BOOL TrackPopupMenu(LPCITEMIDLIST pidl, int x, int y, HWND hWnd)
{
ATLASSERT(pidl);
ATLASSERT(::IsWindow(hWnd));
CComPtr<IShellFolder> spFolder;
CPidl pidlItem;
if( !AtlGetShellPidl(pidl, &spFolder, &pidlItem) ) return FALSE;
// Get a pointer to the item's IContextMenu interface and call
// IContextMenu::QueryContextMenu to initialize a context menu.
BOOL bResult = FALSE;
CComPtr<IContextMenu> spContextMenu;
LPCITEMIDLIST lpPidl = pidlItem;
if( FAILED( spFolder->GetUIObjectOf(hWnd, 1, &lpPidl, IID_IContextMenu, NULL, (LPVOID*) &spContextMenu))) return FALSE;
// Do we need to display the popup menu?
HMENU hMenu = ::CreatePopupMenu();
int nCmd = 0;
if( SUCCEEDED( spContextMenu->QueryContextMenu(
hMenu,
0,
1,
0x7FFF,
CMF_EXPLORE)) )
{
m_spCtxMenu2 = spContextMenu;
// Display the context menu.
nCmd = ::TrackPopupMenu(hMenu,
TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD,
x, y,
0,
hWnd,
NULL);
m_spCtxMenu2.Release();
}
// If a command is available (from the menu, perhaps), execute it.
if( nCmd ) {
CMINVOKECOMMANDINFO ici = { 0 };
ici.cbSize = sizeof(CMINVOKECOMMANDINFO);
ici.fMask = 0;
ici.hwnd = hWnd;
ici.lpVerb = MAKEINTRESOURCEA(nCmd - 1);
ici.lpParameters = NULL;
ici.lpDirectory = NULL;
ici.nShow = SW_SHOWNORMAL;
ici.dwHotKey = 0;
ici.hIcon = NULL;
if( SUCCEEDED( spContextMenu->InvokeCommand(&ici)) ) bResult = TRUE;
}
if( hMenu ) ::DestroyMenu(hMenu);
return bResult;
}
// To fix the "Send To" problem with Shell Context menus you
// must chain your window message map with this map.
// E.g. Use "CHAIN_MSG_MAP_MEMBER(m_menu)" in the owner's map.
// I guess that subclassing the window would have been a nicer
// solution.
BEGIN_MSG_MAP(CExplorerMenu)
MESSAGE_HANDLER(WM_INITMENUPOPUP, OnShellMenuMsg)
MESSAGE_HANDLER(WM_DRAWITEM, OnShellMenuMsg)
MESSAGE_HANDLER(WM_MEASUREITEM, OnShellMenuMsg)
MESSAGE_HANDLER(WM_MENUCHAR, OnShellMenuMsg)
END_MSG_MAP()
LRESULT OnShellMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
bHandled = FALSE;
if( (uMsg == WM_DRAWITEM || uMsg == WM_MEASUREITEM) && (wParam != 0) ) return 0; // Only for menus
if( m_spCtxMenu2 ) m_spCtxMenu2->HandleMenuMsg(uMsg, wParam, lParam);
return 0;
}
};
#endif // !defined(AFX_SHELLCTRLS_H__20010531_6E5C_D354_4C09_0080AD509054__INCLUDED_)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -