OSDN Git Service

Moved more functions into MUtils library, especially all the Qt initialization code...
authorLoRd_MuldeR <mulder2@gmx.de>
Sat, 29 Nov 2014 00:22:46 +0000 (01:22 +0100)
committerLoRd_MuldeR <mulder2@gmx.de>
Sat, 29 Nov 2014 00:22:46 +0000 (01:22 +0100)
12 files changed:
MUtilities_VS2013.vcxproj
MUtilities_VS2013.vcxproj.filters
include/MUtils/GUI.h [new file with mode: 0644]
include/MUtils/OSSupport.h
include/MUtils/Startup.h
include/MUtils/Terminal.h
src/ErrorHandler_Win32.cpp
src/GUI.cpp [new file with mode: 0644]
src/OSSupport_Win32.cpp
src/Startup.cpp
src/Terminal_Win32.cpp
src/Utils_Win32.h [new file with mode: 0644]

index ef947ea..77f48a3 100644 (file)
@@ -19,6 +19,7 @@
     <ClCompile Include="src\DLLMain.cpp" />
     <ClCompile Include="src\ErrorHandler_Win32.cpp" />
     <ClCompile Include="src\Global.cpp" />
+    <ClCompile Include="src\GUI.cpp" />
     <ClCompile Include="src\KeccakHash.cpp" />
     <ClCompile Include="src\OSSupport_Win32.cpp" />
     <ClCompile Include="src\Startup.cpp" />
     <ClInclude Include="include\MUtils\ErrorHandler.h" />
     <ClInclude Include="include\MUtils\Exception.h" />
     <ClInclude Include="include\MUtils\Global.h" />
+    <ClInclude Include="include\MUtils\GUI.h" />
     <ClInclude Include="include\MUtils\KeccakHash.h" />
     <ClInclude Include="include\MUtils\OSSupport.h" />
     <ClInclude Include="include\MUtils\Startup.h" />
     <ClInclude Include="include\MUtils\Terminal.h" />
     <ClInclude Include="src\DirLocker.h" />
+    <ClInclude Include="src\Utils_Win32.h" />
     <CustomBuild Include="include\Mutils\UpdateChecker.h">
       <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">"$(QTDIR)\bin\moc.exe" -o "$(SolutionDir)tmp\$(ProjectName)\MOC_%(Filename).cpp" "%(FullPath)"</Command>
       <Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">MOC "$(SolutionDir)tmp\$(ProjectName)\MOC_%(Filename).cpp"</Message>
index a031eeb..2c07910 100644 (file)
@@ -54,6 +54,9 @@
     <ClCompile Include="src\ErrorHandler_Win32.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="src\GUI.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="src\CriticalSection_Win32.h">
     <ClInclude Include="include\MUtils\ErrorHandler.h">
       <Filter>Public Headers</Filter>
     </ClInclude>
+    <ClInclude Include="include\MUtils\GUI.h">
+      <Filter>Public Headers</Filter>
+    </ClInclude>
+    <ClInclude Include="src\Utils_Win32.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <CustomBuild Include="include\Mutils\UpdateChecker.h">
diff --git a/include/MUtils/GUI.h b/include/MUtils/GUI.h
new file mode 100644 (file)
index 0000000..a5e9cf5
--- /dev/null
@@ -0,0 +1,49 @@
+///////////////////////////////////////////////////////////////////////////////
+// MuldeR's Utilities for Qt
+// Copyright (C) 2004-2014 LoRd_MuldeR <MuldeR2@GMX.de>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//
+// http://www.gnu.org/licenses/lgpl-2.1.txt
+//////////////////////////////////////////////////////////////////////////////////
+
+#pragma once
+
+//MUtils
+#include <MUtils/Global.h>
+
+///////////////////////////////////////////////////////////////////////////////
+
+namespace MUtils
+{
+       namespace GUI
+       {
+               typedef enum
+               {
+                       USER_EVENT = 1000,           /*QEvent::User*/
+                       USER_EVENT_QUERYENDSESSION = USER_EVENT + 666,
+                       USER_EVENT_ENDSESSION      = USER_EVENT + 667
+               }
+               user_events_t;
+
+               //Broadcast message
+               MUTILS_API bool broadcast(int eventType, const bool &onlyToVisible);
+
+               //Force quit application
+               MUTILS_API void force_quit(void);
+       }
+}
+
+///////////////////////////////////////////////////////////////////////////////
index 3c4cea5..1cd5498 100644 (file)
@@ -106,6 +106,7 @@ namespace MUtils
                //Get the OS version
                MUTILS_API const Version::os_version_t &os_version(void);
                MUTILS_API const char *os_friendly_name(const MUtils::OS::Version::os_version_t &os_version);
+               MUTILS_API const bool &running_on_wine(void);
 
                //Get known Folder
                MUTILS_API const QString &known_folder(known_folder_t folder_id);
@@ -113,9 +114,15 @@ namespace MUtils
                //Current Date
                MUTILS_API QDate current_date(void);
 
+               //Check for process elevation
+               MUTILS_API bool is_elevated(bool *bIsUacEnabled = NULL);
+
                //Network Status
                MUTILS_API int network_status(void);
 
+               //Message handler
+               MUTILS_API bool handle_os_message(const void *const message, long *result);
+
                //Error handling
                MUTILS_API void fatal_exit(const wchar_t* const errorMessage);
        }
index 17239c7..6017d83 100644 (file)
@@ -35,6 +35,9 @@ namespace MUtils
 
                //Startup Application
                MUTILS_API int startup(int &argc, char **argv, main_function_t *const entry_point);
+
+               //Initialize Qt
+               MUTILS_API bool init_qt(int &argc, char **argv, const QString &appName);
        }
 }
 
index 41b2ac7..e5039be 100644 (file)
@@ -25,8 +25,7 @@
 #include <MUtils/Global.h>
 
 //Qt
-#include <QString>
-#include <QDate>
+#include <QIcon>
 
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -39,6 +38,9 @@ namespace MUtils
 
                //Terminal output
                MUTILS_API void write(const int &type, const char *const message);
+
+               //Terminal icon
+               MUTILS_API void set_icon(const QIcon &icon);
        }
 }
 
index 7a4222e..cdbb2e4 100644 (file)
@@ -66,6 +66,7 @@ void MUtils::ErrorHandler::initialize(void)
        SetUnhandledExceptionFilter(my_exception_handler);
        SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL);
        _set_invalid_parameter_handler(my_invalid_param_handler);
+       SetDllDirectoryW(L""); /*don'tload DLL from "current" directory*/
        
        static const int signal_num[6] = { SIGABRT, SIGFPE, SIGILL, SIGINT, SIGSEGV, SIGTERM };
 
@@ -73,6 +74,7 @@ void MUtils::ErrorHandler::initialize(void)
        {
                signal(signal_num[i], my_signal_handler);
        }
+
 }
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/src/GUI.cpp b/src/GUI.cpp
new file mode 100644 (file)
index 0000000..7453c6f
--- /dev/null
@@ -0,0 +1,74 @@
+///////////////////////////////////////////////////////////////////////////////
+// MuldeR's Utilities for Qt
+// Copyright (C) 2004-2014 LoRd_MuldeR <MuldeR2@GMX.de>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//
+// http://www.gnu.org/licenses/lgpl-2.1.txt
+//////////////////////////////////////////////////////////////////////////////////
+
+#include <MUtils/GUI.h>
+
+//Qt
+#include <QApplication>
+#include <QWidget>
+
+///////////////////////////////////////////////////////////////////////////////
+// BROADCAST
+///////////////////////////////////////////////////////////////////////////////
+
+bool MUtils::GUI::broadcast(int eventType, const bool &onlyToVisible)
+{
+       if(QApplication *app = dynamic_cast<QApplication*>(QApplication::instance()))
+       {
+               qDebug("Broadcasting %d", eventType);
+               
+               bool allOk = true;
+               QEvent poEvent(static_cast<QEvent::Type>(eventType));
+               QWidgetList list = app->topLevelWidgets();
+
+               while(!list.isEmpty())
+               {
+                       QWidget *widget = list.takeFirst();
+                       if(!onlyToVisible || widget->isVisible())
+                       {
+                               if(!app->sendEvent(widget, &poEvent))
+                               {
+                                       allOk = false;
+                               }
+                       }
+               }
+
+               qDebug("Broadcast %d done (%s)", eventType, (allOk ? "OK" : "Stopped"));
+               return allOk;
+       }
+       else
+       {
+               qWarning("Broadcast failed, could not get QApplication instance!");
+               return false;
+       }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// BROADCAST
+///////////////////////////////////////////////////////////////////////////////
+
+void MUtils::GUI::force_quit(void)
+{
+       qApp->closeAllWindows();
+       qApp->quit();
+}
+
+///////////////////////////////////////////////////////////////////////////////
index e03eae7..46dd086 100644 (file)
 
 #pragma once
 
-//Internal
-#include <MUtils/Global.h>
-#include <MUtils/OSSupport.h>
-#include "CriticalSection_Win32.h"
-
 //Win32 API
 #define WIN32_LEAN_AND_MEAN 1
 #include <Windows.h>
 #include <Sensapi.h>
 #include <Shellapi.h>
 
+//Internal
+#include <MUtils/Global.h>
+#include <MUtils/OSSupport.h>
+#include <MUtils/GUI.h>
+#include "CriticalSection_Win32.h"
+
 //Qt
 #include <QMap>
 #include <QReadWriteLock>
@@ -261,6 +262,7 @@ const MUtils::OS::Version::os_version_t &MUtils::OS::os_version(void)
                qWarning("Failed to determin the operating system version!");
        }
 
+       //Completed
        g_os_version_initialized = true;
        return g_os_version_info;
 }
@@ -279,6 +281,55 @@ const char *MUtils::OS::os_friendly_name(const MUtils::OS::Version::os_version_t
 }
 
 ///////////////////////////////////////////////////////////////////////////////
+// WINE DETECTION
+///////////////////////////////////////////////////////////////////////////////
+
+static bool g_wine_deteced = false;
+static bool g_wine_initialized = false;
+static QReadWriteLock g_wine_lock;
+
+static const bool detect_wine(void)
+{
+       bool is_wine = false;
+       
+       QLibrary ntdll("ntdll.dll");
+       if(ntdll.load())
+       {
+               if(ntdll.resolve("wine_nt_to_unix_file_name") != NULL) is_wine = true;
+               if(ntdll.resolve("wine_get_version")          != NULL) is_wine = true;
+               ntdll.unload();
+       }
+
+       return is_wine;
+}
+
+const bool &MUtils::OS::running_on_wine(void)
+{
+       QReadLocker readLock(&g_wine_lock);
+
+       //Already initialized?
+       if(g_wine_initialized)
+       {
+               return g_wine_deteced;
+       }
+
+       readLock.unlock();
+       QWriteLocker writeLock(&g_wine_lock);
+
+       //Initialized now?
+       if(g_wine_initialized)
+       {
+               return g_wine_deteced;
+       }
+
+       //Try to detect Wine
+       g_wine_deteced = detect_wine();
+       g_wine_initialized = true;
+
+       return g_wine_deteced;
+}
+
+///////////////////////////////////////////////////////////////////////////////
 // KNWON FOLDERS
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -458,6 +509,62 @@ QDate MUtils::OS::current_date(void)
 }
 
 ///////////////////////////////////////////////////////////////////////////////
+// PROCESS ELEVATION
+///////////////////////////////////////////////////////////////////////////////
+
+bool MUtils::OS::is_elevated(bool *bIsUacEnabled)
+{
+       if(bIsUacEnabled)
+       {
+               *bIsUacEnabled = false;
+       }
+
+       bool bIsProcessElevated = false;
+       HANDLE hToken = NULL;
+       
+       if(OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
+       {
+               TOKEN_ELEVATION_TYPE tokenElevationType;
+               DWORD returnLength;
+               if(GetTokenInformation(hToken, TokenElevationType, &tokenElevationType, sizeof(TOKEN_ELEVATION_TYPE), &returnLength))
+               {
+                       if(returnLength == sizeof(TOKEN_ELEVATION_TYPE))
+                       {
+                               switch(tokenElevationType)
+                               {
+                               case TokenElevationTypeDefault:
+                                       qDebug("Process token elevation type: Default -> UAC is disabled.\n");
+                                       break;
+                               case TokenElevationTypeFull:
+                                       qWarning("Process token elevation type: Full -> potential security risk!\n");
+                                       bIsProcessElevated = true;
+                                       if(bIsUacEnabled) *bIsUacEnabled = true;
+                                       break;
+                               case TokenElevationTypeLimited:
+                                       qDebug("Process token elevation type: Limited -> not elevated.\n");
+                                       if(bIsUacEnabled) *bIsUacEnabled = true;
+                                       break;
+                               default:
+                                       qWarning("Unknown tokenElevationType value: %d", tokenElevationType);
+                                       break;
+                               }
+                       }
+                       else
+                       {
+                               qWarning("GetTokenInformation() return an unexpected size!");
+                       }
+               }
+               CloseHandle(hToken);
+       }
+       else
+       {
+               qWarning("Failed to open process token!");
+       }
+
+       return bIsProcessElevated;
+}
+
+///////////////////////////////////////////////////////////////////////////////
 // NETWORK STATE
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -473,6 +580,36 @@ int MUtils::OS::network_status(void)
 }
 
 ///////////////////////////////////////////////////////////////////////////////
+// MESSAGE HANDLER
+///////////////////////////////////////////////////////////////////////////////
+
+bool MUtils::OS::handle_os_message(const void *const message, long *result)
+{
+       const MSG *const msg = reinterpret_cast<const MSG*>(message);
+
+       switch(msg->message)
+       {
+       case WM_QUERYENDSESSION:
+               qWarning("WM_QUERYENDSESSION message received!");
+               *result = MUtils::GUI::broadcast(MUtils::GUI::USER_EVENT_QUERYENDSESSION, false) ? TRUE : FALSE;
+               return true;
+       case WM_ENDSESSION:
+               qWarning("WM_ENDSESSION message received!");
+               if(msg->wParam == TRUE)
+               {
+                       MUtils::GUI::broadcast(MUtils::GUI::USER_EVENT_ENDSESSION, false);
+                       MUtils::GUI::force_quit();
+                       exit(1);
+               }
+               *result = 0;
+               return true;
+       default:
+               /*ignore this message and let Qt handle it*/
+               return false;
+       }
+}
+
+///////////////////////////////////////////////////////////////////////////////
 // FATAL EXIT
 ///////////////////////////////////////////////////////////////////////////////
 
index 32c80bd..de8d6b3 100644 (file)
 #include <MUtils/Exception.h>
 
 //Qt
-#include <QtGlobal>
+#include <QApplication>
+#include <QMutex>
+#include <QStringList>
+#include <QLibraryInfo>
+#include <QTextCodec>
+#include <QImageReader>
+#include <QFont>
+#include <QMessageBox>
 
 ///////////////////////////////////////////////////////////////////////////////
 // MESSAGE HANDLER
@@ -48,6 +55,11 @@ static void qt_message_handler(QtMsgType type, const char *msg)
        }
 }
 
+static bool qt_event_filter(void *message, long *result)
+{
+       return MUtils::OS::handle_os_message(message, result);
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 // STARTUP FUNCTION
 ///////////////////////////////////////////////////////////////////////////////
@@ -105,3 +117,154 @@ int MUtils::Startup::startup(int &argc, char **argv, main_function_t *const entr
 }
 
 ///////////////////////////////////////////////////////////////////////////////
+// QT INITIALIZATION
+///////////////////////////////////////////////////////////////////////////////
+
+static QMutex g_qt_lock;
+static QScopedPointer<QApplication> g_application;
+
+static const char *const g_imageformats[] = {"bmp", "png", "jpg", "gif", "ico", "xpm", "svg", NULL};
+
+bool MUtils::Startup::init_qt(int &argc, char **argv, const QString &appName)
+{
+       QMutexLocker lock(&g_qt_lock);
+       const QStringList &arguments = MUtils::OS::arguments();
+
+       //Don't initialized again, if done already
+       if(!g_application.isNull())
+       {
+               return true;
+       }
+
+       //Extract executable name from argv[] array
+       QString executableName = QLatin1String("LameXP.exe");
+       if(arguments.count() > 0)
+       {
+               static const char *delimiters = "\\/:?";
+               executableName = arguments[0].trimmed();
+               for(int i = 0; delimiters[i]; i++)
+               {
+                       int temp = executableName.lastIndexOf(QChar(delimiters[i]));
+                       if(temp >= 0) executableName = executableName.mid(temp + 1);
+               }
+               executableName = executableName.trimmed();
+               if(executableName.isEmpty())
+               {
+                       executableName = QLatin1String("LameXP.exe");
+               }
+       }
+
+       //Check Qt version
+#ifdef QT_BUILD_KEY
+       qDebug("Using Qt v%s [%s], %s, %s", qVersion(), QLibraryInfo::buildDate().toString(Qt::ISODate).toLatin1().constData(), (qSharedBuild() ? "DLL" : "Static"), QLibraryInfo::buildKey().toLatin1().constData());
+       qDebug("Compiled with Qt v%s [%s], %s\n", QT_VERSION_STR, QT_PACKAGEDATE_STR, QT_BUILD_KEY);
+       if(_stricmp(qVersion(), QT_VERSION_STR))
+       {
+               qFatal("%s", QApplication::tr("Executable '%1' requires Qt v%2, but found Qt v%3.").arg(executableName, QString::fromLatin1(QT_VERSION_STR), QString::fromLatin1(qVersion())).toLatin1().constData());
+               return false;
+       }
+       if(QLibraryInfo::buildKey().compare(QString::fromLatin1(QT_BUILD_KEY), Qt::CaseInsensitive))
+       {
+               qFatal("%s", QApplication::tr("Executable '%1' was built for Qt '%2', but found Qt '%3'.").arg(executableName, QString::fromLatin1(QT_BUILD_KEY), QLibraryInfo::buildKey()).toLatin1().constData());
+               return false;
+       }
+#else
+       qDebug("Using Qt v%s [%s], %s", qVersion(), QLibraryInfo::buildDate().toString(Qt::ISODate).toLatin1().constData(), (qSharedBuild() ? "DLL" : "Static"));
+       qDebug("Compiled with Qt v%s [%s]\n", QT_VERSION_STR, QT_PACKAGEDATE_STR);
+#endif
+
+       //Check the Windows version
+       
+       const MUtils::OS::Version::os_version_t &osVersion = MUtils::OS::os_version();
+       if((osVersion.type != MUtils::OS::Version::OS_WINDOWS) || (osVersion < MUtils::OS::Version::WINDOWS_WINXP))
+       {
+               qFatal("%s", QApplication::tr("Executable '%1' requires Windows XP or later.").arg(executableName).toLatin1().constData());
+       }
+
+       //Check whether we are running on a supported Windows version
+       if(const char *const friendlyName = MUtils::OS::os_friendly_name(osVersion))
+       {
+               qDebug("Running on %s (NT v%u.%u).\n", friendlyName, osVersion.versionMajor, osVersion.versionMinor);
+       }
+       else
+       {
+               const QString message = QString().sprintf("Running on an unknown WindowsNT-based system (v%u.%u).", osVersion.versionMajor, osVersion.versionMinor);
+               qWarning("%s\n", MUTILS_UTF8(message));
+               MUtils::OS::system_message_wrn(MUTILS_WCHR(message), L"LameXP");
+       }
+
+       //Check for compat mode
+       if(osVersion.overrideFlag && (osVersion <= MUtils::OS::Version::WINDOWS_WN100))
+       {
+               qWarning("Windows compatibility mode detected!");
+               if(!arguments.contains("--ignore-compat-mode", Qt::CaseInsensitive))
+               {
+                       qFatal("%s", QApplication::tr("Executable '%1' doesn't support Windows compatibility mode.").arg(executableName).toLatin1().constData());
+                       return false;
+               }
+       }
+
+       //Check for Wine
+       if(MUtils::OS::running_on_wine())
+       {
+               qWarning("It appears we are running under Wine, unexpected things might happen!\n");
+       }
+
+       //Set text Codec for locale
+       QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
+
+       //Create Qt application instance
+       g_application.reset(new QApplication(argc, argv));
+
+       //Load plugins from application directory
+       QCoreApplication::setLibraryPaths(QStringList() << QApplication::applicationDirPath());
+       qDebug("Library Path:\n%s\n", MUTILS_UTF8(QApplication::libraryPaths().first()));
+
+       //Set application properties
+       g_application->setApplicationName(appName);
+       g_application->setOrganizationName("LoRd_MuldeR");
+       g_application->setOrganizationDomain("mulder.at.gg");
+       g_application->setEventFilter(qt_event_filter);
+
+       //Check for supported image formats
+       QList<QByteArray> supportedFormats = QImageReader::supportedImageFormats();
+       for(int i = 0; g_imageformats[i]; i++)
+       {
+               if(!supportedFormats.contains(g_imageformats[i]))
+               {
+                       qFatal("Qt initialization error: QImageIOHandler for '%s' missing!", g_imageformats[i]);
+                       return false;
+               }
+       }
+       
+       //Enable larger/smaller font size
+       double fontScaleFactor = 1.0;
+       if(arguments.contains("--huge-font",  Qt::CaseInsensitive)) fontScaleFactor = 1.500;
+       if(arguments.contains("--big-font",   Qt::CaseInsensitive)) fontScaleFactor = 1.250;
+       if(arguments.contains("--small-font", Qt::CaseInsensitive)) fontScaleFactor = 0.875;
+       if(arguments.contains("--tiny-font",  Qt::CaseInsensitive)) fontScaleFactor = 0.750;
+       if(!qFuzzyCompare(fontScaleFactor, 1.0))
+       {
+               qWarning("Application font scale factor set to: %.3f\n", fontScaleFactor);
+               QFont appFont = g_application->font();
+               appFont.setPointSizeF(appFont.pointSizeF() * fontScaleFactor);
+               g_application->setFont(appFont);
+       }
+
+       //Check for process elevation
+       if(MUtils::OS::is_elevated() && (!MUtils::OS::running_on_wine()))
+       {
+               QMessageBox messageBox(QMessageBox::Warning, "LameXP", "<nobr>LameXP was started with 'elevated' rights, altough LameXP does not need these rights.<br>Running an applications with unnecessary rights is a potential security risk!</nobr>", QMessageBox::NoButton, NULL, Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint | Qt::WindowStaysOnTopHint);
+               messageBox.addButton("Quit Program (Recommended)", QMessageBox::NoRole);
+               messageBox.addButton("Ignore", QMessageBox::NoRole);
+               if(messageBox.exec() == 0)
+               {
+                       return NULL;
+               }
+       }
+
+       //Successful
+       return g_application.data();
+}
+
+///////////////////////////////////////////////////////////////////////////////
index eff8630..b3ba9d9 100644 (file)
 // http://www.gnu.org/licenses/gpl-2.0.txt
 ///////////////////////////////////////////////////////////////////////////////
 
-#include <MUtils/Terminal.h>
+//Windows includes
+#define NOMINMAX
+#define WIN32_LEAN_AND_MEAN 1
+#include <Windows.h>
+
 
 //Internal
+#include <MUtils/Terminal.h>
 #include <MUtils/Global.h>
 #include <MUtils/OSSupport.h>
+#include "Utils_Win32.h"
 #include "CriticalSection_Win32.h"
 
-//Windows includes
-#define NOMINMAX
-#define WIN32_LEAN_AND_MEAN 1
-#include <Windows.h>
-
 //Qt
 #include <QFile>
 #include <QStringList>
+#include <QIcon>
+#include <QLibrary>
 
 //CRT
 #include <iostream>
@@ -182,18 +185,18 @@ void MUtils::Terminal::setup(int &argc, char **argv, const bool forceEnabled)
                                g_filebufStdErr.reset(new std::filebuf(hfStdErr));
                                std::cerr.rdbuf(g_filebufStdErr.data());
                        }
-               }
 
-               HWND hwndConsole = GetConsoleWindow();
-               if((hwndConsole != NULL) && (hwndConsole != INVALID_HANDLE_VALUE))
-               {
-                       HMENU hMenu = GetSystemMenu(hwndConsole, 0);
-                       EnableMenuItem(hMenu, SC_CLOSE, MF_BYCOMMAND | MF_GRAYED);
-                       RemoveMenu(hMenu, SC_CLOSE, MF_BYCOMMAND);
+                       const HWND hwndConsole = GetConsoleWindow();
+                       if((hwndConsole != NULL) && (hwndConsole != INVALID_HANDLE_VALUE))
+                       {
+                               HMENU hMenu = GetSystemMenu(hwndConsole, 0);
+                               EnableMenuItem(hMenu, SC_CLOSE, MF_BYCOMMAND | MF_GRAYED);
+                               RemoveMenu(hMenu, SC_CLOSE, MF_BYCOMMAND);
 
-                       SetWindowPos (hwndConsole, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED);
-                       SetWindowLong(hwndConsole, GWL_STYLE, GetWindowLong(hwndConsole, GWL_STYLE) & (~WS_MAXIMIZEBOX) & (~WS_MINIMIZEBOX));
-                       SetWindowPos (hwndConsole, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED);
+                               SetWindowPos (hwndConsole, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED);
+                               SetWindowLong(hwndConsole, GWL_STYLE, GetWindowLong(hwndConsole, GWL_STYLE) & (~WS_MAXIMIZEBOX) & (~WS_MINIMIZEBOX));
+                               SetWindowPos (hwndConsole, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED);
+                       }
                }
        }
 }
@@ -327,3 +330,29 @@ void MUtils::Terminal::write(const int &type, const char *const message)
                write_logfile_helper(g_log_file.data(), type, message);
        }
 }
+
+///////////////////////////////////////////////////////////////////////////////
+// TERMINAL ICON
+///////////////////////////////////////////////////////////////////////////////
+
+void MUtils::Terminal::set_icon(const QIcon &icon)
+{
+       MUtils::Internal::CSLocker lock(g_terminal_lock);
+
+       if(!(icon.isNull() || MUtils::OS::running_on_wine()))
+       {
+               QLibrary kernel32("kernel32.dll");
+               if(kernel32.load())
+               {
+                       typedef DWORD (__stdcall *SetConsoleIconFun)(HICON);
+                       if(SetConsoleIconFun SetConsoleIconPtr = (SetConsoleIconFun) kernel32.resolve("SetConsoleIcon"))
+                       {
+                               if(HICON hIcon = qicon_to_hicon(icon, 16, 16))
+                               {
+                                       SetConsoleIconPtr(hIcon);
+                                       DestroyIcon(hIcon);
+                               }
+                       }
+               }
+       }
+}
diff --git a/src/Utils_Win32.h b/src/Utils_Win32.h
new file mode 100644 (file)
index 0000000..f074410
--- /dev/null
@@ -0,0 +1,45 @@
+///////////////////////////////////////////////////////////////////////////////
+// MuldeR's Utilities for Qt
+// Copyright (C) 2004-2014 LoRd_MuldeR <MuldeR2@GMX.de>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//
+// http://www.gnu.org/licenses/lgpl-2.1.txt
+//////////////////////////////////////////////////////////////////////////////////
+
+#pragma once
+
+//Win32 API
+#ifndef _INC_WINDOWS
+#define WIN32_LEAN_AND_MEAN 1
+#include <Windows.h>
+#endif //_INC_WINDOWS
+
+///////////////////////////////////////////////////////////////////////////////
+// QICON TO HICON
+///////////////////////////////////////////////////////////////////////////////
+
+static HICON qicon_to_hicon(const QIcon &icon, const int w, const int h)
+{
+       if(!icon.isNull())
+       {
+               QPixmap pixmap = icon.pixmap(w, h);
+               if(!pixmap.isNull())
+               {
+                       return pixmap.toWinHICON();
+               }
+       }
+       return NULL;
+}