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.
 
 
 
 
 
 

1238 lines
42 KiB

//+-------------------------------------------------------------------------
//
// 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<LONG>(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<LONG>(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 <windowsx.h>
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<CDataObject *>(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<BR>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();
}
}