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.