📄 shlview.cpp
字号:
/******************************************************************
*
* Project.....: Windows View (Namespace Extension)
*
* Application.: WINVIEW.dll
* Module......: ShlView.cpp
* Description.: IShellView implementation
*
* Compiler....: MS Visual C++
* Written by..: D. Esposito
*
* Environment.: Windows 9x/NT
*
*******************************/
/*---------------------------------------------------------------*/
// INCLUDE section
/*---------------------------------------------------------------*/
#include "ShlView.h"
#include "Guid.h"
#include "resource.h"
#include "EnumProc.h"
/*---------------------------------------------------------------*/
// Constructor and destructor
/*---------------------------------------------------------------*/
#pragma comment( lib, "comctl32.lib" )
CShellView::CShellView( CShellFolder *pFolder, LPCITEMIDLIST pidl )
{
// init common controls
INITCOMMONCONTROLSEX iccex;
iccex.dwSize = sizeof(INITCOMMONCONTROLSEX);
iccex.dwICC = ICC_LISTVIEW_CLASSES;
InitCommonControlsEx(&iccex);
m_hMenu = NULL;
// get the PIDL manager
m_pPidlMgr = new CPidlMgr();
if( !m_pPidlMgr )
{
delete this;
return;
}
m_pSFParent = pFolder;
if( m_pSFParent )
m_pSFParent->AddRef();
// get the shell's memory manager
if( FAILED(SHGetMalloc(&m_pMalloc)) )
{
delete this;
return;
}
// other settings
m_pidl = m_pPidlMgr->Copy(pidl);
m_uState = SVUIA_DEACTIVATE;
m_ObjRefCount = 1;
g_DllRefCount++;
}
CShellView::~CShellView()
{
if( m_pidl )
{
m_pPidlMgr->Delete( m_pidl );
m_pidl = NULL;
}
if( m_pSFParent )
m_pSFParent->Release();
if( m_pMalloc )
m_pMalloc->Release();
if( m_pPidlMgr )
delete m_pPidlMgr;
g_DllRefCount--;
}
/*---------------------------------------------------------------*/
// IUnknown methods
/*---------------------------------------------------------------*/
STDMETHODIMP CShellView::QueryInterface( REFIID riid, LPVOID *ppReturn )
{
*ppReturn = NULL;
if(IsEqualIID(riid, IID_IUnknown))
*ppReturn = this;
else
if(IsEqualIID(riid, IID_IOleWindow))
*ppReturn = (IOleWindow*)this;
else
if(IsEqualIID(riid, IID_IOleCommandTarget))
*ppReturn = (IOleCommandTarget*)this;
else
if(IsEqualIID(riid, IID_IShellView))
*ppReturn = (IShellView*)this;
if( *ppReturn )
{
LPUNKNOWN pUnk = (LPUNKNOWN)(*ppReturn);
pUnk->AddRef();
return S_OK;
}
return E_NOINTERFACE;
}
STDMETHODIMP_(DWORD) CShellView::AddRef()
{
return ++m_ObjRefCount;
}
STDMETHODIMP_(DWORD) CShellView::Release()
{
if(--m_ObjRefCount == 0)
{
delete this;
return 0;
}
return m_ObjRefCount;
}
/*---------------------------------------------------------------*/
// IOleWindow methods
/*---------------------------------------------------------------*/
STDMETHODIMP CShellView::GetWindow(HWND *phWnd)
{
*phWnd = m_hWnd;
return S_OK;
}
STDMETHODIMP CShellView::ContextSensitiveHelp(BOOL fEnterMode)
{
return E_NOTIMPL;
}
/*---------------------------------------------------------------*/
// IOleCommandTarget methods
/*---------------------------------------------------------------*/
STDMETHODIMP CShellView::QueryStatus( const GUID *pguidCmdGroup,
ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText )
{
// our command group only
if( pguidCmdGroup && (*pguidCmdGroup != CLSID_CmdGrp) )
return OLECMDERR_E_UNKNOWNGROUP;
if(!prgCmds)
return E_POINTER;
// return info for all of the commands
for( UINT i=0; i < cCmds; i++ )
{
switch( prgCmds[i].cmdID )
{
case IDM_WIN_PROCESS:
case IDM_WIN_PROPERTIES:
prgCmds[i].cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
break;
}
}
return S_OK;
}
STDMETHODIMP CShellView::Exec( const GUID *pguidCmdGroup,
DWORD nCmdID, DWORD nCmdExecOpt, VARIANTARG *pvaIn,
VARIANTARG *pvaOut)
{
// our command group only
if( pguidCmdGroup && (*pguidCmdGroup == CLSID_CmdGrp) )
{
OnCommand( nCmdID, 0, NULL );
return S_OK;
}
return OLECMDERR_E_UNKNOWNGROUP;
}
/*---------------------------------------------------------------*/
// IShellView methods
/*---------------------------------------------------------------*/
// TranslateAccelerator
STDMETHODIMP CShellView::TranslateAccelerator( LPMSG pMsg )
{
return E_NOTIMPL;
}
// EnableModeless
STDMETHODIMP CShellView::EnableModeless( BOOL fEnable )
{
return E_NOTIMPL;
}
// Refresh
STDMETHODIMP CShellView::Refresh( VOID )
{
ListView_DeleteAllItems(m_hwndList);
FillList();
return S_OK;
}
// UIActivate
STDMETHODIMP CShellView::UIActivate(UINT uState)
{
// Exit if the state hasn't changed since last time
if(m_uState == uState)
return S_OK;
// Modify the menu
OnActivate(uState);
// Modify the status bar
if(uState != SVUIA_DEACTIVATE)
{
TCHAR szName[MAX_PATH] = {0};
// Add more parts if needed... as is, it's equivalent to SB_SIMPLE
int aParts[1] = {-1};
// Set the number of parts
m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETPARTS, 1,
reinterpret_cast<LPARAM>(aParts), NULL);
m_pPidlMgr->GetPidlPath(m_pidl, szName);
m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXT, 0,
reinterpret_cast<LPARAM>(szName), NULL);
}
return S_OK;
}
// CreateViewWindow
STDMETHODIMP CShellView::CreateViewWindow( LPSHELLVIEW pPrevView,
LPCFOLDERSETTINGS lpfs, LPSHELLBROWSER psb, LPRECT prcView,
HWND *phWnd )
{
WNDCLASS wc;
*phWnd = NULL;
// register the class
if( !GetClassInfo(g_hInst, NS_CLASS_NAME, &wc) )
{
ZeroMemory( &wc, sizeof(WNDCLASS) );
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = g_hInst;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = NS_CLASS_NAME;
if( !RegisterClass(&wc) )
return E_FAIL;
}
// set up the member variables
m_pShellBrowser = psb;
m_FolderSettings = *lpfs;
// get the parent window
m_pShellBrowser->GetWindow( &m_hwndParent );
// create the window, parent of the listview
*phWnd = CreateWindowEx( 0, NS_CLASS_NAME, NULL,
WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS,
prcView->left, prcView->top,
prcView->right - prcView->left,
prcView->bottom - prcView->top,
m_hwndParent, NULL, g_hInst, this );
if( !*phWnd )
return E_FAIL;
m_pShellBrowser->AddRef();
return S_OK;
}
// DestroyViewWindow
STDMETHODIMP CShellView::DestroyViewWindow( VOID )
{
// clean up the UI
UIActivate( SVUIA_DEACTIVATE );
if( m_hMenu )
DestroyMenu(m_hMenu);
DestroyWindow( m_hWnd );
m_pShellBrowser->Release();
return S_OK;
}
// GetCurrentInfo
STDMETHODIMP CShellView::GetCurrentInfo( LPFOLDERSETTINGS lpfs )
{
*lpfs = m_FolderSettings;
return S_OK;
}
// AddPropertySheetPages
STDMETHODIMP CShellView::AddPropertySheetPages( DWORD dwReserved,
LPFNADDPROPSHEETPAGE lpfn, LPARAM lParam )
{
return E_NOTIMPL;
}
// SaveViewState
STDMETHODIMP CShellView::SaveViewState( VOID )
{
return E_NOTIMPL;
}
// SelectItem
STDMETHODIMP CShellView::SelectItem( LPCITEMIDLIST pidl, UINT u )
{
return E_NOTIMPL;
}
// GetItemObject
STDMETHODIMP CShellView::GetItemObject( UINT, REFIID, LPVOID* )
{
return E_NOTIMPL;
}
/*---------------------------------------------------------------*/
// Private Class Members
/*---------------------------------------------------------------*/
// OnActivate
LRESULT CShellView::OnActivate(UINT uState)
{
// Has state changed since the last time we were called?
if(m_uState == uState)
return S_OK;
// Destroy all our previous changes to the menu
OnDeactivate();
// If active...
if(uState != SVUIA_DEACTIVATE)
{
// Step 1: create a new menu
m_hMenu = CreateMenu();
if(m_hMenu)
{
// Step 2: Share it with the shell through a menu group descriptor
OLEMENUGROUPWIDTHS omw = {0, 0, 0, 0, 0, 0};
m_pShellBrowser->InsertMenusSB(m_hMenu, &omw);
// Step 3: Change the menu
// Step 3.1: Build and insert the 'Windows View' top level menu
TCHAR szText[MAX_PATH] = {0};
LoadString(g_hInst, IDS_MI_WINVIEW, szText, MAX_PATH);
MENUITEMINFO mii;
ZeroMemory(&mii, sizeof(MENUITEMINFO));
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_STATE;
mii.fType = MFT_STRING;
mii.fState = MFS_ENABLED;
mii.dwTypeData = szText;
mii.hSubMenu = BuildWinViewMenu();
if(mii.hSubMenu)
InsertMenuItem(m_hMenu, FCIDM_MENU_HELP, FALSE, &mii);
// Step 3.2: Get the Help menu and merge
ZeroMemory(&mii, sizeof(MENUITEMINFO));
mii.cbSize = sizeof(MENUITEMINFO);
mii.fMask = MIIM_SUBMENU;
if(GetMenuItemInfo(m_hMenu, FCIDM_MENU_HELP, FALSE, &mii))
MergeHelpMenu(mii.hSubMenu);
// Step 3.3: Remove the Edit menu
DeleteMenu(m_hMenu, FCIDM_MENU_EDIT, MF_BYCOMMAND);
// Step 3.4: If we have the focus, add items to the File menu
if(uState == SVUIA_ACTIVATE_FOCUS)
{
// Get the File menu and merge
ZeroMemory(&mii, sizeof(MENUITEMINFO));
mii.cbSize = sizeof(MENUITEMINFO);
mii.fMask = MIIM_SUBMENU;
if(GetMenuItemInfo(m_hMenu, FCIDM_MENU_FILE, FALSE, &mii))
MergeFileMenu(mii.hSubMenu);
}
// Set the new menu
m_pShellBrowser->SetMenuSB(m_hMenu, NULL, m_hWnd);
}
}
// Save the current state
m_uState = uState;
return 0;
}
// OnDeactivate
void CShellView::OnDeactivate()
{
if(m_uState != SVUIA_DEACTIVATE)
{
if(m_hMenu)
{
m_pShellBrowser->SetMenuSB(NULL, NULL, NULL);
m_pShellBrowser->RemoveMenusSB(m_hMenu);
DestroyMenu(m_hMenu);
m_hMenu = NULL;
}
m_uState = SVUIA_DEACTIVATE;
}
}
// BuildWinViewMenu
HMENU CShellView::BuildWinViewMenu()
{
HMENU hSubMenu = CreatePopupMenu();
if(hSubMenu)
{
TCHAR szText[100] = {0};
MENUITEMINFO mii;
// Add "Properties" to "Windows View"
LoadString(g_hInst, IDS_MI_PROPERTIES, szText, 100);
ZeroMemory(&mii, sizeof(MENUITEMINFO));
mii.cbSize = sizeof(MENUITEMINFO);
mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
mii.fType = MFT_STRING;
mii.fState = MFS_ENABLED;
mii.dwTypeData = szText;
mii.wID = IDM_WIN_PROPERTIES;
// Add at the end of the menu
InsertMenuItem(hSubMenu, static_cast<UINT>(-1), TRUE, &mii);
// Add "Process View" to "Windows View"
LoadString(g_hInst, IDS_MI_PROCESSVIEW, szText, 100);
ZeroMemory(&mii, sizeof(MENUITEMINFO));
mii.cbSize = sizeof(MENUITEMINFO);
mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
mii.fType = MFT_STRING;
mii.fState = MFS_ENABLED;
mii.dwTypeData = szText;
mii.wID = IDM_WIN_PROCESS;
// Add at the end of the menu
InsertMenuItem(hSubMenu, static_cast<UINT>(-1), TRUE, &mii);
}
return hSubMenu;
}
// MergeFileMenu
void CShellView::MergeFileMenu( HMENU hSubMenu )
{
if( hSubMenu )
{
MENUITEMINFO mii;
CHAR szText[MAX_PATH];
ZeroMemory( &mii, sizeof(MENUITEMINFO) );
// add "Process View"
LoadString(g_hInst, IDS_MI_PROCESSVIEW, szText, 20 );
mii.cbSize = sizeof(MENUITEMINFO);
mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
mii.fType = MFT_STRING;
mii.fState = MFS_ENABLED;
mii.dwTypeData = szText;
mii.wID = IDM_WIN_PROCESS;
InsertMenuItem( hSubMenu, 0, TRUE, &mii );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -