diff options
Diffstat (limited to 'src/winmain/qtmain_winrt.cpp')
-rw-r--r-- | src/winmain/qtmain_winrt.cpp | 95 |
1 files changed, 75 insertions, 20 deletions
diff --git a/src/winmain/qtmain_winrt.cpp b/src/winmain/qtmain_winrt.cpp index d0f138269f..151294d2c4 100644 --- a/src/winmain/qtmain_winrt.cpp +++ b/src/winmain/qtmain_winrt.cpp @@ -44,16 +44,29 @@ linking to the Qt DLL. When a Windows application starts, the WinMain function is - invoked. WinMain creates the WinRT application which in turn - calls the main entry point. + invoked. This WinMain creates the WinRT application + container, which in turn calls the application's main() + entry point within the newly created GUI thread. */ -extern "C" int main(int, char **); +#include <new.h> + +typedef struct +{ + int newmode; +} _startupinfo; + +extern "C" { + int __getmainargs(int *argc, char ***argv, char ***env, int expandWildcards, _startupinfo *info); + int main(int, char **); +} #include <qbytearray.h> #include <qstring.h> #include <qlist.h> #include <qvector.h> +#include <qdir.h> +#include <qstandardpaths.h> #include <wrl.h> #include <Windows.ApplicationModel.core.h> @@ -66,22 +79,22 @@ using namespace Microsoft::WRL; #define CoreApplicationClass RuntimeClass_Windows_ApplicationModel_Core_CoreApplication typedef ITypedEventHandler<Core::CoreApplicationView *, Activation::IActivatedEventArgs *> ActivatedHandler; +static int g_mainExitCode; + class AppContainer : public Microsoft::WRL::RuntimeClass<Core::IFrameworkView> { public: - AppContainer(int argc, wchar_t **argv) : m_argc(argc) + AppContainer(int argc, char *argv[]) : m_argc(argc) { m_argv.reserve(argc); - for (int i = 0; i < argc; ++i) { - QByteArray arg = QString::fromWCharArray(argv[i]).toLocal8Bit(); - m_argv.append(qstrdup(arg.constData())); - } + for (int i = 0; i < argc; ++i) + m_argv.append(argv[i]); } ~AppContainer() { - foreach (const char *arg, m_argv) - delete[] arg; + for (int i = m_argc; i < m_argv.size(); ++i) + delete[] m_argv[i]; } // IFrameworkView Methods @@ -95,7 +108,33 @@ public: HRESULT __stdcall Load(HSTRING) { return S_OK; } HRESULT __stdcall Run() { - return main(m_argv.count(), m_argv.data()); + bool develMode = false; + bool debugWait = false; + foreach (const QByteArray &arg, m_argv) { + if (arg == "-qdevel") + develMode = true; + if (arg == "-qdebug") + debugWait = true; + } + if (develMode) { + // Write a PID file to help runner + const QString pidFileName = QDir(QStandardPaths::writableLocation(QStandardPaths::DataLocation)) + .absoluteFilePath(QString::number(uint(GetCurrentProcessId())) + QStringLiteral(".pid")); + CREATEFILE2_EXTENDED_PARAMETERS params = { + sizeof(CREATEFILE2_EXTENDED_PARAMETERS), + FILE_ATTRIBUTE_NORMAL, FILE_FLAG_DELETE_ON_CLOSE + }; + // (Unused) handle will automatically be closed when the app exits + CreateFile2(reinterpret_cast<LPCWSTR>(pidFileName.utf16()), + 0, FILE_SHARE_READ|FILE_SHARE_DELETE, CREATE_ALWAYS, ¶ms); + } + // Wait for debugger before continuing + if (debugWait) { + while (!IsDebuggerPresent()) + WaitForSingleObjectEx(GetCurrentThread(), 1, true); + } + g_mainExitCode = main(m_argv.count(), m_argv.data()); + return S_OK; } HRESULT __stdcall Uninitialize() { return S_OK; } @@ -110,9 +149,11 @@ private: m_argv.resize(m_argc); HSTRING arguments; launchArgs->get_Arguments(&arguments); - foreach (const QByteArray &arg, QString::fromWCharArray( - WindowsGetStringRawBuffer(arguments, nullptr)).toLocal8Bit().split(' ')) { - m_argv.append(qstrdup(arg.constData())); + if (arguments) { + foreach (const QByteArray &arg, QString::fromWCharArray( + WindowsGetStringRawBuffer(arguments, nullptr)).toLocal8Bit().split(' ')) { + m_argv.append(qstrdup(arg.constData())); + } } } return S_OK; @@ -126,19 +167,32 @@ private: class AppViewSource : public Microsoft::WRL::RuntimeClass<Core::IFrameworkViewSource> { public: - AppViewSource(int argc, wchar_t *argv[]) : argc(argc), argv(argv) { } + AppViewSource(int argc, char **argv) : m_argc(argc), m_argv(argv) { } HRESULT __stdcall CreateView(Core::IFrameworkView **frameworkView) { - return (*frameworkView = Make<AppContainer>(argc, argv).Detach()) ? S_OK : E_OUTOFMEMORY; + return (*frameworkView = Make<AppContainer>(m_argc, m_argv).Detach()) ? S_OK : E_OUTOFMEMORY; } private: - int argc; - wchar_t **argv; + int m_argc; + char **m_argv; }; // Main entry point for Appx containers -int wmain(int argc, wchar_t *argv[]) +int __stdcall WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { + int argc = 0; + char **argv, **env; + _startupinfo info = { _query_new_mode() }; + if (int init = __getmainargs(&argc, &argv, &env, false, &info)) + return init; + + for (int i = 0; env && env[i]; ++i) { + QByteArray var(env[i]); + int split = var.indexOf('='); + if (split > 0) + qputenv(var.mid(0, split), var.mid(split + 1)); + } + if (FAILED(RoInitialize(RO_INIT_MULTITHREADED))) return 1; @@ -146,5 +200,6 @@ int wmain(int argc, wchar_t *argv[]) if (FAILED(RoGetActivationFactory(qHString(CoreApplicationClass), IID_PPV_ARGS(&appFactory)))) return 2; - return appFactory->Run(Make<AppViewSource>(argc, argv).Get()); + appFactory->Run(Make<AppViewSource>(argc, argv).Get()); + return g_mainExitCode; } |