home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Troubleshooting Netware Systems
/
CSTRIAL0196.BIN
/
attach
/
msj
/
v10n08
/
oleq0895.exe
/
IFDROP.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1995-08-01
|
7KB
|
264 lines
#define STRICT
#include <windows.h>
#include <windowsx.h>
#include "resource.h"
// include ANSI/UNICODE shims
#include "S816.h"
// reentrant thread-safe version of GetInterfaceName
BOOL GetInterfaceName(REFIID riid,
LPTSTR szName,
LONG cb)
{
BOOL result = FALSE;
*szName = 0;
HKEY hkey;
// open the Interface (IID) key
LONG r = RegOpenKeyEx( HKEY_CLASSES_ROOT, __TEXT("Interface"),
0, KEY_QUERY_VALUE, &hkey);
if (r == ERROR_SUCCESS)
{
OLECHAR szGuid[64];
// convert IID to a string (unicode)
StringFromGUID2(riid, szGuid, sizeof(szGuid));
// read value at corresponding key
r = RegQueryValue(hkey, __TEXTCVAR(szGuid), szName, &cb);
result = (r == ERROR_SUCCESS);
RegCloseKey(hkey);
}
return result;
}
// convenient non-tread-safe version (note static data)
LPCTSTR GetInterfaceName(REFIID riid)
{
static TCHAR szName[128];
if (!GetInterfaceName(riid, szName, sizeof(szName)))
lstrcpy(szName, __TEXT("Unknown IID"));
return szName;
}
// test for a single interface
BOOL IsInterfaceSupported(IUnknown *punk,
REFIID riid)
{
// try interface
IUnknown *punkIf;
HRESULT hr = punk->QueryInterface(riid, (void**)&punkIf);
// clean up
if (SUCCEEDED(hr))
punkIf->Release();
return SUCCEEDED(hr);
}
// Test for all registered interfaces
DWORD GetSupportedInterfaces(IUnknown *punk,
IID *iids,
DWORD nArraySize)
{
DWORD result = 0;
HKEY hkey;
// open the Interface (IID) key
LONG r = RegOpenKeyEx( HKEY_CLASSES_ROOT, __TEXT("Interface"),
0, KEY_QUERY_VALUE, &hkey);
if (r == ERROR_SUCCESS)
{
DWORD index = 0;
TCHAR szGuid[128];
// get each subkey
while (ERROR_SUCCESS == RegEnumKey(hkey, index, szGuid, sizeof(szGuid)))
{
// convert key name to GUID (note: IIDFromString is not const-correct)
IID iid;
IIDFromString(LPOLESTR(LPCOLESTR(OLESTRCVAR(szGuid))), &iid);
// test the IID and append to array if supported
if (IsInterfaceSupported(punk, iid) && result < nArraySize)
iids[result++] = iid;
index++;
}
RegCloseKey(hkey);
}
return result;
}
// a simple COM class to implement our drop target
class CoDrop : public IDropTarget {
ULONG m_cRef;
HWND m_hwndDlg;
public:
CoDrop(HWND hwndDlg = 0)
: m_cRef(1), // note: no class factory
m_hwndDlg(hwndDlg)
{
}
void SetHwnd(HWND hwndDlg)
{
m_hwndDlg = hwndDlg;
}
STDMETHODIMP QueryInterface(REFIID riid, void**ppv)
{
if (riid == IID_IUnknown || riid == IID_IDropTarget)
LPUNKNOWN(*ppv = LPDROPTARGET(this))->AddRef();
else
*ppv = 0;
return ResultFromScode(*ppv ? S_OK : E_NOINTERFACE);
}
// since object's of this class will not be heap-based,
// we'll just cheat on AddRef/Release
STDMETHODIMP_(ULONG) AddRef(void) { return 2; }
STDMETHODIMP_(ULONG) Release(void) { return 1; }
// DragEnter, DragOver and DragLeave are all no-ops
STDMETHODIMP DragEnter(LPDATAOBJECT, DWORD, POINTL, DWORD *pdwEffect)
{
*pdwEffect = DROPEFFECT_COPY;
return NOERROR;
}
STDMETHODIMP DragOver(DWORD, POINTL, DWORD *pdwEffect)
{
*pdwEffect = DROPEFFECT_COPY;
return NOERROR;
}
STDMETHODIMP DragLeave(void)
{
return NOERROR;
}
// Drop is where we do the actual querying of the object
STDMETHODIMP Drop(LPDATAOBJECT lpdo, DWORD, POINTL, DWORD *pdwEffect)
{
IUnknown *punkTarget = 0;
IStorage *lpStg = 0;
// We're about to make a lot of out-of-proc calls,
// so at least attempt to give the user some feedback
HCURSOR hcur = GetCursor();
SetCursor(LoadCursor(0, IDC_WAIT));
// Try to get at an embedded object if possible
if (NOERROR == OleQueryCreateFromData(lpdo))
{
// create a dummy storage for the object(STGM_DELETEONRELEASE)
StgCreateDocfile(0, STGM_DIRECT | STGM_READWRITE
| STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE,
0, &lpStg);
// attempt to create the embedding
if (SUCCEEDED(OleCreateFromData(lpdo, IID_IUnknown,
OLERENDER_NONE, 0, 0,
lpStg, (void**)&punkTarget)))
{
// put the object into the running state
// (otherwise, we're simply checking the handler)
OleRun(punkTarget);
// Get the ProgID for display
CLSID clsid;
IPersist *ppersist;
punkTarget->QueryInterface(IID_IPersist, (void**)&ppersist);
if (ppersist)
{
ppersist->GetClassID(&clsid);
LPOLESTR szProgID;
ProgIDFromCLSID(clsid, &szProgID);
SetDlgItemText(m_hwndDlg, IDC_EDIT, __TEXTCVAR(szProgID));
ppersist->Release();
CoTaskMemFree(szProgID);
}
else
SetDlgItemText(m_hwndDlg, IDC_EDIT,
__TEXT("Unknown Embedding Type"));
}
}
else
{
// there is not embedding on the cursor,
// so just inspect the IDataObject
// that is on the cursor
(punkTarget = lpdo)->AddRef();
SetDlgItemText(m_hwndDlg, IDC_EDIT,
__TEXT("Simple Dragged Data Object"));
}
// OK, now get the list of supported interfaces
IID iids[32];
DWORD count = GetSupportedInterfaces(punkTarget, iids, 32);
// fill in the list box
SetCursor(hcur);
HWND hwndList = GetDlgItem(m_hwndDlg, IDC_LIST);
ListBox_ResetContent(hwndList);
for (DWORD i = 0; i < count; i++)
{
ListBox_AddString(hwndList, GetInterfaceName(iids[i]));
}
// release the storage and target objects
if (lpStg)
lpStg->Release();
punkTarget->Release();
// we certainly don't want to accept this object for real!
*pdwEffect = DROPEFFECT_NONE;
return NOERROR;
}
};
// declare a single instance of the DropTarget class
CoDrop codrop;
BOOL CALLBACK
DlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
// bind the drop target to the dialog
codrop.SetHwnd(hwnd);
RegisterDragDrop(hwnd, &codrop);
return TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDCANCEL)
EndDialog(hwnd, IDCANCEL);
return TRUE;
case WM_DESTROY:
// unbind the drop target from the dialog
RevokeDragDrop(hwnd);
return FALSE;
}
return FALSE;
}
// the standard WinMain for an Applet
int WINAPI
WinMain(HINSTANCE hinstance, HINSTANCE, LPSTR, int)
{
OleInitialize(0);
DialogBox(hinstance, MAKEINTRESOURCE(IDD_DIALOG1), 0, DlgProc);
OleUninitialize();
return 0;
}