//+------------------------------------------------------------------------- // // Microsoft Windows // // Copyright (C) Microsoft Corporation, 1999 - 1999 // // File: DsplComp.cpp // //-------------------------------------------------------------------------- #include "stdafx.h" #include "displ2.h" #include "DsplMgr2.h" // local proto HRESULT ApplyOption (int nCommandID); extern HINSTANCE g_hinst; // in displ2.cpp HSCOPEITEM g_root_scope_item = 0; CComponent::CComponent() { m_pResultData = NULL; m_pHeaderCtrl = NULL; m_pComponentData = NULL; // the guy who created me m_IsTaskPad = 0; // TODO: should get this from the persisted data m_pConsole = NULL; m_TaskPadCount = 0; m_toggle = FALSE; m_toggleEntry = FALSE; } CComponent::~CComponent() { _ASSERT (m_pResultData == NULL); _ASSERT (m_pHeaderCtrl == NULL); } HRESULT CComponent::Initialize (LPCONSOLE lpConsole) { _ASSERT(lpConsole != NULL); _ASSERT (m_pResultData == NULL); // should be called only once... _ASSERT (m_pHeaderCtrl == NULL); // should be called only once... m_pConsole = lpConsole; // hang onto this HRESULT hresult = lpConsole->QueryInterface(IID_IResultData, (VOID**)&m_pResultData); _ASSERT (m_pResultData != NULL); hresult = lpConsole->QueryInterface(IID_IHeaderCtrl, (VOID**)&m_pHeaderCtrl); _ASSERT (m_pHeaderCtrl != NULL); if (m_pHeaderCtrl) // Give the console the header control interface pointer lpConsole->SetHeader(m_pHeaderCtrl); #ifdef TODO_ADD_THIS_LATER hr = lpConsole->QueryResultImageList(&m_pImageResult); _ASSERT(hr == S_OK); hr = lpConsole->QueryConsoleVerb(&m_pConsoleVerb); _ASSERT(hr == S_OK); // Load the bitmaps from the dll for the results pane m_hbmp16x16 = LoadBitmap(g_hinst, MAKEINTRESOURCE(IDB_RESULT_16x16)); _ASSERT(m_hbmp16x16); m_hbmp32x32 = LoadBitmap(g_hinst, MAKEINTRESOURCE(IDB_RESULT_32x32)); _ASSERT(m_hbmp32x32); #endif return hresult; } HRESULT CComponent::Destroy (long cookie) { if (m_pResultData) { m_pResultData->Release (); m_pResultData = NULL; } if (m_pHeaderCtrl) { m_pHeaderCtrl->Release (); m_pHeaderCtrl = NULL; } // hmmm... I wonder if I have to release my IConsole pointer? it doesn't look like it.... return S_OK; } HRESULT CComponent::Notify (LPDATAOBJECT lpDataObject, MMC_NOTIFY_TYPE event, long arg, long param) { switch (event) { case MMCN_SHOW: return OnShow (lpDataObject, arg, param); case MMCN_ADD_IMAGES: return OnAddImages (lpDataObject, arg, param); case MMCN_DBLCLICK: return OnDblClick (lpDataObject, arg, param); case MMCN_SELECT: // return OnSelect (lpDataObject, arg, param); break; case MMCN_REFRESH: // return OnRefresh (lpDataObject, arg, param); case MMCN_VIEW_CHANGE: case MMCN_CLICK: case MMCN_BTN_CLICK: case MMCN_ACTIVATE: case MMCN_MINIMIZED: break; case MMCN_LISTPAD: return OnListPad (lpDataObject, arg, param); case MMCN_RESTORE_VIEW: return OnRestoreView (lpDataObject, arg, param); default: return E_UNEXPECTED; } return S_OK; } HRESULT CComponent::GetResultViewType (long cookie, LPOLESTR* ppViewType, long* pViewOptions) { *ppViewType = NULL; *pViewOptions = MMC_VIEW_OPTIONS_NONE; // only allow taskpad when root is selected if (cookie != 0) m_IsTaskPad = 0; // special case for taskpads only if (m_IsTaskPad != 0) { USES_CONVERSION; TCHAR szBuffer[MAX_PATH*2]; // a little extra lstrcpy (szBuffer, _T("res://")); TCHAR * temp = szBuffer + lstrlen(szBuffer); switch (m_IsTaskPad) { case IDM_CUSTOMPAD: // get "res://"-type string for custom taskpad ::GetModuleFileName (g_hinst, temp, MAX_PATH); lstrcat (szBuffer, _T("/default.htm")); break; case IDM_TASKPAD: // get "res://"-type string for custom taskpad ::GetModuleFileName (NULL, temp, MAX_PATH); lstrcat (szBuffer, _T("/default.htm")); break; case IDM_TASKPAD_WALLPAPER_OPTIONS: // get "res://"-type string for custom taskpad ::GetModuleFileName (NULL, temp, MAX_PATH); lstrcat (szBuffer, _T("/default.htm#wallpaper_options")); break; case IDM_TASKPAD_LISTVIEW: // get "res://"-type string for custom taskpad // ::GetModuleFileName (g_hinst, temp, MAX_PATH); // lstrcat (szBuffer, _T("/listview.htm")); ::GetModuleFileName (NULL, temp, MAX_PATH); lstrcat (szBuffer, _T("/horizontal.htm")); break; case IDM_DEFAULT_LISTVIEW: // get "res://"-type string for custom taskpad ::GetModuleFileName (NULL, temp, MAX_PATH); lstrcat (szBuffer, _T("/listpad.htm")); break; default: _ASSERT (0); return S_FALSE; } // return URL *ppViewType = CoTaskDupString (T2OLE(szBuffer)); if (!*ppViewType) return E_OUTOFMEMORY; // or S_FALSE ??? return S_OK; } return S_FALSE; // false for default } HRESULT CComponent::QueryDataObject (long cookie, DATA_OBJECT_TYPES type, LPDATAOBJECT* ppDataObject) { _ASSERT (ppDataObject != NULL); CDataObject *pdo = new CDataObject (cookie, type); *ppDataObject = pdo; if (!pdo) return E_OUTOFMEMORY; return S_OK; } HRESULT CComponent::GetDisplayInfo (RESULTDATAITEM* prdi) { _ASSERT(prdi != NULL); if (prdi) { // Provide strings for scope tree items if (prdi->bScopeItem == TRUE) { if (prdi->mask & RDI_STR) { if (prdi->nCol == 0) { switch (prdi->lParam) { case DISPLAY_MANAGER_WALLPAPER: if (m_toggle == FALSE) prdi->str = (LPOLESTR)L"Wallpaper"; else prdi->str = (LPOLESTR)L"RenamedWallpaper"; break; case DISPLAY_MANAGER_PATTERN: prdi->str = (LPOLESTR)L"Pattern"; break; case DISPLAY_MANAGER_PATTERN_CHILD: prdi->str = (LPOLESTR)L"Pattern child"; break; default: prdi->str = (LPOLESTR)L"Hey! You shouldn't see this!"; break; } } else if (prdi->nCol == 1) prdi->str = (LPOLESTR)L"Display Option"; else prdi->str = (LPOLESTR)L"Error:Should not see this!"; } if (prdi->mask & RDI_IMAGE) prdi->nImage = 0; } else { // listpad uses lparam on -1, anything else is wallpaper if (prdi->lParam == -1) { if (prdi->mask & RDI_STR) if (m_toggleEntry == FALSE) prdi->str = (LPOLESTR)L"here's a listpad entry"; else prdi->str = (LPOLESTR)L"Changed listpad entry"; if (prdi->mask & RDI_IMAGE) prdi->nImage = 0; } else { lParamWallpaper * lpwp = NULL; if (prdi->lParam) lpwp = (lParamWallpaper *)prdi->lParam; if (prdi->mask & RDI_STR) { if (prdi->nCol == 0) { if (lpwp && (!IsBadReadPtr (lpwp, sizeof (lParamWallpaper)))) prdi->str = lpwp->filename; else prdi->str = (LPOLESTR)L"hmm.... error"; } else if (prdi->nCol == 1) prdi->str = (LPOLESTR)L"result pane display name col 1"; else prdi->str = (LPOLESTR)L"Error:Should not see this!"; } if (prdi->mask & RDI_IMAGE) { switch (prdi->lParam) { case DISPLAY_MANAGER_WALLPAPER: case DISPLAY_MANAGER_PATTERN: case DISPLAY_MANAGER_PATTERN_CHILD: prdi->nImage = 0; break; default: prdi->nImage = 3; break; } } } } } return S_OK; } HRESULT CComponent::CompareObjects (LPDATAOBJECT lpDataObjectA, LPDATAOBJECT lpDataObjectB) { return E_NOTIMPL;} // private functions HRESULT CComponent::OnShow(LPDATAOBJECT pDataObject, long arg, long param) { USES_CONVERSION; CDataObject * pcdo = (CDataObject *)pDataObject; if (arg == 0) { // de-selecting: free up resources, if any if (pcdo->GetCookie() == DISPLAY_MANAGER_WALLPAPER) { // enumerate result data items RESULTDATAITEM rdi; ZeroMemory(&rdi, sizeof(rdi)); rdi.mask = RDI_PARAM | RDI_STATE; rdi.nIndex = -1; while (1) { if (m_pResultData->GetNextItem (&rdi) != S_OK) break; if (rdi.lParam) { lParamWallpaper * lpwp = (lParamWallpaper *)rdi.lParam; delete lpwp; } } m_pResultData->DeleteAllRsltItems (); } return S_OK; } // init column headers _ASSERT (m_pHeaderCtrl != NULL); m_pHeaderCtrl->InsertColumn (0, L"Name", 0, 120); if (m_pComponentData) { if (m_pResultData) // use large icons by default m_pResultData->SetViewMode (m_pComponentData->GetViewMode ()); } // add our stuff RESULTDATAITEM rdi; ZeroMemory(&rdi, sizeof(rdi)); rdi.mask = RDI_PARAM | RDI_STR | RDI_IMAGE; rdi.nImage = (int)MMC_CALLBACK; rdi.str = MMC_CALLBACK; if (pcdo->GetCookie () == DISPLAY_MANAGER_WALLPAPER) { // enumerate all .bmp files in "c:\winnt.40\" (windows directory) TCHAR path[MAX_PATH]; GetWindowsDirectory (path, MAX_PATH); lstrcat (path, _T("\\*.bmp")); int i = 0; // first do "(none)" lParamWallpaper * lpwp = new lParamWallpaper; wcscpy (lpwp->filename, L"(none)"); rdi.lParam = reinterpret_cast(lpwp); rdi.nImage = i++; m_pResultData->InsertItem (&rdi); WIN32_FIND_DATA fd; ZeroMemory(&fd, sizeof(fd)); HANDLE hFind = FindFirstFile (path, &fd); if (hFind != INVALID_HANDLE_VALUE) { do { if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) || (fd.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) || (fd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) ) continue; // files only // new a struct to hold info, and cast to lParam. lParamWallpaper * lpwp = new lParamWallpaper; wcscpy (lpwp->filename, T2OLE(fd.cFileName)); // rdi.str = lpwp->filename; rdi.lParam = reinterpret_cast(lpwp); rdi.nImage = i++; m_pResultData->InsertItem (&rdi); } while (FindNextFile (hFind, &fd) == TRUE); FindClose(hFind); } } else { // DISPLAY_MANAGER_PATTERN ; // hard code a few things. } return S_OK; } #include inline long LongScanBytes (long bits) { bits += 31; bits /= 8; bits &= ~3; return bits; } void GetBitmaps (TCHAR * fn, HBITMAP * smallbm, HBITMAP * largebm) { *smallbm = *largebm = (HBITMAP)NULL; // in case of error // read bmp file into DIB DWORD dwRead; HANDLE hf = CreateFile (fn, GENERIC_READ, FILE_SHARE_READ, (LPSECURITY_ATTRIBUTES) NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, (HANDLE) NULL); if (hf != (HANDLE)HFILE_ERROR) { BITMAPFILEHEADER bmfh; ReadFile(hf, &bmfh, sizeof(BITMAPFILEHEADER), &dwRead, (LPOVERLAPPED)NULL); BITMAPINFOHEADER bmih; ReadFile(hf, &bmih, sizeof(BITMAPINFOHEADER), &dwRead, (LPOVERLAPPED)NULL); // Allocate memory for the DIB DWORD dwSize = sizeof(BITMAPINFOHEADER); if (bmih.biBitCount*bmih.biPlanes <= 8) dwSize += (sizeof(RGBQUAD))*(1<<(bmih.biBitCount*bmih.biPlanes)); dwSize += bmih.biHeight*LongScanBytes (bmih.biWidth*(bmih.biBitCount*bmih.biPlanes)); BITMAPINFOHEADER * lpbmih = (BITMAPINFOHEADER *)GlobalAllocPtr(GHND, dwSize); if (lpbmih) { *lpbmih = bmih; RGBQUAD * rgbq = (RGBQUAD *)&lpbmih[1]; char * bits = (char *)rgbq; if (bmih.biBitCount*bmih.biPlanes <= 8) { ReadFile (hf, rgbq, ((1<<(bmih.biBitCount*bmih.biPlanes))*sizeof(RGBQUAD)), &dwRead, (LPOVERLAPPED) NULL); bits += dwRead; } SetFilePointer (hf, bmfh.bfOffBits, NULL, FILE_BEGIN); ReadFile (hf, bits, dwSize - (bits - (char *)lpbmih), &dwRead, (LPOVERLAPPED) NULL); // we should now have a decent DIB HWND hwnd = GetDesktopWindow (); HDC hdc = GetDC (hwnd); HDC hcompdc = CreateCompatibleDC (hdc); // SetStretchBltMode (hcompdc, COLORONCOLOR); // SetStretchBltMode (hcompdc, WHITEONBLACK); SetStretchBltMode (hcompdc, HALFTONE); HGDIOBJ hold; // *smallbm = CreateCompatibleBitmap (hcompdc, 16, 16); *smallbm = CreateCompatibleBitmap (hdc, 16, 16); if (*smallbm) { hold = SelectObject (hcompdc, (HGDIOBJ)(*smallbm)); StretchDIBits (hcompdc, // handle of device context 0, 0, 16, 16, 0, 0, lpbmih->biWidth, lpbmih->biHeight, (CONST VOID *)bits, (CONST BITMAPINFO *)lpbmih, DIB_RGB_COLORS, // usage SRCCOPY // raster operation code ); SelectObject (hcompdc, hold); } // *largebm = CreateCompatibleBitmap (hcompdc, 32, 32); *largebm = CreateCompatibleBitmap (hdc, 32, 32); if (*largebm) { // testing /* HDC nullDC = GetDC (NULL); hold = SelectObject (nullDC, (HGDIOBJ)*largebm); StretchDIBits (nullDC, // handle of device context 0, 0, lpbmih->biWidth, lpbmih->biHeight, 0, 0, lpbmih->biWidth, lpbmih->biHeight, (CONST VOID *)bits, (CONST BITMAPINFO *)lpbmih, DIB_RGB_COLORS, // usage SRCCOPY // raster operation code ); SelectObject (hdc, hold); ReleaseDC (NULL, nullDC); */ // testing hold = SelectObject (hcompdc, (HGDIOBJ)*largebm); StretchDIBits (hcompdc, // handle of device context 0, 0, 32, 32, 0, 0, lpbmih->biWidth, lpbmih->biHeight, (CONST VOID *)bits, (CONST BITMAPINFO *)lpbmih, DIB_RGB_COLORS, // usage SRCCOPY // raster operation code ); SelectObject (hcompdc, hold); } DeleteDC (hcompdc); ReleaseDC (hwnd, hdc); GlobalFreePtr (lpbmih); } CloseHandle(hf); } } HRESULT CComponent::OnAddImages (LPDATAOBJECT pDataObject, long arg, long param) { IImageList * pImageList = (IImageList *)arg; HSCOPEITEM hsi = (HSCOPEITEM)param; _ASSERT (pImageList != NULL); CDataObject * cdo = (CDataObject *)pDataObject; if (cdo->GetCookie () != DISPLAY_MANAGER_WALLPAPER) { if (cdo->GetCookie () == 0) { g_root_scope_item = hsi; if (cdo->GetType () == CCT_RESULT) { // add a custom image HBITMAP hbmSmall, hbmLarge; GetBitmaps (_T("c:\\winnt\\dax.bmp"), &hbmSmall, &hbmLarge); pImageList->ImageListSetStrip ((long *)hbmSmall, (long *)hbmLarge, 3, RGB(1, 0, 254)); DeleteObject (hbmSmall); DeleteObject (hbmLarge); } } return S_OK; // TODO: for now } // create HBITMAPs from bmp files int i = 0; // create some invisible bitmaps { BYTE bits[] = { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}; HBITMAP hbmSmall = CreateBitmap (16, 16, 1, 1, (CONST VOID *)bits); HBITMAP hbmLarge = CreateBitmap (32, 32, 1, 1, (CONST VOID *)bits); pImageList->ImageListSetStrip ((long *)hbmSmall, (long *)hbmLarge, i++, RGB(1, 0, 254)); DeleteObject (hbmSmall); DeleteObject (hbmLarge); } TCHAR path[MAX_PATH]; GetWindowsDirectory (path, MAX_PATH); TCHAR * pfqfn = path + lstrlen(path) + 1; lstrcat (path, _T("\\*.bmp")); WIN32_FIND_DATA fd; ZeroMemory(&fd, sizeof(fd)); HANDLE hFind = FindFirstFile (path, &fd); if (hFind != INVALID_HANDLE_VALUE) { do { if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) || (fd.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) || (fd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) ) continue; // files only lstrcpy (pfqfn, fd.cFileName); HBITMAP hbmSmall, hbmLarge; GetBitmaps (path, &hbmSmall, &hbmLarge); pImageList->ImageListSetStrip ((long *)hbmSmall, (long *)hbmLarge, i++, RGB(1, 0, 254)); DeleteObject (hbmSmall); DeleteObject (hbmLarge); } while (FindNextFile (hFind, &fd) == TRUE); FindClose(hFind); } return S_OK; } #ifdef TODO_FIGURE_THIS_OUT HRESULT CComponent::OnSelect(LPDATAOBJECT pDataObject, long arg, long param) { if (!HIWORD(arg)) // being de-selected return S_OK; // don't care about this if (LOWORD(arg)) // in scope pane return S_OK; // don't care about this, either CDataObject *cdo = (CDataObject *)pDataObject; if (cdo->GetCookie() != DISPLAY_MANAGER_WALLPAPER) return S_OK; // TODO: do patterns later // // Bail if we couldn't get the console verb interface, or if the // selected item is the root; // if (!m_pConsoleVerb || pdo->GetCookieType() == COOKIE_IS_ROOT) { return S_OK; } // // Use selections and set which verbs are allowed // if (bScope) { if (pdo->GetCookieType() == COOKIE_IS_STATUS) { hr = m_pConsoleVerb->SetVerbState(MMC_VERB_REFRESH, ENABLED, TRUE); _ASSERT(hr == S_OK); } } else { // // Selection is in the result pane // } return S_OK; } #endif HRESULT CComponent::OnDblClick(LPDATAOBJECT pDataObject, long arg, long param) {//see note in CComponent::Command, below !!! _ASSERT (pDataObject); _ASSERT (m_pResultData); // hmmm: no documentation on arg or param.... CDataObject *cdo = (CDataObject *)pDataObject; lParamWallpaper * lpwp = (lParamWallpaper *)cdo->GetCookie(); if (lpwp) if (!IsBadReadPtr (lpwp, sizeof (lParamWallpaper))) { USES_CONVERSION; SystemParametersInfo (SPI_SETDESKWALLPAPER, 0, (void *)OLE2T(lpwp->filename), SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE); } return S_OK; } HRESULT CComponent::OnListPad (LPDATAOBJECT pDataObject, long arg, long param) { if (arg == TRUE) { // attaching IImageList* pImageList = NULL; m_pConsole->QueryResultImageList (&pImageList); if (pImageList) { HBITMAP hbmSmall, hbmLarge; GetBitmaps (_T("c:\\winnt\\dax.bmp"), &hbmSmall, &hbmLarge); pImageList->ImageListSetStrip ((long *)hbmSmall, (long *)hbmLarge, 0, RGB(1, 0, 254)); pImageList->Release(); } // m_pResultData->SetViewMode (LVS_ICON); m_pResultData->SetViewMode (LVS_REPORT); m_pHeaderCtrl->InsertColumn (0, L"Name", 0, 170); // populate listview control via IResultData RESULTDATAITEM rdi; ZeroMemory(&rdi, sizeof(rdi)); rdi.mask = RDI_PARAM | RDI_STR | RDI_IMAGE; rdi.nImage = (int)MMC_CALLBACK; rdi.str = MMC_CALLBACK; rdi.lParam = -1; for (int i=0; i<11; i++) m_pResultData->InsertItem (&rdi); } return S_OK; } HRESULT CComponent::OnRestoreView (LPDATAOBJECT pDataObject, long arg, long param) { MMC_RESTORE_VIEW* pmrv = (MMC_RESTORE_VIEW*)arg; BOOL * pb = (BOOL *)param; _ASSERT (pmrv); _ASSERT (pb); // some versioning (not really necessary since this is the new rev.) if (pmrv->dwSize < sizeof(MMC_RESTORE_VIEW)) return E_FAIL; // version too old // maintain my internal state if (pmrv->pViewType) { USES_CONVERSION; // there are going to be two cases: // 1. custom html pages (res in my .dll) // 2. default html pages (res in mmc.exe) // get path to my .dll and compare to pViewType TCHAR szPath[MAX_PATH]; ::GetModuleFileName (g_hinst, szPath, MAX_PATH); if (wcsstr (pmrv->pViewType, T2OLE(szPath))) { // custom html if (wcsstr (pmrv->pViewType, L"/default.htm")) m_IsTaskPad = IDM_CUSTOMPAD; else if (wcsstr (pmrv->pViewType, L"/listview.htm")) m_IsTaskPad = IDM_TASKPAD_LISTVIEW; else { // this will happen when you can get to a taskpad by clicking // on a task, but there is no corresponding view menu option // to select. Therefore do something reasonable. // In my case, I can get to "wallpapr.htm" by either custom // or default routes (which is probably rather unusual). So, // I think I'll just leave the m_IsTaskPad value alone if // it's non-NULL, else pick one. if (m_IsTaskPad == 0) m_IsTaskPad = IDM_TASKPAD; } } else { // default html if (wcsstr (pmrv->pViewType, L"/default.htm#wallpaper_options")) m_IsTaskPad = IDM_TASKPAD_WALLPAPER_OPTIONS; else if (wcsstr (pmrv->pViewType, L"/default.htm")) m_IsTaskPad = IDM_TASKPAD; else if (wcsstr (pmrv->pViewType, L"/listpad.htm")) m_IsTaskPad = IDM_DEFAULT_LISTVIEW; else if (wcsstr (pmrv->pViewType, L"/horizontal.htm")) m_IsTaskPad = IDM_TASKPAD_LISTVIEW; else { _ASSERT (0 && "can't find MMC's resources"); return E_FAIL; } } } else m_IsTaskPad = 0; *pb = TRUE; // I'm handling the new history notify return S_OK; } // IExtendContextMenu HRESULT CComponent::AddMenuItems (LPDATAOBJECT pDataObject, LPCONTEXTMENUCALLBACK pContextMenuCallback, long *pInsertionAllowed) { CDataObject * cdo = (CDataObject *)pDataObject; switch (cdo->GetCookie ()) { case DISPLAY_MANAGER_WALLPAPER: case DISPLAY_MANAGER_PATTERN: return S_OK; case 0: // root // this is when they pull down the view menu if (*pInsertionAllowed & CCM_INSERTIONALLOWED_VIEW) { // add my taskpads and delete thingy CONTEXTMENUITEM m[] = { {L"Custom TaskPad", L"Custom TaskPad", IDM_CUSTOMPAD, CCM_INSERTIONPOINTID_PRIMARY_VIEW, 0, 0}, {L"Default TaskPad", L"Default TaskPad", IDM_TASKPAD, CCM_INSERTIONPOINTID_PRIMARY_VIEW, 0, 0}, {L"Wallpaper Options TaskPad", L"Wallpaper Options TaskPad", IDM_TASKPAD_WALLPAPER_OPTIONS, CCM_INSERTIONPOINTID_PRIMARY_VIEW, 0, 0}, {L"Horizontal ListView", L"ListView TaskPad", IDM_TASKPAD_LISTVIEW, CCM_INSERTIONPOINTID_PRIMARY_VIEW, 0, 0}, {L"Default ListPad", L"Default ListPad", IDM_DEFAULT_LISTVIEW, CCM_INSERTIONPOINTID_PRIMARY_VIEW, 0, 0}, {L"DeleteRootChildren", L"just testing", IDM_DELETECHILDREN, CCM_INSERTIONPOINTID_PRIMARY_VIEW, 0, 0}, {L"RenameRoot", L"just testing", IDM_RENAMEROOT, CCM_INSERTIONPOINTID_PRIMARY_VIEW, 0, 0}, {L"RenameWallPaperNode",L"just testing", IDM_RENAMEWALL, CCM_INSERTIONPOINTID_PRIMARY_VIEW, 0, 0}, {L"ChangeIcon", L"just testing", IDM_CHANGEICON, CCM_INSERTIONPOINTID_PRIMARY_VIEW, 0, 0}, {L"Pre-Load", L"just testing", IDM_PRELOAD, CCM_INSERTIONPOINTID_PRIMARY_VIEW, 0, 0}, {L"Test IConsoleVerb", L"just testing", IDM_CONSOLEVERB, CCM_INSERTIONPOINTID_PRIMARY_VIEW, 0, 0} }; if (m_IsTaskPad == IDM_CUSTOMPAD) m[0].fFlags = MF_CHECKED; if (m_IsTaskPad == IDM_TASKPAD) m[1].fFlags = MF_CHECKED; if (m_IsTaskPad == IDM_TASKPAD_WALLPAPER_OPTIONS) m[2].fFlags = MF_CHECKED; if (m_IsTaskPad == IDM_TASKPAD_LISTVIEW) m[3].fFlags = MF_CHECKED; if (m_IsTaskPad == IDM_DEFAULT_LISTVIEW) m[4].fFlags = MF_CHECKED; if (m_pComponentData->GetPreload() == TRUE) m[9].fFlags = MF_CHECKED; pContextMenuCallback->AddItem (&m[0]); pContextMenuCallback->AddItem (&m[1]); pContextMenuCallback->AddItem (&m[2]); pContextMenuCallback->AddItem (&m[3]); pContextMenuCallback->AddItem (&m[4]); pContextMenuCallback->AddItem (&m[5]); pContextMenuCallback->AddItem (&m[6]); pContextMenuCallback->AddItem (&m[7]); pContextMenuCallback->AddItem (&m[8]); pContextMenuCallback->AddItem (&m[9]); return pContextMenuCallback->AddItem (&m[10]); } return S_OK; default: break; } // add to context menu, only if in result pane: // this is when they right-click on the result pane. if (cdo->GetType() == CCT_RESULT) { CONTEXTMENUITEM cmi; cmi.strName = L"Center"; cmi.strStatusBarText = L"Center Desktop Wallpaper"; cmi.lCommandID = IDM_CENTER; cmi.lInsertionPointID = CCM_INSERTIONPOINTID_PRIMARY_TOP; cmi.fFlags = 0; cmi.fSpecialFlags = CCM_SPECIAL_DEFAULT_ITEM; pContextMenuCallback->AddItem (&cmi); cmi.strName = L"Tile"; cmi.strStatusBarText = L"Tile Desktop Wallpaper"; cmi.lCommandID = IDM_TILE; cmi.lInsertionPointID = CCM_INSERTIONPOINTID_PRIMARY_TOP; cmi.fFlags = 0; cmi.fSpecialFlags = 0; // CCM_SPECIAL_DEFAULT_ITEM; pContextMenuCallback->AddItem (&cmi); cmi.strName = L"Stretch"; cmi.strStatusBarText = L"Stretch Desktop Wallpaper"; cmi.lCommandID = IDM_STRETCH; cmi.lInsertionPointID = CCM_INSERTIONPOINTID_PRIMARY_TOP; cmi.fFlags = 0; cmi.fSpecialFlags = 0; // CCM_SPECIAL_DEFAULT_ITEM; pContextMenuCallback->AddItem (&cmi); } return S_OK; } HRESULT CComponent::Command (long nCommandID, LPDATAOBJECT pDataObject) { m_IsTaskPad = 0; CDataObject * cdo = reinterpret_cast(pDataObject); switch (nCommandID) { case IDM_TILE: case IDM_CENTER: case IDM_STRETCH: // write registry key: { HKEY hkey; HRESULT r = RegOpenKeyEx (HKEY_CURRENT_USER, _T("Control Panel\\Desktop"), 0, KEY_ALL_ACCESS, &hkey); if (r == ERROR_SUCCESS) { // write new value(s) DWORD dwType = REG_SZ; TCHAR szBuffer[2]; // first do "TileWallpaper" if (nCommandID == IDM_TILE) lstrcpy (szBuffer, _T("1")); else lstrcpy (szBuffer, _T("0")); DWORD dwCount = sizeof(TCHAR)*(1+lstrlen (szBuffer)); r = RegSetValueEx (hkey, (LPCTSTR)_T("TileWallpaper"), NULL, dwType, (CONST BYTE *)&szBuffer, dwCount); // then do "WallpaperStyle" if (nCommandID == IDM_STRETCH) lstrcpy (szBuffer, _T("2")); else lstrcpy (szBuffer, _T("0")); r = RegSetValueEx (hkey, (LPCTSTR)_T("WallpaperStyle"), NULL, dwType, (CONST BYTE *)&szBuffer, dwCount); // close up shop RegCloseKey(hkey); _ASSERT(r == ERROR_SUCCESS); /* [HKEY_CURRENT_USER\Control Panel\Desktop] "CoolSwitch"="1" "CoolSwitchRows"="3" "CoolSwitchColumns"="7" "CursorBlinkRate"="530" "ScreenSaveTimeOut"="900" "ScreenSaveActive"="0" "ScreenSaverIsSecure"="0" "Pattern"="(None)" "Wallpaper"="C:\\WINNT\\dax.bmp" "TileWallpaper"="0" "GridGranularity"="0" "IconSpacing"="75" "IconTitleWrap"="1" "IconTitleFaceName"="MS Sans Serif" "IconTitleSize"="9" "IconTitleStyle"="0" "DragFullWindows"="1" "HungAppTimeout"="5000" "WaitToKillAppTimeout"="20000" "AutoEndTasks"="0" "FontSmoothing"="0" "MenuShowDelay"="400" "DragHeight"="2" "DragWidth"="2" "WheelScrollLines"="3" "WallpaperStyle"="0" */ } } break; case IDM_TASKPAD: case IDM_CUSTOMPAD: case IDM_TASKPAD_LISTVIEW: case IDM_DEFAULT_LISTVIEW: case IDM_TASKPAD_WALLPAPER_OPTIONS: if (cdo->GetCookie() == 0) { HSCOPEITEM root = m_pComponentData->GetRoot(); if (root) { // we should now be ready for taskpad "view" m_IsTaskPad = nCommandID; // set before selecting node // cause new view to be "created" m_pConsole->SelectScopeItem (root); } } return S_OK; case IDM_DELETECHILDREN: if (g_root_scope_item != 0) m_pComponentData->myDeleteItem (g_root_scope_item, TRUE); return S_OK; case IDM_RENAMEROOT: if (g_root_scope_item != 0) m_pComponentData->myRenameItem (g_root_scope_item, L"Yippee!"); return S_OK; case IDM_RENAMEWALL: if (m_toggle) m_toggle = FALSE; else m_toggle = TRUE; m_pComponentData->myRenameItem (m_pComponentData->GetWallPaperNode(), NULL); return S_OK; case IDM_CHANGEICON: m_pComponentData->myChangeIcon (); return S_OK; case IDM_PRELOAD: m_pComponentData->myPreLoad(); return S_OK; case IDM_CONSOLEVERB: TestConsoleVerb(); return S_OK; default: return E_UNEXPECTED; } return OnDblClick (pDataObject, NULL, NULL); // note what I'm passing! } long CComponent::GetViewMode () { long vm = LVS_ICON; if (m_pResultData) m_pResultData->GetViewMode (&vm); return vm; } /////////////////////////////////////////////////////////////////////////////// // IExtendTaskPad interface members HRESULT CComponent::TaskNotify (IDataObject * pdo, VARIANT * pvarg, VARIANT * pvparam) { if (pvarg->vt == VT_BSTR) { USES_CONVERSION; OLECHAR * path = pvarg->bstrVal; // replace any '*' with ' ': see enumtask.cpp // hash mechanism can't handle spaces, and // filenames can't have '*'s, so this works out ok. OLECHAR * temp; while (temp = wcschr (path, '*')) *temp = ' '; // now go do it! SystemParametersInfo (SPI_SETDESKWALLPAPER, 0, (void *)OLE2T(path), SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE); return S_OK; } if (pvarg->vt == VT_I4) { switch (pvarg->lVal) { case 1: if (m_pComponentData->GetWallPaperNode () != (HSCOPEITEM)0) { _ASSERT (m_pConsole != NULL); m_pConsole->SelectScopeItem (m_pComponentData->GetWallPaperNode()); return S_OK; } break; case 2: // Center return ApplyOption (IDM_CENTER); case 3: // Tile return ApplyOption (IDM_TILE); case 4: // Stretch return ApplyOption (IDM_STRETCH); case -1: if (m_toggleEntry == FALSE) m_toggleEntry = TRUE; else m_toggleEntry = FALSE; // empty and repopulate listpad m_pResultData->DeleteAllRsltItems(); m_pHeaderCtrl->DeleteColumn (0); OnListPad (NULL, TRUE, 0); return S_OK; } } ::MessageBox (NULL, _T("unrecognized task notification"), _T("Display Manager"), MB_OK); return S_OK; } HRESULT CComponent::GetTitle (LPOLESTR szGroup, LPOLESTR * pszTitle) { *pszTitle = CoTaskDupString (L"Display Manager TaskPad"); if (!pszTitle) return E_OUTOFMEMORY; return S_OK; } HRESULT CComponent::GetDescriptiveText (LPOLESTR szGroup, LPOLESTR * pszTitle) { *pszTitle = CoTaskDupString (L"Bill's Handy-Dandy Display Manager TaskPad Sample"); if (!pszTitle) return E_OUTOFMEMORY; return S_OK; } HRESULT CComponent::GetBackground (LPOLESTR szGroup, MMC_TASK_DISPLAY_OBJECT * pdo) { USES_CONVERSION; if(NULL==szGroup) return E_FAIL; if (szGroup[0] == 0) { // bitmap case pdo->eDisplayType = MMC_TASK_DISPLAY_TYPE_BITMAP; MMC_TASK_DISPLAY_BITMAP *pdb = &pdo->uBitmap; // fill out bitmap URL TCHAR szBuffer[MAX_PATH*2]; // that should be enough _tcscpy (szBuffer, _T("res://")); ::GetModuleFileName (g_hinst, szBuffer + _tcslen(szBuffer), MAX_PATH); _tcscat (szBuffer, _T("/img\\ntbanner.gif")); pdb->szMouseOverBitmap = CoTaskDupString (T2OLE(szBuffer)); if (pdb->szMouseOverBitmap) return S_OK; return E_OUTOFMEMORY; } else { // symbol case pdo->eDisplayType = MMC_TASK_DISPLAY_TYPE_SYMBOL; MMC_TASK_DISPLAY_SYMBOL *pds = &pdo->uSymbol; // fill out symbol stuff pds->szFontFamilyName = CoTaskDupString (L"Kingston"); // name of font family if (pds->szFontFamilyName) { TCHAR szBuffer[MAX_PATH*2]; // that should be enough _tcscpy (szBuffer, _T("res://")); ::GetModuleFileName (g_hinst, szBuffer + _tcslen(szBuffer), MAX_PATH); _tcscat (szBuffer, _T("/KINGSTON.eot")); pds->szURLtoEOT = CoTaskDupString (T2OLE(szBuffer)); // "res://"-type URL to EOT file if (pds->szURLtoEOT) { pds->szSymbolString = CoTaskDupString (T2OLE(_T("A
BCDEFGHIJKLMNOPQRSTUVWXYZ"))); // 1 or more symbol characters if (pds->szSymbolString) return S_OK; CoTaskFreeString (pds->szURLtoEOT); } CoTaskFreeString (pds->szFontFamilyName); } return E_OUTOFMEMORY; } } HRESULT CComponent::EnumTasks (IDataObject * pdo, LPOLESTR szTaskGroup, IEnumTASK** ppEnumTASK) { HRESULT hresult = S_OK; CEnumTasks * pet = new CEnumTasks; if (!pet) hresult = E_OUTOFMEMORY; else { pet->AddRef (); // make sure release works properly on failure hresult = pet->Init (pdo, szTaskGroup); if (hresult == S_OK) hresult = pet->QueryInterface (IID_IEnumTASK, (void **)ppEnumTASK); pet->Release (); } return hresult; } HRESULT CComponent::GetListPadInfo (LPOLESTR szGroup, MMC_LISTPAD_INFO * pListPadInfo) { pListPadInfo->szTitle = CoTaskDupString (L"Display Manager ListPad Title"); pListPadInfo->szButtonText = CoTaskDupString (L"Change..."); pListPadInfo->nCommandID = -1; return S_OK; } HRESULT ApplyOption (int nCommandID) { switch (nCommandID) { case IDM_TILE: case IDM_CENTER: case IDM_STRETCH: // write registry key: { HKEY hkey; HRESULT r = RegOpenKeyEx (HKEY_CURRENT_USER, _T("Control Panel\\Desktop"), 0, KEY_ALL_ACCESS, &hkey); if (r == ERROR_SUCCESS) { // write new value(s) DWORD dwType = REG_SZ; TCHAR szBuffer[2]; // first do "TileWallpaper" if (nCommandID == IDM_TILE) lstrcpy (szBuffer, _T("1")); else lstrcpy (szBuffer, _T("0")); DWORD dwCount = sizeof(TCHAR)*(1+lstrlen (szBuffer)); r = RegSetValueEx (hkey, (LPCTSTR)_T("TileWallpaper"), NULL, dwType, (CONST BYTE *)&szBuffer, dwCount); // then do "WallpaperStyle" if (nCommandID == IDM_STRETCH) lstrcpy (szBuffer, _T("2")); else lstrcpy (szBuffer, _T("0")); r = RegSetValueEx (hkey, (LPCTSTR)_T("WallpaperStyle"), NULL, dwType, (CONST BYTE *)&szBuffer, dwCount); // close up shop RegCloseKey(hkey); _ASSERT(r == ERROR_SUCCESS); /* [HKEY_CURRENT_USER\Control Panel\Desktop] "CoolSwitch"="1" "CoolSwitchRows"="3" "CoolSwitchColumns"="7" "CursorBlinkRate"="530" "ScreenSaveTimeOut"="900" "ScreenSaveActive"="0" "ScreenSaverIsSecure"="0" "Pattern"="(None)" "Wallpaper"="C:\\WINNT\\dax.bmp" "TileWallpaper"="0" "GridGranularity"="0" "IconSpacing"="75" "IconTitleWrap"="1" "IconTitleFaceName"="MS Sans Serif" "IconTitleSize"="9" "IconTitleStyle"="0" "DragFullWindows"="1" "HungAppTimeout"="5000" "WaitToKillAppTimeout"="20000" "AutoEndTasks"="0" "FontSmoothing"="0" "MenuShowDelay"="400" "DragHeight"="2" "DragWidth"="2" "WheelScrollLines"="3" "WallpaperStyle"="0" */ } if (r == ERROR_SUCCESS) ::MessageBox (NULL, _T("Option set Successfully!"), _T("Display Manager"), MB_OK); return r; } default: break; } return S_FALSE; } void CComponent::TestConsoleVerb(void) { IConsoleVerb* pConsoleVerb = NULL; m_pConsole->QueryConsoleVerb (&pConsoleVerb); _ASSERT (pConsoleVerb != NULL); if (pConsoleVerb) { pConsoleVerb->SetVerbState (MMC_VERB_PASTE, ENABLED, TRUE); pConsoleVerb->Release(); } }