瀏覽代碼

Z991239-635 #comment feature: 添加mod_BootManager实体

gifur 5 年之前
父節點
當前提交
aa281239ef

+ 32 - 0
Module/mod_BootManager/CMakeLists.txt

@@ -0,0 +1,32 @@
+define_moudle("BootManager")
+
+set(CMAKE_AUTOUIC ON)
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_AUTORCC ON)
+
+if(MSVC)
+find_package(Qt5 COMPONENTS Widgets REQUIRED 
+    HINTS "C:/Qt/Qt5.14.2/5.14.2/msvc2017/" NO_SYSTEM_ENVIRONMENT_PATH )
+else()
+find_package(Qt5 COMPONENTS Widgets REQUIRED 
+    HINTS "/opt/Qt5.14.2/5.14.2/gcc_64/lib/cmake/" NO_SYSTEM_ENVIRONMENT_PATH )
+endif(MSVC)
+
+file(GLOB ${MODULE_PREFIX}_SRCS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
+    "${CMAKE_CURRENT_SOURCE_DIR}/*.h" "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp"
+    "${CMAKE_CURRENT_SOURCE_DIR}/*.hpp")
+
+file(GLOB QT_SRCS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
+    "${CMAKE_CURRENT_SOURCE_DIR}/Widgets/*")
+
+list(APPEND ${MODULE_PREFIX}_SRCS ${QT_SRCS})
+
+set(MOD_VERSION_STRING "1.0.0-dev1")
+add_module_libraries(${MODULE_PREFIX} ${MODULE_NAME} ${MOD_VERSION_STRING})
+
+set(${MODULE_PREFIX}_LIBS ${MODULE_BASE_LIBS} Qt5::Widgets)
+target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
+
+target_include_directories(${MODULE_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
+
+deploy_module(${MODULE_PREFIX} ${MODULE_NAME})

+ 464 - 0
Module/mod_BootManager/Widgets/Base/qmfcapp.cpp

@@ -0,0 +1,464 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Solutions component.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**   * Redistributions of source code must retain the above copyright
+**     notice, this list of conditions and the following disclaimer.
+**   * Redistributions in binary form must reproduce the above copyright
+**     notice, this list of conditions and the following disclaimer in
+**     the documentation and/or other materials provided with the
+**     distribution.
+**   * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+**     of its contributors may be used to endorse or promote products derived
+**     from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Implementation of the QMfcApp classes
+
+#ifdef QT3_SUPPORT
+#undef QT3_SUPPORT
+#endif
+
+#ifdef UNICODE
+#undef UNICODE
+#endif
+
+#include "qmfcapp.h"
+
+#include <QEventLoop>
+#include <QAbstractEventDispatcher>
+#include <QWidget>
+
+#ifdef QTWINMIGRATE_WITHMFC
+#include <afxwin.h>
+#else
+#include <qt_windows.h>
+#endif
+
+#ifdef QTWINMIGRATE_WITHMFC
+CWinApp *QMfcApp::mfc_app = 0;
+char **QMfcApp::mfc_argv = 0;
+int QMfcApp::mfc_argc = 0;
+#endif
+
+#if QT_VERSION >= 0x050000
+#define QT_WA(unicode, ansi) unicode
+
+QMfcAppEventFilter::QMfcAppEventFilter() : QAbstractNativeEventFilter()
+{
+}
+
+bool QMfcAppEventFilter::nativeEventFilter(const QByteArray &, void *message, long *result)
+{
+    return static_cast<QMfcApp*>(qApp)->winEventFilter((MSG*)message, result);
+}
+#endif
+
+/*! \class QMfcApp qmfcapp.h
+    \brief The QMfcApp class provides merging of the MFC and Qt event loops.
+
+    QMfcApp is responsible for driving both the Qt and MFC event loop.
+    It replaces the standard MFC event loop provided by
+    CWinApp::Run(), and is used instead of the QApplication parent
+    class.
+
+    To replace the MFC event loop reimplement the CWinApp::Run()
+    function in the CWinApp subclass usually created by the MFC
+    Application Wizard, and use either the static run() function, or
+    an instance of QMfcApp created earlier through the static
+    instance() function or the constructor.
+
+    The QMfcApp class also provides a static API pluginInstance() that
+    drives the Qt event loop when loaded into an MFC or Win32 application.
+    This is useful for developing Qt based DLLs or plugins, or if the
+    MFC application's event handling can not be modified.
+*/
+
+static int modalLoopCount = 0;
+
+HHOOK hhook;
+LRESULT CALLBACK QtFilterProc(int nCode, WPARAM wParam, LPARAM lParam)
+{
+    if (qApp) {
+        // don't process deferred-deletes while in a modal loop
+        if (modalLoopCount)
+            qApp->sendPostedEvents();
+        else
+            qApp->sendPostedEvents(0, -1);
+    }
+
+    return CallNextHookEx(hhook, nCode, wParam, lParam);
+}
+
+/*!
+    Inform Qt that a modal loop is about to be entered, and that DeferredDelete
+    events should not be processed. Call this function before calling Win32
+    or MFC functions that enter a modal event loop (i.e. MessageBox).
+
+    This is only required if the Qt UI code hooks into an existing Win32
+    event loop using QMfcApp::pluginInstance.
+
+    \sa exitModalLoop()
+*/
+void QMfcApp::enterModalLoop()
+{
+    ++modalLoopCount;
+}
+
+/*!
+    Inform Qt that a modal loop has been exited, and that DeferredDelete
+    events should not be processed. Call this function after the blocking
+    Win32 or MFC function (i.e. MessageBox) returned.
+
+    This is only required if the Qt UI code hooks into an existing Win32
+    event loop using QMfcApp::pluginInstance.
+
+    \sa enterModalLoop()
+*/
+void QMfcApp::exitModalLoop()
+{
+    --modalLoopCount;
+    Q_ASSERT(modalLoopCount >= 0);
+}
+
+/*!
+    If there is no global QApplication object (i.e. qApp is null) this
+    function creates a QApplication instance and returns true;
+    otherwise it does nothing and returns false.
+
+    The application installs an event filter that drives the Qt event
+    loop while the MFC or Win32 application continues to own the event
+    loop.
+
+    Use this static function if the application event loop code can not be
+    easily modified, or when developing a plugin or DLL that will be loaded
+    into an existing Win32 or MFC application. If \a plugin is non-null then
+    the function loads the respective DLL explicitly to avoid unloading from
+    memory.
+
+    \code
+    BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpvReserved)
+    {
+	if (dwReason == DLL_PROCESS_ATTACH)
+	    QMfcApp::pluginInstance(hInstance);
+
+	return TRUE;
+    }
+    \endcode
+
+    Set \a plugin to 0 when calling this function from within the same executable
+    module.
+
+    If this function is used, call enterModalLoop and exitModalLoop whenever you
+    call a Win32 or MFC function that opens a local event loop.
+
+    \code
+    void Dialog::someSlot()
+    {
+        QMfcApp::enterModalLoop();
+        MessageBox(...);
+        QMfcApp::exitModalLoop();
+    }
+    \endcode
+*/
+bool QMfcApp::pluginInstance(Qt::HANDLE plugin)
+{
+    if (qApp)
+	return FALSE;
+
+    QT_WA({
+	hhook = SetWindowsHookExW(WH_GETMESSAGE, QtFilterProc, 0, GetCurrentThreadId());
+    }, {
+	hhook = SetWindowsHookExA(WH_GETMESSAGE, QtFilterProc, 0, GetCurrentThreadId());
+    });
+
+    int argc = 0;
+    (void)new QApplication(argc, 0);
+
+    if (plugin) {
+	char filename[256];
+	if (GetModuleFileNameA((HINSTANCE)plugin, filename, 255))
+	    LoadLibraryA(filename);
+    }
+
+    return TRUE;
+}
+
+#if QT_VERSION >= 0x050000
+Q_GLOBAL_STATIC(QMfcAppEventFilter, qmfcEventFilter);
+#endif
+
+#ifdef QTWINMIGRATE_WITHMFC
+/*!
+    Runs the event loop for both Qt and the MFC application object \a
+    mfcApp, and returns the result. This function calls \c instance()
+    if no QApplication object exists and deletes the object it
+    created.
+
+    Calling this static function in a reimplementation of
+    CWinApp::Run() is the simpliest way to use the QMfcApp class:
+
+    \code
+    int MyMfcApp::Run()
+    {
+        return QMfcApp::run(this);
+    }
+    \endcode
+
+    Since a QApplication object must exist before Qt widgets can be
+    created you cannot use this function if you want to use Qt-based
+    user interface elements in, for example, the InitInstance()
+    function of CWinApp. In such cases, create an instance of
+    QApplication explicitly using instance() or the constructor.
+
+    \sa instance()
+*/
+int QMfcApp::run(CWinApp *mfcApp)
+{
+    bool ownInstance = !qApp;
+    if (ownInstance)
+	instance(mfcApp);
+    int result = qApp->exec();
+
+    if (mfcApp) {
+        int mfcRes = mfcApp->ExitInstance();
+        if (mfcRes && !result)
+            result = mfcRes;
+    }
+
+    if (ownInstance)
+	delete qApp;
+
+    return result;
+}
+
+/*!
+    Creates an instance of QApplication, passing the command line of
+    \a mfcApp to the QApplication constructor, and returns the new
+    object. The returned object must be destroyed by the caller.
+
+    Use this static function if you want to perform additional
+    initializations after creating the application object, or if you
+    want to create Qt GUI elements in the InitInstance()
+    reimplementation of CWinApp:
+
+    \code
+    BOOL MyMfcApp::InitInstance()
+    {
+	// standard MFC initialization
+	// ...
+
+	// This sets the global qApp pointer
+	QMfcApp::instance(this);
+
+	// Qt GUI initialization
+    }
+
+    BOOL MyMfcApp::Run()
+    {
+	int result = QMfcApp::run(this);
+	delete qApp;
+	return result;
+    }
+    \endcode
+
+    \sa run()
+*/
+QApplication *QMfcApp::instance(CWinApp *mfcApp)
+{
+    mfc_app = mfcApp;
+    if (mfc_app) {
+#if defined(UNICODE)
+	QString exeName((QChar*)mfc_app->m_pszExeName, wcslen(mfc_app->m_pszExeName));
+	QString cmdLine((QChar*)mfc_app->m_lpCmdLine, wcslen(mfc_app->m_lpCmdLine));
+#else
+        QString exeName = QString::fromLocal8Bit(mfc_app->m_pszExeName);
+	QString cmdLine = QString::fromLocal8Bit(mfc_app->m_lpCmdLine);
+#endif
+	QStringList arglist = QString(exeName + " " + cmdLine).split(' ');
+
+	mfc_argc = arglist.count();
+	mfc_argv = new char*[mfc_argc+1];
+	int a;
+	for (a = 0; a < mfc_argc; ++a) {
+	    QString arg = arglist[a];
+	    mfc_argv[a] = new char[arg.length()+1];
+	    qstrcpy(mfc_argv[a], arg.toLocal8Bit().data());
+	}
+	mfc_argv[a] = 0;
+    }
+
+    return new QMfcApp(mfcApp, mfc_argc, mfc_argv);
+}
+
+
+static bool qmfc_eventFilter(void *message)
+{
+    long result = 0;
+    return static_cast<QMfcApp*>(qApp)->winEventFilter((MSG*)message, &result);
+}
+
+/*!
+    Creates an instance of QMfcApp. \a mfcApp must point to the
+    existing instance of CWinApp. \a argc and \a argv are passed on
+    to the QApplication constructor.
+
+    Use the static function instance() to automatically use the
+    command line passed to the CWinApp.
+
+    \code
+    QMfcApp *qtApp;
+
+    BOOL MyMfcApp::InitInstance()
+    {
+	// standard MFC initialization
+
+	int argc = ...
+	char **argv = ...
+
+	qtApp = new QMfcApp(this, argc, argv);
+
+	// Qt GUI initialization
+    }
+
+    BOOL MyMfcApp::Run()
+    {
+	int result = qtApp->exec();
+	delete qtApp;
+	qtApp = 0;
+
+	return result;
+    }
+    \endcode
+
+    \sa instance() run()
+*/
+QMfcApp::QMfcApp(CWinApp *mfcApp, int &argc, char **argv)
+: QApplication(argc, argv), idleCount(0), doIdle(FALSE)
+{
+    mfc_app = mfcApp;
+#if QT_VERSION >= 0x050000
+    QAbstractEventDispatcher::instance()->installNativeEventFilter(qmfcEventFilter());
+#else
+    QAbstractEventDispatcher::instance()->setEventFilter(qmfc_eventFilter);
+#endif
+    setQuitOnLastWindowClosed(false);
+}
+#endif
+
+QMfcApp::QMfcApp(int &argc, char **argv) : QApplication(argc, argv)
+{
+#if QT_VERSION >= 0x050000
+    QAbstractEventDispatcher::instance()->installNativeEventFilter(qmfcEventFilter());
+#endif
+}
+/*!
+    Destroys the QMfcApp object, freeing all allocated resources.
+*/
+QMfcApp::~QMfcApp()
+{
+    if (hhook) {
+	UnhookWindowsHookEx(hhook);
+	hhook = 0;
+    }
+
+#ifdef QTWINMIGRATE_WITHMFC
+    for (int a = 0; a < mfc_argc; ++a) {
+	char *arg = mfc_argv[a];
+	delete[] arg;
+    }
+    delete []mfc_argv;
+
+    mfc_argc = 0;
+    mfc_argv = 0;
+    mfc_app = 0;
+#endif
+}
+
+/*!
+    \reimp
+*/
+bool QMfcApp::winEventFilter(MSG *msg, long *result)
+{
+    static bool recursion = false;
+    if (recursion)
+        return false;
+
+    recursion = true;
+
+    QWidget *widget = QWidget::find((WId)msg->hwnd);
+    HWND toplevel = 0;
+    if (widget) {
+        HWND parent = (HWND)widget->winId();
+        while(parent) {
+            toplevel = parent;
+            parent = GetParent(parent);
+        }
+        HMENU menu = toplevel ? GetMenu(toplevel) : 0;
+        if (menu && GetFocus() == msg->hwnd) {
+            if (msg->message == WM_SYSKEYUP && msg->wParam == VK_MENU) {
+                // activate menubar on Alt-up and move focus away
+                SetFocus(toplevel);
+                SendMessage(toplevel, msg->message, msg->wParam, msg->lParam);
+                widget->setFocus();
+                recursion = false;
+                return TRUE;
+            } else if (msg->message == WM_SYSKEYDOWN && msg->wParam != VK_MENU) {
+                SendMessage(toplevel, msg->message, msg->wParam, msg->lParam);
+                SendMessage(toplevel, WM_SYSKEYUP, VK_MENU, msg->lParam);
+                recursion = false;
+                return TRUE;
+            }
+        }
+    }
+#ifdef QTWINMIGRATE_WITHMFC
+    else if (mfc_app) {
+        MSG tmp;
+        while (doIdle && !PeekMessage(&tmp, 0, 0, 0, PM_NOREMOVE)) {
+            if (!mfc_app->OnIdle(idleCount++))
+                doIdle = FALSE;
+        }
+        if (mfc_app->IsIdleMessage(msg)) {
+            doIdle = TRUE;
+            idleCount = 0;
+        }
+    }
+    if (mfc_app && mfc_app->PreTranslateMessage(msg)) {
+        recursion = false;
+	return TRUE;
+    }
+#endif
+
+    recursion = false;
+#if QT_VERSION < 0x050000
+    return QApplication::winEventFilter(msg, result);
+#else
+    Q_UNUSED(result);
+    return false;
+#endif
+}

+ 110 - 0
Module/mod_BootManager/Widgets/Base/qmfcapp.h

@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Solutions component.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**   * Redistributions of source code must retain the above copyright
+**     notice, this list of conditions and the following disclaimer.
+**   * Redistributions in binary form must reproduce the above copyright
+**     notice, this list of conditions and the following disclaimer in
+**     the documentation and/or other materials provided with the
+**     distribution.
+**   * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+**     of its contributors may be used to endorse or promote products derived
+**     from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+// Declaration of the QMfcApp classes
+
+#ifndef QMFCAPP_H
+#define QMFCAPP_H
+
+#include <QApplication>
+
+#if defined(_AFXDLL) && defined(_MSC_VER)
+#define QTWINMIGRATE_WITHMFC
+class CWinApp;
+#endif
+
+#if defined(Q_OS_WIN)
+#  if !defined(QT_QTWINMIGRATE_EXPORT) && !defined(QT_QTWINMIGRATE_IMPORT)
+#    define QT_QTWINMIGRATE_EXPORT
+#  elif defined(QT_QTWINMIGRATE_IMPORT)
+#    if defined(QT_QTWINMIGRATE_EXPORT)
+#      undef QT_QTWINMIGRATE_EXPORT
+#    endif
+#    define QT_QTWINMIGRATE_EXPORT __declspec(dllimport)
+#  elif defined(QT_QTWINMIGRATE_EXPORT)
+#    undef QT_QTWINMIGRATE_EXPORT
+#    define QT_QTWINMIGRATE_EXPORT __declspec(dllexport)
+#  endif
+#else
+#  define QT_QTWINMIGRATE_EXPORT
+#endif
+
+#if QT_VERSION >= 0x050000
+#include <QAbstractNativeEventFilter>
+
+class QT_QTWINMIGRATE_EXPORT QMfcAppEventFilter : public QAbstractNativeEventFilter
+{
+public:
+    QMfcAppEventFilter();
+    bool nativeEventFilter(const QByteArray &eventType, void *message, long *result);
+};
+#endif
+
+class QT_QTWINMIGRATE_EXPORT QMfcApp : public QApplication
+{
+public:
+    static bool pluginInstance(Qt::HANDLE plugin = 0);
+
+#ifdef QTWINMIGRATE_WITHMFC
+    static int run(CWinApp *mfcApp);
+    static QApplication *instance(CWinApp *mfcApp);
+    QMfcApp(CWinApp *mfcApp, int &argc, char **argv);
+#endif
+    QMfcApp(int &argc, char **argv);
+    ~QMfcApp();
+
+    bool winEventFilter(MSG *msg, long *result);
+
+    static void enterModalLoop();
+    static void exitModalLoop();
+
+private:
+#ifdef QTWINMIGRATE_WITHMFC
+    static char ** mfc_argv;
+    static int mfc_argc;
+    static CWinApp *mfc_app;
+#endif
+
+    int idleCount;
+    bool doIdle;
+};
+
+#endif // QMFCAPP_H

+ 362 - 0
Module/mod_BootManager/Widgets/Base/qwinhost.cpp

@@ -0,0 +1,362 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Solutions component.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**   * Redistributions of source code must retain the above copyright
+**     notice, this list of conditions and the following disclaimer.
+**   * Redistributions in binary form must reproduce the above copyright
+**     notice, this list of conditions and the following disclaimer in
+**     the documentation and/or other materials provided with the
+**     distribution.
+**   * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+**     of its contributors may be used to endorse or promote products derived
+**     from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Implementation of the QWinHost classes
+
+#ifdef QT3_SUPPORT
+#undef QT3_SUPPORT
+#endif
+
+#include "qwinhost.h"
+
+#include <QEvent>
+#include <qt_windows.h>
+
+#if QT_VERSION >= 0x050000
+#define QT_WA(unicode, ansi) unicode
+#endif
+
+/*!
+    \class QWinHost qwinhost.h
+    \brief The QWinHost class provides an API to use native Win32
+    windows in Qt applications.
+
+    QWinHost exists to provide a QWidget that can act as a parent for
+    any native Win32 control. Since QWinHost is a proper QWidget, it
+    can be used as a toplevel widget (e.g. 0 parent) or as a child of
+    any other QWidget.
+
+    QWinHost integrates the native control into the Qt user interface,
+    e.g. handles focus switches and laying out.
+
+    Applications moving to Qt may have custom Win32 controls that will
+    take time to rewrite with Qt. Such applications can use these
+    custom controls as children of QWinHost widgets. This allows the
+    application's user interface to be replaced gradually.
+
+    When the QWinHost is destroyed, and the Win32 window hasn't been
+    set with setWindow(), the window will also be destroyed.
+*/
+
+/*!
+    Creates an instance of QWinHost. \a parent and \a f are
+    passed on to the QWidget constructor. The widget has by default
+    no background.
+
+    \warning You cannot change the parent widget of the QWinHost instance 
+    after the native window has been created, i.e. do not call 
+    QWidget::setParent or move the QWinHost into a different layout.
+*/
+QWinHost::QWinHost(QWidget *parent, Qt::WindowFlags f)
+: QWidget(parent, f), wndproc(0),own_hwnd(false), hwnd(0)
+{
+    setAttribute(Qt::WA_NoBackground);
+    setAttribute(Qt::WA_NoSystemBackground);
+}
+
+/*!
+    Destroys the QWinHost object. If the hosted Win32 window has not
+    been set explicitly using setWindow() the window will be
+    destroyed.
+*/
+QWinHost::~QWinHost()
+{
+    if (wndproc) {
+#if defined(GWLP_WNDPROC)
+	QT_WA({
+	    SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)wndproc);
+	},{
+	    SetWindowLongPtrA(hwnd, GWLP_WNDPROC, (LONG_PTR)wndproc);
+	})
+#else
+	QT_WA({
+	    SetWindowLong(hwnd, GWL_WNDPROC, (LONG)wndproc);
+	},{
+	    SetWindowLongA(hwnd, GWL_WNDPROC, (LONG)wndproc);
+	})
+#endif
+    }
+
+    if (hwnd && own_hwnd)
+	DestroyWindow(hwnd);
+}
+
+/*!
+    Reimplement this virtual function to create and return the native
+    Win32 window. \a parent is the handle to this widget, and \a
+    instance is the handle to the application instance. The returned HWND
+    must be a child of the \a parent HWND.
+
+    The default implementation returns null. The window returned by a
+    reimplementation of this function is owned by this QWinHost
+    instance and will be destroyed in the destructor.
+
+    This function is called by the implementation of polish() if no
+    window has been set explicitly using setWindow(). Call polish() to
+    force this function to be called.
+
+    \sa setWindow()
+*/
+HWND QWinHost::createWindow(HWND parent, HINSTANCE instance)
+{
+    Q_UNUSED(parent);
+    Q_UNUSED(instance);
+    return 0;
+}
+
+/*!
+    Ensures that the window provided a child of this widget, unless
+    it is a WS_OVERLAPPED window.
+*/
+void QWinHost::fixParent()
+{
+    if (!hwnd)
+        return;
+    if (!::IsWindow(hwnd)) {
+        hwnd = 0;
+        return;
+    }
+    if (::GetParent(hwnd) == (HWND)winId())
+        return;
+    long style = GetWindowLong(hwnd, GWL_STYLE);
+    if (style & WS_OVERLAPPED)
+        return;
+    ::SetParent(hwnd, (HWND)winId());
+}
+
+/*!
+    Sets the native Win32 window to \a window. If \a window is not a child 
+    window of this widget, then it is reparented to become one. If \a window 
+    is not a child window (i.e. WS_OVERLAPPED is set), then this function does nothing.
+
+    The lifetime of the window handle will be managed by Windows, QWinHost does not
+    call DestroyWindow. To verify that the handle is destroyed when expected, handle
+    WM_DESTROY in the window procedure.
+
+    \sa window(), createWindow()
+*/
+void QWinHost::setWindow(HWND window)
+{
+    if (hwnd && own_hwnd)
+	DestroyWindow(hwnd);
+
+    hwnd = window;
+    fixParent();
+
+    own_hwnd = false;
+}
+
+/*!
+    Returns the handle to the native Win32 window, or null if no
+    window has been set or created yet.
+
+    \sa setWindow(), createWindow()
+*/
+HWND QWinHost::window() const
+{
+    return hwnd;
+}
+
+void *getWindowProc(QWinHost *host)
+{
+    return host ? host->wndproc : 0;
+}
+
+LRESULT CALLBACK WinHostProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+    QWinHost *widget = qobject_cast<QWinHost*>(QWidget::find((WId)::GetParent(hwnd)));
+    WNDPROC oldproc = (WNDPROC)getWindowProc(widget);
+    if (widget) {
+	switch(msg) {
+	case WM_LBUTTONDOWN:
+	    if (::GetFocus() != hwnd && (widget->focusPolicy() & Qt::ClickFocus)) {
+		widget->setFocus(Qt::MouseFocusReason);
+	    }
+	    break;
+
+	case WM_SYSKEYDOWN:
+	case WM_SYSKEYUP:
+	    QT_WA({
+            SendMessage((HWND)widget->winId(), msg, wParam, lParam);
+	    }, {
+            SendMessageA((HWND)widget->winId(), msg, wParam, lParam);
+	    })
+	    break;
+
+	case WM_KEYDOWN:
+	    if (wParam == VK_TAB) {
+		QT_WA({
+            SendMessage((HWND)widget->winId(), msg, wParam, lParam);
+		}, {
+            SendMessageA((HWND)widget->winId(), msg, wParam, lParam);
+		})
+	    }
+	    break;
+
+	default:
+	    break;
+	}
+    }
+
+    QT_WA({
+	if (oldproc)
+	    return CallWindowProc(oldproc, hwnd, msg, wParam, lParam);
+	return DefWindowProc(hwnd,msg,wParam,lParam);
+    }, {
+	if (oldproc)
+	    return CallWindowProcA(oldproc, hwnd, msg, wParam, lParam);
+	return DefWindowProcA(hwnd,msg,wParam,lParam);
+    })
+}
+
+/*!
+    \reimp
+*/
+bool QWinHost::event(QEvent *e)
+{
+    switch(e->type()) {
+    case QEvent::Polish:
+        if (!hwnd) {
+            hwnd = createWindow(HWND(winId()), GetModuleHandle(0));
+            fixParent();
+            own_hwnd = hwnd != 0;
+        }
+        if (hwnd && !wndproc && GetParent(hwnd) == (HWND)winId()) {
+#if defined(GWLP_WNDPROC)
+            QT_WA({
+                wndproc = (void*)GetWindowLongPtr(hwnd, GWLP_WNDPROC);
+                SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)WinHostProc);
+            }, {
+                wndproc = (void*)GetWindowLongPtrA(hwnd, GWLP_WNDPROC);
+                SetWindowLongPtrA(hwnd, GWLP_WNDPROC, (LONG_PTR)WinHostProc);
+            })
+#else
+                QT_WA({
+                wndproc = (void*)GetWindowLong(hwnd, GWL_WNDPROC);
+                SetWindowLong(hwnd, GWL_WNDPROC, (LONG)WinHostProc);
+            }, {
+                wndproc = (void*)GetWindowLongA(hwnd, GWL_WNDPROC);
+                SetWindowLongA(hwnd, GWL_WNDPROC, (LONG)WinHostProc);
+            })
+#endif
+
+            LONG style;
+            QT_WA({
+                style = GetWindowLong(hwnd, GWL_STYLE);
+            }, {
+                style = GetWindowLongA(hwnd, GWL_STYLE);
+            })
+            if (style & WS_TABSTOP)
+                setFocusPolicy(Qt::FocusPolicy(focusPolicy() | Qt::StrongFocus));
+        }
+        break;
+    case QEvent::WindowBlocked:
+        if (hwnd)
+            EnableWindow(hwnd, false);
+        break;
+    case QEvent::WindowUnblocked:
+        if (hwnd)
+            EnableWindow(hwnd, true);
+        break;
+    }
+    return QWidget::event(e);
+}
+
+/*!
+    \reimp
+*/
+void QWinHost::showEvent(QShowEvent *e)
+{
+    QWidget::showEvent(e);
+
+    if (hwnd)
+	SetWindowPos(hwnd, HWND_TOP, 0, 0, width(), height(), SWP_SHOWWINDOW);
+}
+
+/*!
+    \reimp
+*/
+void QWinHost::focusInEvent(QFocusEvent *e)
+{
+    QWidget::focusInEvent(e);
+
+    if (hwnd)
+	::SetFocus(hwnd);
+}
+
+/*!
+    \reimp
+*/
+void QWinHost::resizeEvent(QResizeEvent *e)
+{
+    QWidget::resizeEvent(e);
+
+    if (hwnd)
+	SetWindowPos(hwnd, HWND_TOP, 0, 0, width(), height(), 0);
+}
+
+/*!
+    \reimp
+*/
+#if QT_VERSION >= 0x050000
+bool QWinHost::nativeEvent(const QByteArray &eventType, void *message, long *result)
+#else
+bool QWinHost::winEvent(MSG *msg, long *result)
+#endif
+{
+#if QT_VERSION >= 0x050000
+    MSG *msg = (MSG *)message;
+#endif
+    switch (msg->message)
+    {
+    case WM_SETFOCUS:
+        if (hwnd) {
+            ::SetFocus(hwnd);
+            return true;
+        }
+    default:
+        break;
+    }
+#if QT_VERSION >= 0x050000
+    return QWidget::nativeEvent(eventType, message, result);
+#else
+    return QWidget::winEvent(msg, result);
+#endif
+}

+ 98 - 0
Module/mod_BootManager/Widgets/Base/qwinhost.h

@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Solutions component.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**   * Redistributions of source code must retain the above copyright
+**     notice, this list of conditions and the following disclaimer.
+**   * Redistributions in binary form must reproduce the above copyright
+**     notice, this list of conditions and the following disclaimer in
+**     the documentation and/or other materials provided with the
+**     distribution.
+**   * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+**     of its contributors may be used to endorse or promote products derived
+**     from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+// Declaration of the QWinHost classes
+
+#ifndef QWINHOST_H
+#define QWINHOST_H
+
+#include <QWidget>
+
+#if defined(Q_OS_WIN)
+#  if !defined(QT_QTWINMIGRATE_EXPORT) && !defined(QT_QTWINMIGRATE_IMPORT)
+#    define QT_QTWINMIGRATE_EXPORT
+#  elif defined(QT_QTWINMIGRATE_IMPORT)
+#    if defined(QT_QTWINMIGRATE_EXPORT)
+#      undef QT_QTWINMIGRATE_EXPORT
+#    endif
+#    define QT_QTWINMIGRATE_EXPORT __declspec(dllimport)
+#  elif defined(QT_QTWINMIGRATE_EXPORT)
+#    undef QT_QTWINMIGRATE_EXPORT
+#    define QT_QTWINMIGRATE_EXPORT __declspec(dllexport)
+#  endif
+#else
+#  define QT_QTWINMIGRATE_EXPORT
+#endif
+
+class QT_QTWINMIGRATE_EXPORT QWinHost : public QWidget
+{
+    Q_OBJECT
+public:
+    QWinHost(QWidget *parent = 0, Qt::WindowFlags f = 0);
+    ~QWinHost();
+
+    void setWindow(HWND);
+    HWND window() const;
+
+protected:
+    virtual HWND createWindow(HWND parent, HINSTANCE instance);
+
+    bool event(QEvent *e);
+    void showEvent(QShowEvent *);
+    void focusInEvent(QFocusEvent*);
+    void resizeEvent(QResizeEvent*);
+
+#if QT_VERSION >= 0x050000
+    bool nativeEvent(const QByteArray &eventType, void *message, long *result);
+#else
+    bool winEvent(MSG *msg, long *result);
+#endif
+
+private:
+    void fixParent();
+    friend void* getWindowProc(QWinHost*);
+
+    void *wndproc;
+    bool own_hwnd;
+    HWND hwnd;
+};
+
+#endif // QWINHOST_H

+ 396 - 0
Module/mod_BootManager/Widgets/Base/qwinwidget.cpp

@@ -0,0 +1,396 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Solutions component.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**   * Redistributions of source code must retain the above copyright
+**     notice, this list of conditions and the following disclaimer.
+**   * Redistributions in binary form must reproduce the above copyright
+**     notice, this list of conditions and the following disclaimer in
+**     the documentation and/or other materials provided with the
+**     distribution.
+**   * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+**     of its contributors may be used to endorse or promote products derived
+**     from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Implementation of the QWinWidget classes
+
+#ifdef QT3_SUPPORT
+#undef QT3_SUPPORT
+#endif
+
+#ifdef UNICODE
+#undef UNICODE
+#endif
+
+#include "qmfcapp.h"
+
+#ifdef QTWINMIGRATE_WITHMFC
+#include <afxwin.h>
+#endif
+
+#include <qevent.h>
+
+#include "qwinwidget.h"
+
+#include <qt_windows.h>
+
+#if QT_VERSION >= 0x050000
+#include <QWindow>
+#include <qpa/qplatformnativeinterface.h>
+#define QT_WA(unicode, ansi) unicode
+#endif
+
+/*!
+    \class QWinWidget qwinwidget.h
+    \brief The QWinWidget class is a Qt widget that can be child of a
+    native Win32 widget.
+
+    The QWinWidget class is the bridge between an existing application
+    user interface developed using native Win32 APIs or toolkits like
+    MFC, and Qt based GUI elements.
+
+    Using QWinWidget as the parent of QDialogs will ensure that
+    modality, placement and stacking works properly throughout the
+    entire application. If the child widget is a top level window that
+    uses the \c WDestructiveClose flag, QWinWidget will destroy itself
+    when the child window closes down.
+
+    Applications moving to Qt can use QWinWidget to add new
+    functionality, and gradually replace the existing interface.
+*/
+
+/*!
+    Creates an instance of QWinWidget. \a hParentWnd is the handle to
+    the native Win32 parent. If a \a parent is provided the object is
+    owned by that QObject. \a f is passed on to the QWidget constructor.
+*/
+QWinWidget::QWinWidget(HWND hParentWnd, QObject *parent, Qt::WindowFlags f)
+: QWidget(0, f), hParent(hParentWnd), prevFocus(0), reenable_parent(false)
+{
+    if (parent)
+        QObject::setParent(parent);
+
+    init();
+}
+
+#ifdef QTWINMIGRATE_WITHMFC
+/*!
+    \overload
+
+    Creates an instance of QWinWidget. \a parentWnd is a pointer to an
+    MFC window object. If a \a parent is provided the object is owned
+    by that QObject. \a f is passed on to the QWidget constructor.
+*/
+QWinWidget::QWinWidget(CWnd *parentWnd, QObject *parent, Qt::WindowFlags f)
+: QWidget(0, f), hParent(parentWnd ? parentWnd->m_hWnd : 0), prevFocus(0), reenable_parent(false)
+{
+    if (parent)
+        QObject::setParent(parent);
+
+    init();
+}
+#endif
+
+
+void QWinWidget::init() 
+{
+    Q_ASSERT(hParent);
+
+    if (hParent) {
+#if QT_VERSION >= 0x050000
+        setProperty("_q_embedded_native_parent_handle", WId(hParent));
+#endif
+	// make the widget window style be WS_CHILD so SetParent will work
+	QT_WA({
+        SetWindowLong((HWND)winId(), GWL_STYLE, WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
+	}, {
+        SetWindowLongA((HWND)winId(), GWL_STYLE, WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
+	})
+#if QT_VERSION >= 0x050000
+        QWindow *window = windowHandle();
+        HWND h = static_cast<HWND>(QGuiApplication::platformNativeInterface()->
+                                nativeResourceForWindow("handle", window));
+        SetParent(h, hParent);
+        window->setFlags(Qt::FramelessWindowHint);
+#else
+        SetParent(winId(), hParent);
+#endif
+        QEvent e(QEvent::EmbeddingControl);
+        QApplication::sendEvent(this, &e);
+    }
+}
+
+/*!
+    Destroys this object, freeing all allocated resources.
+*/
+QWinWidget::~QWinWidget()
+{
+}
+
+/*!
+    Returns the handle of the native Win32 parent window.
+*/
+HWND QWinWidget::parentWindow() const
+{
+    return hParent;
+}
+
+/*!
+    \reimp
+*/
+void QWinWidget::childEvent(QChildEvent *e)
+{
+    QObject *obj = e->child();
+    if (obj->isWidgetType()) {
+        if (e->added()) {
+	    if (obj->isWidgetType()) {
+	        obj->installEventFilter(this);
+	    }
+        } else if (e->removed() && reenable_parent) {
+	    reenable_parent = false;
+	    EnableWindow(hParent, true);
+            obj->removeEventFilter(this);
+        }
+    }
+    QWidget::childEvent(e);
+}
+
+/*! \internal */
+void QWinWidget::saveFocus()
+{
+    if (!prevFocus)
+	prevFocus = ::GetFocus();
+    if (!prevFocus)
+	prevFocus = parentWindow();
+}
+
+/*!
+    Shows this widget. Overrides QWidget::show().
+    
+    \sa showCentered()
+*/
+void QWinWidget::show()
+{
+    saveFocus();
+    QWidget::show();
+}
+
+/*!
+    Centers this widget over the native parent window. Use this
+    function to have Qt toplevel windows (i.e. dialogs) positioned
+    correctly over their native parent windows.
+
+    \code
+    QWinWidget qwin(hParent);
+    qwin.center();
+
+    QMessageBox::information(&qwin, "Caption", "Information Text");
+    \endcode
+
+    This will center the message box over the client area of hParent.
+*/
+void QWinWidget::center()
+{
+    const QWidget *child = findChild<QWidget*>();
+    if (child && !child->isWindow()) {
+        qWarning("QWinWidget::center: Call this function only for QWinWidgets with toplevel children");
+    }
+    RECT r;
+    GetWindowRect(hParent, &r);
+    setGeometry((r.right-r.left)/2+r.left, (r.bottom-r.top)/2+r.top,0,0);
+}
+
+/*!
+    \obsolete
+
+    Call center() instead.
+*/
+void QWinWidget::showCentered()
+{
+    center();
+    show();
+}
+
+/*!
+    Sets the focus to the window that had the focus before this widget
+    was shown, or if there was no previous window, sets the focus to
+    the parent window.
+*/
+void QWinWidget::resetFocus()
+{
+    if (prevFocus)
+	::SetFocus(prevFocus);
+    else
+	::SetFocus(parentWindow());
+}
+
+/*! \reimp
+*/
+#if QT_VERSION >= 0x050000
+bool QWinWidget::nativeEvent(const QByteArray &, void *message, long *)
+#else
+bool QWinWidget::winEvent(MSG *msg, long *)
+#endif
+{
+#if QT_VERSION >= 0x050000
+    MSG *msg = (MSG *)message;
+#endif
+    if (msg->message == WM_SETFOCUS) {
+        Qt::FocusReason reason;
+        if (::GetKeyState(VK_LBUTTON) < 0 || ::GetKeyState(VK_RBUTTON) < 0)
+            reason = Qt::MouseFocusReason;
+        else if (::GetKeyState(VK_SHIFT) < 0)
+            reason = Qt::BacktabFocusReason;
+        else
+            reason = Qt::TabFocusReason;
+        QFocusEvent e(QEvent::FocusIn, reason);
+        QApplication::sendEvent(this, &e);
+    }
+
+    return false;
+}
+
+/*!
+    \reimp
+*/
+bool QWinWidget::eventFilter(QObject *o, QEvent *e)
+{
+    QWidget *w = (QWidget*)o;
+
+    switch (e->type()) {
+    case QEvent::WindowDeactivate:
+	if (w->isModal() && w->isHidden())
+	    BringWindowToTop(hParent);
+	break;
+
+    case QEvent::Hide:
+	if (reenable_parent) {
+	    EnableWindow(hParent, true);
+	    reenable_parent = false;
+	}
+	resetFocus();
+        if (w->testAttribute(Qt::WA_DeleteOnClose) && w->isWindow())
+	    deleteLater();
+	break;
+
+    case QEvent::Show:
+	if (w->isWindow()) {
+	    saveFocus();
+	    hide();
+	    if (w->isModal() && !reenable_parent) {
+		EnableWindow(hParent, false);
+		reenable_parent = true;
+	    }
+	}
+	break;
+
+    case QEvent::Close:
+    	::SetActiveWindow(hParent);
+	if (w->testAttribute(Qt::WA_DeleteOnClose))
+	    deleteLater();
+	break;
+
+    default:
+	break;
+    }
+    
+    return QWidget::eventFilter(o, e);
+}
+
+/*! \reimp
+*/
+void QWinWidget::focusInEvent(QFocusEvent *e)
+{
+    QWidget *candidate = this;
+
+    switch (e->reason()) {
+    case Qt::TabFocusReason:
+    case Qt::BacktabFocusReason:
+        while (!(candidate->focusPolicy() & Qt::TabFocus)) {
+            candidate = candidate->nextInFocusChain();
+            if (candidate == this) {
+                candidate = 0;
+                break;
+            }
+        }
+        if (candidate) {
+            candidate->setFocus(e->reason());
+            if (e->reason() == Qt::BacktabFocusReason || e->reason() == Qt::TabFocusReason) {
+                candidate->setAttribute(Qt::WA_KeyboardFocusChange);
+                candidate->window()->setAttribute(Qt::WA_KeyboardFocusChange);
+            }
+            if (e->reason() == Qt::BacktabFocusReason)
+                QWidget::focusNextPrevChild(false);
+        }
+        break;
+    default:
+        break;
+    }
+}
+
+/*! \reimp
+*/
+bool QWinWidget::focusNextPrevChild(bool next)
+{
+    QWidget *curFocus = focusWidget();
+    if (!next) {
+        if (!curFocus->isWindow()) {
+            QWidget *nextFocus = curFocus->nextInFocusChain();
+            QWidget *prevFocus = 0;
+            QWidget *topLevel = 0;
+            while (nextFocus != curFocus) {
+                if (nextFocus->focusPolicy() & Qt::TabFocus) {
+                    prevFocus = nextFocus;
+                    topLevel = 0;
+                } else if (nextFocus->isWindow()) {
+                    topLevel = nextFocus;
+                }
+                nextFocus = nextFocus->nextInFocusChain();
+            }
+
+            if (!topLevel) {
+                return QWidget::focusNextPrevChild(false);
+            }
+        }
+    } else {
+        QWidget *nextFocus = curFocus;
+        while (1) {
+            nextFocus = nextFocus->nextInFocusChain();
+            if (nextFocus->isWindow())
+                break;
+            if (nextFocus->focusPolicy() & Qt::TabFocus) {
+                return QWidget::focusNextPrevChild(true);
+            }
+        }
+    }
+
+    ::SetFocus(hParent);
+
+    return true;
+}

+ 107 - 0
Module/mod_BootManager/Widgets/Base/qwinwidget.h

@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Solutions component.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**   * Redistributions of source code must retain the above copyright
+**     notice, this list of conditions and the following disclaimer.
+**   * Redistributions in binary form must reproduce the above copyright
+**     notice, this list of conditions and the following disclaimer in
+**     the documentation and/or other materials provided with the
+**     distribution.
+**   * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+**     of its contributors may be used to endorse or promote products derived
+**     from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+// Declaration of the QWinWidget classes
+
+#ifndef QWINWIDGET_H
+#define QWINWIDGET_H
+
+#include <QWidget>
+#include "qmfcapp.h"
+
+class CWnd;
+
+#if defined(Q_OS_WIN)
+#  if !defined(QT_QTWINMIGRATE_EXPORT) && !defined(QT_QTWINMIGRATE_IMPORT)
+#    define QT_QTWINMIGRATE_EXPORT
+#  elif defined(QT_QTWINMIGRATE_IMPORT)
+#    if defined(QT_QTWINMIGRATE_EXPORT)
+#      undef QT_QTWINMIGRATE_EXPORT
+#    endif
+#    define QT_QTWINMIGRATE_EXPORT __declspec(dllimport)
+#  elif defined(QT_QTWINMIGRATE_EXPORT)
+#    undef QT_QTWINMIGRATE_EXPORT
+#    define QT_QTWINMIGRATE_EXPORT __declspec(dllexport)
+#  endif
+#else
+#  define QT_QTWINMIGRATE_EXPORT
+#endif
+
+class QT_QTWINMIGRATE_EXPORT QWinWidget : public QWidget
+{
+    Q_OBJECT
+public:
+    QWinWidget( HWND hParentWnd, QObject *parent = 0, Qt::WindowFlags f = 0 );
+#ifdef QTWINMIGRATE_WITHMFC
+    QWinWidget( CWnd *parnetWnd, QObject *parent = 0, Qt::WindowFlags f = 0 );
+#endif
+    ~QWinWidget();
+
+    void show();
+    void center();
+    void showCentered();
+
+    HWND parentWindow() const;
+
+protected:
+    void childEvent( QChildEvent *e );
+    bool eventFilter( QObject *o, QEvent *e );
+
+    bool focusNextPrevChild(bool next);
+    void focusInEvent(QFocusEvent *e);
+#if QT_VERSION >= 0x050000
+    bool nativeEvent(const QByteArray &eventType, void *message, long *result);
+#else
+    bool winEvent(MSG *msg, long *result);
+#endif
+
+private:
+    void init();
+
+    void saveFocus();
+    void resetFocus();
+
+    HWND hParent;
+    HWND prevFocus;
+    bool reenable_parent;
+};
+
+#endif // QWINWIDGET_H

+ 43 - 0
Module/mod_BootManager/Widgets/BootGlobal.h

@@ -0,0 +1,43 @@
+#ifndef BOOTGLOBAL_H
+#define BOOTGLOBAL_H
+
+#include <QWidget>
+#include <QColor>
+#include <QLayout>
+
+inline static QColor GetLeftBackgoundColor()
+{
+    return QColor(101, 105, 108, 255); //#65696C
+}
+
+inline static QColor GetRightBackgoundColor()
+{
+    return QColor(161, 163, 165, 255); //#A1A3A5
+}
+
+inline static QColor GetGlobalBackgoundColor()
+{
+    return QColor(161, 163, 165, 255); //#A1A3A5
+}
+
+inline static QString GetLogoPicPath()
+{
+    return ":/Pics/res/Logo.png";
+}
+
+inline static void SetWidgetBackgroundColor(QWidget* widget, QColor color)
+{
+    QPalette labelPalette;
+    labelPalette.setColor(QPalette::Background, color);
+    widget->setAutoFillBackground(true);
+    widget->setPalette(labelPalette);
+}
+
+inline static void SlimLayout(QLayout *layout)
+{
+    layout->setContentsMargins(0, 0, 0, 0);
+    //layout->setMargin(0);
+    layout->setSpacing(0);
+}
+
+#endif // BOOTGLOBAL_H

+ 185 - 0
Module/mod_BootManager/Widgets/BootWidget.cpp

@@ -0,0 +1,185 @@
+#include "BootWidget.h"
+#include "BootGlobal.h"
+#include "ui_BootWidget.h"
+
+#include <QLabel>
+#include <QScreen>
+
+BootWidget::BootWidget(QWidget *parent)
+    : QWidget(parent),mSplitter(NULL),mListEvtLog(NULL)
+{
+    setWindowIcon(QIcon(":/res/FavIcon.ico"));
+    setMinimumSize(1920, 1080);
+    SetFullMode();
+    Init();
+}
+
+BootWidget::~BootWidget()
+{
+
+}
+
+void BootWidget::SetFullMode()
+{
+    setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
+    setAttribute(Qt::WA_TranslucentBackground);
+
+    /*
+    setWindowFlags(Qt::Window | Qt::FramelessWindowHint
+                   | Qt::WindowStaysOnTopHint|Qt::Tool
+                   |Qt::X11BypassWindowManagerHint);
+    */
+
+    //setParent(nullptr);
+
+    QList<QScreen *> listScreens =  QGuiApplication::screens();  //多显示器
+    QRect rect = listScreens.at(0)->geometry();
+    const int desktopWidth = rect.width();
+    const int desktopHeight = rect.height();
+    setMinimumSize(desktopWidth, desktopHeight);
+}
+
+void BootWidget::Demo_FulfillLog()
+{
+    for(int i=1; i<=20; ++i)
+    {
+        QString str = QString(QStringLiteral("我是第%1串字符串")).arg(i);
+        QBaseListWidgetItem* item = new QErrorListWidgetItem(str);
+        // 为啥子类不能直接调用父类的接口??
+        item->AppentToWidget(mListEvtLog);
+    }
+}
+
+void BootWidget::Demo_FulfillFatalMsg()
+{
+    for(int i=1; i<1024; ++i)
+    {
+        QString str = QString(QStringLiteral("我是第%1串字符串")).arg(i);
+        QBaseListWidgetItem* item = new QTipListWidgetItem(str);
+        item->AppentToWidget(mListImportantTip);
+    }
+}
+
+void BootWidget::Init()
+{
+    QFont font;
+    font.setFamily(QStringLiteral("微软雅黑"));
+    //font.setPointSize(12);
+    this->setFont(font);
+/*
+    mSplitter = new QSplitter(Qt::Horizontal, this);
+
+
+    mListEvtLog = new QListWidget(this);
+    mListImportantTip = new QListWidget(this);
+
+    auto *rightWidget = new QWidget(mSplitter);
+    auto *layoutColumn = new QVBoxLayout(rightWidget);
+    layoutColumn->addWidget(mListImportantTip);
+
+    mSplitter->addWidget(mListEvtLog);
+    mSplitter->addWidget(rightWidget);
+    mSplitter->setStretchFactor(0, 80);
+    mSplitter->setStretchFactor(1, 20);
+    mSplitter->setAutoFillBackground(true);
+    //mSplitter->setHandleWidth(0);
+
+    QVBoxLayout *centerLayout = new QVBoxLayout(this);
+    centerLayout->addWidget(mSplitter);
+    this->setLayout(centerLayout);
+*/
+
+    auto *layoutCenter = new QHBoxLayout(this);
+    auto *layoutLeft = new QVBoxLayout(this);
+    auto *layoutRight = new QVBoxLayout(this);
+    auto *layoutRightArea = new QVBoxLayout(this);
+
+    SlimLayout(layoutCenter);
+    SlimLayout(layoutLeft);
+    SlimLayout(layoutRight);
+    SlimLayout(layoutRightArea);
+
+    layoutRight->addLayout(layoutRightArea);
+
+    mListEvtLog = new QLeftInfoListWidget(this);
+    layoutLeft->addWidget(mListEvtLog);
+    Demo_FulfillLog();
+
+    // LOGO
+    mLogoLabel = new QLabel(this);
+    QPixmap logoPixmap(GetLogoPicPath());
+    if(false)
+    {
+        const int labelWidth = mLogoLabel->width();
+        const int labelHeight = mLogoLabel->height();
+        //logoPixmap = logoPixmap.scaled(labelWidth, labelHeight, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+        logoPixmap = logoPixmap.scaled(labelWidth, labelHeight, Qt::KeepAspectRatio);
+    } else {
+        //const int pixWidth = logoPixmap.width();
+        //const int pixlHeight = logoPixmap.height();
+        //mLogoLabel->resize(pixWidth, pixlHeight);
+    }
+    mLogoLabel->setAlignment(Qt::AlignCenter);
+    mLogoLabel->setPixmap(logoPixmap);
+    //mLogoLabel->setScaledContents(true);
+    SetWidgetBackgroundColor(mLogoLabel, GetRightBackgoundColor());
+
+    // TerminalInfo
+    QLabel* terminalLabel = new QLabel(this);
+    terminalLabel->setText("7715012020 CMB.LIB V1.2.3.4");
+    terminalLabel->setAlignment(Qt::AlignCenter);
+    SetWidgetBackgroundColor(terminalLabel, GetRightBackgoundColor());
+
+
+    // Entity boot information
+    QLabel* entityBootLabel = new QLabel(this);
+    //equals: entityBootLabel->setText(QString::fromLocal8Bit(("11/55 个模块启动成功")));
+    entityBootLabel->setText(QStringLiteral("11/55 个模块启动成功"));
+    entityBootLabel->setAlignment(Qt::AlignCenter);
+    QFont fontLabel;
+    fontLabel.setBold(true);
+    fontLabel.setPointSize(12);
+    entityBootLabel->setFont(fontLabel);
+    //entityBootLabel->setStyleSheet("font-size:40px;font-style:blod");
+    SetWidgetBackgroundColor(entityBootLabel, GetRightBackgoundColor());
+    // no effect.
+    //entityBootLabel->setContentsMargins(0,1000,0,1000);
+    entityBootLabel->setMargin(10);
+
+    layoutRightArea->addWidget(mLogoLabel);
+    layoutRightArea->addWidget(terminalLabel);
+    layoutRightArea->addWidget(entityBootLabel);
+
+    mListImportantTip = new QRightInfoListWidget(this);
+    layoutRightArea->addWidget(mListImportantTip);
+
+    /*
+    mTextEidtFatalMsg = new QPlainTextEdit(this);
+    mTextEidtFatalMsg->setReadOnly(true);
+    mTextEidtFatalMsg->setMaximumBlockCount(1024);
+    mTextEidtFatalMsg->setBackgroundVisible(false);
+    layoutRightArea->addWidget(mTextEidtFatalMsg);
+    */
+    Demo_FulfillFatalMsg();
+
+    layoutCenter->addLayout(layoutLeft);
+    layoutCenter->addLayout(layoutRight);
+    layoutCenter->setStretch(0, 80);
+    layoutCenter->setStretch(1, 20);
+
+    this->setLayout(layoutCenter);
+}
+
+void BootWidget::paintEvent(QPaintEvent *event)
+{
+    /*
+    QPixmap logoPixmap(GetLogoPicPath());
+    const int pixWidth = logoPixmap.width();
+    const int pixlHeight = logoPixmap.height();
+
+    const int labelWidth = mLogoLabel->width();
+    const int newLabelHeight = labelWidth / (pixWidth / pixlHeight);
+    mLogoLabel->resize(labelWidth, newLabelHeight);
+    */
+}
+

+ 37 - 0
Module/mod_BootManager/Widgets/BootWidget.h

@@ -0,0 +1,37 @@
+#ifndef BOOTWIDGET_H
+#define BOOTWIDGET_H
+
+#include <QWidget>
+#include <QSplitter>
+#include <QPlainTextEdit>
+#include <QLabel>
+
+#include "QInfoListWidget.h"
+
+class BootWidget : public QWidget
+{
+    Q_OBJECT
+
+public:
+    BootWidget(QWidget *parent = nullptr);
+    ~BootWidget();
+
+    void paintEvent(QPaintEvent *event);
+
+private:
+    void Init();
+    void SetFullMode();
+
+    void Demo_FulfillLog();
+    void Demo_FulfillFatalMsg();
+
+private:
+    QSplitter *mSplitter;
+    QLeftInfoListWidget *mListEvtLog;
+    QRightInfoListWidget *mListImportantTip;
+
+    QLabel* mLogoLabel;
+
+    QPlainTextEdit* mTextEidtFatalMsg;
+};
+#endif // BOOTWIDGET_H

+ 20 - 0
Module/mod_BootManager/Widgets/BootWidget.ui

@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>BootWidget</class>
+ <widget class="QWidget" name="BootWidget">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>800</width>
+    <height>600</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>BootWidget</string>
+  </property>
+  <layout class="QHBoxLayout" name="horizontalLayout_2"/>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>

+ 148 - 0
Module/mod_BootManager/Widgets/QInfoListWidget.cpp

@@ -0,0 +1,148 @@
+#include "QInfoListWidget.h"
+#include "BootGlobal.h"
+#include <QScrollBar>
+
+
+//static const QColor g_sLeftBackgroundColor = QColor(101, 105, 108, 255); //#65696C
+//static const QColor g_sRightBackgroundColor = QColor(161, 163, 165, 255); //#A1A3A5
+
+namespace  {
+
+int ColorDodge(int primaryColor, int secondaryColors)
+{
+    if(secondaryColors >= 255) {
+        return 255;
+    }
+    //基色 +(基色 * 混合色)/(255 - 混合色)= 结果色
+    int result = (primaryColor + (uint)(primaryColor * secondaryColors) / (255 - secondaryColors));
+    if(result > 255) {
+        result = 255;
+    } else if(result < 0) {
+        result = 0;
+    }
+    return result;
+}
+
+QColor GetSortedDisplayColor(const QListWidget* parent)
+{
+    const int stepMax = 100;
+    const int currItemsCount = parent->count();
+
+    const int j = (stepMax - currItemsCount % stepMax);
+    const int gradientR = ColorDodge(205, j);
+    const int gradientG = ColorDodge(38, j);
+    const int gradientB = ColorDodge(38, j);
+    return QColor(gradientR, gradientG, gradientB, 255);
+
+    //const int colorMax = (int)Qt::transparent;
+    //return QColor(Qt::GlobalColor(currItemsCount % colorMax));
+}
+
+}
+
+
+QBaseListWidgetItem::QBaseListWidgetItem(const QString &text, InfoType it, LevelType lt)
+    :QListWidgetItem(text),infoType(it),levelType(lt)
+{
+    setFlags(Qt::ItemIsEnabled | Qt::NoItemFlags);
+
+}
+
+void QBaseListWidgetItem::AppentToWidget(QInfoListWidget* container, bool insertFront)
+{
+    if(insertFront)
+    {
+        container->insertItem(0, this);
+        container->setCurrentRow(0);
+    } else {
+        container->addItem(this);
+        container->setCurrentRow(container->count()-1);
+    }
+    setForeground(FrontColor());
+    setBackground(BackgroundColor());
+}
+
+QColor QBaseListWidgetItem::FrontColor() const
+{
+    auto colorValue = Qt::black;
+    return QColor(Qt::GlobalColor(colorValue));
+}
+
+QColor QBaseListWidgetItem::BackgroundColor() const
+{
+    return GetLeftBackgoundColor();
+}
+
+
+
+
+
+QInfoListWidgetItem::QInfoListWidgetItem(const QString &text, LevelType lt)
+    :QBaseListWidgetItem(text, Info, lt)
+{
+
+}
+
+QColor QErrorListWidgetItem::FrontColor() const
+{
+    auto colorValue = Qt::red;
+    return QColor(colorValue);
+}
+
+QColor QTipListWidgetItem::FrontColor() const
+{
+    QListWidget* parent = listWidget();
+    if(parent != nullptr)
+        return GetSortedDisplayColor(parent);
+    auto colorValue = Qt::red;
+    return QColor(colorValue);
+}
+
+QColor QTipListWidgetItem::BackgroundColor() const
+{
+    return GetRightBackgoundColor();
+}
+
+
+QInfoListWidget::QInfoListWidget(QWidget* parent)
+    :QListWidget(parent)
+{
+    Init();
+}
+
+void QInfoListWidget::Init()
+{
+    this->setViewMode(QListView::ListMode);
+    this->setFlow(QListView::TopToBottom);
+    this->setSortingEnabled(false);
+    // Hide the scrollbar
+    this->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+    this->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+    /*disable hightlight when cursor hover*/
+    this->setStyleSheet("QListWidget::item:hover{background: transparent;}");
+    /*hide border*/
+    this->setFrameShape(QListWidget::NoFrame);
+}
+
+void QInfoListWidget::WheelEvent(QWheelEvent* event)
+{
+    int degress = event->angleDelta().ry() * 0.5;
+    if(event->orientation() == Qt::Vertical)
+        verticalScrollBar()->setValue(verticalScrollBar()->value() - degress);
+    event->accept();
+}
+
+void QLeftInfoListWidget::PostInit()
+{
+    qDebug("QLeftInfoListWidget::PostInit()");
+    this->setStyleSheet("QListWidget{background: #65696C;outline:0px;}"
+                        "QListWidget::item:hover{background: #65696C;}");
+}
+
+void QRightInfoListWidget::PostInit()
+{
+    qDebug("QRightInfoListWidget::PostInit()");
+    //SetWidgetBackgroundColor(this, GetRightBackgoundColor());
+    this->setStyleSheet("QListWidget{background: #A1A3A5;outline:0px;}" //去除选中时的虚线
+                        "QListWidget::item:selected,QListWidget::item:hover{background: #A1A3A5;}");
+}

+ 112 - 0
Module/mod_BootManager/Widgets/QInfoListWidget.h

@@ -0,0 +1,112 @@
+#ifndef QINFOLISTWIDGET_H
+#define QINFOLISTWIDGET_H
+
+#include <QWidget>
+#include <QListWidget>
+#include <QWheelEvent>
+
+
+enum InfoType {
+    Info,
+    Event,
+    Warning,
+    Error,
+    Succeed
+};
+
+enum LevelType {
+    None,
+    Lower,
+    Normal,
+    Higher
+};
+
+
+class QInfoListWidget;
+
+
+class QBaseListWidgetItem : public QListWidgetItem
+{
+public:
+    QBaseListWidgetItem(const QString &text, InfoType it, LevelType lt);
+    virtual ~QBaseListWidgetItem() {}
+
+    void AppentToWidget(QInfoListWidget* container, bool insertFront = true);
+
+protected:
+    virtual QColor FrontColor() const;
+    virtual QColor BackgroundColor() const;
+    InfoType infoType;
+    LevelType levelType;
+};
+
+class QInfoListWidgetItem : public QBaseListWidgetItem
+{
+public:
+    QInfoListWidgetItem(const QString &text, LevelType lt = None);
+    virtual ~QInfoListWidgetItem() {}
+};
+
+class QErrorListWidgetItem : public QBaseListWidgetItem
+{
+public:
+    QErrorListWidgetItem(const QString &text, LevelType lt = None)
+        :QBaseListWidgetItem(text, InfoType::Error, lt){}
+    virtual ~QErrorListWidgetItem() {}
+
+private:
+    QColor FrontColor() const;
+};
+
+class QTipListWidgetItem : public QBaseListWidgetItem
+{
+public:
+    QTipListWidgetItem(const QString &text)
+        :QBaseListWidgetItem(text, InfoType::Error, Higher){
+        setTextAlignment(Qt::AlignCenter);
+    }
+    virtual ~QTipListWidgetItem() {}
+
+private:
+    QColor FrontColor() const;
+    QColor BackgroundColor() const;
+};
+
+
+class QInfoListWidget : public QListWidget
+{
+    Q_OBJECT
+public:
+    QInfoListWidget(QWidget* parent = nullptr);
+    virtual ~QInfoListWidget() {}
+
+    virtual void PostInit() { qDebug("parent::PostInit"); }
+
+protected:
+    void Init();
+    void WheelEvent(QWheelEvent* event);
+};
+
+class QLeftInfoListWidget : public QInfoListWidget
+{
+    Q_OBJECT
+public:
+    QLeftInfoListWidget(QWidget* parent = nullptr)
+        :QInfoListWidget(parent){PostInit();}
+    virtual ~QLeftInfoListWidget() {}
+
+    virtual void PostInit() override;
+};
+
+class QRightInfoListWidget : public QInfoListWidget
+{
+    Q_OBJECT
+public:
+    QRightInfoListWidget(QWidget* parent = nullptr)
+        :QInfoListWidget(parent){PostInit();}
+    virtual ~QRightInfoListWidget() {}
+
+    virtual void PostInit() override;
+};
+
+#endif // QINFOLISTWIDGET_H

+ 8 - 0
Module/mod_BootManager/Widgets/res.qrc

@@ -0,0 +1,8 @@
+<RCC>
+    <qresource prefix="/Pics">
+        <file>res/Logo.png</file>
+    </qresource>
+    <qresource prefix="/">
+        <file>res/FavIcon.ico</file>
+    </qresource>
+</RCC>

二進制
Module/mod_BootManager/Widgets/res/FavIcon.ico


二進制
Module/mod_BootManager/Widgets/res/Logo.png


+ 32 - 0
Module/mod_BootManager/mod_BootManager.cpp

@@ -0,0 +1,32 @@
+#include "mod_BootManager.h"
+
+#include "Widgets/BootWidget.h"
+
+#include <thread>
+
+#include <QApplication>
+#include <QMessageBox>
+
+namespace
+{
+    void QtWinThread(BootManager* mgr)
+    {
+        LOG_FUNCTION();
+
+        int argc = 0;
+        QApplication a(argc, 0);
+        BootWidget w;
+        w.show();
+        a.exec();
+    }
+}
+
+void BootManager::QtUIShow()
+{
+    std::thread uiThread(QtWinThread, this);
+    uiThread.detach();
+}
+
+SP_BEGIN_ENTITY_MAP()
+SP_ENTITY(BootManager)
+SP_END_ENTITY_MAP()

+ 46 - 0
Module/mod_BootManager/mod_BootManager.h

@@ -0,0 +1,46 @@
+#ifndef RVC_MOD_BOOT_MANAGER_H_
+#define RVC_MOD_BOOT_MANAGER_H_
+
+#include "SpBase.h"
+#include "SpTest.h"
+#include "modVer.h"
+
+class BootManager : public CEntityBase
+{
+public:
+    BootManager()
+    { 
+    }
+
+    ~BootManager()
+    {
+    }
+
+    const char* GetEntityName() const override
+    {
+        return "BootManager";
+    }
+
+    const char* GetEntityVersion() const override
+    {
+        return MODULE_VERSION_FULL;
+    }
+
+    void OnPreStart(CAutoArray<CSimpleStringA> strArgs,
+                               CSmartPointer<ITransactionContext> pTransactionContext)
+    {
+        ErrorCodeEnum ec(Error_Succeed);
+
+
+        pTransactionContext->SendAnswer(ec);
+    }
+
+    void OnStarted() override
+    {
+        QtUIShow();
+    }
+
+    void QtUIShow();
+};
+
+#endif //RVC_MOD_BOOT_MANAGER_H_

+ 3 - 1
addin/cfg/shell.ini.in

@@ -20,6 +20,7 @@ CenterSetting=0,@LIB_PREFIX@mod_CenterSetting@LIB_SUFFIX@,0x101
 TokenKeeper=0,@LIB_PREFIX@mod_TokenMgr@LIB_SUFFIX@,0x10A
 ;SystemCustomization=0,@LIB_PREFIX@mod_systemcustomization@LIB_SUFFIX@,0x10B
 ;FreeRDPWrap=0,@LIB_PREFIX@mod_FreeRdpWrap@LIB_SUFFIX@,0x10C
+BootManager=0,@LIB_PREFIX@mod_BootManager@LIB_SUFFIX@,0x10D
 ;HolderContext=0,@LIB_PREFIX@mod_HolderContext@LIB_SUFFIX@,0x315
 
 ;Ó²¼þ·þÎñ²ã
@@ -92,9 +93,10 @@ Initializer=0,@LIB_PREFIX@mod_Initializer@LIB_SUFFIX@,0x509
 TestDeamon=1,@LIB_PREFIX@mod_validityVertifier@LIB_SUFFIX@,0xF00
 
 [Startup]
-Number=2
+Number=3
 1=PinPad
 2=CenterSetting
+3=BootManager
 ;the test server run mod_CardSwiper failed because lack of bthprops.cpl, so we seal it.
 ;3=CardSwiper