📄 ieshellcombobox.cpp
字号:
//*******************************************************************************
// COPYRIGHT NOTES
// ---------------
// You may use this source code, compile or redistribute it as part of your application
// for free. You cannot redistribute it as a part of a software development
// library without the agreement of the author. If the sources are
// distributed along with the application, you should leave the original
// copyright notes in the source code without any changes.
// This code can be used WITHOUT ANY WARRANTIES at your own risk.
//
// For the latest updates to this code, check this site:
// http://www.masmex.com
// after Sept 2000
//
// Copyright(C) 2000 Philip Oldaker <email: philip@masmex.com>
//*******************************************************************************
// IEShellComboBox.cpp : implementation file
//
#include "stdafx.h"
#include "UIMessages.h"
#include "IEShellComboBox.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
const CString strURLKey(_T("Software\\Microsoft\\Internet Explorer\\TypedURLs"));
const CString strIEKey(_T("\\CLSID\\{0002DF01-0000-0000-C000-000000000046}\\LocalServer32"));
/////////////////////////////////////////////////////////////////////////////
// CIEShellComboBox
CIEShellComboBox::CIEShellComboBox()
{
m_pidlMyComputer = NULL;
m_pidlMyDocuments = NULL;
m_pidlInternet = NULL;
m_hImageList = NULL;
m_hTreeWnd = NULL;
m_hIcon = NULL;
SHGetMalloc(&m_pMalloc);
m_bInternet = false;
}
CIEShellComboBox::~CIEShellComboBox()
{
DeleteAllItemData();
CShCMSort *pItem=NULL;
STL_FOR_ITERATOR(vecCMSort,m_vItems)
{
pItem = STL_GET_CURRENT(m_vItems);
DeleteItemData((LPTVITEMDATA)pItem->GetItemData());
delete pItem;
}
if (m_pMalloc)
{
if (m_pidlInternet)
m_pMalloc->Free(m_pidlInternet);
if (m_pidlMyComputer)
m_pMalloc->Free(m_pidlMyComputer);
if (m_pidlMyDocuments)
m_pMalloc->Free(m_pidlMyDocuments);
m_pMalloc->Release();
}
if (m_hIcon)
::DestroyIcon(m_hIcon);
}
void CIEShellComboBox::DeleteAllItemData()
{
for(vecItemData::iterator it=m_vecItemData.begin();it != m_vecItemData.end();it++)
{
DeleteItemData(*it);
}
m_vecItemData.erase(m_vecItemData.begin(),m_vecItemData.end());
}
void CIEShellComboBox::DeleteItemData(LPTVITEMDATA pItemData)
{
if (pItemData == NULL)
return;
if (pItemData->lpsfParent)
pItemData->lpsfParent->Release();
if (pItemData->lpi)
m_pMalloc->Free(pItemData->lpi);
if (pItemData->lpifq)
m_pMalloc->Free(pItemData->lpifq);
m_pMalloc->Free(pItemData);
}
LPITEMIDLIST CIEShellComboBox::GetSelectedPidl()
{
int nCurSel = GetCurSel();
if (nCurSel == -1)
return NULL;
LPTVITEMDATA lptvid = (LPTVITEMDATA)GetItemData(nCurSel);
if (lptvid == NULL)
return NULL;
return GetShellPidl().CopyItemIDList(lptvid->lpifq);
}
BEGIN_MESSAGE_MAP(CIEShellComboBox, CComboBoxEx)
//{{AFX_MSG_MAP(CIEShellComboBox)
ON_MESSAGE(WM_APP_CB_IE_HIT_ENTER,OnAppCbIeHitEnter)
ON_WM_CREATE()
ON_WM_DESTROY()
ON_WM_SETFOCUS()
ON_WM_KILLFOCUS()
ON_CONTROL_REFLECT(CBN_DROPDOWN, OnDropDown)
ON_CONTROL_REFLECT(CBN_SELCHANGE, OnSelChange)
//}}AFX_MSG_MAP
ON_MESSAGE(WM_APP_CB_IE_POPULATE,OnCBIEPopulate)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CIEShellComboBox message handlers
void CIEShellComboBox::Populate(LPITEMIDLIST pidlAbsSel)
{
if (m_hImageList == NULL)
SetShellImageList();
if (STL_EMPTY(m_vItems))
InitItems(pidlAbsSel);
if (GetShellPidl().ComparePidls(NULL,pidlAbsSel,m_pidlInternet))
LoadURLPrevList();
else
LoadItems(pidlAbsSel);
}
void CIEShellComboBox::LoadURLPrevList()
{
if (m_ImageList.m_hImageList)
::SendMessage(GetSafeHwnd(), CBEM_SETIMAGELIST, 0, (LPARAM)m_ImageList.m_hImageList);
ResetContent();
HKEY hKey;
if (RegOpenKeyEx(HKEY_CURRENT_USER,strURLKey,0,KEY_READ,&hKey) != ERROR_SUCCESS)
return;
TCHAR szValueName[_MAX_PATH];
BYTE pData[_MAX_PATH];
DWORD dwSizeValueName = sizeof(szValueName)-1;
DWORD dwSizeData = sizeof(pData)-1;
DWORD dwType=0;
COMBOBOXEXITEM item;
ZeroMemory(&item,sizeof(item));
item.mask |= (CBEIF_IMAGE | CBEIF_TEXT | CBEIF_SELECTEDIMAGE);
item.iItem = -1;
item.iImage = 0;
for(DWORD dwIndex=0;RegEnumValue(hKey,
dwIndex,
szValueName,
&dwSizeValueName,
NULL,
&dwType,
pData,
&dwSizeData) == ERROR_SUCCESS;dwIndex++)
{
item.pszText = (LPTSTR)(LPCTSTR)pData;
item.cchTextMax = lstrlen(item.pszText);
InsertItem(&item);
dwSizeValueName = sizeof(szValueName)-1;
dwSizeData = sizeof(pData)-1;
}
RegCloseKey(hKey);
m_bInternet = true;
}
void CIEShellComboBox::InitItems(LPITEMIDLIST pidlAbsSel)
{
LPSHELLFOLDER psfDesktop=NULL;
LPITEMIDLIST pidlDesktop=NULL;
HRESULT hr = SHGetDesktopFolder(&psfDesktop);
SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOP, &pidlDesktop);
SHGetSpecialFolderLocation(NULL, CSIDL_DRIVES, &m_pidlMyComputer);
SHGetSpecialFolderLocation(NULL, CSIDL_PERSONAL, &m_pidlMyDocuments);
SHGetSpecialFolderLocation(NULL, CSIDL_INTERNET, &m_pidlInternet);
int nImage=0, nSelImage=0;
SHFILEINFO fileInfo;
SHGetFileInfo((LPCTSTR)pidlDesktop, NULL, &fileInfo, sizeof(fileInfo), SHGFI_PIDL|SHGFI_ATTRIBUTES|SHGFI_DISPLAYNAME);
m_ShellPidl.GetNormalAndSelectedIcons(pidlDesktop, nImage, nSelImage);
CShCMSort *pItem = new CShCMSort;
pItem->SetText(fileInfo.szDisplayName);
pItem->SetImage(nImage);
pItem->SetSelImage(nSelImage);
LPTVITEMDATA lptvid = (LPTVITEMDATA)m_pMalloc->Alloc(sizeof(TVITEMDATA));
lptvid->lpi = GetShellPidl().CopyItemID(pidlDesktop);
lptvid->lpifq = GetShellPidl().CopyItemIDList(pidlDesktop);
lptvid->lpsfParent = NULL;
STL_ADD_ITEM(m_vItems,pItem);
BuildFolderList(psfDesktop,pidlDesktop,pidlAbsSel,1);
if (m_pMalloc)
{
if (pidlDesktop)
m_pMalloc->Free(pidlDesktop);
}
psfDesktop->Release();
}
void CIEShellComboBox::BuildFolderList(LPSHELLFOLDER pFolder,LPITEMIDLIST pidl,LPITEMIDLIST pidlAbsSel, int nIndent)
{
vecCMSort vItems;
AddItems(vItems,pFolder,pidl,nIndent);
// Sort the this node based on pidls
STL_SORT(vItems,pFolder,STL_SORT_FUNC);
CShCMSort *pItem=NULL;
STL_FOR_ITERATOR(vecCMSort,vItems)
{
pItem = STL_GET_CURRENT(vItems);
STL_ADD_ITEM(m_vItems,pItem);
if (GetShellPidl().ComparePidls(pFolder,pItem->GetPidl(),m_pidlMyComputer))
{
LPSHELLFOLDER pSubFolder=NULL;
HRESULT hr = pFolder->BindToObject(pItem->GetPidl(), 0, IID_IShellFolder,(LPVOID*)&pSubFolder);
if (SUCCEEDED(hr))
{
BuildFolderList(pSubFolder,pItem->GetPidl(),pidlAbsSel,nIndent+1);
pSubFolder->Release();
}
}
}
}
void CIEShellComboBox::LoadItems(LPITEMIDLIST pidlAbsSel)
{
if (m_hImageList)
::SendMessage(GetSafeHwnd(), CBEM_SETIMAGELIST, 0, (LPARAM)m_hImageList);
GetComboBoxCtrl()->ResetContent();
DeleteAllItemData();
CShCMSort *pItem=NULL;
int nCount = GetShellPidl().GetCount(pidlAbsSel);
LPITEMIDLIST pidlCompare=NULL;
int nSelItem=-1;
int nItem=0;
int n=0;
int nIndent=0;
CString sPath;
STL_FOR_ITERATOR(vecCMSort,m_vItems)
{
pItem = STL_GET_CURRENT(m_vItems);
nItem = AddItem(pItem);
nIndent = pItem->GetIndent();
if (nIndent == 0)
nIndent = 1;
// TRACE2("Getting pidl %d of %u\n",nIndent,nCount);
pidlCompare=GetShellPidl().CopyItemID(pidlAbsSel,nIndent);
// Desktop item
if (nCount == 0 && n == 0)
{
nSelItem = 0;
sPath = pItem->GetText();
}
else if (nCount == 1 && GetShellPidl().ComparePidls(NULL,pItem->GetPidl(),pidlAbsSel) == true)
{
nSelItem = nItem;
sPath = pItem->GetText();
}
else if (GetShellPidl().CompareMemPidls(pItem->GetPidl(),pidlCompare) == true
&& GetShellPidl().CompareMemPidls(pItem->GetPidl(),m_pidlMyComputer) == false)
{
LPITEMIDLIST pidlAbs=NULL;
CString sDisplayName;
CShCMSort Item;
int nImage=0;
int nSelImage=0;
for(int i=nIndent+1;i < (nCount+1);i++)
{
pidlAbs = GetShellPidl().CopyAbsItemID(pidlAbsSel,i);
if (pidlAbs)
{
GetShellPidl().SHPidlToPathEx(pidlAbs,sPath,NULL);
GetShellPidl().GetDisplayName(pidlAbs,sDisplayName);
GetShellPidl().GetNormalAndSelectedIcons(pidlAbs,nImage,nSelImage);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -