|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1993.
//
// File: ext.cxx
//
// Contents: Shell extension handler for network objects
//
// Classes: CNetObj
//
// History: 26-Sep-95 BruceFo Created
//
//--------------------------------------------------------------------------
#include "headers.hxx"
#pragma hdrstop
#include <pages.hxx>
#define DONT_WANT_SHELLDEBUG
#include <shlobjp.h>
#include "resource.h"
#include "ext.hxx"
#include "util.hxx"
//--------------------------------------------------------------------------
//
// Shell DLL communication
//
typedef UINT (WINAPI *SHELLGETNETRESOURCE)( HNRES hnres, UINT iItem, LPNETRESOURCE pnresOut, UINT cbMax );
HINSTANCE g_hShellLibrary = NULL; SHELLGETNETRESOURCE g_pFuncGNR = NULL; UINT g_cfNetResource = 0;
BOOL LoadShellDllEntries(VOID);
//--------------------------------------------------------------------------
/*
* Helper functions used to communicate with shell32.dll */
BOOL LoadShellDllEntries(VOID) { if (g_hShellLibrary) { return TRUE; }
g_hShellLibrary = LoadLibrary(TEXT("shell32.dll")); if (NULL == g_hShellLibrary) { return FALSE; }
g_pFuncGNR = (SHELLGETNETRESOURCE)GetProcAddress(g_hShellLibrary, (LPSTR)IntToPtr(SHGetNetResourceORD)); if (NULL == g_pFuncGNR) { return FALSE; }
return TRUE; }
//+-------------------------------------------------------------------------
//
// Member: CNetObj::CNetObj
//
// Synopsis: Constructor
//
// History: 4-Apr-95 BruceFo Created
//
//--------------------------------------------------------------------------
CNetObj::CNetObj( VOID ) : _uRefs(0), _pDataObject(NULL), _hkeyProgID(NULL) { INIT_SIG(CNetObj);
AddRef(); // give it the correct initial reference count. add to the DLL reference count
}
//+-------------------------------------------------------------------------
//
// Member: CNetObj::~CNetObj
//
// Synopsis: Destructor
//
// History: 4-Apr-95 BruceFo Created
//
//--------------------------------------------------------------------------
CNetObj::~CNetObj() { CHECK_SIG(CNetObj);
if (_pDataObject) { _pDataObject->Release(); }
if (_hkeyProgID) { LONG l = RegCloseKey(_hkeyProgID); if (l != ERROR_SUCCESS) { appDebugOut((DEB_ERROR, "CNetObj::destructor. Error closing registry key, 0x%08lx\n", l)); } _hkeyProgID = NULL; } }
//+-------------------------------------------------------------------------
//
// Member: CNetObj::Initialize
//
// Derivation: IShellExtInit
//
// Synopsis: Initialize the shell extension. Stashes away the argument data.
//
// History: 4-Apr-95 BruceFo Created
//
// Notes: This method can be called more than once.
//
//--------------------------------------------------------------------------
STDMETHODIMP CNetObj::Initialize( LPCITEMIDLIST pidlFolder, LPDATAOBJECT pDataObject, HKEY hkeyProgID ) { CHECK_SIG(CNetObj);
CNetObj::~CNetObj();
if (!LoadShellDllEntries()) { return E_FAIL; }
// Duplicate the pDataObject pointer
_pDataObject = pDataObject; if (pDataObject) { pDataObject->AddRef(); }
// Duplicate the handle
if (hkeyProgID) { LONG l = RegOpenKeyEx(hkeyProgID, NULL, 0L, MAXIMUM_ALLOWED, &_hkeyProgID); if (l != ERROR_SUCCESS) { appDebugOut((DEB_ERROR, "CNetObj::Initialize. Error duplicating registry key, 0x%08lx\n", l)); } }
return S_OK; }
//+-------------------------------------------------------------------------
//
// Member: CNetObj::AddPages
//
// Derivation: IShellPropSheetExt
//
// Synopsis: (from shlobj.h)
// "The explorer calls this member function when it finds a
// registered property sheet extension for a particular type
// of object. For each additional page, the extension creates
// a page object by calling CreatePropertySheetPage API and
// calls lpfnAddPage.
//
// Arguments: lpfnAddPage -- Specifies the callback function.
// lParam -- Specifies the opaque handle to be passed to the
// callback function.
//
// History: 4-Apr-95 BruceFo Created
//
//--------------------------------------------------------------------------
STDMETHODIMP CNetObj::AddPages( LPFNADDPROPSHEETPAGE lpfnAddPage, LPARAM lParam ) { CHECK_SIG(CNetObj);
//
// Call IDataObject::GetData asking for a g_cfNetResource (i.e., HNRES).
//
STGMEDIUM medium; FORMATETC fmte = { g_cfNetResource ? g_cfNetResource : (g_cfNetResource = RegisterClipboardFormat(CFSTR_NETRESOURCES)), NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; appAssert(NULL != _pDataObject); HRESULT hr = _pDataObject->GetData(&fmte, &medium); CHECK_HRESULT(hr); if (FAILED(hr)) { return hr; }
///////////////// Now I have a 'medium' to release
hr = S_OK;
HNRES hnres = medium.hGlobal;
// Get number of selected items
if (NULL != g_pFuncGNR) { UINT cItems = (*g_pFuncGNR)(hnres, (UINT)-1, NULL, 0); if (cItems > 0) { // Retrieve NETRESOURCE object from clipboard
LPNETRESOURCE pNetRes = (LPNETRESOURCE)_bufNetResource; UINT ret = (*g_pFuncGNR)(hnres, 0, pNetRes, MAX_ONE_RESOURCE); // Get first item
if (ret == 0) { // bad hnres?
appDebugOut((DEB_TRACE, "CNetObj::AddPages. SHGetNetResource returned 0\n")); // NOTE: this is really error
} else if (ret > MAX_ONE_RESOURCE) { // FEATURE: Resize the buf and try again
appDebugOut((DEB_TRACE, "CNetObj::AddPages. buffer too small, needs to be %d\n", ret)); } else { LPTSTR pszTemplate = NULL;
if (RESOURCEDISPLAYTYPE_NETWORK == pNetRes->dwDisplayType) { pszTemplate = MAKEINTRESOURCE(IDD_NETWORK_SUMMARYINFO); } else if (RESOURCEDISPLAYTYPE_DOMAIN == pNetRes->dwDisplayType) { pszTemplate = MAKEINTRESOURCE(IDD_WRKGRP_SUMMARYINFO); } else if (RESOURCEDISPLAYTYPE_SERVER == pNetRes->dwDisplayType) { pszTemplate = MAKEINTRESOURCE(IDD_SERVER_SUMMARYINFO); } else if (RESOURCEDISPLAYTYPE_SHARE == pNetRes->dwDisplayType) { pszTemplate = MAKEINTRESOURCE(IDD_SHARE_SUMMARYINFO); } else { appDebugOut((DEB_TRACE, "CNetObj::AddPages. Unknown net resource type!\n")); }
//
// Create a property sheet page object from a dialog box.
//
if (NULL != pszTemplate) { FillAndAddPage( lpfnAddPage, lParam, CPage::DlgProcPage, pszTemplate); } } } else { appDebugOut((DEB_TRACE, "CNetObj::AddPages. NO net resources!\n")); // NOTE: this is really error
} } else { appDebugOut((DEB_TRACE, "CNetObj::AddPages. No SHGetNetResource function!\n")); // NOTE: this is really error
}
ReleaseStgMedium(&medium); return hr; }
BOOL CNetObj::FillAndAddPage( LPFNADDPROPSHEETPAGE lpfnAddPage, LPARAM lParam, DLGPROC pfnDlg, LPTSTR pszTemplate ) { PROPSHEETPAGE psp; HPROPSHEETPAGE hpage;
psp.dwSize = sizeof(psp); // no extra data.
psp.dwFlags = PSP_USEREFPARENT; psp.hInstance = g_hInstance; psp.pszTemplate = pszTemplate; psp.hIcon = NULL; psp.pszTitle = NULL; psp.pfnDlgProc = pfnDlg; psp.pfnCallback = NULL; psp.pcRefParent = &g_NonOLEDLLRefs;
//
// We need to backlink ourselves because we are using member variable
// of this class.
//
psp.lParam = (LPARAM)this; this->AddRef();
hpage = CreatePropertySheetPage(&psp); if (NULL != hpage) { if (!lpfnAddPage(hpage, lParam)) { DestroyPropertySheetPage(hpage); } }
return TRUE; }
//+-------------------------------------------------------------------------
//
// Member: CNetObj::ReplacePages
//
// Derivation: IShellPropSheetExt
//
// Synopsis: (From shlobj.h)
// "The explorer never calls this member of property sheet
// extensions. The explorer calls this member of control panel
// extensions, so that they can replace some of default control
// panel pages (such as a page of mouse control panel)."
//
// Arguments: uPageID -- Specifies the page to be replaced.
// lpfnReplace -- Specifies the callback function.
// lParam -- Specifies the opaque handle to be passed to the
// callback function.
//
// History: 4-Apr-95 BruceFo Created
//
//--------------------------------------------------------------------------
STDMETHODIMP CNetObj::ReplacePage( UINT uPageID, LPFNADDPROPSHEETPAGE lpfnReplaceWith, LPARAM lParam ) { CHECK_SIG(CNetObj);
appAssert(!"CNetObj::ReplacePage called, not implemented"); return E_NOTIMPL; }
// dummy function to export to get linking to work
HRESULT PropDummyFunction() { return S_OK; }
|