SF.net SVN: geany: [2416] trunk

eht16 at users.sourceforge.net eht16 at xxxxx
Wed Mar 26 18:54:35 UTC 2008


Revision: 2416
          http://geany.svn.sourceforge.net/geany/?rev=2416&view=rev
Author:   eht16
Date:     2008-03-26 11:53:59 -0700 (Wed, 26 Mar 2008)

Log Message:
-----------
Add support for resolving Windows shortcuts when opening files and open the shortcut's target.

Modified Paths:
--------------
    trunk/ChangeLog
    trunk/src/document.c
    trunk/src/win32.c
    trunk/src/win32.h

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2008-03-26 17:52:27 UTC (rev 2415)
+++ trunk/ChangeLog	2008-03-26 18:53:59 UTC (rev 2416)
@@ -7,6 +7,9 @@
  * plugins/vcdiff.c:
    Fix two memory leaks and prevent showing two dialog boxes with the
    same error message.
+ * src/document.c, src/win32.c, src/win32.h:
+   Add support for resolving Windows shortcuts when opening files and
+   open the shortcut's target.
 
 
 2008-03-26  Nick Treleaven  <nick(dot)treleaven(at)btinternet(dot)com>

Modified: trunk/src/document.c
===================================================================
--- trunk/src/document.c	2008-03-26 17:52:27 UTC (rev 2415)
+++ trunk/src/document.c	2008-03-26 18:53:59 UTC (rev 2416)
@@ -71,6 +71,7 @@
 #include "callbacks.h"
 #include "geanyobject.h"
 #include "highlighting.h"
+#include "win32.h"
 
 
 /* dynamic array of document elements to hold all information of the notebook tabs */
@@ -996,7 +997,12 @@
 			return -1;
 		}
 
+#ifdef G_OS_WIN32
+		/* if filename is a shortcut, try to resolve it */
+		locale_filename = win32_get_shortcut_target(filename); 
+#else
 		locale_filename = g_strdup(filename);
+#endif
 		/* try to get the UTF-8 equivalent for the filename, fallback to filename if error */
 		utf8_filename = utils_get_utf8_from_locale(locale_filename);
 

Modified: trunk/src/win32.c
===================================================================
--- trunk/src/win32.c	2008-03-26 17:52:27 UTC (rev 2415)
+++ trunk/src/win32.c	2008-03-26 18:53:59 UTC (rev 2416)
@@ -1137,4 +1137,85 @@
 	return hTempFile;
 }
 
+
+/* From GDK (they got it from MS Knowledge Base article Q130698) */
+static gboolean resolve_link(HWND hWnd, wchar_t *link, gchar **lpszPath)
+{
+	WIN32_FILE_ATTRIBUTE_DATA wfad;
+	HRESULT hres;
+	IShellLinkW *pslW = NULL;
+	IPersistFile *ppf = NULL;
+
+	/* Check if the file is empty first because IShellLink::Resolve for some reason succeeds
+	 * with an empty file and returns an empty "link target". (#524151) */
+	if (!GetFileAttributesExW(link, GetFileExInfoStandard, &wfad) ||
+		(wfad.nFileSizeHigh == 0 && wfad.nFileSizeLow == 0))
+	{
+	  return FALSE;
+	}
+
+	/* Assume failure to start with: */
+	*lpszPath = 0;
+
+	CoInitialize(NULL);
+
+	hres = CoCreateInstance(
+		&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, &IID_IShellLinkW, (LPVOID *) &pslW);
+
+	if (SUCCEEDED(hres))
+	{
+		/* The IShellLink interface supports the IPersistFile interface.
+		 * Get an interface pointer to it. */
+		hres = pslW->lpVtbl->QueryInterface(pslW, &IID_IPersistFile, (LPVOID *) &ppf);
+	}     
+
+	if (SUCCEEDED(hres))
+	{
+		/* Load the file. */
+		hres = ppf->lpVtbl->Load(ppf, link, STGM_READ);
+	}
+
+	if (SUCCEEDED(hres))
+	{
+		/* Resolve the link by calling the Resolve() interface function. */
+		hres = pslW->lpVtbl->Resolve(pslW, hWnd, SLR_ANY_MATCH | SLR_NO_UI);
+	}
+
+	if (SUCCEEDED(hres))
+	{
+		wchar_t wtarget[MAX_PATH];
+
+		hres = pslW->lpVtbl->GetPath(pslW, wtarget, MAX_PATH, NULL, 0);
+		if (SUCCEEDED(hres))
+			*lpszPath = g_utf16_to_utf8(wtarget, -1, NULL, NULL, NULL);
+	}
+
+	if (ppf)
+		ppf->lpVtbl->Release(ppf);
+
+	if (pslW)
+		pslW->lpVtbl->Release(pslW);
+
+	return SUCCEEDED(hres);
+}
+
+
+/* Checks whether file_name is a Windows shortcut. file_name is expected in UTF-8 encoding.
+ * If file_name is a Windows shortcut, it returns the target in UTF-8 encoding.
+ * If it is not a shortcut, it returns a newly allocated copy of file_name. */
+gchar *win32_get_shortcut_target(const gchar *file_name)
+{
+	gchar *path = NULL;
+	wchar_t *wfilename = g_utf8_to_utf16(file_name, -1, NULL, NULL, NULL);
+
+	resolve_link(GDK_WINDOW_HWND(app->window->window), wfilename, &path);
+	g_free(wfilename);
+	
+	if (path == NULL)
+		return g_strdup(file_name);
+	else
+		return path;
+}
+
+
 #endif

Modified: trunk/src/win32.h
===================================================================
--- trunk/src/win32.h	2008-03-26 17:52:27 UTC (rev 2415)
+++ trunk/src/win32.h	2008-03-26 18:53:59 UTC (rev 2416)
@@ -59,4 +59,6 @@
 gboolean win32_spawn(const gchar *dir, gchar **argv, gchar **env, GSpawnFlags flags,
 					 gchar **std_out, gchar **std_err, gint *exit_status, GError **error);
 
+gchar *win32_get_shortcut_target(const gchar *file_name);
+
 #endif


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.



More information about the Commits mailing list