Moved more functions into MUtils library, especially all the Qt initialization code and some more OS-specific stuff.

This commit is contained in:
LoRd_MuldeR 2014-11-29 01:22:46 +01:00
parent cfbf1e0747
commit 52b230f2db
12 changed files with 548 additions and 25 deletions

View 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" />
@ -32,11 +33,13 @@
<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>

View 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">
@ -89,6 +92,12 @@
<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">

49
include/MUtils/GUI.h Normal file
View File

@ -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);
}
}
///////////////////////////////////////////////////////////////////////////////

View 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);
}

View 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);
}
}

View 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);
}
}

View 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);
}
}
///////////////////////////////////////////////////////////////////////////////

74
src/GUI.cpp Normal file
View File

@ -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();
}
///////////////////////////////////////////////////////////////////////////////

View File

@ -21,11 +21,6 @@
#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>
@ -34,6 +29,12 @@
#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;
}
@ -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<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
///////////////////////////////////////////////////////////////////////////////

View File

@ -27,7 +27,14 @@
#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();
}
///////////////////////////////////////////////////////////////////////////////

View File

@ -20,21 +20,24 @@
// http://www.gnu.org/licenses/gpl-2.0.txt
///////////////////////////////////////////////////////////////////////////////
#include <MUtils/Terminal.h>
//Internal
#include <MUtils/Global.h>
#include <MUtils/OSSupport.h>
#include "CriticalSection_Win32.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"
//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);
}
}
}
}
}

45
src/Utils_Win32.h Normal file
View File

@ -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;
}