440 lines
13 KiB
C++
440 lines
13 KiB
C++
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Microsoft Windows
|
||
|
//
|
||
|
// Copyright (C) Microsoft Corporation, 1999 - 1999
|
||
|
//
|
||
|
// File: DsplMgr2.cpp
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
// DsplMgr2.cpp : Implementation of CDsplMgr2
|
||
|
#include "stdafx.h"
|
||
|
#include "displ2.h"
|
||
|
#include "DsplMgr2.h"
|
||
|
|
||
|
extern HINSTANCE g_hinst; // in displ2.cpp
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// CDsplMgr2
|
||
|
|
||
|
CDsplMgr2::CDsplMgr2()
|
||
|
{
|
||
|
m_lpIConsole = NULL;
|
||
|
m_lpIConsoleNameSpace = NULL;
|
||
|
m_lpIImageList = NULL;
|
||
|
m_ViewMode = LVS_ICON; // default (if not persisting)
|
||
|
m_pComponent = NULL;
|
||
|
m_rootscopeitem = NULL;
|
||
|
m_WallPaperNodeID = (HSCOPEITEM)0; // unexpanded
|
||
|
m_toggle = FALSE;
|
||
|
m_bPreload = FALSE;
|
||
|
}
|
||
|
CDsplMgr2::~CDsplMgr2()
|
||
|
{
|
||
|
_ASSERT (m_lpIConsole == NULL);
|
||
|
_ASSERT (m_lpIConsoleNameSpace == NULL);
|
||
|
_ASSERT (m_lpIImageList == NULL);
|
||
|
if(m_pComponent)
|
||
|
m_pComponent->Release ();
|
||
|
}
|
||
|
HRESULT CDsplMgr2::Initialize (LPUNKNOWN pUnknown)
|
||
|
{
|
||
|
// testing
|
||
|
// return E_FAIL;
|
||
|
// testing
|
||
|
|
||
|
if (pUnknown == NULL)
|
||
|
return E_UNEXPECTED;
|
||
|
|
||
|
_ASSERT (m_lpIConsole == NULL);
|
||
|
_ASSERT (m_lpIConsoleNameSpace == NULL);
|
||
|
|
||
|
// this is my big chance to grab IConsole and IConsoleNameSpace pointers
|
||
|
|
||
|
HRESULT hresult1 = pUnknown->QueryInterface (IID_IConsole, (void **)&m_lpIConsole);
|
||
|
_ASSERT(hresult1 == S_OK && m_lpIConsole != NULL);
|
||
|
|
||
|
HRESULT hresult2 = pUnknown->QueryInterface (IID_IConsoleNameSpace, (void **)&m_lpIConsoleNameSpace);
|
||
|
_ASSERT(hresult2 == S_OK && m_lpIConsoleNameSpace != NULL);
|
||
|
|
||
|
if (hresult1 || hresult2)
|
||
|
return E_UNEXPECTED; // we're dead
|
||
|
|
||
|
// this is where we can add our images
|
||
|
HRESULT hresult = m_lpIConsole->QueryScopeImageList(&m_lpIImageList);
|
||
|
if (m_lpIImageList) {
|
||
|
_ASSERT(hresult == S_OK);
|
||
|
|
||
|
// Load the bitmaps from the dll
|
||
|
HBITMAP hbmSmall = LoadBitmap (g_hinst, MAKEINTRESOURCE(IDB_SCOPE_16X16));
|
||
|
if (hbmSmall) {
|
||
|
hresult = m_lpIImageList->ImageListSetStrip (
|
||
|
(long*)hbmSmall,
|
||
|
(long*)hbmSmall,
|
||
|
0,
|
||
|
RGB(0,255,0));
|
||
|
_ASSERT(hresult == S_OK);
|
||
|
DeleteObject (hbmSmall);
|
||
|
}
|
||
|
}
|
||
|
return hresult;
|
||
|
}
|
||
|
HRESULT CDsplMgr2::CreateComponent (LPCOMPONENT * ppComponent)
|
||
|
{
|
||
|
//
|
||
|
// MMC asks us for a pointer to the IComponent interface
|
||
|
//
|
||
|
// For those getting up to speed with COM...
|
||
|
// If we had implemented IUnknown with its methods QueryInterface, AddRef, and Release
|
||
|
// in our CComponent class...
|
||
|
// The following line would have worked
|
||
|
//
|
||
|
// pNewSnapin = new CComponent(this);
|
||
|
//
|
||
|
// In this code we will have ATL take care of IUnknown for us and create an object
|
||
|
// in the following manner...
|
||
|
_ASSERT(ppComponent != NULL);
|
||
|
*ppComponent = NULL;
|
||
|
|
||
|
HRESULT hresult = CComObject<CComponent>::CreateInstance(&m_pComponent);
|
||
|
_ASSERT(m_pComponent != NULL);
|
||
|
if (m_pComponent) {
|
||
|
// Store IComponentData
|
||
|
// Can't have a constructor with parameters, so pass it in this way.
|
||
|
m_pComponent->SetComponentData (this);
|
||
|
|
||
|
m_pComponent->AddRef(); // bump reference count to 1 (so I can hang onto it)
|
||
|
hresult = m_pComponent->QueryInterface(IID_IComponent, reinterpret_cast<void**>(ppComponent));
|
||
|
}
|
||
|
return hresult;
|
||
|
}
|
||
|
HRESULT CDsplMgr2::Notify (LPDATAOBJECT lpDataObject, MMC_NOTIFY_TYPE event, long arg, long param)
|
||
|
{
|
||
|
HRESULT hresult = S_OK;
|
||
|
|
||
|
switch (event)
|
||
|
{
|
||
|
case MMCN_EXPAND:
|
||
|
hresult = OnExpand(lpDataObject, arg, param);
|
||
|
break;
|
||
|
|
||
|
case MMCN_PRELOAD:
|
||
|
m_rootscopeitem = (HSCOPEITEM)arg;
|
||
|
m_bPreload = TRUE;
|
||
|
myChangeIcon();
|
||
|
break;
|
||
|
|
||
|
case MMCN_DELETE:
|
||
|
case MMCN_RENAME:
|
||
|
case MMCN_SELECT:
|
||
|
case MMCN_PROPERTY_CHANGE:
|
||
|
case MMCN_REMOVE_CHILDREN:
|
||
|
case MMCN_EXPANDSYNC:
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
ATLTRACE(_T("CComponentData::Notify: unexpected event %x\n"), event);
|
||
|
_ASSERT(FALSE);
|
||
|
hresult = E_UNEXPECTED;
|
||
|
break;
|
||
|
}
|
||
|
return hresult;
|
||
|
}
|
||
|
HRESULT CDsplMgr2::Destroy ()
|
||
|
{
|
||
|
if (m_lpIConsole) {
|
||
|
m_lpIConsole->Release();
|
||
|
m_lpIConsole = NULL;
|
||
|
}
|
||
|
if (m_lpIConsoleNameSpace) {
|
||
|
m_lpIConsoleNameSpace->Release();
|
||
|
m_lpIConsoleNameSpace = NULL;
|
||
|
}
|
||
|
if (m_lpIImageList) {
|
||
|
m_lpIImageList->Release();
|
||
|
m_lpIImageList = NULL;
|
||
|
}
|
||
|
return S_OK;
|
||
|
}
|
||
|
HRESULT CDsplMgr2::QueryDataObject (long cookie, DATA_OBJECT_TYPES type, LPDATAOBJECT* ppDataObject)
|
||
|
{
|
||
|
HRESULT hresult = S_OK;
|
||
|
|
||
|
CDataObject *pdo = new CDataObject (cookie, type);
|
||
|
*ppDataObject = pdo;
|
||
|
if (pdo == NULL)
|
||
|
hresult = E_OUTOFMEMORY;
|
||
|
#ifdef DO_WE_NEED_THIS
|
||
|
else {
|
||
|
//
|
||
|
// The cookie represents a snapin manager or scope pane item.
|
||
|
//
|
||
|
// If the passed-in cookie is NULL, it is our snapins main root node folder
|
||
|
// We never needed to ask for this to be created. MMC did this for us.
|
||
|
//
|
||
|
// Else If the passed-in cookie is non-NULL, then it should be one we
|
||
|
// created when we added a node to the scope pane. See OnExpand.
|
||
|
//
|
||
|
|
||
|
if (cookie) {
|
||
|
// cookie is the lparam field that we passed in SCOPEDATAITEM
|
||
|
// used for the m_pConsoleNameSpace->InsertItem(&sdi);
|
||
|
; // pdoNew->SetCookie(cookie, CCT_SCOPE, COOKIE_IS_STATUS);
|
||
|
} else {
|
||
|
// In this case the node is our top node, and was placed there for us.
|
||
|
; // pdoNew->SetCookie(0, type, COOKIE_IS_ROOT);
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
pdo->SetPreload (m_bPreload);
|
||
|
return hresult;
|
||
|
}
|
||
|
HRESULT CDsplMgr2::GetDisplayInfo (SCOPEDATAITEM* psdi)
|
||
|
{
|
||
|
_ASSERT (psdi != NULL);
|
||
|
|
||
|
/*
|
||
|
const DWORD SDI_STR = 0x00002;
|
||
|
const DWORD SDI_IMAGE = 0x00004;
|
||
|
const DWORD SDI_OPENIMAGE = 0x00008;
|
||
|
const DWORD SDI_STATE = 0x00010;
|
||
|
const DWORD SDI_PARAM = 0x00020;
|
||
|
const DWORD SDI_CHILDREN = 0x00040;
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
// The top 4 bit of the mask determines the relative position of this item,
|
||
|
// relative to the SCOPEDATAITEM::relativeID. By default it is the parent.
|
||
|
|
||
|
// For SDI_PARENT, SCOPEDATAITEM::relativeID is the HSCOPEITEM of the parent.
|
||
|
// As you can see by the SDI_PARENT value it is a no-op. Since by default
|
||
|
// SCOPEDATAITEM::relativeID is treated as the parents ID.
|
||
|
const DWORD SDI_PARENT = 0x00000000;
|
||
|
|
||
|
// For SDI_PREVIOUS, SCOPEDATAITEM::relativeID is the HSCOPEITEM of the previous sibling
|
||
|
const DWORD SDI_PREVIOUS = 0x10000000;
|
||
|
|
||
|
// For SDI_NEXT, SCOPEDATAITEM::relativeID is the HSCOPEITEM of the next sibling.
|
||
|
const DWORD SDI_NEXT = 0x20000000;
|
||
|
|
||
|
// For SDI_PARENT, bit 27 determines whether the item is to be inserted as the
|
||
|
// first child. By default this item will inserted as the last child.
|
||
|
const DWORD SDI_FIRST = 0x08000000;
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
typedef struct _SCOPEDATAITEM
|
||
|
{
|
||
|
DWORD mask;
|
||
|
LPOLESTR displayname;
|
||
|
int nImage;
|
||
|
int nOpenImage;
|
||
|
UINT nState;
|
||
|
int cChildren;
|
||
|
LPARAM lParam;
|
||
|
HSCOPEITEM relativeID;
|
||
|
HSCOPEITEM ID;
|
||
|
} SCOPEDATAITEM;
|
||
|
|
||
|
typedef SCOPEDATAITEM* LPSCOPEDATAITEM;
|
||
|
|
||
|
typedef enum _MMC_SCOPE_ITEM_STATE
|
||
|
{
|
||
|
MMC_SCOPE_ITEM_STATE_NORMAL = 0x0001, // Not bold. To set or get.
|
||
|
MMC_SCOPE_ITEM_STATE_BOLD = 0x0002, // To set or get.
|
||
|
MMC_SCOPE_ITEM_STATE_EXPANDEDONCE = 0x0003, // Only to get.
|
||
|
|
||
|
} MMC_SCOPE_ITEM_STATE;
|
||
|
*/
|
||
|
|
||
|
if (psdi) {
|
||
|
if(psdi->mask & SDI_STR) {
|
||
|
switch (psdi->lParam) {
|
||
|
case DISPLAY_MANAGER_WALLPAPER:
|
||
|
if (m_toggle)
|
||
|
psdi->displayname = (LPOLESTR)L"Renamed Wallpaper";
|
||
|
else
|
||
|
psdi->displayname = (LPOLESTR)L"Wallpaper";
|
||
|
break;
|
||
|
case DISPLAY_MANAGER_PATTERN:
|
||
|
psdi->displayname = (LPOLESTR)L"Pattern";
|
||
|
break;
|
||
|
case DISPLAY_MANAGER_PATTERN_CHILD:
|
||
|
psdi->displayname = (LPOLESTR)L"Pattern test child";
|
||
|
break;
|
||
|
default:
|
||
|
psdi->displayname = (LPOLESTR)L"Hey! You shouldn't see this!";
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return S_OK;
|
||
|
}
|
||
|
HRESULT CDsplMgr2::CompareObjects (LPDATAOBJECT lpDataObjectA, LPDATAOBJECT lpDataObjectB)
|
||
|
{ return !S_OK; }
|
||
|
|
||
|
HRESULT CDsplMgr2::OnExpand(LPDATAOBJECT pDataObject, long arg, long param)
|
||
|
{
|
||
|
_ASSERT(m_lpIConsoleNameSpace != NULL); // make sure we QI'ed for the interface
|
||
|
_ASSERT(pDataObject != NULL);
|
||
|
|
||
|
if (arg == TRUE) { // expanding, FALSE => contracting
|
||
|
CDataObject *pdo = (CDataObject *)pDataObject; // TODO: hmm....
|
||
|
|
||
|
// the code below makes sure that we're dealing only with the root node
|
||
|
if (pdo->GetCookie () == 0) { // 0 == root
|
||
|
// hang onto to root HSCOPEITEM (param) for later
|
||
|
m_rootscopeitem = (HSCOPEITEM)param;
|
||
|
|
||
|
// Place our folder(s) into the scope pane
|
||
|
SCOPEDATAITEM sdi;
|
||
|
ZeroMemory(&sdi, sizeof(sdi));
|
||
|
sdi.mask = SDI_STR | // displayname is valid
|
||
|
SDI_PARAM | // lParam is valid
|
||
|
SDI_IMAGE | // nImage is valid
|
||
|
SDI_OPENIMAGE | // nOpenImage is valid
|
||
|
SDI_PARENT;
|
||
|
sdi.relativeID = (HSCOPEITEM) param;
|
||
|
sdi.nImage = 0;
|
||
|
sdi.nOpenImage = 1;
|
||
|
sdi.displayname = MMC_CALLBACK;
|
||
|
|
||
|
sdi.lParam = (LPARAM) DISPLAY_MANAGER_WALLPAPER;
|
||
|
m_lpIConsoleNameSpace->InsertItem(&sdi);
|
||
|
|
||
|
m_WallPaperNodeID = sdi.ID;
|
||
|
|
||
|
sdi.lParam = (LPARAM) DISPLAY_MANAGER_PATTERN;
|
||
|
return m_lpIConsoleNameSpace->InsertItem(&sdi);
|
||
|
}
|
||
|
if (pdo->GetCookie () == DISPLAY_MANAGER_PATTERN) {
|
||
|
// add another node, so I can test deleteitem stuff
|
||
|
|
||
|
// hang onto to root HSCOPEITEM (param) for later
|
||
|
m_patternscopeitem = (HSCOPEITEM)param;
|
||
|
|
||
|
// Place our folder into the scope pane
|
||
|
SCOPEDATAITEM sdi;
|
||
|
ZeroMemory(&sdi, sizeof(sdi));
|
||
|
sdi.mask = SDI_STR | // displayname is valid
|
||
|
SDI_PARAM | // lParam is valid
|
||
|
SDI_IMAGE | // nImage is valid
|
||
|
SDI_OPENIMAGE | // nOpenImage is valid
|
||
|
SDI_PARENT;
|
||
|
sdi.relativeID = (HSCOPEITEM) param;
|
||
|
sdi.nImage = 0;
|
||
|
sdi.nOpenImage = 1;
|
||
|
sdi.displayname = MMC_CALLBACK;
|
||
|
|
||
|
sdi.lParam = (LPARAM) DISPLAY_MANAGER_PATTERN_CHILD;
|
||
|
return m_lpIConsoleNameSpace->InsertItem(&sdi);
|
||
|
}
|
||
|
}
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
//// IPersistStream interface members
|
||
|
STDMETHODIMP CDsplMgr2::GetClassID (CLSID *pClassID)
|
||
|
{
|
||
|
if (pClassID) {
|
||
|
*pClassID = CLSID_DsplMgr2;
|
||
|
return S_OK;
|
||
|
}
|
||
|
return E_POINTER;
|
||
|
}
|
||
|
|
||
|
HRESULT CDsplMgr2::IsDirty ()
|
||
|
{
|
||
|
// get current ViewMode and compare against my value
|
||
|
if (m_pComponent == NULL)
|
||
|
return S_FALSE;
|
||
|
long vm = m_pComponent->GetViewMode ();
|
||
|
if (m_ViewMode == vm)
|
||
|
return S_FALSE;
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
HRESULT CDsplMgr2::Load (IStream *pStream)
|
||
|
{
|
||
|
// testing
|
||
|
// return E_FAIL;
|
||
|
// testing
|
||
|
|
||
|
_ASSERT (pStream);
|
||
|
|
||
|
// we have a long specifying ViewMode (LVS_ICON, LVS_REPORT, etc.)
|
||
|
return pStream->Read (&m_ViewMode, sizeof(long), NULL);
|
||
|
}
|
||
|
|
||
|
HRESULT CDsplMgr2::Save (IStream *pStream, BOOL fClearDirty)
|
||
|
{
|
||
|
_ASSERT (pStream);
|
||
|
|
||
|
if (m_pComponent) // get current value
|
||
|
m_ViewMode = m_pComponent->GetViewMode ();
|
||
|
|
||
|
// write ViewMode
|
||
|
HRESULT hr = pStream->Write (&m_ViewMode, sizeof(long), NULL);
|
||
|
return hr == S_OK ? S_OK : STG_E_CANTSAVE;
|
||
|
}
|
||
|
|
||
|
HRESULT CDsplMgr2::GetSizeMax (ULARGE_INTEGER *pcbSize)
|
||
|
{
|
||
|
_ASSERT (pcbSize);
|
||
|
ULISet32 (*pcbSize, sizeof(long));
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
// other public stuff
|
||
|
void CDsplMgr2::myRenameItem (HSCOPEITEM hsi, LPOLESTR szName)
|
||
|
{
|
||
|
if (m_toggle)
|
||
|
m_toggle = FALSE;
|
||
|
else
|
||
|
m_toggle = TRUE;
|
||
|
|
||
|
SCOPEDATAITEM item;
|
||
|
ZeroMemory (&item, sizeof(SCOPEDATAITEM));
|
||
|
item.mask = SDI_STR;
|
||
|
item.displayname = MMC_CALLBACK;
|
||
|
item.ID = hsi;
|
||
|
|
||
|
m_lpIConsoleNameSpace->SetItem (&item);
|
||
|
}
|
||
|
|
||
|
void CDsplMgr2::myChangeIcon (void)
|
||
|
{
|
||
|
_ASSERT (m_lpIImageList != NULL);
|
||
|
_ASSERT (m_rootscopeitem != NULL); // shoulda been selected by now.
|
||
|
|
||
|
HBITMAP hbmSmall = LoadBitmap (g_hinst, MAKEINTRESOURCE(IDB_SCOPE_16X16_CUSTOM));
|
||
|
if (!hbmSmall)
|
||
|
return;
|
||
|
HRESULT hr = m_lpIImageList->ImageListSetStrip (
|
||
|
(long*)hbmSmall,
|
||
|
(long*)hbmSmall,
|
||
|
0,
|
||
|
RGB(0,255,0));
|
||
|
_ASSERT (hr == S_OK);
|
||
|
DeleteObject (hbmSmall);
|
||
|
|
||
|
SCOPEDATAITEM item;
|
||
|
ZeroMemory (&item, sizeof(SCOPEDATAITEM));
|
||
|
item.mask = SDI_IMAGE | SDI_OPENIMAGE;
|
||
|
item.nImage = 0; // (int)MMC_CALLBACK;
|
||
|
item.nOpenImage = 1; // (int)MMC_CALLBACK;
|
||
|
item.ID = m_rootscopeitem;
|
||
|
|
||
|
m_lpIConsoleNameSpace->SetItem (&item);
|
||
|
}
|
||
|
void CDsplMgr2::myPreLoad (void)
|
||
|
{
|
||
|
// toggle state
|
||
|
if (m_bPreload == TRUE)
|
||
|
m_bPreload = FALSE;
|
||
|
else
|
||
|
m_bPreload = TRUE;
|
||
|
}
|