📄 shellview.cpp
字号:
//
// ShellView.cpp
//
#define INC_OLE2
#include <Windows.h>
#include <WinDef.h>
#include <shlobj.h>
#include <tchar.h>
#include <Time.h>
#include <ShlWapi.h>
#include "ShellFolder.h"
#include "ShellView.h"
#include "EnumIDL.h"
#include "resource.h"
extern HINSTANCE g_hInstance;
extern UINT g_uiRefThisDll;
extern HIMAGELIST g_hImageListSmall;
extern HIMAGELIST g_hImageListLarge;
NS_TOOLBUTTONINFO g_tbInfo[] =
{
INTHIS_DLL, {0, ID_FILEPOPUPMENU_FOLDER, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0 },
STD, {STD_FILENEW, ID_FILEPOPUPMENU_FILE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0 },
STD, {0, 0, 0, TBSTYLE_SEP, 0, 0 },
STD, {STD_PROPERTIES, ID_VIEWPOPUP_PROPERTIES, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0 },
STD, {0, 0, 0, TBSTYLE_SEP, 0, 0 },
VIEW,{ VIEW_LARGEICONS, ID_VIEWPOPUP_LARGEICONS, TBSTATE_ENABLED, TBSTYLE_CHECKGROUP, 0, 0 },
VIEW,{ VIEW_SMALLICONS, ID_VIEWPOPUP_SMALLICONS, TBSTATE_ENABLED, TBSTYLE_CHECKGROUP, 0, 0 },
VIEW,{ VIEW_LIST, ID_VIEWPOPUP_LIST, TBSTATE_ENABLED, TBSTYLE_CHECKGROUP, 0, 0 },
VIEW,{ VIEW_DETAILS, ID_VIEWPOPUP_DETAILS, TBSTATE_ENABLED, TBSTYLE_CHECKGROUP, 0, 0 },
VIEW,{ -1, -1, -1, -1, -1, -1 }
};
CShellView::CShellView(CShellFolder *pFolder,
LPCITEMIDLIST pidl)
{
if(FAILED(SHGetMalloc(&m_pMalloc)))
{
// Raise an exception too
delete this;
return;
}
InitCommonControls();
m_dwRefCount = 1;
g_uiRefThisDll++;
m_hWndListCtrl = NULL;
m_hMenu = NULL;
m_pSF = pFolder;
m_hWnd = NULL;
m_hWndParent = NULL;
m_pPidlMgr = new CPidlMgr;
m_pidl = m_pPidlMgr->Copy(pidl);
}
CShellView::~CShellView()
{
g_uiRefThisDll--;
}
///////////////////////////////////////////////////////////////////////////
// IUnknown Implementation
STDMETHODIMP CShellView::QueryInterface(REFIID riid, LPVOID *ppReturn)
{
*ppReturn = NULL;
//IUnknown
if(IsEqualIID(riid, IID_IUnknown))
{
*ppReturn = this;
}
//IOleWindow
else if(IsEqualIID(riid, IID_IOleWindow))
{
*ppReturn = (IOleWindow*)this;
}
//IShellView
else if(IsEqualIID(riid, IID_IShellView))
{
*ppReturn = (IShellView *)this;
}
if(*ppReturn)
{
(*(LPUNKNOWN*)ppReturn)->AddRef();
return S_OK;
}
return E_NOINTERFACE;
}
STDMETHODIMP_(DWORD) CShellView::AddRef()
{
return ++m_dwRefCount;
}
STDMETHODIMP_(DWORD) CShellView::Release()
{
if(--m_dwRefCount == 0)
{
delete this;
return 0;
}
return m_dwRefCount;
}
///////////////////////////////////////////////////////////////////////////
// IOleWindow Implementation
STDMETHODIMP CShellView::GetWindow(HWND *phWnd)
{
*phWnd = m_hWnd;
return S_OK;
}
STDMETHODIMP CShellView::ContextSensitiveHelp(BOOL fEnterMode)
{
return E_NOTIMPL;
}
///////////////////////////////////////////////////////////////////////////
// IShellView Implementation
STDMETHODIMP CShellView::TranslateAccelerator(LPMSG pMsg)
{
return E_NOTIMPL;
}
STDMETHODIMP CShellView::EnableModeless(BOOL fEnable)
{
return E_NOTIMPL;
}
STDMETHODIMP CShellView::UIActivate(UINT uiState)
{
if (m_uiState == uiState)
{
return S_OK;
}
onActivate(uiState);
if(uiState != SVUIA_DEACTIVATE)
{
LRESULT lResult;
int nPartArray[] = {100, -1};
TCHAR szText[MAX_PATH];
int nCount = ListView_GetItemCount(m_hWndListCtrl);
wsprintf(szText, "%d item%s", nCount, nCount > 1 ? "s" : "");
m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETPARTS, 2,
(LPARAM)nPartArray, &lResult);
m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXT, 0,
(LPARAM)szText, &lResult);
m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXT, 1,
(LPARAM)"", &lResult);
}
return S_OK;
}
STDMETHODIMP CShellView::Refresh(void)
{
ListView_DeleteAllItems(m_hWndListCtrl);
refreshListCtrl();
return S_OK;
}
STDMETHODIMP CShellView::CreateViewWindow(LPSHELLVIEW pPrevView,
LPCFOLDERSETTINGS lpfs,
LPSHELLBROWSER psb,
LPRECT prcView,
HWND *phWnd)
{
WNDCLASS wc = { 0 };
*phWnd = NULL;
// Register the class once
if(!GetClassInfo(g_hInstance, NAMESPACEVIEW_CLASS, &wc))
{
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC) nameSpaceWndProc;
wc.cbClsExtra = NULL;
wc.cbWndExtra = NULL;
wc.hInstance = g_hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = NAMESPACEVIEW_CLASS;
if (RegisterClass(&wc) == 0)
{
return E_FAIL;
}
}
// Store the browser pointer
m_pShellBrowser = psb;
m_pShellBrowser->AddRef();
m_fsFolderSettings = *lpfs;
m_pShellBrowser->GetWindow(&m_hWndParent);
*phWnd = CreateWindowEx(0, NAMESPACEVIEW_CLASS,
NULL,
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS,
prcView->left, prcView->top,
prcView->right - prcView->left,
prcView->bottom - prcView->top,
m_hWndParent,
NULL,
g_hInstance,
(LPVOID) this);
if(NULL == *phWnd)
{
return E_FAIL;
}
mergeToolBars();
return S_OK;
}
STDMETHODIMP CShellView::DestroyViewWindow(void)
{
RevokeDragDrop(m_hWndListCtrl);
DestroyWindow(m_hWndListCtrl);
UIActivate(SVUIA_DEACTIVATE);
DestroyWindow(m_hWnd);
m_pShellBrowser->Release();
return S_OK;
}
STDMETHODIMP CShellView::GetCurrentInfo(LPFOLDERSETTINGS lpfs)
{
*lpfs = m_fsFolderSettings;
return S_OK;
}
STDMETHODIMP CShellView::AddPropertySheetPages( DWORD dwReserved,
LPFNADDPROPSHEETPAGE lpfn,
LPARAM lParam)
{
return E_NOTIMPL;
}
STDMETHODIMP CShellView::SaveViewState(void)
{
return E_NOTIMPL;
}
STDMETHODIMP CShellView::SelectItem(LPCITEMIDLIST pidlItem, UINT uFlags)
{
return E_NOTIMPL;
}
STDMETHODIMP CShellView::GetItemObject(UINT uItem, REFIID riid,
LPVOID *ppvOut)
{
*ppvOut = NULL;
return E_NOTIMPL;
}
LRESULT CALLBACK CShellView::nameSpaceWndProc(HWND hWnd,
UINT uiMsg, WPARAM wParam,
LPARAM lParam)
{
CShellView *pThis = (CShellView*) GetWindowLong(hWnd, GWL_USERDATA);
switch (uiMsg)
{
case WM_NCCREATE:
{
LPCREATESTRUCT lpcs = (LPCREATESTRUCT) lParam;
pThis = (CShellView*) (lpcs->lpCreateParams);
SetWindowLong(hWnd, GWL_USERDATA, (LONG)pThis);
//set the window handle
pThis->m_hWnd = hWnd;
}
break;
case WM_CREATE:
return pThis->onCreate();
case WM_ERASEBKGND:
return pThis->onEraseBkGnd((HDC) wParam);
case WM_SIZE:
return pThis->onSize(LOWORD(lParam), HIWORD(lParam));
case WM_NOTIFY:
return pThis->onNotify((UINT)wParam, (LPNMHDR)lParam);
case WM_COMMAND:
return pThis->onCommand((HWND) lParam, HIWORD(wParam), LOWORD(wParam));
case WM_SETFOCUS:
return pThis->onSetFocus((HWND) wParam);
case WM_CONTEXTMENU:
return pThis->onContextMenu(LOWORD(lParam), HIWORD(lParam), FALSE);
}
return DefWindowProc(hWnd, uiMsg, wParam, lParam);
}
///////////////////////////////////////////////////////////
// Message Handlers
long CShellView::onEraseBkGnd(HDC hDC)
{
return 1L;
}
LRESULT CShellView::onSize(WORD nCx, WORD nCy)
{
if(::IsWindow(m_hWndListCtrl))
{
MoveWindow(m_hWndListCtrl, 0, 0, nCx, nCy, FALSE);
}
return 0;
}
LRESULT CShellView::onNotify(UINT CtlID, LPNMHDR lpnmh)
{
switch(lpnmh->code)
{
case NM_DBLCLK:
case NM_RETURN:
// TODO : Handler default action...
return 0;
case LVN_GETDISPINFO:
{
// TODO : Set Display Info
LV_DISPINFO *lpdi = (LV_DISPINFO *)lpnmh;
return 0;
}
case NM_RCLICK:
{
LV_DISPINFO *lpdi = (LV_DISPINFO *)lpnmh;
// TODO : Show context menu for the view
return 0;
}
return 0;
case LVN_BEGINDRAG:
{
return 0;
}
case LVN_ITEMCHANGED:
{
NMLISTVIEW *pNMLV = (NMLISTVIEW *) lpnmh;
selChange(pNMLV);
}
}
return 0;
}
void CShellView::selChange(NMLISTVIEW *pNMLV)
{
int nSel = ListView_GetSelectedCount(m_hWndListCtrl);
if (nSel > 0)
{
TCHAR szText[MAX_PATH];
wsprintf(szText, "%d item%s selected.", nSel, nSel > 1 ? "s" : "");
LRESULT lResult;
m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXT, 0, (LPARAM)szText, &lResult);
int nItem = -1;
LONGLONG llTotal = 0;
while ((nItem = ListView_GetNextItem(m_hWndListCtrl, nItem, LVNI_SELECTED)) != -1)
{
LVITEM lvi = { 0 };
lvi.mask = LVIF_PARAM;
lvi.iItem = nItem;
ListView_GetItem(m_hWndListCtrl, &lvi);
LPITEMIDLIST pidl = (LPITEMIDLIST)lvi.lParam;
LPMYPIDLDATA pData = m_pPidlMgr->GetDataPointer(pidl);
if (pData)
{
LONGLONG ll = pData->dwSizeHigh;
ll <<= 32;
ll |= pData->dwSizeLow;
llTotal += ll;
}
}
if (llTotal)
{
TCHAR szTemp[MAX_PATH];
WCHAR szwTemp[_MAX_PATH];
StrFormatByteSizeW(llTotal, szwTemp,_MAX_PATH);
WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK,
szwTemp, -1, szTemp, _MAX_PATH, NULL, NULL);
TCHAR szTemp2[_MAX_PATH];
wsprintf(szTemp2, "%s", szTemp);
m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXT, 1, (LPARAM)szTemp2, &lResult);
}
else
{
m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXT, 1, (LPARAM)"", &lResult);
}
}
}
#define ID_LISTVIEW 1001
#define LISTVIEW_STYLES (WS_CHILD|WS_BORDER|WS_VISIBLE|LVS_SHAREIMAGELISTS)
LRESULT CShellView::onCreate(void)
{
DWORD dwStyle = LISTVIEW_STYLES;
switch (m_fsFolderSettings.ViewMode)
{
case FVM_ICON:
dwStyle |= LVS_ICON|LVS_AUTOARRANGE;
break;
case FVM_SMALLICON:
dwStyle |= LVS_SMALLICON|LVS_AUTOARRANGE;
break;
case FVM_LIST:
dwStyle |= LVS_LIST|LVS_AUTOARRANGE;
break;
case FVM_DETAILS:
dwStyle |= LVS_REPORT|LVS_AUTOARRANGE;
break;
}
m_hWndListCtrl = CreateWindowEx(WS_EX_CLIENTEDGE, WC_LISTVIEW, NULL,
dwStyle, 0, 0, 0, 0,
m_hWnd, (HMENU)ID_LISTVIEW, g_hInstance,
NULL);
ShowWindow(m_hWndListCtrl, SW_SHOW);
InvalidateRect(m_hWndListCtrl, NULL, TRUE);
UpdateWindow(m_hWndListCtrl);
initListCtrl();
refreshListCtrl();
LPDROPTARGET pDropTarget = NULL;
HRESULT hr = m_pSF->CreateViewObject(m_hWndListCtrl, IID_IDropTarget, (LPVOID *) &pDropTarget);
if (SUCCEEDED(hr))
{
RegisterDragDrop(m_hWndListCtrl, pDropTarget);
}
// TODO : Add code to create a window / list view control here
return S_OK;
}
void CShellView::initListCtrl()
{
ListView_SetImageList(m_hWndListCtrl, g_hImageListSmall, LVSIL_SMALL);
ListView_SetImageList(m_hWndListCtrl, g_hImageListLarge, LVSIL_NORMAL);
// TODO : Add extra initialization code here
}
void CShellView::refreshListCtrl()
{
if (::IsWindow(m_hWndListCtrl) == FALSE)
{
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -