home *** CD-ROM | disk | FTP | other *** search
/ Troubleshooting Netware Systems / CSTRIAL0196.BIN / attach / msj / v10n08 / oleq0895.exe / IFDROP.CPP < prev    next >
C/C++ Source or Header  |  1995-08-01  |  7KB  |  264 lines

  1. #define STRICT
  2. #include <windows.h>
  3. #include <windowsx.h>
  4.  
  5. #include "resource.h"
  6.  
  7. // include ANSI/UNICODE shims
  8. #include "S816.h"
  9.  
  10.  
  11. // reentrant thread-safe version of GetInterfaceName
  12.  
  13. BOOL GetInterfaceName(REFIID riid, 
  14.               LPTSTR szName, 
  15.               LONG cb)
  16. {
  17.   BOOL result = FALSE;
  18.   *szName = 0;
  19.   HKEY hkey;
  20.  
  21. // open the Interface (IID) key
  22.   LONG r = RegOpenKeyEx( HKEY_CLASSES_ROOT, __TEXT("Interface"),
  23.              0, KEY_QUERY_VALUE, &hkey);
  24.  
  25.   if (r == ERROR_SUCCESS) 
  26.      {
  27.      OLECHAR szGuid[64];
  28.      // convert IID to a string (unicode)
  29.      StringFromGUID2(riid, szGuid, sizeof(szGuid));
  30.  
  31.      // read value at corresponding key
  32.      r = RegQueryValue(hkey, __TEXTCVAR(szGuid), szName, &cb);
  33.      result = (r == ERROR_SUCCESS);
  34.      RegCloseKey(hkey);
  35.      }
  36.  
  37.   return result;
  38. }
  39.  
  40. // convenient non-tread-safe version (note static data)
  41.  
  42. LPCTSTR GetInterfaceName(REFIID riid)
  43. {
  44.    static TCHAR szName[128];
  45.    if (!GetInterfaceName(riid, szName, sizeof(szName)))
  46.       lstrcpy(szName, __TEXT("Unknown IID"));
  47.    return szName;
  48. }
  49.  
  50. // test for a single interface
  51. BOOL IsInterfaceSupported(IUnknown *punk, 
  52.               REFIID riid)
  53. {
  54.   // try interface
  55.   IUnknown *punkIf;
  56.   HRESULT hr = punk->QueryInterface(riid, (void**)&punkIf);
  57.   // clean up
  58.   if (SUCCEEDED(hr))
  59.     punkIf->Release();
  60.                      
  61.   return SUCCEEDED(hr); 
  62. }
  63.  
  64. // Test for all registered interfaces
  65. DWORD GetSupportedInterfaces(IUnknown *punk,
  66.                  IID *iids,
  67.                  DWORD nArraySize)
  68. {
  69.   DWORD result = 0;
  70.   HKEY hkey;
  71.  
  72.   // open the Interface (IID) key
  73.   LONG r = RegOpenKeyEx( HKEY_CLASSES_ROOT, __TEXT("Interface"),
  74.              0, KEY_QUERY_VALUE, &hkey);
  75.  
  76.   if (r == ERROR_SUCCESS) 
  77.      {
  78.      DWORD index = 0;
  79.      TCHAR szGuid[128];
  80.      // get each subkey
  81.      while (ERROR_SUCCESS == RegEnumKey(hkey, index, szGuid, sizeof(szGuid)))
  82.     {
  83.     // convert key name to GUID (note: IIDFromString is not const-correct)
  84.     IID iid;
  85.     IIDFromString(LPOLESTR(LPCOLESTR(OLESTRCVAR(szGuid))), &iid);
  86.  
  87.     // test the IID and append to array if supported
  88.     if (IsInterfaceSupported(punk, iid) && result < nArraySize)
  89.         iids[result++] = iid;
  90.     index++;
  91.     }
  92.      RegCloseKey(hkey);
  93.      }
  94.   return result;
  95. }
  96.  
  97.  
  98. // a simple COM class to implement our drop target
  99. class CoDrop : public IDropTarget {
  100.     ULONG m_cRef;
  101.     HWND m_hwndDlg;
  102. public:
  103.     CoDrop(HWND hwndDlg = 0)
  104.            : m_cRef(1),  // note: no class factory
  105.            m_hwndDlg(hwndDlg)
  106.     {
  107.     }
  108.  
  109.     void SetHwnd(HWND hwndDlg)
  110.     {
  111.        m_hwndDlg = hwndDlg;
  112.     }
  113.     
  114.     STDMETHODIMP QueryInterface(REFIID riid, void**ppv)
  115.        {
  116.        if (riid == IID_IUnknown || riid == IID_IDropTarget)
  117.            LPUNKNOWN(*ppv = LPDROPTARGET(this))->AddRef();
  118.        else
  119.            *ppv = 0;
  120.        return ResultFromScode(*ppv ? S_OK : E_NOINTERFACE);
  121.        }
  122.  
  123.     // since object's of this class will not be heap-based, 
  124.     // we'll just cheat on AddRef/Release
  125.     STDMETHODIMP_(ULONG) AddRef(void) { return 2; }
  126.     STDMETHODIMP_(ULONG) Release(void) { return 1; }
  127.  
  128.     // DragEnter, DragOver and DragLeave are all no-ops
  129.     STDMETHODIMP DragEnter(LPDATAOBJECT, DWORD, POINTL, DWORD *pdwEffect)
  130.        {
  131.        *pdwEffect = DROPEFFECT_COPY;
  132.        return NOERROR;
  133.        }
  134.  
  135.     STDMETHODIMP DragOver(DWORD, POINTL, DWORD *pdwEffect)
  136.        {
  137.        *pdwEffect = DROPEFFECT_COPY;
  138.        return NOERROR;
  139.        }
  140.  
  141.     STDMETHODIMP DragLeave(void)
  142.        {
  143.        return NOERROR;
  144.        }
  145.  
  146.     // Drop is where we do the actual querying of the object
  147.     STDMETHODIMP Drop(LPDATAOBJECT lpdo, DWORD, POINTL, DWORD *pdwEffect)
  148.        {
  149.        IUnknown *punkTarget = 0;
  150.        IStorage *lpStg = 0;
  151.  
  152.        // We're about to make a lot of out-of-proc calls, 
  153.        // so at least attempt to give the user some feedback
  154.        HCURSOR hcur = GetCursor();
  155.        SetCursor(LoadCursor(0, IDC_WAIT));
  156.  
  157.        // Try to get at an embedded object if possible
  158.        if (NOERROR == OleQueryCreateFromData(lpdo))
  159.           {
  160.           // create a dummy storage for the object(STGM_DELETEONRELEASE)
  161.           StgCreateDocfile(0, STGM_DIRECT | STGM_READWRITE 
  162.                   | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE,
  163.                   0, &lpStg);
  164.  
  165.           // attempt to create the embedding
  166.           if (SUCCEEDED(OleCreateFromData(lpdo, IID_IUnknown, 
  167.                 OLERENDER_NONE, 0, 0, 
  168.                 lpStg, (void**)&punkTarget))) 
  169.          {
  170.          // put the object into the running state 
  171.          // (otherwise, we're simply checking the handler)
  172.          OleRun(punkTarget);
  173.  
  174.          // Get the ProgID for display
  175.          CLSID clsid;
  176.          IPersist *ppersist;
  177.          punkTarget->QueryInterface(IID_IPersist, (void**)&ppersist);
  178.          if (ppersist)
  179.             {
  180.             ppersist->GetClassID(&clsid);
  181.             LPOLESTR szProgID;
  182.             ProgIDFromCLSID(clsid, &szProgID);
  183.             SetDlgItemText(m_hwndDlg, IDC_EDIT, __TEXTCVAR(szProgID));
  184.             ppersist->Release();
  185.             CoTaskMemFree(szProgID);
  186.             }
  187.          else
  188.             SetDlgItemText(m_hwndDlg, IDC_EDIT, 
  189.                    __TEXT("Unknown Embedding Type"));
  190.          }
  191.           }
  192.        else
  193.           {
  194.           // there is not embedding on the cursor, 
  195.           // so just inspect the IDataObject
  196.           // that is on the cursor
  197.           (punkTarget = lpdo)->AddRef();
  198.           SetDlgItemText(m_hwndDlg, IDC_EDIT, 
  199.                  __TEXT("Simple Dragged Data Object"));
  200.           }
  201.  
  202.        // OK, now get the list of supported interfaces
  203.        IID iids[32];
  204.        DWORD count = GetSupportedInterfaces(punkTarget, iids, 32);
  205.  
  206.        // fill in the list box
  207.        SetCursor(hcur);
  208.        HWND hwndList = GetDlgItem(m_hwndDlg, IDC_LIST);
  209.        ListBox_ResetContent(hwndList);
  210.  
  211.        for (DWORD i = 0; i < count; i++)
  212.           {
  213.           ListBox_AddString(hwndList, GetInterfaceName(iids[i]));
  214.           }
  215.  
  216.        // release the storage and target objects
  217.        if (lpStg) 
  218.           lpStg->Release();
  219.  
  220.           punkTarget->Release();
  221.  
  222.           // we certainly don't want to accept this object for real!
  223.           *pdwEffect = DROPEFFECT_NONE;
  224.           return NOERROR;
  225.        }
  226.  
  227. };
  228.  
  229. // declare a single instance of the DropTarget class
  230. CoDrop codrop;
  231.  
  232. BOOL CALLBACK 
  233. DlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  234. {
  235.    switch (message)
  236.       { 
  237.       case WM_INITDIALOG:
  238.      // bind the drop target to the dialog
  239.      codrop.SetHwnd(hwnd);
  240.      RegisterDragDrop(hwnd, &codrop);
  241.      return TRUE;
  242.       case WM_COMMAND:
  243.      if (LOWORD(wParam) == IDCANCEL)
  244.         EndDialog(hwnd, IDCANCEL);
  245.      return TRUE;
  246.       case WM_DESTROY:
  247.      // unbind the drop target from the dialog
  248.      RevokeDragDrop(hwnd);
  249.      return FALSE;
  250.       }
  251.  
  252.    return FALSE;
  253. }
  254.  
  255. // the standard WinMain for an Applet
  256. int WINAPI 
  257. WinMain(HINSTANCE hinstance, HINSTANCE, LPSTR, int)
  258. {
  259.    OleInitialize(0);
  260.    DialogBox(hinstance, MAKEINTRESOURCE(IDD_DIALOG1), 0, DlgProc);
  261.    OleUninitialize();
  262.    return 0;
  263. }
  264.