Changeset 135 for smplayer/trunk/src/winfileassoc.cpp
- Timestamp:
- Oct 24, 2012, 8:25:23 PM (13 years ago)
- Location:
- smplayer/trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
smplayer/trunk
- Property svn:mergeinfo changed
/smplayer/vendor/current merged: 133
- Property svn:mergeinfo changed
-
smplayer/trunk/src/winfileassoc.cpp
r124 r135 16 16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 17 18 19 18 Winfileassoc.cpp 20 19 21 Handles file associations in Windows Vista/XP/2000/NT/ME/98/95.20 Handles file associations in Windows 7/Vista/XP/2000. 22 21 We assume that the code is run without administrator privileges, so the associations are done for current user only. 23 22 System-wide associations require writing to HKEY_CLASSES_ROOT and we don't want to get our hands dirty with that. … … 25 24 26 25 Optionally, during uninstall, it would be a good idea to call RestoreFileAssociations for all media types so 27 that we can clean up the registry and restore the old associations for current user. 26 that we can clean up the registry and restore the old associations for current user. 28 27 29 28 Vista: 30 The code can only register the app as default program for selected extensions and check if it is the default. 29 The code can only register the app as default program for selected extensions and check if it is the default. 31 30 It cannot restore 'old' default application, since this doesn't seem to be possible with the current Vista API. 32 31 33 Tested on: Win98, Win2000, WinXP, Vista. 34 NOT tested on: Win95, ME and NT 4.0 (it should work on 95, ME; Not sure about NT 4.0). 32 Add libole32.a library if compiling with MinGW. In smplayer.pro, under 'win32 {': LIBS += libole32 33 34 Tested on: WinXP, Vista, Win7. 35 35 36 36 Author: Florin Braghis (florin@libertv.ro) … … 41 41 #include <QApplication> 42 42 #include <QFileInfo> 43 44 WinFileAssoc::WinFileAssoc( const QString ClassId, const QString AppName ) 45 { 46 m_ClassId = ClassId; 47 m_AppName = AppName; 48 m_ClassId2 = QFileInfo(QApplication::applicationFilePath()).fileName(); 49 } 50 51 //Associates all extensions in the fileExtensions list with current app. 52 //Returns number of extensions processed successfully. 53 int WinFileAssoc::CreateFileAssociations(const QStringList& fileExtensions) 54 { 55 if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA) 56 { 57 return VistaSetAppsAsDefault(fileExtensions); 58 } 59 60 QSettings RegCR ("HKEY_CLASSES_ROOT", QSettings::NativeFormat); //Read only on NT+ 61 QSettings RegCU ("HKEY_CURRENT_USER", QSettings::NativeFormat); 62 63 if (!RegCU.isWritable() || RegCU.status() != QSettings::NoError) 64 return 0; 65 66 if (RegCR.status() != QSettings::NoError) 67 return 0; 68 69 if (QSysInfo::WindowsVersion < QSysInfo::WV_NT && !RegCR.isWritable()) //Win98 70 return 0; 71 72 //Check if classId exists in the registry 73 if (!RegCR.contains(m_ClassId) && !RegCU.contains("Software/Classes/" + m_ClassId)) 74 { 75 //If doesn't exist (user didn't run the setup program), try to create the ClassId for current user. 76 if (!CreateClassId(QApplication::applicationFilePath(), "SMPlayer Media Player")) 77 return 0; 78 } 79 80 int count = 0; 81 foreach(const QString& fileExtension, fileExtensions) 82 { 83 QString ExtKeyName = QString("Software/Microsoft/Windows/CurrentVersion/Explorer/FileExts/.%1").arg(fileExtension); 84 QString ClassesKeyName = m_ClassId; 85 86 QString BackupKeyName = ClassesKeyName + "/" + fileExtension; 87 QString CUKeyName = "Software/Classes/." + fileExtension; 88 89 //Save current ClassId for current user 90 QString KeyVal = RegCU.value(CUKeyName + "/.").toString(); 91 92 if (KeyVal.length() == 0 || KeyVal == m_ClassId) 93 { 94 //No registered app for this extension for current user. 95 //Check the system-wide (HKEY_CLASSES_ROOT) ClassId for this extension 96 KeyVal = RegCR.value("." + fileExtension + "/.").toString(); 97 } 98 99 if (KeyVal != m_ClassId) 100 RegCU.setValue(CUKeyName + "/MPlayer_Backup", KeyVal); 101 102 //Save last ProgId and Application values from the Exts key 103 KeyVal = RegCU.value(ExtKeyName + "/Progid").toString(); 104 105 if (KeyVal != m_ClassId && KeyVal != m_ClassId2) 106 RegCU.setValue(ExtKeyName + "/MPlayer_Backup_ProgId", KeyVal); 107 108 KeyVal = RegCU.value(ExtKeyName + "/Application").toString(); 109 if (KeyVal != m_ClassId || KeyVal != m_ClassId2) 110 RegCU.setValue(ExtKeyName + "/MPlayer_Backup_Application", KeyVal); 111 112 //Create the associations 113 if (QSysInfo::WindowsVersion >= QSysInfo::WV_NT) 114 { 115 RegCU.setValue(CUKeyName + "/.", m_ClassId); //Extension class 116 RegCU.setValue(ExtKeyName + "/Progid", m_ClassId); //Explorer FileExt association 117 118 } 119 else 120 { 121 //Windows ME/98/95 support 122 RegCR.setValue("." + fileExtension + "/.", m_ClassId); 123 } 124 125 if (RegCU.status() == QSettings::NoError && RegCR.status() == QSettings::NoError) 126 count++; 127 } 128 129 return count; 130 } 131 132 //Checks if extensions in extensionsToCheck are registered with this application. Returns a list of registered extensions. 133 //Returns false if there was an error accessing the registry. 134 //Returns true and 0 elements in registeredExtensions if no extension is associated with current app. 135 bool WinFileAssoc::GetRegisteredExtensions( const QStringList& extensionsToCheck, QStringList& registeredExtensions) 136 { 137 registeredExtensions.clear(); 138 139 if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA) 140 { 141 return VistaGetDefaultApps(extensionsToCheck, registeredExtensions); 142 } 143 144 QSettings RegCR ("HKEY_CLASSES_ROOT", QSettings::NativeFormat); 145 QSettings RegCU ("HKEY_CURRENT_USER", QSettings::NativeFormat); 146 147 if (RegCR.status() != QSettings::NoError) 148 return false; 149 150 if (RegCU.status() != QSettings::NoError) 151 return false; 152 153 foreach(const QString& fileExtension, extensionsToCheck) 154 { 155 bool bRegistered = false; 156 //Check the explorer extension (Always use this program to open this kind of file...) 157 158 if (QSysInfo::WindowsVersion >= QSysInfo::WV_NT) 159 { 160 QString FileExtsKey = QString("Software/Microsoft/Windows/CurrentVersion/Explorer/FileExts/.%1").arg(fileExtension); 161 QString CurClassId = RegCU.value(FileExtsKey + "/Progid").toString(); 162 QString CurAppId = RegCU.value(FileExtsKey + "/Application").toString(); 163 164 if (CurClassId.size()) //Registered with Open With... / ProgId ? 165 { 166 bRegistered = (CurClassId == m_ClassId) || (0 == CurClassId.compare(m_ClassId2, Qt::CaseInsensitive)); 167 } 168 else 169 if (CurAppId.size()) 170 { 171 //If user uses Open With..., explorer creates it's own ClassId under Application, usually "smplayer.exe" 172 bRegistered = (CurAppId == m_ClassId) || (0 == CurAppId.compare(m_ClassId2, Qt::CaseInsensitive)); 173 } 174 else 175 { 176 //No classId means that no associations exists in Default Programs or Explorer 177 //Check the default per-user association 178 bRegistered = RegCU.value("Software/Classes/." + fileExtension + "/.").toString() == m_ClassId; 179 } 180 } 181 182 //Finally, check the system-wide association 183 if (!bRegistered) 184 bRegistered = RegCR.value("." + fileExtension + "/.").toString() == m_ClassId; 185 186 187 if (bRegistered) 188 registeredExtensions.append(fileExtension); 189 } 190 191 return true; 192 } 193 194 //Restores file associations to old defaults (if any) for all extensions in the fileExtensions list. 195 //Cleans up our backup keys from the registry. 196 //Returns number of extensions successfully processed (error if fileExtensions.count() != return value && count > 0). 197 int WinFileAssoc::RestoreFileAssociations(const QStringList& fileExtensions) 198 { 199 if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA) 200 return 0; //Not supported by the API 201 202 QSettings RegCR ("HKEY_CLASSES_ROOT", QSettings::NativeFormat); 203 QSettings RegCU ("HKEY_CURRENT_USER", QSettings::NativeFormat); 204 205 if (!RegCU.isWritable() || RegCU.status() != QSettings::NoError) 206 return 0; 207 208 if (RegCR.status() != QSettings::NoError) 209 return 0; 210 211 if (QSysInfo::WindowsVersion < QSysInfo::WV_NT && !RegCR.isWritable()) //Win98 212 return 0; 213 214 int count = 0; 215 foreach(const QString& fileExtension, fileExtensions) 216 { 217 QString ExtKeyName = QString("Software/Microsoft/Windows/CurrentVersion/Explorer/FileExts/.%1").arg(fileExtension); 218 QString OldProgId = RegCU.value(ExtKeyName + "/MPlayer_Backup_ProgId").toString(); 219 QString OldApp = RegCU.value(ExtKeyName + "/MPlayer_Backup_Application").toString(); 220 QString OldClassId = RegCU.value("Software/Classes/." + fileExtension + "/MPlayer_Backup").toString(); 221 222 //Restore old explorer ProgId 223 if (!OldProgId.isEmpty() && OldProgId != m_ClassId) 224 RegCU.setValue(ExtKeyName + "/Progid", OldProgId); 225 else 226 { 227 QString CurProgId = RegCU.value(ExtKeyName + "/Progid").toString(); 228 if ((CurProgId == m_ClassId) || (0 == CurProgId.compare(m_ClassId2, Qt::CaseInsensitive))) //Only remove if we own it 229 RegCU.remove(ExtKeyName + "/Progid"); 230 } 231 232 //Restore old explorer Application 233 if (!OldApp.isEmpty() && OldApp != m_ClassId) 234 RegCU.setValue(ExtKeyName + "/Application", OldApp); 235 else 236 { 237 QString CurApp = RegCU.value(ExtKeyName + "/Application").toString(); 238 if ((CurApp == m_ClassId) || (0 == CurApp.compare(m_ClassId2, Qt::CaseInsensitive))) //Only remove if we own it 239 RegCU.remove(ExtKeyName + "/Application"); 240 } 241 242 if (QSysInfo::WindowsVersion >= QSysInfo::WV_NT) 243 { 244 //Restore old association for current user 245 if (!OldClassId.isEmpty() && OldClassId != m_ClassId) 246 RegCU.setValue("Software/Classes/." + fileExtension + "/.", OldClassId); 247 else 248 { 249 if (RegCU.value("Software/Classes/." + fileExtension + "/.").toString() == m_ClassId) //Only remove if we own it 250 RegCU.remove("Software/Classes/." + fileExtension); 251 } 252 } 253 else 254 { 255 //Windows 98 ==> Write to HKCR 256 if (!OldClassId.isEmpty() && OldClassId != m_ClassId) 257 RegCR.setValue("." + fileExtension + "/.", OldClassId); 258 else 259 { 260 if (RegCR.value("." + fileExtension + "/.").toString() == m_ClassId) 261 RegCR.remove("." + fileExtension); 262 } 263 } 264 265 //Remove our keys: 266 //CurrentUserClasses/.ext/MPlayerBackup 267 //Explorer: Backup_Application and Backup_ProgId 268 RegCU.remove("Software/Classes/." + fileExtension + "/MPlayer_Backup"); 269 RegCU.remove(ExtKeyName + "/MPlayer_Backup_Application"); 270 RegCU.remove(ExtKeyName + "/MPlayer_Backup_ProgId"); 271 } 272 return count; 273 } 274 275 //Creates a ClassId for current application. 276 //Note: It's better to create the classId from the installation program. 277 bool WinFileAssoc::CreateClassId(const QString& executablePath, const QString& friendlyName) 278 { 279 QString RootKeyName; 280 QString classId; 281 282 if (QSysInfo::WindowsVersion >= QSysInfo::WV_NT) 283 { 284 classId = "Software/Classes/" + m_ClassId; 285 RootKeyName = "HKEY_CURRENT_USER"; 286 } 287 else 288 { 289 classId = m_ClassId; 290 RootKeyName = "HKEY_CLASSES_ROOT"; //Windows 95/98/ME 291 } 292 293 QSettings Reg (RootKeyName, QSettings::NativeFormat); 294 if (!Reg.isWritable() || Reg.status() != QSettings::NoError) 295 return false; 296 297 QString appPath = executablePath; 298 appPath.replace('/', '\\'); //Explorer gives 'Access Denied' if we write the path with forward slashes to the registry 299 300 //Add our ProgId to the HKCR classes 301 Reg.setValue(classId + "/shell/open/FriendlyAppName", friendlyName); 302 Reg.setValue(classId + "/shell/open/command/.", QString("\"%1\" \"%2\"").arg(appPath, "%1")); 303 Reg.setValue(classId + "/DefaultIcon/.", QString("\"%1\",1").arg(appPath)); 304 //Add "Enqueue" command 305 Reg.setValue(classId + "/shell/enqueue/.", QObject::tr("Enqueue in SMPlayer")); 306 Reg.setValue(classId + "/shell/enqueue/command/.", QString("\"%1\" -add-to-playlist \"%2\"").arg(appPath, "%1")); 307 return true; 308 } 309 //Remove ClassId from the registry. 310 //Called when no associations exist. Note: It's better to do this in the Setup program. 43 #include <windows.h> 44 45 WinFileAssoc::WinFileAssoc(const QString ClassId, const QString AppName) 46 { 47 m_ClassId = ClassId; 48 m_AppName = AppName; 49 m_ClassId2 = QFileInfo(QApplication::applicationFilePath()).fileName(); 50 } 51 52 // Associates all extensions in the fileExtensions list with current app. 53 // Returns number of extensions processed successfully. 54 int WinFileAssoc::CreateFileAssociations(const QStringList &fileExtensions) 55 { 56 if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA) { 57 return VistaSetAppsAsDefault(fileExtensions); 58 } 59 60 QSettings RegCR("HKEY_CLASSES_ROOT", QSettings::NativeFormat); //Read only on NT+ 61 QSettings RegCU("HKEY_CURRENT_USER", QSettings::NativeFormat); 62 63 if (!RegCU.isWritable() || RegCU.status() != QSettings::NoError) 64 return 0; 65 66 if (RegCR.status() != QSettings::NoError) 67 return 0; 68 69 // Check if classId exists in the registry 70 if (!RegCR.contains(m_ClassId) && !RegCU.contains("Software/Classes/" + m_ClassId)) { 71 // If doesn't exist (user didn't run the setup program), try to create the ClassId for current user. 72 if (!CreateClassId(QApplication::applicationFilePath(), "SMPlayer Media Player")) 73 return 0; 74 } 75 76 int count = 0; 77 foreach(const QString & fileExtension, fileExtensions) { 78 QString ExtKeyName = QString("Software/Microsoft/Windows/CurrentVersion/Explorer/FileExts/.%1").arg(fileExtension); 79 QString ClassesKeyName = m_ClassId; 80 81 QString BackupKeyName = ClassesKeyName + "/" + fileExtension; 82 QString CUKeyName = "Software/Classes/." + fileExtension; 83 84 // Save current ClassId for current user 85 QString KeyVal = RegCU.value(CUKeyName + "/.").toString(); 86 87 if (KeyVal.length() == 0 || KeyVal == m_ClassId) { 88 // No registered app for this extension for current user. 89 // Check the system-wide (HKEY_CLASSES_ROOT) ClassId for this extension 90 KeyVal = RegCR.value("." + fileExtension + "/.").toString(); 91 } 92 93 if (KeyVal != m_ClassId) 94 RegCU.setValue(CUKeyName + "/MPlayer_Backup", KeyVal); 95 96 // Save last ProgId and Application values from the Exts key 97 KeyVal = RegCU.value(ExtKeyName + "/Progid").toString(); 98 99 if (KeyVal != m_ClassId && KeyVal != m_ClassId2) 100 RegCU.setValue(ExtKeyName + "/MPlayer_Backup_ProgId", KeyVal); 101 102 KeyVal = RegCU.value(ExtKeyName + "/Application").toString(); 103 104 if (KeyVal != m_ClassId || KeyVal != m_ClassId2) 105 RegCU.setValue(ExtKeyName + "/MPlayer_Backup_Application", KeyVal); 106 107 // Create the associations 108 RegCU.setValue(CUKeyName + "/.", m_ClassId); // Extension class 109 RegCU.setValue(ExtKeyName + "/Progid", m_ClassId); // Explorer FileExt association 110 111 if (RegCU.status() == QSettings::NoError && RegCR.status() == QSettings::NoError) 112 count++; 113 } 114 115 return count; 116 } 117 118 // Checks if extensions in extensionsToCheck are registered with this application. Returns a list of registered extensions. 119 // Returns false if there was an error accessing the registry. 120 // Returns true and 0 elements in registeredExtensions if no extension is associated with current app. 121 bool WinFileAssoc::GetRegisteredExtensions(const QStringList &extensionsToCheck, QStringList ®isteredExtensions) 122 { 123 registeredExtensions.clear(); 124 125 if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA) { 126 return VistaGetDefaultApps(extensionsToCheck, registeredExtensions); 127 } 128 129 QSettings RegCR("HKEY_CLASSES_ROOT", QSettings::NativeFormat); 130 QSettings RegCU("HKEY_CURRENT_USER", QSettings::NativeFormat); 131 132 if (RegCR.status() != QSettings::NoError) 133 return false; 134 135 if (RegCU.status() != QSettings::NoError) 136 return false; 137 138 foreach(const QString & fileExtension, extensionsToCheck) { 139 bool bRegistered = false; 140 // Check the Explorer extension (Always use this program to open this kind of file...) 141 142 QString FileExtsKey = QString("Software/Microsoft/Windows/CurrentVersion/Explorer/FileExts/.%1").arg(fileExtension); 143 QString CurClassId = RegCU.value(FileExtsKey + "/Progid").toString(); 144 QString CurAppId = RegCU.value(FileExtsKey + "/Application").toString(); 145 146 if (CurClassId.size()) { // Registered with Open With... / ProgId ? 147 bRegistered = (CurClassId == m_ClassId) || (0 == CurClassId.compare(m_ClassId2, Qt::CaseInsensitive)); 148 } else if (CurAppId.size()) { 149 // If user uses Open With..., explorer creates it's own ClassId under Application, usually "smplayer.exe" 150 bRegistered = (CurAppId == m_ClassId) || (0 == CurAppId.compare(m_ClassId2, Qt::CaseInsensitive)); 151 } else { 152 // No classId means that no associations exists in Default Programs or Explorer 153 // Check the default per-user association 154 bRegistered = RegCU.value("Software/Classes/." + fileExtension + "/.").toString() == m_ClassId; 155 } 156 157 // Finally, check the system-wide association 158 if (!bRegistered) 159 bRegistered = RegCR.value("." + fileExtension + "/.").toString() == m_ClassId; 160 161 if (bRegistered) 162 registeredExtensions.append(fileExtension); 163 } 164 165 return true; 166 } 167 168 // Restores file associations to old defaults (if any) for all extensions in the fileExtensions list. 169 // Cleans up our backup keys from the registry. 170 // Returns number of extensions successfully processed (error if fileExtensions.count() != return value && count > 0). 171 int WinFileAssoc::RestoreFileAssociations(const QStringList &fileExtensions) 172 { 173 if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA) 174 return 0; // Not supported by the API 175 176 QSettings RegCR("HKEY_CLASSES_ROOT", QSettings::NativeFormat); 177 QSettings RegCU("HKEY_CURRENT_USER", QSettings::NativeFormat); 178 179 if (!RegCU.isWritable() || RegCU.status() != QSettings::NoError) 180 return 0; 181 182 if (RegCR.status() != QSettings::NoError) 183 return 0; 184 185 int count = 0; 186 foreach(const QString & fileExtension, fileExtensions) { 187 QString ExtKeyName = QString("Software/Microsoft/Windows/CurrentVersion/Explorer/FileExts/.%1").arg(fileExtension); 188 QString OldProgId = RegCU.value(ExtKeyName + "/MPlayer_Backup_ProgId").toString(); 189 QString OldApp = RegCU.value(ExtKeyName + "/MPlayer_Backup_Application").toString(); 190 QString OldClassId = RegCU.value("Software/Classes/." + fileExtension + "/MPlayer_Backup").toString(); 191 192 // Restore old explorer ProgId 193 if (!OldProgId.isEmpty() && OldProgId != m_ClassId) 194 RegCU.setValue(ExtKeyName + "/Progid", OldProgId); 195 else { 196 QString CurProgId = RegCU.value(ExtKeyName + "/Progid").toString(); 197 198 if ((CurProgId == m_ClassId) || (0 == CurProgId.compare(m_ClassId2, Qt::CaseInsensitive))) //Only remove if we own it 199 RegCU.remove(ExtKeyName + "/Progid"); 200 } 201 202 // Restore old explorer Application 203 if (!OldApp.isEmpty() && OldApp != m_ClassId) 204 RegCU.setValue(ExtKeyName + "/Application", OldApp); 205 else { 206 QString CurApp = RegCU.value(ExtKeyName + "/Application").toString(); 207 208 if ((CurApp == m_ClassId) || (0 == CurApp.compare(m_ClassId2, Qt::CaseInsensitive))) //Only remove if we own it 209 RegCU.remove(ExtKeyName + "/Application"); 210 } 211 212 // Restore old association for current user 213 if (!OldClassId.isEmpty() && OldClassId != m_ClassId) 214 RegCU.setValue("Software/Classes/." + fileExtension + "/.", OldClassId); 215 else { 216 if (RegCU.value("Software/Classes/." + fileExtension + "/.").toString() == m_ClassId) //Only remove if we own it 217 RegCU.remove("Software/Classes/." + fileExtension); 218 } 219 220 // Remove our keys: 221 // CurrentUserClasses/.ext/MPlayerBackup 222 // Explorer: Backup_Application and Backup_ProgId 223 RegCU.remove("Software/Classes/." + fileExtension + "/MPlayer_Backup"); 224 RegCU.remove(ExtKeyName + "/MPlayer_Backup_Application"); 225 RegCU.remove(ExtKeyName + "/MPlayer_Backup_ProgId"); 226 } 227 return count; 228 } 229 230 // Creates a ClassId for current application. 231 // Note: It's better to create the classId from the installation program. 232 bool WinFileAssoc::CreateClassId(const QString &executablePath, const QString &friendlyName) 233 { 234 QString RootKeyName; 235 QString classId; 236 237 classId = "Software/Classes/" + m_ClassId; 238 RootKeyName = "HKEY_CURRENT_USER"; 239 240 QSettings Reg(RootKeyName, QSettings::NativeFormat); 241 242 if (!Reg.isWritable() || Reg.status() != QSettings::NoError) 243 return false; 244 245 QString appPath = executablePath; 246 appPath.replace('/', '\\'); // Explorer gives 'Access Denied' if we write the path with forward slashes to the registry 247 248 // Add our ProgId to the HKCR classes 249 Reg.setValue(classId + "/shell/open/FriendlyAppName", friendlyName); 250 Reg.setValue(classId + "/shell/open/command/.", QString("\"%1\" \"%2\"").arg(appPath, "%1")); 251 Reg.setValue(classId + "/DefaultIcon/.", QString("\"%1\",1").arg(appPath)); 252 253 // Add "Enqueue" command 254 Reg.setValue(classId + "/shell/enqueue/.", QObject::tr("Enqueue in SMPlayer")); 255 Reg.setValue(classId + "/shell/enqueue/command/.", QString("\"%1\" -add-to-playlist \"%2\"").arg(appPath, "%1")); 256 return true; 257 } 258 259 // Remove ClassId from the registry. 260 // Called when no associations exist. Note: It's better to do this in the Setup program. 311 261 bool WinFileAssoc::RemoveClassId() 312 262 { 313 QString RootKeyName; 314 QString classId; 315 316 if (QSysInfo::WindowsVersion >= QSysInfo::WV_NT) 317 { 318 classId = "Software/Classes/" + m_ClassId; 319 RootKeyName = "HKEY_CURRENT_USER"; 320 } 321 else 322 { 323 classId = m_ClassId; 324 RootKeyName = "HKEY_CLASSES_ROOT"; //Windows 95/98/ME 325 } 326 327 QSettings RegCU (RootKeyName, QSettings::NativeFormat); 328 329 if (!RegCU.isWritable() || RegCU.status() != QSettings::NoError) 330 return false; 331 332 RegCU.remove(classId); 333 return true; 334 } 335 336 //Windows Vista specific implementation 337 //Add libole32.a library if compiling with mingw. 338 //In smplayer.pro, under win32{ : 339 // LIBS += libole32 340 #ifdef WIN32 341 #include <windows.h> 263 QString RootKeyName; 264 QString classId; 265 266 classId = "Software/Classes/" + m_ClassId; 267 RootKeyName = "HKEY_CURRENT_USER"; 268 269 QSettings RegCU(RootKeyName, QSettings::NativeFormat); 270 271 if (!RegCU.isWritable() || RegCU.status() != QSettings::NoError) 272 return false; 273 274 RegCU.remove(classId); 275 return true; 276 } 277 278 // Windows Vista specific implementation 342 279 343 280 #if !defined(IApplicationAssociationRegistration) 344 281 345 typedef enum tagASSOCIATIONLEVEL 346 { 347 AL_MACHINE, 348 AL_EFFECTIVE, 349 AL_USER 282 typedef enum tagASSOCIATIONLEVEL { 283 AL_MACHINE, 284 AL_EFFECTIVE, 285 AL_USER 350 286 } ASSOCIATIONLEVEL; 351 287 352 typedef enum tagASSOCIATIONTYPE 353 { 354 AT_FILEEXTENSION, 355 AT_URLPROTOCOL, 356 AT_STARTMENUCLIENT, 357 AT_MIMETYPE 288 typedef enum tagASSOCIATIONTYPE { 289 AT_FILEEXTENSION, 290 AT_URLPROTOCOL, 291 AT_STARTMENUCLIENT, 292 AT_MIMETYPE 358 293 } ASSOCIATIONTYPE; 359 294 360 295 MIDL_INTERFACE("4e530b0a-e611-4c77-a3ac-9031d022281b") 361 IApplicationAssociationRegistration : public IUnknown362 {296 IApplicationAssociationRegistration : 297 public IUnknown { 363 298 public: 364 365 366 367 LPWSTR *ppszAssociation) = 0;368 369 370 371 372 BOOL *pfDefault) = 0;373 374 375 BOOL *pfDefault) = 0;376 377 378 379 380 virtual HRESULT STDMETHODCALLTYPE ClearUserAssociations(void) = 0;299 virtual HRESULT STDMETHODCALLTYPE QueryCurrentDefault(LPCWSTR pszQuery, 300 ASSOCIATIONTYPE atQueryType, 301 ASSOCIATIONLEVEL alQueryLevel, 302 LPWSTR * ppszAssociation) = 0; 303 virtual HRESULT STDMETHODCALLTYPE QueryAppIsDefault(LPCWSTR pszQuery, 304 ASSOCIATIONTYPE atQueryType, 305 ASSOCIATIONLEVEL alQueryLevel, 306 LPCWSTR pszAppRegistryName, 307 BOOL * pfDefault) = 0; 308 virtual HRESULT STDMETHODCALLTYPE QueryAppIsDefaultAll(ASSOCIATIONLEVEL alQueryLevel, 309 LPCWSTR pszAppRegistryName, 310 BOOL * pfDefault) = 0; 311 virtual HRESULT STDMETHODCALLTYPE SetAppAsDefault(LPCWSTR pszAppRegistryName, 312 LPCWSTR pszSet, 313 ASSOCIATIONTYPE atSetType) = 0; 314 virtual HRESULT STDMETHODCALLTYPE SetAppAsDefaultAll(LPCWSTR pszAppRegistryName) = 0; 315 virtual HRESULT STDMETHODCALLTYPE ClearUserAssociations(void) = 0; 381 316 }; 382 317 #endif 383 318 384 static const CLSID CLSID_ApplicationAssociationReg = {0x591209C7,0x767B,0x42B2,{0x9F,0xBA,0x44,0xEE,0x46,0x15,0xF2,0xC7}}; 385 static const IID IID_IApplicationAssociationReg = {0x4e530b0a,0xe611,0x4c77,{0xa3,0xac,0x90,0x31,0xd0,0x22,0x28,0x1b}}; 386 387 int WinFileAssoc::VistaSetAppsAsDefault(const QStringList& fileExtensions) 388 { 389 IApplicationAssociationRegistration* pAAR; 390 HRESULT hr = CoCreateInstance(CLSID_ApplicationAssociationReg, 391 NULL, CLSCTX_INPROC, IID_IApplicationAssociationReg, (void**)&pAAR); 392 393 int count = 0; 394 if (SUCCEEDED(hr) && (pAAR != NULL)) 395 { 396 foreach(const QString& fileExtension, fileExtensions) 397 { 398 hr = pAAR->SetAppAsDefault((const WCHAR*)m_AppName.utf16(), 399 (const WCHAR*)QString("." + fileExtension).utf16(), 400 AT_FILEEXTENSION); 401 402 if (SUCCEEDED(hr)) 403 count++; 404 } 405 pAAR->Release(); 406 } 407 return count; 408 } 409 410 bool WinFileAssoc::VistaGetDefaultApps(const QStringList &extensions, QStringList& registeredExt) 411 { 412 IApplicationAssociationRegistration* pAAR; 413 414 HRESULT hr = CoCreateInstance(CLSID_ApplicationAssociationReg, 415 NULL, CLSCTX_INPROC, IID_IApplicationAssociationReg, (void**)&pAAR); 416 417 if (SUCCEEDED(hr) && (pAAR != NULL)) 418 { 419 foreach(const QString& fileExtension, extensions) 420 { 421 BOOL bIsDefault = FALSE; 422 hr = pAAR->QueryAppIsDefault((const WCHAR*)QString("." + fileExtension).utf16(), 423 AT_FILEEXTENSION, 424 AL_EFFECTIVE, 425 (const WCHAR*)m_AppName.utf16(), 426 &bIsDefault); 427 if (SUCCEEDED(hr) && bIsDefault) 428 { 429 registeredExt.append(fileExtension); 430 } 431 } 432 433 pAAR->Release(); 434 return true; 435 } 436 return false; 437 } 438 #else 439 bool WinFileAssoc::VistaGetDefaultApps(const QStringList &extensions, QStringList& registeredExt) 440 { 441 return false; 442 } 443 444 int WinFileAssoc::VistaSetAppsAsDefault(const QStringList& extensions) 445 { 446 return 0; 447 } 448 #endif 449 319 static const CLSID CLSID_ApplicationAssociationReg = {0x591209C7, 0x767B, 0x42B2, {0x9F, 0xBA, 0x44, 0xEE, 0x46, 0x15, 0xF2, 0xC7}}; 320 static const IID IID_IApplicationAssociationReg = {0x4e530b0a, 0xe611, 0x4c77, {0xa3, 0xac, 0x90, 0x31, 0xd0, 0x22, 0x28, 0x1b}}; 321 322 int WinFileAssoc::VistaSetAppsAsDefault(const QStringList &fileExtensions) 323 { 324 IApplicationAssociationRegistration *pAAR; 325 HRESULT hr = CoCreateInstance(CLSID_ApplicationAssociationReg, 326 NULL, CLSCTX_INPROC, IID_IApplicationAssociationReg, (void **)&pAAR); 327 328 int count = 0; 329 330 if (SUCCEEDED(hr) && (pAAR != NULL)) { 331 foreach(const QString & fileExtension, fileExtensions) { 332 hr = pAAR->SetAppAsDefault((const WCHAR *)m_AppName.utf16(), 333 (const WCHAR *)QString("." + fileExtension).utf16(), 334 AT_FILEEXTENSION); 335 336 if (SUCCEEDED(hr)) 337 count++; 338 } 339 pAAR->Release(); 340 } 341 342 return count; 343 } 344 345 bool WinFileAssoc::VistaGetDefaultApps(const QStringList &extensions, QStringList ®isteredExt) 346 { 347 IApplicationAssociationRegistration *pAAR; 348 349 HRESULT hr = CoCreateInstance(CLSID_ApplicationAssociationReg, 350 NULL, CLSCTX_INPROC, IID_IApplicationAssociationReg, (void **)&pAAR); 351 352 if (SUCCEEDED(hr) && (pAAR != NULL)) { 353 foreach(const QString & fileExtension, extensions) { 354 BOOL bIsDefault = FALSE; 355 hr = pAAR->QueryAppIsDefault((const WCHAR *)QString("." + fileExtension).utf16(), 356 AT_FILEEXTENSION, 357 AL_EFFECTIVE, 358 (const WCHAR *)m_AppName.utf16(), 359 &bIsDefault); 360 361 if (SUCCEEDED(hr) && bIsDefault) { 362 registeredExt.append(fileExtension); 363 } 364 } 365 366 pAAR->Release(); 367 return true; 368 } 369 370 return false; 371 }
Note:
See TracChangeset
for help on using the changeset viewer.