Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

439 lines
13 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1999 - 1999
  6. //
  7. // File: DsplMgr2.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. // DsplMgr2.cpp : Implementation of CDsplMgr2
  11. #include "stdafx.h"
  12. #include "displ2.h"
  13. #include "DsplMgr2.h"
  14. extern HINSTANCE g_hinst; // in displ2.cpp
  15. /////////////////////////////////////////////////////////////////////////////
  16. // CDsplMgr2
  17. CDsplMgr2::CDsplMgr2()
  18. {
  19. m_lpIConsole = NULL;
  20. m_lpIConsoleNameSpace = NULL;
  21. m_lpIImageList = NULL;
  22. m_ViewMode = LVS_ICON; // default (if not persisting)
  23. m_pComponent = NULL;
  24. m_rootscopeitem = NULL;
  25. m_WallPaperNodeID = (HSCOPEITEM)0; // unexpanded
  26. m_toggle = FALSE;
  27. m_bPreload = FALSE;
  28. }
  29. CDsplMgr2::~CDsplMgr2()
  30. {
  31. _ASSERT (m_lpIConsole == NULL);
  32. _ASSERT (m_lpIConsoleNameSpace == NULL);
  33. _ASSERT (m_lpIImageList == NULL);
  34. if(m_pComponent)
  35. m_pComponent->Release ();
  36. }
  37. HRESULT CDsplMgr2::Initialize (LPUNKNOWN pUnknown)
  38. {
  39. // testing
  40. // return E_FAIL;
  41. // testing
  42. if (pUnknown == NULL)
  43. return E_UNEXPECTED;
  44. _ASSERT (m_lpIConsole == NULL);
  45. _ASSERT (m_lpIConsoleNameSpace == NULL);
  46. // this is my big chance to grab IConsole and IConsoleNameSpace pointers
  47. HRESULT hresult1 = pUnknown->QueryInterface (IID_IConsole, (void **)&m_lpIConsole);
  48. _ASSERT(hresult1 == S_OK && m_lpIConsole != NULL);
  49. HRESULT hresult2 = pUnknown->QueryInterface (IID_IConsoleNameSpace, (void **)&m_lpIConsoleNameSpace);
  50. _ASSERT(hresult2 == S_OK && m_lpIConsoleNameSpace != NULL);
  51. if (hresult1 || hresult2)
  52. return E_UNEXPECTED; // we're dead
  53. // this is where we can add our images
  54. HRESULT hresult = m_lpIConsole->QueryScopeImageList(&m_lpIImageList);
  55. if (m_lpIImageList) {
  56. _ASSERT(hresult == S_OK);
  57. // Load the bitmaps from the dll
  58. HBITMAP hbmSmall = LoadBitmap (g_hinst, MAKEINTRESOURCE(IDB_SCOPE_16X16));
  59. if (hbmSmall) {
  60. hresult = m_lpIImageList->ImageListSetStrip (
  61. (long*)hbmSmall,
  62. (long*)hbmSmall,
  63. 0,
  64. RGB(0,255,0));
  65. _ASSERT(hresult == S_OK);
  66. DeleteObject (hbmSmall);
  67. }
  68. }
  69. return hresult;
  70. }
  71. HRESULT CDsplMgr2::CreateComponent (LPCOMPONENT * ppComponent)
  72. {
  73. //
  74. // MMC asks us for a pointer to the IComponent interface
  75. //
  76. // For those getting up to speed with COM...
  77. // If we had implemented IUnknown with its methods QueryInterface, AddRef, and Release
  78. // in our CComponent class...
  79. // The following line would have worked
  80. //
  81. // pNewSnapin = new CComponent(this);
  82. //
  83. // In this code we will have ATL take care of IUnknown for us and create an object
  84. // in the following manner...
  85. _ASSERT(ppComponent != NULL);
  86. *ppComponent = NULL;
  87. HRESULT hresult = CComObject<CComponent>::CreateInstance(&m_pComponent);
  88. _ASSERT(m_pComponent != NULL);
  89. if (m_pComponent) {
  90. // Store IComponentData
  91. // Can't have a constructor with parameters, so pass it in this way.
  92. m_pComponent->SetComponentData (this);
  93. m_pComponent->AddRef(); // bump reference count to 1 (so I can hang onto it)
  94. hresult = m_pComponent->QueryInterface(IID_IComponent, reinterpret_cast<void**>(ppComponent));
  95. }
  96. return hresult;
  97. }
  98. HRESULT CDsplMgr2::Notify (LPDATAOBJECT lpDataObject, MMC_NOTIFY_TYPE event, long arg, long param)
  99. {
  100. HRESULT hresult = S_OK;
  101. switch (event)
  102. {
  103. case MMCN_EXPAND:
  104. hresult = OnExpand(lpDataObject, arg, param);
  105. break;
  106. case MMCN_PRELOAD:
  107. m_rootscopeitem = (HSCOPEITEM)arg;
  108. m_bPreload = TRUE;
  109. myChangeIcon();
  110. break;
  111. case MMCN_DELETE:
  112. case MMCN_RENAME:
  113. case MMCN_SELECT:
  114. case MMCN_PROPERTY_CHANGE:
  115. case MMCN_REMOVE_CHILDREN:
  116. case MMCN_EXPANDSYNC:
  117. break;
  118. default:
  119. ATLTRACE(_T("CComponentData::Notify: unexpected event %x\n"), event);
  120. _ASSERT(FALSE);
  121. hresult = E_UNEXPECTED;
  122. break;
  123. }
  124. return hresult;
  125. }
  126. HRESULT CDsplMgr2::Destroy ()
  127. {
  128. if (m_lpIConsole) {
  129. m_lpIConsole->Release();
  130. m_lpIConsole = NULL;
  131. }
  132. if (m_lpIConsoleNameSpace) {
  133. m_lpIConsoleNameSpace->Release();
  134. m_lpIConsoleNameSpace = NULL;
  135. }
  136. if (m_lpIImageList) {
  137. m_lpIImageList->Release();
  138. m_lpIImageList = NULL;
  139. }
  140. return S_OK;
  141. }
  142. HRESULT CDsplMgr2::QueryDataObject (long cookie, DATA_OBJECT_TYPES type, LPDATAOBJECT* ppDataObject)
  143. {
  144. HRESULT hresult = S_OK;
  145. CDataObject *pdo = new CDataObject (cookie, type);
  146. *ppDataObject = pdo;
  147. if (pdo == NULL)
  148. hresult = E_OUTOFMEMORY;
  149. #ifdef DO_WE_NEED_THIS
  150. else {
  151. //
  152. // The cookie represents a snapin manager or scope pane item.
  153. //
  154. // If the passed-in cookie is NULL, it is our snapins main root node folder
  155. // We never needed to ask for this to be created. MMC did this for us.
  156. //
  157. // Else If the passed-in cookie is non-NULL, then it should be one we
  158. // created when we added a node to the scope pane. See OnExpand.
  159. //
  160. if (cookie) {
  161. // cookie is the lparam field that we passed in SCOPEDATAITEM
  162. // used for the m_pConsoleNameSpace->InsertItem(&sdi);
  163. ; // pdoNew->SetCookie(cookie, CCT_SCOPE, COOKIE_IS_STATUS);
  164. } else {
  165. // In this case the node is our top node, and was placed there for us.
  166. ; // pdoNew->SetCookie(0, type, COOKIE_IS_ROOT);
  167. }
  168. }
  169. #endif
  170. pdo->SetPreload (m_bPreload);
  171. return hresult;
  172. }
  173. HRESULT CDsplMgr2::GetDisplayInfo (SCOPEDATAITEM* psdi)
  174. {
  175. _ASSERT (psdi != NULL);
  176. /*
  177. const DWORD SDI_STR = 0x00002;
  178. const DWORD SDI_IMAGE = 0x00004;
  179. const DWORD SDI_OPENIMAGE = 0x00008;
  180. const DWORD SDI_STATE = 0x00010;
  181. const DWORD SDI_PARAM = 0x00020;
  182. const DWORD SDI_CHILDREN = 0x00040;
  183. */
  184. /*
  185. // The top 4 bit of the mask determines the relative position of this item,
  186. // relative to the SCOPEDATAITEM::relativeID. By default it is the parent.
  187. // For SDI_PARENT, SCOPEDATAITEM::relativeID is the HSCOPEITEM of the parent.
  188. // As you can see by the SDI_PARENT value it is a no-op. Since by default
  189. // SCOPEDATAITEM::relativeID is treated as the parents ID.
  190. const DWORD SDI_PARENT = 0x00000000;
  191. // For SDI_PREVIOUS, SCOPEDATAITEM::relativeID is the HSCOPEITEM of the previous sibling
  192. const DWORD SDI_PREVIOUS = 0x10000000;
  193. // For SDI_NEXT, SCOPEDATAITEM::relativeID is the HSCOPEITEM of the next sibling.
  194. const DWORD SDI_NEXT = 0x20000000;
  195. // For SDI_PARENT, bit 27 determines whether the item is to be inserted as the
  196. // first child. By default this item will inserted as the last child.
  197. const DWORD SDI_FIRST = 0x08000000;
  198. */
  199. /*
  200. typedef struct _SCOPEDATAITEM
  201. {
  202. DWORD mask;
  203. LPOLESTR displayname;
  204. int nImage;
  205. int nOpenImage;
  206. UINT nState;
  207. int cChildren;
  208. LPARAM lParam;
  209. HSCOPEITEM relativeID;
  210. HSCOPEITEM ID;
  211. } SCOPEDATAITEM;
  212. typedef SCOPEDATAITEM* LPSCOPEDATAITEM;
  213. typedef enum _MMC_SCOPE_ITEM_STATE
  214. {
  215. MMC_SCOPE_ITEM_STATE_NORMAL = 0x0001, // Not bold. To set or get.
  216. MMC_SCOPE_ITEM_STATE_BOLD = 0x0002, // To set or get.
  217. MMC_SCOPE_ITEM_STATE_EXPANDEDONCE = 0x0003, // Only to get.
  218. } MMC_SCOPE_ITEM_STATE;
  219. */
  220. if (psdi) {
  221. if(psdi->mask & SDI_STR) {
  222. switch (psdi->lParam) {
  223. case DISPLAY_MANAGER_WALLPAPER:
  224. if (m_toggle)
  225. psdi->displayname = (LPOLESTR)L"Renamed Wallpaper";
  226. else
  227. psdi->displayname = (LPOLESTR)L"Wallpaper";
  228. break;
  229. case DISPLAY_MANAGER_PATTERN:
  230. psdi->displayname = (LPOLESTR)L"Pattern";
  231. break;
  232. case DISPLAY_MANAGER_PATTERN_CHILD:
  233. psdi->displayname = (LPOLESTR)L"Pattern test child";
  234. break;
  235. default:
  236. psdi->displayname = (LPOLESTR)L"Hey! You shouldn't see this!";
  237. break;
  238. }
  239. }
  240. }
  241. return S_OK;
  242. }
  243. HRESULT CDsplMgr2::CompareObjects (LPDATAOBJECT lpDataObjectA, LPDATAOBJECT lpDataObjectB)
  244. { return !S_OK; }
  245. HRESULT CDsplMgr2::OnExpand(LPDATAOBJECT pDataObject, long arg, long param)
  246. {
  247. _ASSERT(m_lpIConsoleNameSpace != NULL); // make sure we QI'ed for the interface
  248. _ASSERT(pDataObject != NULL);
  249. if (arg == TRUE) { // expanding, FALSE => contracting
  250. CDataObject *pdo = (CDataObject *)pDataObject; // TODO: hmm....
  251. // the code below makes sure that we're dealing only with the root node
  252. if (pdo->GetCookie () == 0) { // 0 == root
  253. // hang onto to root HSCOPEITEM (param) for later
  254. m_rootscopeitem = (HSCOPEITEM)param;
  255. // Place our folder(s) into the scope pane
  256. SCOPEDATAITEM sdi;
  257. ZeroMemory(&sdi, sizeof(sdi));
  258. sdi.mask = SDI_STR | // displayname is valid
  259. SDI_PARAM | // lParam is valid
  260. SDI_IMAGE | // nImage is valid
  261. SDI_OPENIMAGE | // nOpenImage is valid
  262. SDI_PARENT;
  263. sdi.relativeID = (HSCOPEITEM) param;
  264. sdi.nImage = 0;
  265. sdi.nOpenImage = 1;
  266. sdi.displayname = MMC_CALLBACK;
  267. sdi.lParam = (LPARAM) DISPLAY_MANAGER_WALLPAPER;
  268. m_lpIConsoleNameSpace->InsertItem(&sdi);
  269. m_WallPaperNodeID = sdi.ID;
  270. sdi.lParam = (LPARAM) DISPLAY_MANAGER_PATTERN;
  271. return m_lpIConsoleNameSpace->InsertItem(&sdi);
  272. }
  273. if (pdo->GetCookie () == DISPLAY_MANAGER_PATTERN) {
  274. // add another node, so I can test deleteitem stuff
  275. // hang onto to root HSCOPEITEM (param) for later
  276. m_patternscopeitem = (HSCOPEITEM)param;
  277. // Place our folder into the scope pane
  278. SCOPEDATAITEM sdi;
  279. ZeroMemory(&sdi, sizeof(sdi));
  280. sdi.mask = SDI_STR | // displayname is valid
  281. SDI_PARAM | // lParam is valid
  282. SDI_IMAGE | // nImage is valid
  283. SDI_OPENIMAGE | // nOpenImage is valid
  284. SDI_PARENT;
  285. sdi.relativeID = (HSCOPEITEM) param;
  286. sdi.nImage = 0;
  287. sdi.nOpenImage = 1;
  288. sdi.displayname = MMC_CALLBACK;
  289. sdi.lParam = (LPARAM) DISPLAY_MANAGER_PATTERN_CHILD;
  290. return m_lpIConsoleNameSpace->InsertItem(&sdi);
  291. }
  292. }
  293. return S_OK;
  294. }
  295. ///////////////////////////////////////////////////////////////////////////////
  296. //// IPersistStream interface members
  297. STDMETHODIMP CDsplMgr2::GetClassID (CLSID *pClassID)
  298. {
  299. if (pClassID) {
  300. *pClassID = CLSID_DsplMgr2;
  301. return S_OK;
  302. }
  303. return E_POINTER;
  304. }
  305. HRESULT CDsplMgr2::IsDirty ()
  306. {
  307. // get current ViewMode and compare against my value
  308. if (m_pComponent == NULL)
  309. return S_FALSE;
  310. long vm = m_pComponent->GetViewMode ();
  311. if (m_ViewMode == vm)
  312. return S_FALSE;
  313. return S_OK;
  314. }
  315. HRESULT CDsplMgr2::Load (IStream *pStream)
  316. {
  317. // testing
  318. // return E_FAIL;
  319. // testing
  320. _ASSERT (pStream);
  321. // we have a long specifying ViewMode (LVS_ICON, LVS_REPORT, etc.)
  322. return pStream->Read (&m_ViewMode, sizeof(long), NULL);
  323. }
  324. HRESULT CDsplMgr2::Save (IStream *pStream, BOOL fClearDirty)
  325. {
  326. _ASSERT (pStream);
  327. if (m_pComponent) // get current value
  328. m_ViewMode = m_pComponent->GetViewMode ();
  329. // write ViewMode
  330. HRESULT hr = pStream->Write (&m_ViewMode, sizeof(long), NULL);
  331. return hr == S_OK ? S_OK : STG_E_CANTSAVE;
  332. }
  333. HRESULT CDsplMgr2::GetSizeMax (ULARGE_INTEGER *pcbSize)
  334. {
  335. _ASSERT (pcbSize);
  336. ULISet32 (*pcbSize, sizeof(long));
  337. return S_OK;
  338. }
  339. // other public stuff
  340. void CDsplMgr2::myRenameItem (HSCOPEITEM hsi, LPOLESTR szName)
  341. {
  342. if (m_toggle)
  343. m_toggle = FALSE;
  344. else
  345. m_toggle = TRUE;
  346. SCOPEDATAITEM item;
  347. ZeroMemory (&item, sizeof(SCOPEDATAITEM));
  348. item.mask = SDI_STR;
  349. item.displayname = MMC_CALLBACK;
  350. item.ID = hsi;
  351. m_lpIConsoleNameSpace->SetItem (&item);
  352. }
  353. void CDsplMgr2::myChangeIcon (void)
  354. {
  355. _ASSERT (m_lpIImageList != NULL);
  356. _ASSERT (m_rootscopeitem != NULL); // shoulda been selected by now.
  357. HBITMAP hbmSmall = LoadBitmap (g_hinst, MAKEINTRESOURCE(IDB_SCOPE_16X16_CUSTOM));
  358. if (!hbmSmall)
  359. return;
  360. HRESULT hr = m_lpIImageList->ImageListSetStrip (
  361. (long*)hbmSmall,
  362. (long*)hbmSmall,
  363. 0,
  364. RGB(0,255,0));
  365. _ASSERT (hr == S_OK);
  366. DeleteObject (hbmSmall);
  367. SCOPEDATAITEM item;
  368. ZeroMemory (&item, sizeof(SCOPEDATAITEM));
  369. item.mask = SDI_IMAGE | SDI_OPENIMAGE;
  370. item.nImage = 0; // (int)MMC_CALLBACK;
  371. item.nOpenImage = 1; // (int)MMC_CALLBACK;
  372. item.ID = m_rootscopeitem;
  373. m_lpIConsoleNameSpace->SetItem (&item);
  374. }
  375. void CDsplMgr2::myPreLoad (void)
  376. {
  377. // toggle state
  378. if (m_bPreload == TRUE)
  379. m_bPreload = FALSE;
  380. else
  381. m_bPreload = TRUE;
  382. }