Qt 4.8
qdesktopservices_win.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include <qsettings.h>
43 #include <qdir.h>
44 #include <private/qsystemlibrary_p.h>
45 #include <qurl.h>
46 #include <qstringlist.h>
47 #include <qprocess.h>
48 #include <qtemporaryfile.h>
49 #include <qcoreapplication.h>
50 
51 #include <qt_windows.h>
52 #include <shlobj.h>
53 #if !defined(Q_OS_WINCE)
54 # include <intshcut.h>
55 #else
56 # include <qguifunctions_wince.h>
57 #endif
58 
59 #ifndef CSIDL_MYMUSIC
60 #define CSIDL_MYMUSIC 13
61 #define CSIDL_MYVIDEO 14
62 #endif
63 
64 #ifndef QT_NO_DESKTOPSERVICES
65 
67 
68 static bool openDocument(const QUrl &file)
69 {
70  if (!file.isValid())
71  return false;
72  QString filePath = file.toLocalFile();
73  if (filePath.isEmpty())
74  filePath = file.toString();
75  quintptr returnValue = (quintptr)ShellExecute(0, 0, (wchar_t*)filePath.utf16(), 0, 0, SW_SHOWNORMAL);
76  return (returnValue > 32); //ShellExecute returns a value greater than 32 if successful
77 }
78 
79 static QString expandEnvStrings(const QString &command)
80 {
81 #if defined(Q_OS_WINCE)
82  return command;
83 #else
84  wchar_t buffer[MAX_PATH];
85  if (ExpandEnvironmentStrings((wchar_t*)command.utf16(), buffer, MAX_PATH))
86  return QString::fromWCharArray(buffer);
87  else
88  return command;
89 #endif
90 }
91 
92 static bool launchWebBrowser(const QUrl &url)
93 {
94  if (url.scheme() == QLatin1String("mailto")) {
95  //Retrieve the commandline for the default mail client
96  //the default key used below is the command line for the mailto: shell command
97  DWORD bufferSize = sizeof(wchar_t) * MAX_PATH;
98  long returnValue = -1;
99  QString command;
100 
101  HKEY handle;
102  LONG res;
103  wchar_t keyValue[MAX_PATH] = {0};
104  QString keyName(QLatin1String("mailto"));
105 
106  //Check if user has set preference, otherwise use default.
107  res = RegOpenKeyEx(HKEY_CURRENT_USER,
108  L"Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\mailto\\UserChoice",
109  0, KEY_READ, &handle);
110  if (res == ERROR_SUCCESS) {
111  returnValue = RegQueryValueEx(handle, L"Progid", 0, 0, reinterpret_cast<unsigned char*>(keyValue), &bufferSize);
112  if (!returnValue)
113  keyName = QString::fromUtf16((const ushort*)keyValue);
114  RegCloseKey(handle);
115  }
116  keyName += QLatin1String("\\Shell\\Open\\Command");
117  res = RegOpenKeyExW(HKEY_CLASSES_ROOT, (const wchar_t*)keyName.utf16(), 0, KEY_READ, &handle);
118  if (res != ERROR_SUCCESS)
119  return false;
120 
121  bufferSize = sizeof(wchar_t) * MAX_PATH;
122  returnValue = RegQueryValueEx(handle, L"", 0, 0, reinterpret_cast<unsigned char*>(keyValue), &bufferSize);
123  if (!returnValue)
124  command = QString::fromRawData((QChar*)keyValue, bufferSize);
125  RegCloseKey(handle);
126 
127  if (returnValue)
128  return false;
129 
130  command = expandEnvStrings(command);
131  command = command.trimmed();
132  //Make sure the path for the process is in quotes
133  int index = -1 ;
134  if (command[0]!= QLatin1Char('\"')) {
135  index = command.indexOf(QLatin1String(".exe "), 0, Qt::CaseInsensitive);
136  command.insert(index+4, QLatin1Char('\"'));
137  command.insert(0, QLatin1Char('\"'));
138  }
139  //pass the url as the parameter
140  index = command.lastIndexOf(QLatin1String("%1"));
141  if (index != -1){
142  command.replace(index, 2, url.toString());
143  }
144  //start the process
145  PROCESS_INFORMATION pi;
146  ZeroMemory(&pi, sizeof(pi));
147  STARTUPINFO si;
148  ZeroMemory(&si, sizeof(si));
149  si.cb = sizeof(si);
150 
151  returnValue = CreateProcess(NULL, (wchar_t*)command.utf16(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
152 
153  if (!returnValue)
154  return false;
155 
156  CloseHandle(pi.hProcess);
157  CloseHandle(pi.hThread);
158  return true;
159  }
160 
161  if (!url.isValid())
162  return false;
163 
164  if (url.scheme().isEmpty())
165  return openDocument(url);
166 
167  quintptr returnValue = (quintptr)ShellExecute(0, 0, (wchar_t *)QString::fromUtf8(url.toEncoded().constData()).utf16(),
168  0, 0, SW_SHOWNORMAL);
169  return (returnValue > 32);
170 }
171 
173 {
174  QString result;
175 
176 #ifndef Q_OS_WINCE
177  QSystemLibrary library(QLatin1String("shell32"));
178 #else
179  QSystemLibrary library(QLatin1String("coredll"));
180 #endif // Q_OS_WINCE
181  typedef BOOL (WINAPI*GetSpecialFolderPath)(HWND, LPWSTR, int, BOOL);
182  static GetSpecialFolderPath SHGetSpecialFolderPath =
183  (GetSpecialFolderPath)library.resolve("SHGetSpecialFolderPathW");
184  if (!SHGetSpecialFolderPath)
185  return QString();
186 
187  wchar_t path[MAX_PATH];
188 
189  switch (type) {
190  case DataLocation:
191 #if defined Q_WS_WINCE
192  if (SHGetSpecialFolderPath(0, path, CSIDL_APPDATA, FALSE))
193 #else
194  if (SHGetSpecialFolderPath(0, path, CSIDL_LOCAL_APPDATA, FALSE))
195 #endif
196  result = QString::fromWCharArray(path);
198  result = result + QLatin1String("\\") + QCoreApplication::organizationName();
200  result = result + QLatin1String("\\") + QCoreApplication::applicationName();
201  break;
202 
203  case DesktopLocation:
204  if (SHGetSpecialFolderPath(0, path, CSIDL_DESKTOPDIRECTORY, FALSE))
205  result = QString::fromWCharArray(path);
206  break;
207 
208  case DocumentsLocation:
209  if (SHGetSpecialFolderPath(0, path, CSIDL_PERSONAL, FALSE))
210  result = QString::fromWCharArray(path);
211  break;
212 
213  case FontsLocation:
214  if (SHGetSpecialFolderPath(0, path, CSIDL_FONTS, FALSE))
215  result = QString::fromWCharArray(path);
216  break;
217 
219  if (SHGetSpecialFolderPath(0, path, CSIDL_PROGRAMS, FALSE))
220  result = QString::fromWCharArray(path);
221  break;
222 
223  case MusicLocation:
224  if (SHGetSpecialFolderPath(0, path, CSIDL_MYMUSIC, FALSE))
225  result = QString::fromWCharArray(path);
226  break;
227 
228  case MoviesLocation:
229  if (SHGetSpecialFolderPath(0, path, CSIDL_MYVIDEO, FALSE))
230  result = QString::fromWCharArray(path);
231  break;
232 
233  case PicturesLocation:
234  if (SHGetSpecialFolderPath(0, path, CSIDL_MYPICTURES, FALSE))
235  result = QString::fromWCharArray(path);
236  break;
237 
238  case CacheLocation:
239  // Although Microsoft has a Cache key it is a pointer to IE's cache, not a cache
240  // location for everyone. Most applications seem to be using a
241  // cache directory located in their AppData directory
242  return storageLocation(DataLocation) + QLatin1String("\\cache");
243 
245  return QDir::homePath(); break;
246 
248  return QDir::tempPath(); break;
249 
250  default:
251  break;
252  }
253  return result;
254 }
255 
257 {
258  Q_UNUSED(type);
259  return QString();
260 }
261 
263 
264 #endif // QT_NO_DESKTOPSERVICES
static QString fromWCharArray(const wchar_t *, int size=-1)
Returns a copy of the string, where the encoding of string depends on the size of wchar...
Definition: qstring.cpp:1019
#define ShellExecute(a, b, c, d, e, f)
static QString keyName(const QString &rKey)
int type
Definition: qmetatype.cpp:239
bool isValid() const
Returns true if the URL is valid; otherwise returns false.
Definition: qurl.cpp:4303
QIntegerForSizeof< void * >::Unsigned quintptr
Definition: qglobal.h:986
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
QString toString(FormattingOptions options=None) const
Returns the human-displayable string representation of the URL.
Definition: qurl.cpp:5896
static QString storageLocation(StandardLocation type)
Returns the default system directory where files of type belong, or an empty string if the location c...
static QString displayName(StandardLocation type)
Returns a localized display name for the given location type or an empty QString if no relevant locat...
QString & replace(int i, int len, QChar after)
Definition: qstring.cpp:2005
StandardLocation
This enum describes the different locations that can be queried by QDesktopServices::storageLocation ...
static bool openDocument(const QUrl &file)
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
The QUrl class provides a convenient interface for working with URLs.
Definition: qurl.h:61
The QString class provides a Unicode character string.
Definition: qstring.h:83
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:72
static QString fromRawData(const QChar *, int size)
Constructs a QString that uses the first size Unicode characters in the array unicode.
Definition: qstring.cpp:7673
static bool launchWebBrowser(const QUrl &url)
#define CSIDL_MYVIDEO
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
static bool isEmpty(const char *str)
QString trimmed() const Q_REQUIRED_RESULT
Returns a string that has whitespace removed from the start and the end.
Definition: qstring.cpp:4506
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
static QString fromUtf8(const char *, int size=-1)
Returns a QString initialized with the first size bytes of the UTF-8 string str.
Definition: qstring.cpp:4302
int indexOf(QChar c, int from=0, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition: qstring.cpp:2838
#define FALSE
Synonym for false.
Definition: qglobal.h:1019
QString toLocalFile() const
Returns the path of this URL formatted as a local file path.
Definition: qurl.cpp:6412
static QString tempPath()
Returns the absolute path of the system&#39;s temporary directory.
Definition: qdir.cpp:1987
QByteArray toEncoded(FormattingOptions options=None) const
Returns the encoded representation of the URL if it&#39;s valid; otherwise an empty QByteArray is returne...
Definition: qurl.cpp:5949
const char * constData() const
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:433
QString scheme() const
Returns the scheme of the URL.
Definition: qurl.cpp:4550
void * resolve(const char *symbol)
#define CSIDL_MYMUSIC
unsigned short ushort
Definition: qglobal.h:995
int lastIndexOf(QChar c, int from=-1, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition: qstring.cpp:3000
#define CSIDL_APPDATA
Definition: qsettings.cpp:87
quint16 index
static QString organizationName()
static QString applicationName()
static QString expandEnvStrings(const QString &command)
QString & insert(int i, QChar c)
Definition: qstring.cpp:1671
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:55
static QString fromUtf16(const ushort *, int size=-1)
Returns a QString initialized with the first size characters of the Unicode string unicode (ISO-10646...
Definition: qstring.cpp:4329
const ushort * utf16() const
Returns the QString as a &#39;\0\&#39;-terminated array of unsigned shorts.
Definition: qstring.cpp:5290
static QString homePath()
Returns the absolute path of the user&#39;s home directory.
Definition: qdir.cpp:1942