|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1999 - 1999
//
// File: mmcctrl.cpp
//
//--------------------------------------------------------------------------
// MMCCtrl.cpp : Implementation of CMMCCtrl
#include "stdafx.h"
#include "cic.h"
#include "MMCCtrl.h"
#include "MMCTask.h"
#include "DispObj.h"
#include "MMClpi.h"
#include "amcmsgid.h"
#include "findview.h"
#include "strings.h"
void CMMCCtrl::DoConnect () { // if we're not connected...
if (m_spTaskPadHost == NULL) { HWND hwnd = FindMMCView(*dynamic_cast<CComControlBase*>(this)); if (hwnd) Connect (hwnd); } }
void CMMCCtrl::Connect (HWND wndCurrent) { HWND hwndView = FindMMCView(wndCurrent);
if (hwndView) { // get the control's IUnknown
IUnknownPtr spunk; ControlQueryInterface (IID_IUnknown, (void **)&spunk); if (spunk != NULL) { IUnknownPtr spunkMMC; ::SendMessage (hwndView, MMC_MSG_CONNECT_TO_CIC, (WPARAM)&spunkMMC, (LPARAM)(spunk.GetInterfacePtr())); if (spunkMMC != NULL) m_spTaskPadHost = spunkMMC; } } }
/////////////////////////////////////////////////////////////////////////////
// CMMCCtrl
HRESULT CMMCCtrl::OnDraw(ATL_DRAWINFO& di) { if (m_spTaskPadHost == NULL) { // get window from di and find console window
HWND wndCurrent = WindowFromDC (di.hdcDraw); if (wndCurrent) Connect (wndCurrent); } return S_OK; }
HRESULT CMMCCtrl::OnDrawAdvanced(ATL_DRAWINFO & di) { return OnDraw (di); }
STDMETHODIMP CMMCCtrl::TaskNotify(BSTR szClsid, VARIANT * pvArg, VARIANT * pvParam) { DoConnect(); // connect, if not already connected
if(m_spTaskPadHost != NULL) return m_spTaskPadHost->TaskNotify (szClsid, pvArg, pvParam); return E_FAIL; }
STDMETHODIMP CMMCCtrl::GetFirstTask(BSTR szTaskGroup, IDispatch** retval) { // called by script, when it wants buttons, etc.
// validate parameters
_ASSERT (retval); _ASSERT (!IsBadWritePtr(retval, sizeof(IDispatch*))); // TODO: how do I validate a BSTR?
if (retval == NULL || IsBadWritePtr(retval, sizeof(IDispatch*))) return E_INVALIDARG; // should be initialized to this already (see note below)
*retval = NULL;
DoConnect(); // connect, if not already connected
if (m_spTaskPadHost == NULL) // from note above:
return S_OK; // any error, pops up ugly script message box....
// "reset": if we have an old enumerator, blitz it.
if (m_spEnumTASK != NULL) m_spEnumTASK = NULL;
// get new enumerator
m_spTaskPadHost->GetTaskEnumerator (szTaskGroup, &m_spEnumTASK); if(m_spEnumTASK != NULL) return GetNextTask (retval); return S_OK; }
STDMETHODIMP CMMCCtrl::GetNextTask(IDispatch** retval) { // validate parameters
_ASSERT (retval); _ASSERT (!IsBadWritePtr(retval, sizeof(IDispatch*)));
if (retval == NULL || IsBadWritePtr(retval, sizeof(IDispatch*))) return E_INVALIDARG; if (m_spEnumTASK == NULL) return S_OK; // all outa enumerators
MMC_ITASK task; ZeroMemory (&task, sizeof(MMC_ITASK)); HRESULT hresult = m_spEnumTASK->Next (1, (MMC_TASK *)&task, NULL);
if (hresult != S_OK) { // out of tasks (and enumerators): no need to hang onto this any more.
m_spEnumTASK = NULL; return S_OK; } else { // convert MMC_ITASK to ITask object
CComObject<class CMMCTask>* ctask = NULL; hresult = CComObject<CMMCTask>::CreateInstance(&ctask); if (ctask) {
ctask->SetText (task.task.szText); ctask->SetHelp (task.task.szHelpString); ctask->SetClsid(task.szClsid);
hresult = ctask->SetDisplayObject (&task.task.sDisplayObject); if (hresult == S_OK) { switch (task.task.eActionType) { case MMC_ACTION_ID: hresult = ctask->SetCommandID (task.task.nCommandID); break; case MMC_ACTION_LINK: hresult = ctask->SetActionURL (task.task.szActionURL); break; case MMC_ACTION_SCRIPT: hresult = ctask->SetScript (task.task.szScript); break; default: _ASSERT (FALSE); // bad task
hresult = E_UNEXPECTED; break; } }
if (SUCCEEDED(hresult)) ctask->QueryInterface (IID_IDispatch, (void **)retval); else delete ctask; } }
FreeDisplayData (&task.task.sDisplayObject); if (task.task.szText) CoTaskMemFree (task.task.szText); if (task.task.szHelpString) CoTaskMemFree (task.task.szHelpString); if (task.szClsid) CoTaskMemFree (task.szClsid); if (task.task.eActionType != MMC_ACTION_ID) if (task.task.szScript) CoTaskMemFree (task.task.szScript);
return S_OK; }
STDMETHODIMP CMMCCtrl::GetTitle(BSTR szTaskGroup, BSTR * retval) { DoConnect(); // connect, if not already connected
if (m_spTaskPadHost) m_spTaskPadHost->GetTitle (szTaskGroup, retval); return S_OK; }
STDMETHODIMP CMMCCtrl::GetDescriptiveText(BSTR szTaskGroup, BSTR * retval) { DoConnect(); // connect, if not already connected
if (m_spTaskPadHost) m_spTaskPadHost->GetDescriptiveText (szTaskGroup, retval); return S_OK; }
STDMETHODIMP CMMCCtrl::GetBackground(BSTR szTaskGroup, IDispatch** retval) { DoConnect(); // connect, if not already connected
*retval = NULL; if (m_spTaskPadHost) {
MMC_TASK_DISPLAY_OBJECT tdo; ZeroMemory (&tdo, sizeof(tdo));
// pass struct to host (which will pass to snapin)
m_spTaskPadHost->GetBackground (szTaskGroup, &tdo);
// convert struct to IDispatch object
CComObject<class CMMCDisplayObject>* cdo = NULL; CComObject<CMMCDisplayObject>::CreateInstance(&cdo); if (cdo) { cdo->Init (&tdo); IDispatchPtr spIDispatch = cdo; if (*retval = spIDispatch) spIDispatch.Detach(); } FreeDisplayData (&tdo); } return S_OK; }
STDMETHODIMP CMMCCtrl::GetListPadInfo (BSTR szGroup, IDispatch** retval) { *retval = NULL; DoConnect(); // connect, if not already connected
if (m_spTaskPadHost == NULL) return S_OK;
MMC_ILISTPAD_INFO ilpi; ZeroMemory (&ilpi, sizeof(MMC_ILISTPAD_INFO)); m_spTaskPadHost->GetListPadInfo (szGroup, &ilpi);
// convert struct to IDispatch
CComObject<class CMMCListPadInfo>* clpi = NULL; HRESULT hr = CComObject<CMMCListPadInfo>::CreateInstance(&clpi); if (clpi) { // always set clsid, title, button text, even if NULL or empty strings
if (ilpi.szClsid) hr = clpi->SetClsid (ilpi.szClsid); if (hr == S_OK && ilpi.info.szTitle) hr = clpi->SetTitle (ilpi.info.szTitle); if (hr == S_OK) hr = clpi->SetNotifyID (ilpi.info.nCommandID); if (hr == S_OK && ilpi.info.szButtonText) hr = clpi->SetText (ilpi.info.szButtonText);
// NULL button text => no button
// empty button text => button without any text
if (hr == S_OK) hr = clpi->SetHasButton (ilpi.info.szButtonText != NULL);
if (SUCCEEDED(hr)) clpi->QueryInterface (IID_IDispatch, (void **)retval); else delete clpi; }
// free resources
if (ilpi.szClsid) CoTaskMemFree (ilpi.szClsid); if (ilpi.info.szTitle) CoTaskMemFree (ilpi.info.szTitle); if (ilpi.info.szButtonText) CoTaskMemFree (ilpi.info.szButtonText); return S_OK; }
void CMMCCtrl::FreeDisplayData (MMC_TASK_DISPLAY_OBJECT* pdo) { switch (pdo->eDisplayType) { default: break; case MMC_TASK_DISPLAY_TYPE_SYMBOL: if (pdo->uSymbol.szFontFamilyName) CoTaskMemFree (pdo->uSymbol.szFontFamilyName); if (pdo->uSymbol.szURLtoEOT) CoTaskMemFree (pdo->uSymbol.szURLtoEOT); if (pdo->uSymbol.szSymbolString) CoTaskMemFree (pdo->uSymbol.szSymbolString); break; case MMC_TASK_DISPLAY_TYPE_BITMAP: case MMC_TASK_DISPLAY_TYPE_VANILLA_GIF: case MMC_TASK_DISPLAY_TYPE_CHOCOLATE_GIF: if (pdo->uBitmap.szMouseOverBitmap) CoTaskMemFree (pdo->uBitmap.szMouseOverBitmap); if (pdo->uBitmap.szMouseOffBitmap) CoTaskMemFree (pdo->uBitmap.szMouseOffBitmap); break; } }
|