SHELL32: implement ShellLink's IShellExtInit::Initialize() method

Mike McCormack mike at codeweavers.com
Mon Jun 13 08:41:50 CDT 2005


One step further towards correct handling of lnk files.  This enables 
the shell to load a link file from an IDataObject.

It appears that when you "open" a shelllink by double clicking on it, 
the ShellFolder that contains the link is queried with 
IShellFolder_GetUIObjectOf for an IDataObject interface to the object 
that was clicked on.

The shell (ShellExecute) then determines the CLSID of the object (.lnk 
-> lnkfile -> {0021401-0000-0000-C000-000000000046}, creates an object 
of that class, and calls IShellExtInit::Initialize() on it.

With the attached patch, we can load the .lnk file through the right method.

Mike


ChangeLog:
* implement ShellLink's IShellExtInit::Initialize() method
-------------- next part --------------
? dlls/shell32/tests/cabinet.c
? dlls/shell32/tests/pidl.c
Index: dlls/shell32/shelllink.c
===================================================================
RCS file: /home/wine/wine/dlls/shell32/shelllink.c,v
retrieving revision 1.95
diff -u -p -r1.95 shelllink.c
--- dlls/shell32/shelllink.c	13 Jun 2005 11:50:09 -0000	1.95
+++ dlls/shell32/shelllink.c	13 Jun 2005 13:36:47 -0000
@@ -33,6 +33,7 @@
  */
 
 #define COBJMACROS
+#define NONAMELESSUNION
 
 #include "wine/debug.h"
 #include "winerror.h"
@@ -2254,13 +2255,55 @@ ShellLink_ExtInit_Release( IShellExtInit
     return IShellLinkA_Release((IShellLinkA*)This);
 }
 
+/**************************************************************************
+ * ShellLink implementation of IShellExtInit::Initialize()
+ *
+ * Loads the shelllink from the dataobject the shell is pointing to.
+ */
 static HRESULT WINAPI
 ShellLink_ExtInit_Initialize( IShellExtInit* iface, LPCITEMIDLIST pidlFolder,
                               IDataObject *pdtobj, HKEY hkeyProgID )
 {
     _ICOM_THIS_From_IShellExtInit(IShellLinkImpl, iface);
-    FIXME("%p %p %p %p\n", This, pidlFolder, pdtobj, hkeyProgID );
-    return E_NOTIMPL;
+    FORMATETC format;
+    STGMEDIUM stgm;
+    UINT count;
+    HRESULT r = E_FAIL;
+
+    TRACE("%p %p %p %p\n", This, pidlFolder, pdtobj, hkeyProgID );
+
+    if( !pdtobj )
+        return r;
+
+    format.cfFormat = CF_HDROP;
+    format.ptd = NULL;
+    format.dwAspect = DVASPECT_CONTENT;
+    format.lindex = -1;
+    format.tymed = TYMED_HGLOBAL;
+
+    if( FAILED( IDataObject_GetData( pdtobj, &format, &stgm ) ) )
+        return r;
+
+    count = DragQueryFileW( stgm.u.hGlobal, -1, NULL, 0 );
+    if( count == 1 )
+    {
+        LPWSTR path;
+
+        count = DragQueryFileW( stgm.u.hGlobal, 0, NULL, 0 );
+        count++;
+        path = HeapAlloc( GetProcessHeap(), 0, count*sizeof(WCHAR) );
+        if( path )
+        {
+            IPersistFile *pf = (IPersistFile*) &This->lpvtblPersistFile;
+
+            count = DragQueryFileW( stgm.u.hGlobal, 0, path, count );
+            r = IPersistFile_Load( pf, path, 0 );
+            HeapFree( GetProcessHeap(), 0, path );
+        }
+    }
+    ReleaseStgMedium( &stgm );
+
+    return r;
 }
 
 static const IShellExtInitVtbl eivt =


More information about the wine-patches mailing list