diff --git a/MUtilities_VS2013.vcxproj b/MUtilities_VS2013.vcxproj
index ef947ea..77f48a3 100644
--- a/MUtilities_VS2013.vcxproj
+++ b/MUtilities_VS2013.vcxproj
@@ -19,6 +19,7 @@
+
@@ -32,11 +33,13 @@
+
+
"$(QTDIR)\bin\moc.exe" -o "$(SolutionDir)tmp\$(ProjectName)\MOC_%(Filename).cpp" "%(FullPath)"
MOC "$(SolutionDir)tmp\$(ProjectName)\MOC_%(Filename).cpp"
diff --git a/MUtilities_VS2013.vcxproj.filters b/MUtilities_VS2013.vcxproj.filters
index a031eeb..2c07910 100644
--- a/MUtilities_VS2013.vcxproj.filters
+++ b/MUtilities_VS2013.vcxproj.filters
@@ -54,6 +54,9 @@
Source Files
+
+ Source Files
+
@@ -89,6 +92,12 @@
Public Headers
+
+ Public Headers
+
+
+ Header Files
+
diff --git a/include/MUtils/GUI.h b/include/MUtils/GUI.h
new file mode 100644
index 0000000..a5e9cf5
--- /dev/null
+++ b/include/MUtils/GUI.h
@@ -0,0 +1,49 @@
+///////////////////////////////////////////////////////////////////////////////
+// MuldeR's Utilities for Qt
+// Copyright (C) 2004-2014 LoRd_MuldeR
+//
+// 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
+
+///////////////////////////////////////////////////////////////////////////////
+
+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);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
diff --git a/include/MUtils/OSSupport.h b/include/MUtils/OSSupport.h
index 3c4cea5..1cd5498 100644
--- a/include/MUtils/OSSupport.h
+++ b/include/MUtils/OSSupport.h
@@ -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);
}
diff --git a/include/MUtils/Startup.h b/include/MUtils/Startup.h
index 17239c7..6017d83 100644
--- a/include/MUtils/Startup.h
+++ b/include/MUtils/Startup.h
@@ -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);
}
}
diff --git a/include/MUtils/Terminal.h b/include/MUtils/Terminal.h
index 41b2ac7..e5039be 100644
--- a/include/MUtils/Terminal.h
+++ b/include/MUtils/Terminal.h
@@ -25,8 +25,7 @@
#include
//Qt
-#include
-#include
+#include
///////////////////////////////////////////////////////////////////////////////
@@ -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);
}
}
diff --git a/src/ErrorHandler_Win32.cpp b/src/ErrorHandler_Win32.cpp
index 7a4222e..cdbb2e4 100644
--- a/src/ErrorHandler_Win32.cpp
+++ b/src/ErrorHandler_Win32.cpp
@@ -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
index 0000000..7453c6f
--- /dev/null
+++ b/src/GUI.cpp
@@ -0,0 +1,74 @@
+///////////////////////////////////////////////////////////////////////////////
+// MuldeR's Utilities for Qt
+// Copyright (C) 2004-2014 LoRd_MuldeR
+//
+// 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
+
+//Qt
+#include
+#include
+
+///////////////////////////////////////////////////////////////////////////////
+// BROADCAST
+///////////////////////////////////////////////////////////////////////////////
+
+bool MUtils::GUI::broadcast(int eventType, const bool &onlyToVisible)
+{
+ if(QApplication *app = dynamic_cast(QApplication::instance()))
+ {
+ qDebug("Broadcasting %d", eventType);
+
+ bool allOk = true;
+ QEvent poEvent(static_cast(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();
+}
+
+///////////////////////////////////////////////////////////////////////////////
diff --git a/src/OSSupport_Win32.cpp b/src/OSSupport_Win32.cpp
index e03eae7..46dd086 100644
--- a/src/OSSupport_Win32.cpp
+++ b/src/OSSupport_Win32.cpp
@@ -21,11 +21,6 @@
#pragma once
-//Internal
-#include
-#include
-#include "CriticalSection_Win32.h"
-
//Win32 API
#define WIN32_LEAN_AND_MEAN 1
#include
@@ -34,6 +29,12 @@
#include
#include
+//Internal
+#include
+#include
+#include
+#include "CriticalSection_Win32.h"
+
//Qt
#include
#include
@@ -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;
}
@@ -278,6 +280,55 @@ const char *MUtils::OS::os_friendly_name(const MUtils::OS::Version::os_version_t
return NULL;
}
+///////////////////////////////////////////////////////////////////////////////
+// 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
///////////////////////////////////////////////////////////////////////////////
@@ -457,6 +508,62 @@ QDate MUtils::OS::current_date(void)
return (currentDate >= processDate) ? currentDate : processDate;
}
+///////////////////////////////////////////////////////////////////////////////
+// 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
///////////////////////////////////////////////////////////////////////////////
@@ -472,6 +579,36 @@ int MUtils::OS::network_status(void)
return NETWORK_TYPE_ERR;
}
+///////////////////////////////////////////////////////////////////////////////
+// MESSAGE HANDLER
+///////////////////////////////////////////////////////////////////////////////
+
+bool MUtils::OS::handle_os_message(const void *const message, long *result)
+{
+ const MSG *const msg = reinterpret_cast(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
///////////////////////////////////////////////////////////////////////////////
diff --git a/src/Startup.cpp b/src/Startup.cpp
index 32c80bd..de8d6b3 100644
--- a/src/Startup.cpp
+++ b/src/Startup.cpp
@@ -27,7 +27,14 @@
#include
//Qt
-#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
///////////////////////////////////////////////////////////////////////////////
// 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 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 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", "LameXP was started with 'elevated' rights, altough LameXP does not need these rights.
Running an applications with unnecessary rights is a potential security risk!", 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();
+}
+
+///////////////////////////////////////////////////////////////////////////////
diff --git a/src/Terminal_Win32.cpp b/src/Terminal_Win32.cpp
index eff8630..b3ba9d9 100644
--- a/src/Terminal_Win32.cpp
+++ b/src/Terminal_Win32.cpp
@@ -20,21 +20,24 @@
// http://www.gnu.org/licenses/gpl-2.0.txt
///////////////////////////////////////////////////////////////////////////////
-#include
-
-//Internal
-#include
-#include
-#include "CriticalSection_Win32.h"
-
//Windows includes
#define NOMINMAX
#define WIN32_LEAN_AND_MEAN 1
#include
+
+//Internal
+#include
+#include
+#include
+#include "Utils_Win32.h"
+#include "CriticalSection_Win32.h"
+
//Qt
#include
#include
+#include
+#include
//CRT
#include
@@ -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
index 0000000..f074410
--- /dev/null
+++ b/src/Utils_Win32.h
@@ -0,0 +1,45 @@
+///////////////////////////////////////////////////////////////////////////////
+// MuldeR's Utilities for Qt
+// Copyright (C) 2004-2014 LoRd_MuldeR
+//
+// 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
+#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;
+}