windows-nt/Source/XPSP1/NT/printscan/ui/extend/dll/extend.cpp
2020-09-26 16:20:57 +08:00

258 lines
6.2 KiB
C++

////////////////////////////////////
// (C) COPYRIGHT MICROSOFT CORP., 1998-1999
//
// FILE: EXTEND.CPP
//
// DESCRIPTION: Implements core DLL routines as well as web view extensions.
//
#include "precomp.h"
#pragma hdrstop
#include <string.h>
#include <tchar.h>
#include "resource.h"
#include "extidl_i.c"
CComModule _Module;
BEGIN_OBJECT_MAP(ObjectMap)
OBJECT_ENTRY(CLSID_TestShellExt, CShellExt)
OBJECT_ENTRY(CLSID_TestUIExtension, CWiaUIExtension)
END_OBJECT_MAP()
STDAPI DllRegisterServer(void)
{
// registers object, typelib and all interfaces in typelib
return _Module.RegisterServer(TRUE);
}
STDAPI DllUnregisterServer(void)
{
return _Module.UnregisterServer();
}
EXTERN_C
BOOL
DllMain(
HINSTANCE hinst,
DWORD dwReason,
LPVOID lpReserved)
{
switch (dwReason) {
case DLL_PROCESS_ATTACH:
_Module.Init (ObjectMap, hinst);
DisableThreadLibraryCalls(hinst);
break;
case DLL_PROCESS_DETACH:
_Module.Term();
break;
}
return TRUE;
}
extern "C" STDMETHODIMP DllCanUnloadNow(void)
{
return _Module.GetLockCount()==0 ? S_OK : S_FALSE;
}
extern "C" STDAPI DllGetClassObject(
REFCLSID rclsid,
REFIID riid,
LPVOID *ppv)
{
return _Module.GetClassObject(rclsid, riid, ppv);
}
/*****************************************************************************
ShowMessage
Utility function for displaying messageboxes
******************************************************************************/
BOOL ShowMessage (HWND hParent, INT idCaption, INT idMessage)
{
MSGBOXPARAMS mbp;
BOOL bRet;
INT i;
ZeroMemory (&mbp, sizeof(mbp));
mbp.cbSize = sizeof(mbp);
mbp.hwndOwner = hParent;
mbp.hInstance = g_hInst;
mbp.lpszText = MAKEINTRESOURCE(idMessage);
mbp.lpszCaption = MAKEINTRESOURCE(idCaption);
mbp.dwStyle = MB_OK | MB_APPLMODAL;
i = MessageBoxIndirect (&mbp);
bRet = (IDOK==i);
return bRet;
}
/*****************************************************************************
FindLastID
Utility for getting the last relative pidl from a full pidl
******************************************************************************/
// unsafe macros
#define _ILSkip(pidl, cb) ((LPITEMIDLIST)(((BYTE*)(pidl))+cb))
#define ILNext(pidl) _ILSkip(pidl, (pidl)->mkid.cb)
LPITEMIDLIST
FindLastID(LPCITEMIDLIST pidl)
{
LPCITEMIDLIST pidlLast = pidl;
LPCITEMIDLIST pidlNext = pidl;
if (pidl == NULL)
return NULL;
// Find the last one
while (pidlNext->mkid.cb)
{
pidlLast = pidlNext;
pidlNext = ILNext(pidlLast);
}
return (LPITEMIDLIST)pidlLast;
}
/*****************************************************************************
CreateDeviceFromID
Utility for attaching to WIA and getting a root IWiaItem interface
*****************************************************************************/
HRESULT
CreateDeviceFromId (LPWSTR szDeviceId, IWiaItem **ppItem)
{
IWiaDevMgr *pDevMgr;
HRESULT hr = CoCreateInstance (CLSID_WiaDevMgr,
NULL,
CLSCTX_LOCAL_SERVER,
IID_IWiaDevMgr,
reinterpret_cast<LPVOID*>(&pDevMgr));
if (SUCCEEDED(hr))
{
BSTR strId = SysAllocString (szDeviceId);
hr = pDevMgr->CreateDevice (strId, ppItem);
SysFreeString (strId);
pDevMgr->Release ();
}
return hr;
}
/*****************************************************************************\
GetNamesFromDataObject
Return the list of selected item identifiers. Each identifier is of the form
"<DEVICEID>::<FULL PATH NAME>". the list is double-null terminated
*****************************************************************************/
LPWSTR
GetNamesFromDataObject (IDataObject *lpdobj, UINT *puItems)
{
FORMATETC fmt;
STGMEDIUM stg;
LPWSTR szRet = NULL;
LPWSTR szCurrent;
UINT nItems;
size_t size;
if (puItems)
{
*puItems = 0;
}
fmt.cfFormat = (CLIPFORMAT) RegisterClipboardFormat (TEXT("WIAItemNames"));
fmt.dwAspect = DVASPECT_CONTENT;
fmt.lindex = -1;
fmt.ptd = NULL;
fmt.tymed = TYMED_HGLOBAL;
if (lpdobj && puItems && SUCCEEDED(lpdobj->GetData (&fmt, &stg)))
{
szCurrent = reinterpret_cast<LPWSTR>(GlobalLock (stg.hGlobal));
// count the number of items in the double-null terminated string
szRet = szCurrent;
nItems = 0;
while (*szRet)
{
nItems++;
while (*szRet)
{
szRet++;
}
szRet++;
}
*puItems = nItems;
size = (szRet-szCurrent+1)*sizeof(WCHAR);
szRet = new WCHAR[size];
CopyMemory (szRet, szCurrent, size);
GlobalUnlock (stg.hGlobal);
GlobalFree (stg.hGlobal);
}
return szRet;
}
CWiaUIExtension::CWiaUIExtension(void)
{
}
CWiaUIExtension::~CWiaUIExtension(void)
{
}
//
// IWiaUIExtension
//
STDMETHODIMP CWiaUIExtension::DeviceDialog( PDEVICEDIALOGDATA pDeviceDialogData )
{
//
// We are not going to implement an actual device dialog here. Just say "hi" and return.
//
MessageBox( NULL, TEXT("CWiaUIExtension::DeviceDialog is being called"), TEXT("DEBUG"), 0 );
return E_NOTIMPL;
}
STDMETHODIMP CWiaUIExtension::GetDeviceIcon( BSTR bstrDeviceId, HICON *phIcon, ULONG nSize )
{
//
// Load an icon, and copy it, using CopyIcon, so it will still be valid if our interface is freed
//
HICON hIcon = reinterpret_cast<HICON>(LoadImage( _Module.m_hInst, MAKEINTRESOURCE(IDI_TESTDEVICE), IMAGE_ICON, nSize, nSize, LR_DEFAULTCOLOR ));
if (hIcon)
{
*phIcon = CopyIcon(hIcon);
DestroyIcon(hIcon);
return S_OK;
}
return E_NOTIMPL;
}
STDMETHODIMP CWiaUIExtension::GetDeviceBitmapLogo( BSTR bstrDeviceId, HBITMAP *phBitmap, ULONG nMaxWidth, ULONG nMaxHeight )
{
//
// This method is never actually called currently. It is only here for future use.
//
MessageBox( NULL, TEXT("CWiaUIExtension::GetDeviceBitmapLogo is being called"), TEXT("DEBUG"), 0 );
return E_NOTIMPL;
}