diff options
author | jmpoep <OriginalEntryPoint@qq.com> | 2023-12-07 16:51:07 +0800 |
---|---|---|
committer | jmpoep <OriginalEntryPoint@qq.com> | 2023-12-07 16:51:07 +0800 |
commit | 28008a746a31abb7909dd86cb0cd413ac8943b0b (patch) | |
tree | a30b74b8cad548048c3c1551d652828ab76fa9bd /VMProtect/main.cc | |
download | vmprotect-3.5.1-master.tar vmprotect-3.5.1-master.tar.gz vmprotect-3.5.1-master.tar.bz2 vmprotect-3.5.1-master.zip |
Diffstat (limited to 'VMProtect/main.cc')
-rw-r--r-- | VMProtect/main.cc | 228 |
1 files changed, 228 insertions, 0 deletions
diff --git a/VMProtect/main.cc b/VMProtect/main.cc new file mode 100644 index 0000000..6c97308 --- /dev/null +++ b/VMProtect/main.cc @@ -0,0 +1,228 @@ +#include "../core/objects.h" +#include "../core/osutils.h" +#include "application.h" +#include "moc/moc_application.cc" +#include "mainwindow.h" +#include "help_browser.h" + +#ifndef VMP_GNU +#ifndef _DEBUG +#include <QtCore\QtPlugin> +Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin); +#endif +#endif + +class PatchedProxyStyle : public QProxyStyle +{ +public: + PatchedProxyStyle() : QProxyStyle("windows") {} + + int styleHint(StyleHint hint, const QStyleOption *opt, const QWidget *widget, + QStyleHintReturn *returnData) const + { + int ret = 0; + switch (hint) + { + case QStyle::SH_MainWindow_SpaceBelowMenuBar: + ret = 0; + break; + default: + ret = QProxyStyle::styleHint(hint, opt, widget, returnData); + break; + } + return ret; + } + + void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const + { + if(element == QStyle::PE_FrameFocusRect) + { + if (dynamic_cast<const QTabBar *>(widget)) + { + // compensate 'const int OFFSET = 1 + pixelMetric(PM_DefaultFrameWidth)' at qcommonstyle.cpp:1891 + const_cast<QStyleOption *>(option)->rect.adjust(-8, -3, 8, 3); + } + } + QProxyStyle::drawPrimitive(element, option, painter, widget); + } +}; + +/* + Application + */ + +Application::Application(int &argc, char **argv) + : QApplication(argc, argv) +{ + installStylesheet(); + + QStringList arguments = QCoreApplication::arguments(); + if (arguments.length() >= 3 && 0 == arguments.at(1).compare("--help")) + { + help_filename_ = arguments.at(2); + } +#ifdef VMP_GNU + if (isHelpMode()) { + QIcon icon(":/images/help_icon.png"); +#ifdef __APPLE__ + void qt_mac_set_app_icon(const QIcon &); + qt_mac_set_app_icon(icon); +#endif + setWindowIcon(icon); + } +#ifdef __unix__ + else + { + QIcon icon(":/images/logo.png"); + setWindowIcon(icon); + } +#endif +#else + HICON icon = static_cast<HICON>(LoadImageA(GetModuleHandle(NULL), + MAKEINTRESOURCEA(isHelpMode() ? 3 : 1), + IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_LOADTRANSPARENT)); + setWindowIcon(QtWin::fromHICON(icon)); + ::DestroyIcon(icon); +#endif +} + +double Application::stylesheetScaleFactor_ = 96.0 / 72.0, Application::devicePixelRatio_ = 1.0; +void Application::initScalingConstants() +{ + double dpi = 96.0; + QScreen *srn = QApplication::primaryScreen(); + if (srn) + dpi = (double)srn->logicalDotsPerInch(); + + devicePixelRatio_ = +#ifdef __APPLE__ + 1.4 * // проверял на виртуалке (RENDER_DPI для мака, говорят, примерно во столько раз меньше), но подозреваю, что на макбуке с ретиной получим сюрприз +#endif + devicePixelRatio(); + + double dprOverride = QString(qgetenv("VMP_PIXEL_RATIO")).toDouble(); + if (dprOverride != 0.0) + { + devicePixelRatio_ = dprOverride; + } + stylesheetScaleFactor_ = dpi * devicePixelRatio_ / 72.0; // 'point' to pixel +} + +Application::~Application() +{ + QFile t(os::CombineThisAppDataDirectory("styles.qss.tmp").c_str()); + if (t.exists()) + t.remove(); +} + +bool Application::event(QEvent *event) +{ + switch (event->type()) { + case QEvent::FileOpen: + if (isHelpMode() == false) + { + emit fileOpenEvent(static_cast<QFileOpenEvent *>(event)->file()); + return true; + } + default: + return QApplication::event(event); + } + +} + +void Application::installStylesheet() +{ + initScalingConstants(); + std::string qssFileName = os::CombineThisAppDataDirectory("styles.qss"); + if (!QFile::exists(qssFileName.c_str())) + qssFileName = ":/styles.qss"; + + QFile f(qssFileName.c_str()); + if (f.open(QIODevice::ReadOnly)) + { + QByteArray qssData = f.readAll(); + QByteArray qssDataTransformed = transformStylesheet(qssData); + QFile t(os::CombineThisAppDataDirectory("styles.qss.tmp").c_str()); + if (t.open(QIODevice::WriteOnly | QIODevice::Truncate)) + { + t.write(qssDataTransformed); + } + setStyleSheet(qssDataTransformed); + } +} + +QByteArray Application::transformStylesheet(const QByteArray &qssData) +{ + enum { + OUTSIDE, INSIDE + } state = OUTSIDE; + QByteArray ret; + ret.reserve(qssData.length() * 2); + QString current; + for(int idx = 0; idx < qssData.length(); ++idx) + { + char ch = qssData[idx]; + switch(state) + { + case OUTSIDE: + if (ch == '<') + state = INSIDE; + else + ret.append(ch); + break; + case INSIDE: + if (ch == '>') + { + double val = stylesheetScaleFactor_ * current.toDouble(); + char buf[30]; + sprintf_s(buf, "%dpx", int(val + 0.5)); + ret.append(buf); + current.clear(); + state = OUTSIDE; + } else + { + current.append(ch); + } + break; + } + } + return ret; +} + +int main(int argc, char *argv[]) +{ + QString file_name; + +#ifdef VMP_GNU + file_name = QString::fromUtf8(argv[0]); +#else + wchar_t **argv_w = CommandLineToArgvW(GetCommandLineW(), &argc); + if (argc) + file_name = QString::fromWCharArray(argv_w[0]); + LocalFree(argv_w); +#endif + + QDir dir = QFileInfo(file_name).absoluteDir(); +#ifdef __APPLE__ + dir.cdUp(); +#endif + dir.cd("PlugIns"); + + //QApplication::setLibraryPaths(QStringList(dir.absolutePath())); + QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + QApplication::setStyle(new PatchedProxyStyle()); + + Application app(argc, argv); + std::auto_ptr<QMainWindow> win; + if(app.isHelpMode()) + { + win.reset(new HelpBrowser(app.helpFileName())); + win->show(); + } else + { + win.reset(new MainWindow); + win->connect(&app, SIGNAL(fileOpenEvent(const QString &)), win.get(), SLOT(loadFile(const QString &))); + win->showMaximized(); + } + return app.exec(); +} |