mirror of
https://github.com/ONLYOFFICE/desktop-apps.git
synced 2026-04-07 14:09:22 +08:00
[win] online-installer: enhancement
This commit is contained in:
@ -27,7 +27,19 @@ ENV_URL_INSTALL_X86_XP = $$(DESKTOP_URL_INSTALL_CHANNEL_X86_XP)
|
||||
DEFINES += URL_INSTALL_X86_XP=\\\"$${ENV_URL_INSTALL_X86_XP}\\\"
|
||||
}
|
||||
|
||||
ENV_URL_INSTALL_X64_MSI = $$(DESKTOP_URL_INSTALL_CHANNEL_X64_MSI)
|
||||
!isEmpty(ENV_URL_INSTALL_X64_MSI) {
|
||||
DEFINES += URL_INSTALL_X64_MSI=\\\"$${ENV_URL_INSTALL_X64_MSI}\\\"
|
||||
}
|
||||
|
||||
ENV_URL_INSTALL_X86_MSI = $$(DESKTOP_URL_INSTALL_CHANNEL_X86_MSI)
|
||||
!isEmpty(ENV_URL_INSTALL_X86_MSI) {
|
||||
DEFINES += URL_INSTALL_X86_MSI=\\\"$${ENV_URL_INSTALL_X86_MSI}\\\"
|
||||
}
|
||||
|
||||
message(install x64 url: \\\"$$ENV_URL_INSTALL_X64\\\")
|
||||
message(install x86 url: \\\"$$ENV_URL_INSTALL_X86\\\")
|
||||
message(install x64 xp url: \\\"$$ENV_URL_INSTALL_X64_XP\\\")
|
||||
message(install x86 xp url: \\\"$$ENV_URL_INSTALL_X86_XP\\\")
|
||||
message(install x64 msi url: \\\"$$ENV_URL_INSTALL_X64_MSI\\\")
|
||||
message(install x86 msi url: \\\"$$ENV_URL_INSTALL_X86_MSI\\\")
|
||||
|
||||
@ -8,25 +8,70 @@ CONFIG -= debug_and_release debug_and_release_target
|
||||
TEMPLATE = app
|
||||
|
||||
CORE_ROOT_DIR = $$PWD/../../../../core
|
||||
UICLASSES = $$PWD/src/uiclasses
|
||||
|
||||
CONFIG += core_no_dst
|
||||
include($$CORE_ROOT_DIR/Common/base.pri)
|
||||
|
||||
INCLUDEPATH += $$PWD/src
|
||||
INCLUDEPATH += $$PWD/src \
|
||||
$$UICLASSES
|
||||
INCLUDEPATH += $$PWD/../../src/prop
|
||||
|
||||
HEADERS += $$PWD/src/version.h \
|
||||
$$PWD/src/resource.h \
|
||||
$$PWD/src/mainwindow.h \
|
||||
$$PWD/src/cdownloader.h \
|
||||
$$PWD/src/translator.h \
|
||||
$$PWD/src/utils.h
|
||||
$$PWD/src/utils.h \
|
||||
$$UICLASSES/commondefines.h \
|
||||
$$UICLASSES/baseutils.h \
|
||||
$$UICLASSES/common.h \
|
||||
$$UICLASSES/metrics.h \
|
||||
$$UICLASSES/palette.h \
|
||||
$$UICLASSES/drawningengine.h \
|
||||
$$UICLASSES/drawingsurface.h \
|
||||
$$UICLASSES/object.h \
|
||||
$$UICLASSES/application.h \
|
||||
$$UICLASSES/window.h \
|
||||
$$UICLASSES/widget.h \
|
||||
$$UICLASSES/label.h \
|
||||
$$UICLASSES/caption.h \
|
||||
$$UICLASSES/abstractbutton.h \
|
||||
$$UICLASSES/button.h \
|
||||
$$UICLASSES/checkbox.h \
|
||||
$$UICLASSES/radiobutton.h \
|
||||
$$UICLASSES/progressbar.h \
|
||||
$$UICLASSES/layoutitem.h \
|
||||
$$UICLASSES/layout.h \
|
||||
$$UICLASSES/boxlayout.h
|
||||
|
||||
SOURCES += $$PWD/src/main.cpp \
|
||||
$$PWD/src/mainwindow.cpp \
|
||||
$$PWD/src/cdownloader.cpp \
|
||||
$$PWD/src/translator.cpp \
|
||||
$$PWD/src/utils.cpp
|
||||
$$PWD/src/utils.cpp \
|
||||
$$UICLASSES/baseutils.cpp \
|
||||
$$UICLASSES/common.cpp \
|
||||
$$UICLASSES/metrics.cpp \
|
||||
$$UICLASSES/palette.cpp \
|
||||
$$UICLASSES/drawningengine.cpp \
|
||||
$$UICLASSES/drawingsurface.cpp \
|
||||
$$UICLASSES/object.cpp \
|
||||
$$UICLASSES/application.cpp \
|
||||
$$UICLASSES/window.cpp \
|
||||
$$UICLASSES/widget.cpp \
|
||||
$$UICLASSES/label.cpp \
|
||||
$$UICLASSES/caption.cpp \
|
||||
$$UICLASSES/abstractbutton.cpp \
|
||||
$$UICLASSES/button.cpp \
|
||||
$$UICLASSES/checkbox.cpp \
|
||||
$$UICLASSES/radiobutton.cpp \
|
||||
$$UICLASSES/progressbar.cpp \
|
||||
$$UICLASSES/layoutitem.cpp \
|
||||
$$UICLASSES/layout.cpp \
|
||||
$$UICLASSES/boxlayout.cpp
|
||||
|
||||
OTHER_FILES += $$PWD/res/dialog.rc \
|
||||
OTHER_FILES += $$PWD/res/version.rc \
|
||||
$$PWD/res/manifest/online-installer.exe.manifest
|
||||
|
||||
ENV_PRODUCT_VERSION = $$(PRODUCT_VERSION)
|
||||
@ -37,7 +82,8 @@ ENV_PRODUCT_VERSION = $$(PRODUCT_VERSION)
|
||||
}
|
||||
|
||||
CONFIG -= embed_manifest_exe
|
||||
RC_FILE = $$PWD/res/dialog.rc
|
||||
RC_FILE = $$PWD/res/version.rc
|
||||
QMAKE_CXXFLAGS += -D_UNICODE
|
||||
|
||||
contains(QMAKE_TARGET.arch, x86_64):{
|
||||
QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS,5.02
|
||||
@ -59,10 +105,20 @@ build_xp {
|
||||
DEFINES += __OS_WIN_XP
|
||||
}
|
||||
|
||||
DEFINES -= NOMINMAX
|
||||
|
||||
LIBS += -luser32 \
|
||||
-lshell32 \
|
||||
-lshlwapi \
|
||||
-lwinhttp \
|
||||
-lwintrust \
|
||||
-lgdi32 \
|
||||
-lgdiplus \
|
||||
-ladvapi32 \
|
||||
-lrpcrt4 \
|
||||
-lole32 \
|
||||
-lmsi \
|
||||
-lwinmm \
|
||||
-lcomctl32
|
||||
|
||||
OBJECTS_DIR = $$DESTDIR/obj
|
||||
|
||||
@ -1,68 +0,0 @@
|
||||
#pragma code_page(65001)
|
||||
#include <Windows.h>
|
||||
#include "../src/version.h"
|
||||
#include "../src/resource.h"
|
||||
|
||||
IDI_MAINICON ICON DISCARDABLE APP_ICON_PATH
|
||||
IDT_TRANSLATIONS RCDATA APP_LANG_PATH
|
||||
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "./manifest/online-installer.exe.manifest"
|
||||
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION VER_FILEVERSION
|
||||
PRODUCTVERSION VER_PRODUCTVERSION
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK VER_LANG_AND_CHARSET_STR
|
||||
BEGIN
|
||||
VALUE "CompanyName", VER_COMPANYNAME_STR
|
||||
VALUE "FileDescription", VER_FILEDESCRIPTION_STR
|
||||
VALUE "FileVersion", VER_FILEVERSION_STR
|
||||
VALUE "InternalName", VER_INTERNALNAME_STR
|
||||
VALUE "LegalCopyright", VER_LEGALCOPYRIGHT_STR
|
||||
VALUE "LegalTrademarks1", VER_LEGALTRADEMARKS1_STR
|
||||
VALUE "LegalTrademarks2", VER_LEGALTRADEMARKS2_STR
|
||||
VALUE "OriginalFilename", VER_ORIGINALFILENAME_STR
|
||||
VALUE "ProductName", VER_PRODUCTNAME_STR
|
||||
VALUE "ProductVersion", VER_PRODUCTVERSION_STR
|
||||
END
|
||||
END
|
||||
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", VER_LANG_ID, VER_CHARSET_ID
|
||||
END
|
||||
END
|
||||
|
||||
//
|
||||
// Dialog
|
||||
//
|
||||
|
||||
IDD_DIALOG DIALOGEX 0, 0, 320, 100
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_CAPTION | WS_SYSMENU
|
||||
EXSTYLE WS_EX_STATICEDGE
|
||||
CAPTION ""
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
CONTROL "Progress", IDC_PROGRESS, "msctls_progress32", WS_BORDER, 15, 56, 290, 6
|
||||
CONTROL "Icon", IDC_MAIN_ICON, "Static", SS_ICON | SS_CENTER | WS_CHILD | WS_VISIBLE, 15, 10, 32, 32
|
||||
LTEXT "", IDC_LABEL_TITLE, 75, 15, 220, 14, SS_LEFT | WS_CHILD | WS_VISIBLE
|
||||
LTEXT "", IDC_LABEL_MESSAGE, 75, 28, 220, 24, SS_LEFT | WS_CHILD | WS_VISIBLE
|
||||
PUSHBUTTON "", IDC_BUTTON_CANCEL, 225, 72, 80, 18
|
||||
CONTROL "", IDC_SILENT_CHECK, "BUTTON", BS_AUTOCHECKBOX | WS_TABSTOP, 30, 70, 100, 20
|
||||
END
|
||||
|
||||
IDD_DIALOG_RTL DIALOGEX 0, 0, 320, 100
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_CAPTION | WS_SYSMENU
|
||||
EXSTYLE WS_EX_STATICEDGE | WS_EX_LAYOUTRTL
|
||||
CAPTION ""
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
CONTROL "Progress", IDC_PROGRESS, "msctls_progress32", WS_BORDER, 15, 56, 290, 6
|
||||
CONTROL "Icon", IDC_MAIN_ICON, "Static", SS_ICON | SS_CENTER | WS_CHILD | WS_VISIBLE, 15, 10, 32, 32
|
||||
LTEXT "", IDC_LABEL_TITLE, 75, 15, 220, 14, SS_LEFT | WS_CHILD | WS_VISIBLE
|
||||
LTEXT "", IDC_LABEL_MESSAGE, 75, 28, 220, 24, SS_LEFT | WS_CHILD | WS_VISIBLE
|
||||
PUSHBUTTON "", IDC_BUTTON_CANCEL, 225, 72, 80, 18
|
||||
CONTROL "", IDC_SILENT_CHECK, "BUTTON", BS_AUTOCHECKBOX | WS_TABSTOP, 30, 70, 100, 20
|
||||
END
|
||||
BIN
win-linux/extras/online-installer/res/icons/welcome.png
Normal file
BIN
win-linux/extras/online-installer/res/icons/welcome.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
@ -1,246 +1,357 @@
|
||||
|
||||
en.CAPTION_TEXT =ONLYOFFICE Online Installer
|
||||
ru.CAPTION_TEXT =ONLYOFFICE Онлайн Установщик
|
||||
de.CAPTION_TEXT =ONLYOFFICE Online-Installationsprogramm
|
||||
fr.CAPTION_TEXT =Programme d'installation ONLYOFFICE en ligne
|
||||
es.CAPTION_TEXT = Instalador online ONLYOFFICE
|
||||
it.CAPTION_TEXT =Programma di installazione online di ONLYOFFICE
|
||||
ja.CAPTION_TEXT =ONLYOFFICE オンラインインストーラー
|
||||
zh_CN.CAPTION_TEXT =ONLYOFFICE 在线安装程序
|
||||
ro.CAPTION_TEXT =Asistent de Instalare Online ONLYOFFICE
|
||||
ar_SA.CAPTION_TEXT =ONLYOFFICE المثبت عبر الإنترنت
|
||||
bg.CAPTION_TEXT =Онлайн инсталатор на ONLYOFFICE
|
||||
cs.CAPTION_TEXT =Online instalátor ONLYOFFICE
|
||||
el.CAPTION_TEXT =Διαδικτυακό πρόγραμμα εγκατάστασης ONLYOFFICE
|
||||
fi.CAPTION_TEXT =ONLYOFFICE verkkoasennus
|
||||
hy.CAPTION_TEXT =ONLYOFFICE առցանց տեղադրող
|
||||
ko.CAPTION_TEXT =ONLYOFFICE 온라인 설치 프로그램
|
||||
lv.CAPTION_TEXT =ONLYOFFICE tiešsaistes instalētājs
|
||||
nl.CAPTION_TEXT =ONLYOFFICE Online Installatieprogramma
|
||||
pl.CAPTION_TEXT =Instalator ONLYOFFICE online
|
||||
pt_PT.CAPTION_TEXT =Instalador on-line do ONLYOFFICE
|
||||
sk.CAPTION_TEXT =Online inštalátor ONLYOFFICE
|
||||
sl.CAPTION_TEXT =ONLYOFFICE Spletni namestitveni program
|
||||
tr.CAPTION_TEXT =ONLYOFFICE Çevrimiçi Yükleyici
|
||||
uk.CAPTION_TEXT =Онлайн-інсталятор ONLYOFFICE
|
||||
vi.CAPTION_TEXT =Trình cài đặt trực tuyến ONLYOFFICE
|
||||
sr_latn_RS.CAPTION_TEXT =ONLYOFFICE Onlajn Instalater
|
||||
si.CAPTION_TEXT =ඔන්ලිඔෆිස් මාර්ගගත ස්ථාපකය
|
||||
be.CAPTION_TEXT =Анлайн усталёўшчык ONLYOFFICE
|
||||
ca.CAPTION_TEXT =Instal·lador online ONLYOFFICE
|
||||
da.CAPTION_TEXT =ONLYOFFICE Onlineinstallatør
|
||||
gl.CAPTION_TEXT =Instalador en liña de ONLYOFFICE
|
||||
hu.CAPTION_TEXT =ONLYOFFICE Online Telepítő
|
||||
id.CAPTION_TEXT =Installer Online ONLYOFFICE
|
||||
no.CAPTION_TEXT =ONLYOFFICE nettbasert installasjonsprogram
|
||||
et.CAPTION_TEXT =ONLYOFFICE veebipaigaldus
|
||||
lt.CAPTION_TEXT =ONLYOFFICE diegimas internetu
|
||||
hr.CAPTION_TEXT =Mrežni instalacijski program ONLYOFFICE
|
||||
hi.CAPTION_TEXT =ओनलीऑफिस ऑनलाइन इंस्टॉलर
|
||||
sv.CAPTION_TEXT =ONLYOFFICE onlineinstallationsprogram
|
||||
sr_Cyrl_RS.CAPTION_TEXT =ONLYOFFICE Онлајн Инсталатер
|
||||
en.CAPTION =ONLYOFFICE Online Installer
|
||||
ru.CAPTION =ONLYOFFICE Онлайн Установщик
|
||||
de.CAPTION =ONLYOFFICE Online-Installationsprogramm
|
||||
fr.CAPTION =Programme d'installation ONLYOFFICE en ligne
|
||||
es.CAPTION = Instalador online ONLYOFFICE
|
||||
it.CAPTION =Programma di installazione online di ONLYOFFICE
|
||||
ja.CAPTION =ONLYOFFICE オンラインインストーラー
|
||||
zh_CN.CAPTION =ONLYOFFICE 在线安装程序
|
||||
ro.CAPTION =Asistent de Instalare Online ONLYOFFICE
|
||||
ar_SA.CAPTION =ONLYOFFICE المثبت عبر الإنترنت
|
||||
bg.CAPTION =Онлайн инсталатор на ONLYOFFICE
|
||||
cs.CAPTION =Online instalátor ONLYOFFICE
|
||||
el.CAPTION =Διαδικτυακό πρόγραμμα εγκατάστασης ONLYOFFICE
|
||||
fi.CAPTION =ONLYOFFICE verkkoasennus
|
||||
hy.CAPTION =ONLYOFFICE առցանց տեղադրող
|
||||
ko.CAPTION =ONLYOFFICE 온라인 설치 프로그램
|
||||
lv.CAPTION =ONLYOFFICE tiešsaistes instalētājs
|
||||
nl.CAPTION =ONLYOFFICE Online Installatieprogramma
|
||||
pl.CAPTION =Instalator ONLYOFFICE online
|
||||
pt_PT.CAPTION =Instalador on-line do ONLYOFFICE
|
||||
sk.CAPTION =Online inštalátor ONLYOFFICE
|
||||
sl.CAPTION =ONLYOFFICE Spletni namestitveni program
|
||||
tr.CAPTION =ONLYOFFICE Çevrimiçi Yükleyici
|
||||
uk.CAPTION =Онлайн-інсталятор ONLYOFFICE
|
||||
vi.CAPTION =Trình cài đặt trực tuyến ONLYOFFICE
|
||||
sr_latn_RS.CAPTION =ONLYOFFICE Onlajn Instalater
|
||||
si.CAPTION =ඔන්ලිඔෆිස් මාර්ගගත ස්ථාපකය
|
||||
be.CAPTION =Анлайн усталёўшчык ONLYOFFICE
|
||||
ca.CAPTION =Instal·lador online ONLYOFFICE
|
||||
da.CAPTION =ONLYOFFICE Onlineinstallatør
|
||||
gl.CAPTION =Instalador en liña de ONLYOFFICE
|
||||
hu.CAPTION =ONLYOFFICE Online Telepítő
|
||||
id.CAPTION =Installer Online ONLYOFFICE
|
||||
no.CAPTION =ONLYOFFICE nettbasert installasjonsprogram
|
||||
et.CAPTION =ONLYOFFICE veebipaigaldus
|
||||
lt.CAPTION =ONLYOFFICE diegimas internetu
|
||||
hr.CAPTION =Mrežni instalacijski program ONLYOFFICE
|
||||
hi.CAPTION =ओनलीऑफिस ऑनलाइन इंस्टॉलर
|
||||
sv.CAPTION =ONLYOFFICE onlineinstallationsprogram
|
||||
sr_Cyrl_RS.CAPTION =ONLYOFFICE Онлајн Инсталатер
|
||||
|
||||
en.MESSAGE_TEXT_ERR1 =The application cannot continue because this architecture is not supported.
|
||||
ru.MESSAGE_TEXT_ERR1 =Приложение не может продолжить работу, так как эта архитектура не поддерживается.
|
||||
de.MESSAGE_TEXT_ERR1 =Die Anwendung kann nicht fortgesetzt werden, da diese Architektur nicht unterstützt wird.
|
||||
fr.MESSAGE_TEXT_ERR1 =L'application ne peut pas continuer car cette architecture n'est pas prise en charge.
|
||||
es.MESSAGE_TEXT_ERR1 =La aplicación no puede continuar porque esta arquitectura no es compatible.
|
||||
it.MESSAGE_TEXT_ERR1 =L'applicazione non può continuare perché questa architettura non è supportata.
|
||||
ja.MESSAGE_TEXT_ERR1 =このアーキテクチャがサポートされていないため、アプリケーションを続行できません。
|
||||
zh_CN.MESSAGE_TEXT_ERR1 =应用程序无法继续,因为此架构不受支持。
|
||||
ro.MESSAGE_TEXT_ERR1 =Procesul aplicației nu poate continua deoarece această arhitectură nu este acceptată.
|
||||
ar_SA.MESSAGE_TEXT_ERR1 =لا يمكن متابعة التطبيق لأن هذه البنية غير معتمدة.
|
||||
bg.MESSAGE_TEXT_ERR1 =Приложението не може да продължи, защото тази архитектура не се поддържа.
|
||||
cs.MESSAGE_TEXT_ERR1 =Aplikace nemůže pokračovat, protože tato architektura není podporována.
|
||||
el.MESSAGE_TEXT_ERR1 =Η εφαρμογή δεν μπορεί να συνεχιστεί επειδή αυτή η αρχιτεκτονική δεν υποστηρίζεται.
|
||||
fi.MESSAGE_TEXT_ERR1 =Sovellus ei toimi, koska tätä arkkitehtuuria ei tueta.
|
||||
hy.MESSAGE_TEXT_ERR1 =Հավելվածը չի կարող շարունակվել, քանի որ այս ճարտարապետությունը չի աջակցվում:
|
||||
ko.MESSAGE_TEXT_ERR1 =이 아키텍처는 지원되지 않으므로 애플리케이션을 계속할 수 없습니다.
|
||||
lv.MESSAGE_TEXT_ERR1 =Lietojumprogrammu nevar turpināt, jo šī arhitektūra netiek atbalstīta.
|
||||
nl.MESSAGE_TEXT_ERR1 =De toepassing kan niet doorgaan omdat deze architectuur niet wordt ondersteund.
|
||||
pl.MESSAGE_TEXT_ERR1 =Aplikacja nie może zostać uruchomiona, ponieważ dana architektura nie jest obsługiwana.
|
||||
pt_PT.MESSAGE_TEXT_ERR1 =O aplicativo não pode continuar porque esta arquitetura não é suportada.
|
||||
sk.MESSAGE_TEXT_ERR1 =Aplikácia nemôže pokračovať, pretože táto architektúra nie je podporovaná.
|
||||
sl.MESSAGE_TEXT_ERR1 =Aplikacija ne more nadaljevati, ker ta arhitektura ni podprta.
|
||||
tr.MESSAGE_TEXT_ERR1 =Bu mimari desteklenmediği için uygulama devam edemiyor.
|
||||
uk.MESSAGE_TEXT_ERR1 =Застосунок не може продовжити роботу, оскільки ця архітектура не підтримується.
|
||||
vi.MESSAGE_TEXT_ERR1 =Ứng dụng không thể tiếp tục vì cấu trúc này không được hỗ trợ.
|
||||
sr_Latn_RS.MESSAGE_TEXT_ERR1 =Aplikacija ne može nastaviti jer ova arhitektura nije podržana.
|
||||
si.MESSAGE_TEXT_ERR1 =මෙම නිර්මාණ ශිල්පයට සහාය නොදක්වන නිසා මෘදුකාංගයට ඉදිරියට යාමට නොහැකිය.
|
||||
be.MESSAGE_TEXT_ERR1 =Прыкладанне не можа далей працаваць, бо гэтая архітэктура не падтрымліваецца.
|
||||
ca.MESSAGE_TEXT_ERR1 =L'aplicació no pot continuar perquè aquesta arquitectura no és compatible.
|
||||
da.MESSAGE_TEXT_ERR1 =Applikationen kan ikke fortsætte, da denne arkitektur ikke er understøttet.
|
||||
gl.MESSAGE_TEXT_ERR1 =A aplicación non pode continuar porque esta arquitectura non é compatible.
|
||||
hu.MESSAGE_TEXT_ERR1 =Az alkalmazás nem folytatódhat, mert ez az architektúra nem támogatott.
|
||||
id.MESSAGE_TEXT_ERR1 =Aplikasi tidak bisa dilanjutkan karena arsitektur tidak mendukung.
|
||||
no.MESSAGE_TEXT_ERR1 =Applikasjonen kan ikke fortsette fordi denne arkitekturen støttes ikke.
|
||||
et.MESSAGE_TEXT_ERR1 =Rakendusega ei saa jätkata, sest seda arhitektuuri ei toetata.
|
||||
lt.MESSAGE_TEXT_ERR1 =Programa negali būti tęsiama, nes ši architektūra nepalaikoma.
|
||||
hr.MESSAGE_TEXT_ERR1 =Aplikacija ne može nastaviti jer ova arhitektura nije podržana.
|
||||
hi.MESSAGE_TEXT_ERR1 =यह एप्लिकेशन जारी नहीं रह सकती क्योंकि यह आर्किटेक्चर समर्थित नहीं है।
|
||||
sv.MESSAGE_TEXT_ERR1 =Applikationen kan inte fortsätta eftersom denna arkitektur inte stöds.
|
||||
sr_Cyrl_RS.MESSAGE_TEXT_ERR1 =Апликација не може наставити јер ова архитектура није подржана.
|
||||
en.MSG_ERR_ARCH =The application cannot continue because this architecture is not supported.
|
||||
ru.MSG_ERR_ARCH =Приложение не может продолжить работу, так как эта архитектура не поддерживается.
|
||||
de.MSG_ERR_ARCH =Die Anwendung kann nicht fortgesetzt werden, da diese Architektur nicht unterstützt wird.
|
||||
fr.MSG_ERR_ARCH =L'application ne peut pas continuer car cette architecture n'est pas prise en charge.
|
||||
es.MSG_ERR_ARCH =La aplicación no puede continuar porque esta arquitectura no es compatible.
|
||||
it.MSG_ERR_ARCH =L'applicazione non può continuare perché questa architettura non è supportata.
|
||||
ja.MSG_ERR_ARCH =このアーキテクチャがサポートされていないため、アプリケーションを続行できません。
|
||||
zh_CN.MSG_ERR_ARCH =应用程序无法继续,因为此架构不受支持。
|
||||
ro.MSG_ERR_ARCH =Procesul aplicației nu poate continua deoarece această arhitectură nu este acceptată.
|
||||
ar_SA.MSG_ERR_ARCH =لا يمكن متابعة التطبيق لأن هذه البنية غير معتمدة.
|
||||
bg.MSG_ERR_ARCH =Приложението не може да продължи, защото тази архитектура не се поддържа.
|
||||
cs.MSG_ERR_ARCH =Aplikace nemůže pokračovat, protože tato architektura není podporována.
|
||||
el.MSG_ERR_ARCH =Η εφαρμογή δεν μπορεί να συνεχιστεί επειδή αυτή η αρχιτεκτονική δεν υποστηρίζεται.
|
||||
fi.MSG_ERR_ARCH =Sovellus ei toimi, koska tätä arkkitehtuuria ei tueta.
|
||||
hy.MSG_ERR_ARCH =Հավելվածը չի կարող շարունակվել, քանի որ այս ճարտարապետությունը չի աջակցվում:
|
||||
ko.MSG_ERR_ARCH =이 아키텍처는 지원되지 않으므로 애플리케이션을 계속할 수 없습니다.
|
||||
lv.MSG_ERR_ARCH =Lietojumprogrammu nevar turpināt, jo šī arhitektūra netiek atbalstīta.
|
||||
nl.MSG_ERR_ARCH =De toepassing kan niet doorgaan omdat deze architectuur niet wordt ondersteund.
|
||||
pl.MSG_ERR_ARCH =Aplikacja nie może zostać uruchomiona, ponieważ dana architektura nie jest obsługiwana.
|
||||
pt_PT.MSG_ERR_ARCH =O aplicativo não pode continuar porque esta arquitetura não é suportada.
|
||||
sk.MSG_ERR_ARCH =Aplikácia nemôže pokračovať, pretože táto architektúra nie je podporovaná.
|
||||
sl.MSG_ERR_ARCH =Aplikacija ne more nadaljevati, ker ta arhitektura ni podprta.
|
||||
tr.MSG_ERR_ARCH =Bu mimari desteklenmediği için uygulama devam edemiyor.
|
||||
uk.MSG_ERR_ARCH =Застосунок не може продовжити роботу, оскільки ця архітектура не підтримується.
|
||||
vi.MSG_ERR_ARCH =Ứng dụng không thể tiếp tục vì cấu trúc này không được hỗ trợ.
|
||||
sr_Latn_RS.MSG_ERR_ARCH =Aplikacija ne može nastaviti jer ova arhitektura nije podržana.
|
||||
si.MSG_ERR_ARCH =මෙම නිර්මාණ ශිල්පයට සහාය නොදක්වන නිසා මෘදුකාංගයට ඉදිරියට යාමට නොහැකිය.
|
||||
be.MSG_ERR_ARCH =Прыкладанне не можа далей працаваць, бо гэтая архітэктура не падтрымліваецца.
|
||||
ca.MSG_ERR_ARCH =L'aplicació no pot continuar perquè aquesta arquitectura no és compatible.
|
||||
da.MSG_ERR_ARCH =Applikationen kan ikke fortsætte, da denne arkitektur ikke er understøttet.
|
||||
gl.MSG_ERR_ARCH =A aplicación non pode continuar porque esta arquitectura non é compatible.
|
||||
hu.MSG_ERR_ARCH =Az alkalmazás nem folytatódhat, mert ez az architektúra nem támogatott.
|
||||
id.MSG_ERR_ARCH =Aplikasi tidak bisa dilanjutkan karena arsitektur tidak mendukung.
|
||||
no.MSG_ERR_ARCH =Applikasjonen kan ikke fortsette fordi denne arkitekturen støttes ikke.
|
||||
et.MSG_ERR_ARCH =Rakendusega ei saa jätkata, sest seda arhitektuuri ei toetata.
|
||||
lt.MSG_ERR_ARCH =Programa negali būti tęsiama, nes ši architektūra nepalaikoma.
|
||||
hr.MSG_ERR_ARCH =Aplikacija ne može nastaviti jer ova arhitektura nije podržana.
|
||||
hi.MSG_ERR_ARCH =यह एप्लिकेशन जारी नहीं रह सकती क्योंकि यह आर्किटेक्चर समर्थित नहीं है।
|
||||
sv.MSG_ERR_ARCH =Applikationen kan inte fortsätta eftersom denna arkitektur inte stöds.
|
||||
sr_Cyrl_RS.MSG_ERR_ARCH =Апликација не може наставити јер ова архитектура није подржана.
|
||||
|
||||
en.MESSAGE_TEXT_ERR2 =The application is already running.
|
||||
ru.MESSAGE_TEXT_ERR2 =Приложение уже запущено.
|
||||
de.MESSAGE_TEXT_ERR2 =Die Anwendung läuft bereits.
|
||||
fr.MESSAGE_TEXT_ERR2 =Cette application est déjà en cours d'exécution.
|
||||
es.MESSAGE_TEXT_ERR2 =La aplicación ya se está ejecutando.
|
||||
it.MESSAGE_TEXT_ERR2 =L'applicazione sta già funzionando.
|
||||
ja.MESSAGE_TEXT_ERR2 =アプリケーションはすでに実行されています。
|
||||
zh_CN.MESSAGE_TEXT_ERR2 =应用程序已在运行。
|
||||
ro.MESSAGE_TEXT_ERR2 =Aplicația este deja în desfășurare.
|
||||
ar_SA.MESSAGE_TEXT_ERR2 =التطبيق قيد التشغيل بالفعل.
|
||||
bg.MESSAGE_TEXT_ERR2 =Приложението вече работи.
|
||||
cs.MESSAGE_TEXT_ERR2 =Aplikace již běží.
|
||||
el.MESSAGE_TEXT_ERR2 =Η εφαρμογή εκτελείται ήδη.
|
||||
fi.MESSAGE_TEXT_ERR2 =Sovellus on jo käynnissä.
|
||||
hy.MESSAGE_TEXT_ERR2 =Հավելվածն արդեն աշխատում է։
|
||||
ko.MESSAGE_TEXT_ERR2 =애플리케이션이 이미 실행 중입니다.
|
||||
lv.MESSAGE_TEXT_ERR2 =Lietojumprogramma jau darbojas.
|
||||
nl.MESSAGE_TEXT_ERR2 =De toepassing draait al.
|
||||
pl.MESSAGE_TEXT_ERR2 =Aplikacja jest już uruchomiona.
|
||||
pt_PT.MESSAGE_TEXT_ERR2 =O aplicativo já está em execução.
|
||||
sk.MESSAGE_TEXT_ERR2 =Aplikácia je už spustená.
|
||||
sl.MESSAGE_TEXT_ERR2 =Aplikacija se že izvaja.
|
||||
tr.MESSAGE_TEXT_ERR2 =Uygulama zaten çalışıyor.
|
||||
uk.MESSAGE_TEXT_ERR2 =Застосунок вже запущений.
|
||||
vi.MESSAGE_TEXT_ERR2 =Ứng dụng đang chạy.
|
||||
sr_Latn_RS.MESSAGE_TEXT_ERR2 =Aplikacija već radi.
|
||||
si.MESSAGE_TEXT_ERR2 =මෘදුකාංගය දැනටමත් ධාවනය වේ.
|
||||
be.MESSAGE_TEXT_ERR2 =Прыкладанне ўжо запушчана.
|
||||
ca.MESSAGE_TEXT_ERR2 =L'aplicació ja s'està executant.
|
||||
da.MESSAGE_TEXT_ERR2 =Applikationen kører allerede.
|
||||
gl.MESSAGE_TEXT_ERR2 =A aplicación xa se está executando.
|
||||
hu.MESSAGE_TEXT_ERR2 =Az alkalmazás már fut.
|
||||
id.MESSAGE_TEXT_ERR2 =Aplikasi sedang berjalan.
|
||||
no.MESSAGE_TEXT_ERR2 =Applikasjonen kjører allerede.
|
||||
et.MESSAGE_TEXT_ERR2 =Rakendus juba töötab.
|
||||
lt.MESSAGE_TEXT_ERR2 =Programa jau paleista.
|
||||
hr.MESSAGE_TEXT_ERR2 =Aplikacija je već pokrenuta.
|
||||
hi.MESSAGE_TEXT_ERR2 =एप्लीकेशन पहले से ही चल रही है।
|
||||
sv.MESSAGE_TEXT_ERR2 =Applikationen körs redan.
|
||||
sr_Cyrl_RS.MESSAGE_TEXT_ERR2 =Апликација већ ради.
|
||||
en.MSG_ERR_ALREADY_RUNNING =The application is already running.
|
||||
ru.MSG_ERR_ALREADY_RUNNING =Приложение уже запущено.
|
||||
de.MSG_ERR_ALREADY_RUNNING =Die Anwendung läuft bereits.
|
||||
fr.MSG_ERR_ALREADY_RUNNING =Cette application est déjà en cours d'exécution.
|
||||
es.MSG_ERR_ALREADY_RUNNING =La aplicación ya se está ejecutando.
|
||||
it.MSG_ERR_ALREADY_RUNNING =L'applicazione sta già funzionando.
|
||||
ja.MSG_ERR_ALREADY_RUNNING =アプリケーションはすでに実行されています。
|
||||
zh_CN.MSG_ERR_ALREADY_RUNNING =应用程序已在运行。
|
||||
ro.MSG_ERR_ALREADY_RUNNING =Aplicația este deja în desfășurare.
|
||||
ar_SA.MSG_ERR_ALREADY_RUNNING =التطبيق قيد التشغيل بالفعل.
|
||||
bg.MSG_ERR_ALREADY_RUNNING =Приложението вече работи.
|
||||
cs.MSG_ERR_ALREADY_RUNNING =Aplikace již běží.
|
||||
el.MSG_ERR_ALREADY_RUNNING =Η εφαρμογή εκτελείται ήδη.
|
||||
fi.MSG_ERR_ALREADY_RUNNING =Sovellus on jo käynnissä.
|
||||
hy.MSG_ERR_ALREADY_RUNNING =Հավելվածն արդեն աշխատում է։
|
||||
ko.MSG_ERR_ALREADY_RUNNING =애플리케이션이 이미 실행 중입니다.
|
||||
lv.MSG_ERR_ALREADY_RUNNING =Lietojumprogramma jau darbojas.
|
||||
nl.MSG_ERR_ALREADY_RUNNING =De toepassing draait al.
|
||||
pl.MSG_ERR_ALREADY_RUNNING =Aplikacja jest już uruchomiona.
|
||||
pt_PT.MSG_ERR_ALREADY_RUNNING =O aplicativo já está em execução.
|
||||
sk.MSG_ERR_ALREADY_RUNNING =Aplikácia je už spustená.
|
||||
sl.MSG_ERR_ALREADY_RUNNING =Aplikacija se že izvaja.
|
||||
tr.MSG_ERR_ALREADY_RUNNING =Uygulama zaten çalışıyor.
|
||||
uk.MSG_ERR_ALREADY_RUNNING =Застосунок вже запущений.
|
||||
vi.MSG_ERR_ALREADY_RUNNING =Ứng dụng đang chạy.
|
||||
sr_Latn_RS.MSG_ERR_ALREADY_RUNNING =Aplikacija već radi.
|
||||
si.MSG_ERR_ALREADY_RUNNING =මෘදුකාංගය දැනටමත් ධාවනය වේ.
|
||||
be.MSG_ERR_ALREADY_RUNNING =Прыкладанне ўжо запушчана.
|
||||
ca.MSG_ERR_ALREADY_RUNNING =L'aplicació ja s'està executant.
|
||||
da.MSG_ERR_ALREADY_RUNNING =Applikationen kører allerede.
|
||||
gl.MSG_ERR_ALREADY_RUNNING =A aplicación xa se está executando.
|
||||
hu.MSG_ERR_ALREADY_RUNNING =Az alkalmazás már fut.
|
||||
id.MSG_ERR_ALREADY_RUNNING =Aplikasi sedang berjalan.
|
||||
no.MSG_ERR_ALREADY_RUNNING =Applikasjonen kjører allerede.
|
||||
et.MSG_ERR_ALREADY_RUNNING =Rakendus juba töötab.
|
||||
lt.MSG_ERR_ALREADY_RUNNING =Programa jau paleista.
|
||||
hr.MSG_ERR_ALREADY_RUNNING =Aplikacija je već pokrenuta.
|
||||
hi.MSG_ERR_ALREADY_RUNNING =एप्लीकेशन पहले से ही चल रही है।
|
||||
sv.MSG_ERR_ALREADY_RUNNING =Applikationen körs redan.
|
||||
sr_Cyrl_RS.MSG_ERR_ALREADY_RUNNING =Апликација већ ради.
|
||||
|
||||
en.LABEL_MESSAGE_TEXT_ERR5 =An error occurred while running the package.\nPlease try restarting the app later.
|
||||
ru.LABEL_MESSAGE_TEXT_ERR5 =Произошла ошибка при запуске установщика.\nПопробуйте перезапустить приложение позже.
|
||||
de.LABEL_MESSAGE_TEXT_ERR5 =Beim Ausführen des Pakets ist ein Fehler aufgetreten.\nBitte versuchen Sie, die App später neu zu starten.
|
||||
fr.LABEL_MESSAGE_TEXT_ERR5 =Une erreur s'est produit lors de l'exécution du paquet.\nVeuillez réessayer de redémarrer l'application plus tard.
|
||||
es.LABEL_MESSAGE_TEXT_ERR5 =Se ha producido un error al ejecutar el paquete.\nIntente reiniciar la aplicación más tarde.
|
||||
it.LABEL_MESSAGE_TEXT_ERR5 =Si è verificato un errore durante l'esecuzione del pacchetto.\nProva a riavviare l'app più tardi.
|
||||
ja.LABEL_MESSAGE_TEXT_ERR5 =パッケージの実行中にエラーが発生しました。\nアプリを後で再起動してみてください。
|
||||
zh_CN.LABEL_MESSAGE_TEXT_ERR5 =运行软件包时发生错误。\n请稍后尝试重新启动应用程序。
|
||||
ro.LABEL_MESSAGE_TEXT_ERR5 =A intervenit o eroare în timpul executării pachetului.\nÎncercaţi să reporniți aplicația mai târziu.
|
||||
ar_SA.LABEL_MESSAGE_TEXT_ERR5 =حدث خطأ أثناء تشغيل الحزمة.\nالرجاء محاولة إعادة تشغيل التطبيق لاحقا.
|
||||
bg.LABEL_MESSAGE_TEXT_ERR5 =Възникна грешка при стартиране на пакета.\nМоля, опитайте да рестартирате приложението по-късно.
|
||||
cs.LABEL_MESSAGE_TEXT_ERR5 =Při spouštění balíčku došlo k chybě.\nProsím, zkuste aplikaci restartovat později.
|
||||
el.LABEL_MESSAGE_TEXT_ERR5 =Προέκυψε σφάλμα κατά την εκτέλεση του πακέτου.\nΔοκιμάστε να επανεκκινήσετε την εφαρμογή αργότερα.
|
||||
fi.LABEL_MESSAGE_TEXT_ERR5 =Paketin suorittamisen aikana tapahtui virhe. \nOle hyvä ja yritä käynnistää sovellus myöhemmin uudelleen.
|
||||
hy.LABEL_MESSAGE_TEXT_ERR5 =Փաթեթը գործարկելիս սխալ է տեղի ունեցել.\nՓորձեք ավելի ուշ վերագործարկել հավելվածը:
|
||||
ko.LABEL_MESSAGE_TEXT_ERR5 =패키지를 실행하는 동안 오류가 발생했습니다.\n나중에 앱을 다시 시작하세요.
|
||||
lv.LABEL_MESSAGE_TEXT_ERR5 =Palaižot pakotni, radās kļūda.\nMēģiniet restartēt lietotni vēlāk.
|
||||
nl.LABEL_MESSAGE_TEXT_ERR5 =Er is een fout opgetreden tijdens het uitvoeren van het pakket.\Probeer de app later opnieuw te starten.
|
||||
pl.LABEL_MESSAGE_TEXT_ERR5 =Wystąpił błąd podczas uruchamiania pakietu.\nSpróbuj ponownie uruchomić aplikację później.
|
||||
pt_PT.LABEL_MESSAGE_TEXT_ERR5 =Ocorreu um erro ao executar o pacote.\nTente reiniciar o aplicativo mais tarde.
|
||||
sk.LABEL_MESSAGE_TEXT_ERR5 =Počas spúšťania balíka došlo k chybe.\nProsím, skúste reštartovať aplikáciu neskôr.
|
||||
sl.LABEL_MESSAGE_TEXT_ERR5 =Med izvajanjem paketa je prišlo do napake.\nPoskusite znova zagnati aplikacijo pozneje.
|
||||
tr.LABEL_MESSAGE_TEXT_ERR5 =Paket çalıştırılırken bir hata oluştu.\nLütfen uygulamayı daha sonra yeniden başlatmayı deneyin.
|
||||
uk.LABEL_MESSAGE_TEXT_ERR5 =Під час запуску пакету сталася помилка. \nСпробуйте перезапустити застосунок пізніше.
|
||||
vi.LABEL_MESSAGE_TEXT_ERR5 =Đã xảy ra lỗi khi chạy gói.\nVui lòng thử khởi động lại ứng dụng sau.
|
||||
sr_Latn_RS.LABEL_MESSAGE_TEXT_ERR5 =Došlo je do greške prilikom pokretanja paketa.\nMolimo pokušajte da restartujete aplikaciju kasnije.
|
||||
si.LABEL_MESSAGE_TEXT_ERR5 =ඇසුරුම ධාවනයේ දී දෝෂයක් සිදු විය.\nකරුණාකර මෘදුකාංගය නැවත ආරම්භ කර බලන්න.
|
||||
be.LABEL_MESSAGE_TEXT_ERR5 =Падчас запуску пакета адбылася памылка.\nПаспрабуйце перазапусціць прыкладанне пазней.
|
||||
ca.LABEL_MESSAGE_TEXT_ERR5 =S'ha produït un error en executar el paquet.\nProveu de reiniciar l'aplicació més tard.
|
||||
da.LABEL_MESSAGE_TEXT_ERR5 =Der opstod en fejl under drift af pakken.\nPrøv venligst at genstarte appen senere.
|
||||
gl.LABEL_MESSAGE_TEXT_ERR5 =Produciuse un erro ao executar o paquete.\nPor favor, tente reiniciar a aplicación máis tarde.
|
||||
hu.LABEL_MESSAGE_TEXT_ERR5 =Hiba történt a csomag futtatása közben.\nKérjük, próbálja meg később újraindítani az alkalmazást.
|
||||
id.LABEL_MESSAGE_TEXT_ERR5 =Ada kesalahan saat menjalankan paket.\nMohon restart app lagi nanti.
|
||||
no.LABEL_MESSAGE_TEXT_ERR5 =Det oppstod en feil under kjøring av pakken.\nVennligst prøv å starte appen på nytt senere.
|
||||
et.LABEL_MESSAGE_TEXT_ERR5 =Paketi käivitamisel tekkis viga.\nPalun proovige rakenduse taaskäivitamist hiljem.
|
||||
lt.LABEL_MESSAGE_TEXT_ERR5 =Paleidus paketą, įvyko klaida.\nPabandykite kiek vėliau iš naujo paleisti programą.
|
||||
hr.LABEL_MESSAGE_TEXT_ERR5 =Došlo je do pogreške prilikom pokretanja paketa.\nPokušajte ponovno pokrenuti aplikaciju kasnije.
|
||||
hi.LABEL_MESSAGE_TEXT_ERR5 =पैकेज चलाने के दौरान एक त्रुटि उत्पन्न हुई।\nकृपया बाद में ऐप को रीस्टार्ट करने का प्रयास करें।
|
||||
sv.LABEL_MESSAGE_TEXT_ERR5 =Ett fel inträffade vid körning av paketet.\nFörsök starta om appen senare.
|
||||
sr_Cyrl_RS.LABEL_MESSAGE_TEXT_ERR5 =Дошло је до грешке приликом покретања пакета.\nМолимо покушајте да рестартујете апликацију касније.
|
||||
en.MSG_ERR_CLOSE_APP =Setup has detected that %1 is currently running. Please close all instances of it.
|
||||
ru.MSG_ERR_CLOSE_APP =Обнаружен запущенный экземпляр %1. Пожалуйста, закройте все экземпляры приложения.
|
||||
|
||||
en.BUTTON_CANCEL_TEXT =Cancel
|
||||
ru.BUTTON_CANCEL_TEXT =Отмена
|
||||
de.BUTTON_CANCEL_TEXT =Abbrechen
|
||||
fr.BUTTON_CANCEL_TEXT =Annuler
|
||||
es.BUTTON_CANCEL_TEXT =Cancelar
|
||||
it.BUTTON_CANCEL_TEXT =Annulla
|
||||
ja.BUTTON_CANCEL_TEXT =キャンセル
|
||||
zh_CN.BUTTON_CANCEL_TEXT =取消
|
||||
ro.BUTTON_CANCEL_TEXT =Anulare
|
||||
ar_SA.BUTTON_CANCEL_TEXT =إلغاء
|
||||
bg.BUTTON_CANCEL_TEXT =Отказ
|
||||
cs.BUTTON_CANCEL_TEXT =Zrušit
|
||||
el.BUTTON_CANCEL_TEXT =Ακύρωση
|
||||
fi.BUTTON_CANCEL_TEXT =Peruuta
|
||||
hy.BUTTON_CANCEL_TEXT =Չեղարկել
|
||||
ko.BUTTON_CANCEL_TEXT =취소
|
||||
lv.BUTTON_CANCEL_TEXT =Atcelt
|
||||
nl.BUTTON_CANCEL_TEXT =Annuleren
|
||||
pl.BUTTON_CANCEL_TEXT =Anuluj
|
||||
pt_PT.BUTTON_CANCEL_TEXT =Cancelar
|
||||
sk.BUTTON_CANCEL_TEXT =Zrušiť
|
||||
sl.BUTTON_CANCEL_TEXT =Prekliči
|
||||
tr.BUTTON_CANCEL_TEXT =İptal
|
||||
uk.BUTTON_CANCEL_TEXT =Скасувати
|
||||
vi.BUTTON_CANCEL_TEXT =Hủy
|
||||
sr_Latn_RS.BUTTON_CANCEL_TEXT =Otkaži
|
||||
si.BUTTON_CANCEL_TEXT =අවලංගු
|
||||
be.BUTTON_CANCEL_TEXT =Адмяніць
|
||||
ca.BUTTON_CANCEL_TEXT =Cancel·lar
|
||||
da.BUTTON_CANCEL_TEXT =Annuller
|
||||
gl.BUTTON_CANCEL_TEXT =Cancelar
|
||||
hu.BUTTON_CANCEL_TEXT =Törlés
|
||||
id.BUTTON_CANCEL_TEXT =Batal
|
||||
no.BUTTON_CANCEL_TEXT =Avbryt
|
||||
et.BUTTON_CANCEL_TEXT =Tühista
|
||||
lt.BUTTON_CANCEL_TEXT =Atšaukti
|
||||
hr.BUTTON_CANCEL_TEXT =Otkaži
|
||||
hi.BUTTON_CANCEL_TEXT =रद्द करें
|
||||
sv.BUTTON_CANCEL_TEXT =Avbryt
|
||||
sr_Cyrl_RS.BUTTON_CANCEL_TEXT =Откажи
|
||||
en.MSG_REMOVE =This will remove %1 and its components.
|
||||
ru.MSG_REMOVE =Это приведет к удалению %1 и его компонентов.
|
||||
|
||||
en.SILENT_CHECK_TEXT =Silent Installation
|
||||
ru.SILENT_CHECK_TEXT =Тихая установка
|
||||
de.SILENT_CHECK_TEXT =Silent Installation
|
||||
fr.SILENT_CHECK_TEXT =Installation sans assistance
|
||||
es.SILENT_CHECK_TEXT =Instalación silenciosa
|
||||
it.SILENT_CHECK_TEXT =Installazione silenziosa
|
||||
ja.SILENT_CHECK_TEXT =サイレントインストール
|
||||
zh_CN.SILENT_CHECK_TEXT =静默安装
|
||||
ro.SILENT_CHECK_TEXT =Instalare nesupravegheată
|
||||
ar_SA.SILENT_CHECK_TEXT =التثبيت الصامت
|
||||
bg.SILENT_CHECK_TEXT =Тихо инсталиране
|
||||
cs.SILENT_CHECK_TEXT =Tichá instalace
|
||||
el.SILENT_CHECK_TEXT =Αθόρυβη εγκατάσταση
|
||||
fi.SILENT_CHECK_TEXT =Äänetön asennus
|
||||
hy.SILENT_CHECK_TEXT =Լուռ տեղադրում
|
||||
ko.SILENT_CHECK_TEXT =비대화형 방식 설치
|
||||
lv.SILENT_CHECK_TEXT =Klusā instalēšana
|
||||
nl.SILENT_CHECK_TEXT =Stille installatie
|
||||
pl.SILENT_CHECK_TEXT =Instalacja dyskretna
|
||||
pt_PT.SILENT_CHECK_TEXT =Instalação silenciosa
|
||||
sk.SILENT_CHECK_TEXT =Tichá inštalácia
|
||||
sl.SILENT_CHECK_TEXT =Tiha namestitev
|
||||
tr.SILENT_CHECK_TEXT =Sessiz Kurulum
|
||||
uk.SILENT_CHECK_TEXT =Автоматичне інсталювання
|
||||
vi.SILENT_CHECK_TEXT =Cài đặt im lặng
|
||||
sr_Latn_RS.SILENT_CHECK_TEXT =Tiha instalacija
|
||||
si.SILENT_CHECK_TEXT =නිහඬ ස්ථාපනය
|
||||
be.SILENT_CHECK_TEXT =Ціхая ўстаноўка
|
||||
ca.SILENT_CHECK_TEXT =Instal·lació silenciosa
|
||||
da.SILENT_CHECK_TEXT =Lydløs installation
|
||||
gl.SILENT_CHECK_TEXT =Instalación silenciosa
|
||||
hu.SILENT_CHECK_TEXT =Beavatkozás nélküli telepítés
|
||||
id.SILENT_CHECK_TEXT =Instalasi senyap
|
||||
no.SILENT_CHECK_TEXT =Stille installering
|
||||
et.SILENT_CHECK_TEXT =Vaikne paigaldus
|
||||
lt.SILENT_CHECK_TEXT =Tylus diegimas
|
||||
hr.SILENT_CHECK_TEXT =Tiha instalacija
|
||||
hi.SILENT_CHECK_TEXT =मौन इंस्टॉलेशन
|
||||
sv.SILENT_CHECK_TEXT =Obevakad installation
|
||||
sr_Cyrl_RS.SILENT_CHECK_TEXT =Тиха инсталација
|
||||
en.MSG_REPAIR =This will repair the current version of %1.
|
||||
ru.MSG_REPAIR =Это восстановит текущую версию %1.
|
||||
|
||||
en.MSG_UPDATE =This will update %1 to the latest version available.
|
||||
ru.MSG_UPDATE =Это обновит %1 до последней доступной версии.
|
||||
|
||||
en.LABEL_DOWNLOAD =Downloading
|
||||
ru.LABEL_DOWNLOAD =Загрузка
|
||||
|
||||
en.LABEL_INSTALL =Installing
|
||||
ru.LABEL_INSTALL =Установка
|
||||
|
||||
en.LABEL_UPDATING =Updating
|
||||
ru.LABEL_UPDATING =Обновление
|
||||
|
||||
en.LABEL_REPAIRING =Repairing
|
||||
ru.LABEL_REPAIRING =Восстановление
|
||||
|
||||
en.LABEL_UNINSTLING =Uninstalling
|
||||
ru.LABEL_UNINSTLING =Удаление
|
||||
|
||||
en.LABEL_UPDATE_COMPL =Update complete!
|
||||
ru.LABEL_UPDATE_COMPL =Обновление завершено!
|
||||
|
||||
en.LABEL_REPAIR_COMPL =Repairing completed!
|
||||
ru.LABEL_REPAIR_COMPL =Восстановление завершено!
|
||||
|
||||
en.LABEL_UNINST_COMPL =Uninstalling completed!
|
||||
ru.LABEL_UNINST_COMPL =Удаление завершено!
|
||||
|
||||
en.LABEL_VERSION =%1 %2 (%3 %4) is installed
|
||||
ru.LABEL_VERSION =%1 %2 (%3 %4) установлен
|
||||
|
||||
en.LABEL_UNKN_VER =unknown version
|
||||
ru.LABEL_UNKN_VER =неизвестная версия
|
||||
|
||||
en.LABEL_UNKN_PACK =unknown package
|
||||
ru.LABEL_UNKN_PACK =неизвестный пакет
|
||||
|
||||
en.LABEL_NO_OPTIONS =No additional options available.
|
||||
ru.LABEL_NO_OPTIONS =Дополнительные опции недоступны.
|
||||
|
||||
en.LABEL_NO_VER_AVAIL =No version available
|
||||
ru.LABEL_NO_VER_AVAIL =Нет доступной версии
|
||||
|
||||
en.LABEL_WARN_CLOSE =This will install ONLYOFFICE Desktop Editors on your computer.\nIt is reccomended that you close all other applications before continuing.
|
||||
ru.LABEL_WARN_CLOSE =Программа установит ONLYOFFICE Desktop Editors на ваш компьютер.\nРекомендуется закрыть все прочие приложения перед тем, как продолжить.
|
||||
|
||||
en.LABEL_ALMOST_DONE =Just a bit more and we're done
|
||||
ru.LABEL_ALMOST_DONE =Еще немного и мы закончим
|
||||
|
||||
en.LABEL_INSTALL_COMPL =%1 has been successfully installed on your computer.\nTo run the application after closing this installer, select the check box.
|
||||
ru.LABEL_INSTALL_COMPL =%1 успешно установлен на вашем компьютере.\nЧтобы запустить приложение после закрытия этого установщика, установите флажок.
|
||||
|
||||
en.LABEL_ERR_PROD_CODE =Error while retrieving product code.
|
||||
ru.LABEL_ERR_PROD_CODE =Ошибка при получении кода продукта.
|
||||
|
||||
en.LABEL_ERR_PACK_NAME =Error while retrieving package name.
|
||||
ru.LABEL_ERR_PACK_NAME =Ошибка при получении имени пакета.
|
||||
|
||||
en.LABEL_ERR_INSTALL =An error occurred during installation.
|
||||
ru.LABEL_ERR_INSTALL =Во время установки произошла ошибка.
|
||||
|
||||
en.LABEL_ERR_UNINST =An error occurred during uninstalling.
|
||||
ru.LABEL_ERR_UNINST =Во время удаления произошла ошибка.
|
||||
|
||||
en.LABEL_ERR_COMMON =An error occurred:
|
||||
ru.LABEL_ERR_COMMON =Произошла ошибка:
|
||||
|
||||
en.LABEL_ERR_RUNNING =An error occurred while running the package.\nPlease try restarting the app later.
|
||||
ru.LABEL_ERR_RUNNING =Произошла ошибка при запуске установщика.\nПопробуйте перезапустить приложение позже.
|
||||
de.LABEL_ERR_RUNNING =Beim Ausführen des Pakets ist ein Fehler aufgetreten.\nBitte versuchen Sie, die App später neu zu starten.
|
||||
fr.LABEL_ERR_RUNNING =Une erreur s'est produit lors de l'exécution du paquet.\nVeuillez réessayer de redémarrer l'application plus tard.
|
||||
es.LABEL_ERR_RUNNING =Se ha producido un error al ejecutar el paquete.\nIntente reiniciar la aplicación más tarde.
|
||||
it.LABEL_ERR_RUNNING =Si è verificato un errore durante l'esecuzione del pacchetto.\nProva a riavviare l'app più tardi.
|
||||
ja.LABEL_ERR_RUNNING =パッケージの実行中にエラーが発生しました。\nアプリを後で再起動してみてください。
|
||||
zh_CN.LABEL_ERR_RUNNING =运行软件包时发生错误。\n请稍后尝试重新启动应用程序。
|
||||
ro.LABEL_ERR_RUNNING =A intervenit o eroare în timpul executării pachetului.\nÎncercaţi să reporniți aplicația mai târziu.
|
||||
ar_SA.LABEL_ERR_RUNNING =حدث خطأ أثناء تشغيل الحزمة.\nالرجاء محاولة إعادة تشغيل التطبيق لاحقا.
|
||||
bg.LABEL_ERR_RUNNING =Възникна грешка при стартиране на пакета.\nМоля, опитайте да рестартирате приложението по-късно.
|
||||
cs.LABEL_ERR_RUNNING =Při spouštění balíčku došlo k chybě.\nProsím, zkuste aplikaci restartovat později.
|
||||
el.LABEL_ERR_RUNNING =Προέκυψε σφάλμα κατά την εκτέλεση του πακέτου.\nΔοκιμάστε να επανεκκινήσετε την εφαρμογή αργότερα.
|
||||
fi.LABEL_ERR_RUNNING =Paketin suorittamisen aikana tapahtui virhe. \nOle hyvä ja yritä käynnistää sovellus myöhemmin uudelleen.
|
||||
hy.LABEL_ERR_RUNNING =Փաթեթը գործարկելիս սխալ է տեղի ունեցել.\nՓորձեք ավելի ուշ վերագործարկել հավելվածը:
|
||||
ko.LABEL_ERR_RUNNING =패키지를 실행하는 동안 오류가 발생했습니다.\n나중에 앱을 다시 시작하세요.
|
||||
lv.LABEL_ERR_RUNNING =Palaižot pakotni, radās kļūda.\nMēģiniet restartēt lietotni vēlāk.
|
||||
nl.LABEL_ERR_RUNNING =Er is een fout opgetreden tijdens het uitvoeren van het pakket.\Probeer de app later opnieuw te starten.
|
||||
pl.LABEL_ERR_RUNNING =Wystąpił błąd podczas uruchamiania pakietu.\nSpróbuj ponownie uruchomić aplikację później.
|
||||
pt_PT.LABEL_ERR_RUNNING =Ocorreu um erro ao executar o pacote.\nTente reiniciar o aplicativo mais tarde.
|
||||
sk.LABEL_ERR_RUNNING =Počas spúšťania balíka došlo k chybe.\nProsím, skúste reštartovať aplikáciu neskôr.
|
||||
sl.LABEL_ERR_RUNNING =Med izvajanjem paketa je prišlo do napake.\nPoskusite znova zagnati aplikacijo pozneje.
|
||||
tr.LABEL_ERR_RUNNING =Paket çalıştırılırken bir hata oluştu.\nLütfen uygulamayı daha sonra yeniden başlatmayı deneyin.
|
||||
uk.LABEL_ERR_RUNNING =Під час запуску пакету сталася помилка. \nСпробуйте перезапустити застосунок пізніше.
|
||||
vi.LABEL_ERR_RUNNING =Đã xảy ra lỗi khi chạy gói.\nVui lòng thử khởi động lại ứng dụng sau.
|
||||
sr_Latn_RS.LABEL_ERR_RUNNING =Došlo je do greške prilikom pokretanja paketa.\nMolimo pokušajte da restartujete aplikaciju kasnije.
|
||||
si.LABEL_ERR_RUNNING =ඇසුරුම ධාවනයේ දී දෝෂයක් සිදු විය.\nකරුණාකර මෘදුකාංගය නැවත ආරම්භ කර බලන්න.
|
||||
be.LABEL_ERR_RUNNING =Падчас запуску пакета адбылася памылка.\nПаспрабуйце перазапусціць прыкладанне пазней.
|
||||
ca.LABEL_ERR_RUNNING =S'ha produït un error en executar el paquet.\nProveu de reiniciar l'aplicació més tard.
|
||||
da.LABEL_ERR_RUNNING =Der opstod en fejl under drift af pakken.\nPrøv venligst at genstarte appen senere.
|
||||
gl.LABEL_ERR_RUNNING =Produciuse un erro ao executar o paquete.\nPor favor, tente reiniciar a aplicación máis tarde.
|
||||
hu.LABEL_ERR_RUNNING =Hiba történt a csomag futtatása közben.\nKérjük, próbálja meg később újraindítani az alkalmazást.
|
||||
id.LABEL_ERR_RUNNING =Ada kesalahan saat menjalankan paket.\nMohon restart app lagi nanti.
|
||||
no.LABEL_ERR_RUNNING =Det oppstod en feil under kjøring av pakken.\nVennligst prøv å starte appen på nytt senere.
|
||||
et.LABEL_ERR_RUNNING =Paketi käivitamisel tekkis viga.\nPalun proovige rakenduse taaskäivitamist hiljem.
|
||||
lt.LABEL_ERR_RUNNING =Paleidus paketą, įvyko klaida.\nPabandykite kiek vėliau iš naujo paleisti programą.
|
||||
hr.LABEL_ERR_RUNNING =Došlo je do pogreške prilikom pokretanja paketa.\nPokušajte ponovno pokrenuti aplikaciju kasnije.
|
||||
hi.LABEL_ERR_RUNNING =पैकेज चलाने के दौरान एक त्रुटि उत्पन्न हुई।\nकृपया बाद में ऐप को रीस्टार्ट करने का प्रयास करें।
|
||||
sv.LABEL_ERR_RUNNING =Ett fel inträffade vid körning av paketet.\nFörsök starta om appen senare.
|
||||
sr_Cyrl_RS.LABEL_ERR_RUNNING =Дошло је до грешке приликом покретања пакета.\nМолимо покушајте да рестартујете апликацију касније.
|
||||
|
||||
en.LABEL_ERR_CANCELLED =Cancelled!
|
||||
ru.LABEL_ERR_CANCELLED =Отменено!
|
||||
|
||||
en.BUTTON_INSTALL =Install
|
||||
ru.BUTTON_INSTALL =Установить
|
||||
|
||||
en.BUTTON_CANCEL =Cancel
|
||||
ru.BUTTON_CANCEL =Отмена
|
||||
de.BUTTON_CANCEL =Abbrechen
|
||||
fr.BUTTON_CANCEL =Annuler
|
||||
es.BUTTON_CANCEL =Cancelar
|
||||
it.BUTTON_CANCEL =Annulla
|
||||
ja.BUTTON_CANCEL =キャンセル
|
||||
zh_CN.BUTTON_CANCEL =取消
|
||||
ro.BUTTON_CANCEL =Anulare
|
||||
ar_SA.BUTTON_CANCEL =إلغاء
|
||||
bg.BUTTON_CANCEL =Отказ
|
||||
cs.BUTTON_CANCEL =Zrušit
|
||||
el.BUTTON_CANCEL =Ακύρωση
|
||||
fi.BUTTON_CANCEL =Peruuta
|
||||
hy.BUTTON_CANCEL =Չեղարկել
|
||||
ko.BUTTON_CANCEL =취소
|
||||
lv.BUTTON_CANCEL =Atcelt
|
||||
nl.BUTTON_CANCEL =Annuleren
|
||||
pl.BUTTON_CANCEL =Anuluj
|
||||
pt_PT.BUTTON_CANCEL =Cancelar
|
||||
sk.BUTTON_CANCEL =Zrušiť
|
||||
sl.BUTTON_CANCEL =Prekliči
|
||||
tr.BUTTON_CANCEL =İptal
|
||||
uk.BUTTON_CANCEL =Скасувати
|
||||
vi.BUTTON_CANCEL =Hủy
|
||||
sr_Latn_RS.BUTTON_CANCEL =Otkaži
|
||||
si.BUTTON_CANCEL =අවලංගු
|
||||
be.BUTTON_CANCEL =Адмяніць
|
||||
ca.BUTTON_CANCEL =Cancel·lar
|
||||
da.BUTTON_CANCEL =Annuller
|
||||
gl.BUTTON_CANCEL =Cancelar
|
||||
hu.BUTTON_CANCEL =Törlés
|
||||
id.BUTTON_CANCEL =Batal
|
||||
no.BUTTON_CANCEL =Avbryt
|
||||
et.BUTTON_CANCEL =Tühista
|
||||
lt.BUTTON_CANCEL =Atšaukti
|
||||
hr.BUTTON_CANCEL =Otkaži
|
||||
hi.BUTTON_CANCEL =रद्द करें
|
||||
sv.BUTTON_CANCEL =Avbryt
|
||||
sr_Cyrl_RS.BUTTON_CANCEL =Откажи
|
||||
|
||||
en.BUTTON_APPLY =Apply
|
||||
ru.BUTTON_APPLY =Применить
|
||||
|
||||
en.BUTTON_CLOSE =Close
|
||||
ru.BUTTON_CLOSE =Закрыть
|
||||
|
||||
en.BUTTON_BACK =Back
|
||||
ru.BUTTON_BACK =Назад
|
||||
|
||||
en.RADIO_UPDATE =Update
|
||||
ru.RADIO_UPDATE =Обновить
|
||||
|
||||
en.RADIO_REPAIR =Repair
|
||||
ru.RADIO_REPAIR =Восстановить
|
||||
|
||||
en.RADIO_UNINST =Uninstall
|
||||
ru.RADIO_UNINST =Удалить
|
||||
|
||||
en.CHECK_SILENT =Silent Installation
|
||||
ru.CHECK_SILENT =Тихая установка
|
||||
de.CHECK_SILENT =Silent Installation
|
||||
fr.CHECK_SILENT =Installation sans assistance
|
||||
es.CHECK_SILENT =Instalación silenciosa
|
||||
it.CHECK_SILENT =Installazione silenziosa
|
||||
ja.CHECK_SILENT =サイレントインストール
|
||||
zh_CN.CHECK_SILENT =静默安装
|
||||
ro.CHECK_SILENT =Instalare nesupravegheată
|
||||
ar_SA.CHECK_SILENT =التثبيت الصامت
|
||||
bg.CHECK_SILENT =Тихо инсталиране
|
||||
cs.CHECK_SILENT =Tichá instalace
|
||||
el.CHECK_SILENT =Αθόρυβη εγκατάσταση
|
||||
fi.CHECK_SILENT =Äänetön asennus
|
||||
hy.CHECK_SILENT =Լուռ տեղադրում
|
||||
ko.CHECK_SILENT =비대화형 방식 설치
|
||||
lv.CHECK_SILENT =Klusā instalēšana
|
||||
nl.CHECK_SILENT =Stille installatie
|
||||
pl.CHECK_SILENT =Instalacja dyskretna
|
||||
pt_PT.CHECK_SILENT =Instalação silenciosa
|
||||
sk.CHECK_SILENT =Tichá inštalácia
|
||||
sl.CHECK_SILENT =Tiha namestitev
|
||||
tr.CHECK_SILENT =Sessiz Kurulum
|
||||
uk.CHECK_SILENT =Автоматичне інсталювання
|
||||
vi.CHECK_SILENT =Cài đặt im lặng
|
||||
sr_Latn_RS.CHECK_SILENT =Tiha instalacija
|
||||
si.CHECK_SILENT =නිහඬ ස්ථාපනය
|
||||
be.CHECK_SILENT =Ціхая ўстаноўка
|
||||
ca.CHECK_SILENT =Instal·lació silenciosa
|
||||
da.CHECK_SILENT =Lydløs installation
|
||||
gl.CHECK_SILENT =Instalación silenciosa
|
||||
hu.CHECK_SILENT =Beavatkozás nélküli telepítés
|
||||
id.CHECK_SILENT =Instalasi senyap
|
||||
no.CHECK_SILENT =Stille installering
|
||||
et.CHECK_SILENT =Vaikne paigaldus
|
||||
lt.CHECK_SILENT =Tylus diegimas
|
||||
hr.CHECK_SILENT =Tiha instalacija
|
||||
hi.CHECK_SILENT =मौन इंस्टॉलेशन
|
||||
sv.CHECK_SILENT =Obevakad installation
|
||||
sr_Cyrl_RS.CHECK_SILENT =Тиха инсталација
|
||||
|
||||
en.CHECK_LAUNCH =Launch
|
||||
ru.CHECK_LAUNCH =Запустить
|
||||
|
||||
en.CHECK_CLR_DATA =Clear cached data
|
||||
ru.CHECK_CLR_DATA =Очистить кэшированные данные
|
||||
|
||||
en.CHECK_CLR_STNGS =Clear user settings
|
||||
ru.CHECK_CLR_STNGS =Очистить пользовательские настройки
|
||||
|
||||
en.CHECK_CLR_ALL =Clear user settings and cached data
|
||||
ru.CHECK_CLR_ALL =Очистить пользовательские настройки и кэшированные данные
|
||||
|
||||
37
win-linux/extras/online-installer/res/version.rc
Normal file
37
win-linux/extras/online-installer/res/version.rc
Normal file
@ -0,0 +1,37 @@
|
||||
#pragma code_page(65001)
|
||||
#include <Windows.h>
|
||||
#include "../src/version.h"
|
||||
#include "../src/resource.h"
|
||||
|
||||
IDI_MAINICON ICON DISCARDABLE APP_ICON_PATH
|
||||
IDI_WELCOME PNG "./icons/welcome.png"
|
||||
IDT_TRANSLATIONS RCDATA APP_LANG_PATH
|
||||
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "./manifest/online-installer.exe.manifest"
|
||||
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION VER_FILEVERSION
|
||||
PRODUCTVERSION VER_PRODUCTVERSION
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK VER_LANG_AND_CHARSET_STR
|
||||
BEGIN
|
||||
VALUE "CompanyName", VER_COMPANYNAME_STR
|
||||
VALUE "FileDescription", VER_FILEDESCRIPTION_STR
|
||||
VALUE "FileVersion", VER_FILEVERSION_STR
|
||||
VALUE "InternalName", VER_INTERNALNAME_STR
|
||||
VALUE "LegalCopyright", VER_LEGALCOPYRIGHT_STR
|
||||
VALUE "LegalTrademarks1", VER_LEGALTRADEMARKS1_STR
|
||||
VALUE "LegalTrademarks2", VER_LEGALTRADEMARKS2_STR
|
||||
VALUE "OriginalFilename", VER_ORIGINALFILENAME_STR
|
||||
VALUE "ProductName", VER_PRODUCTNAME_STR
|
||||
VALUE "ProductVersion", VER_PRODUCTVERSION_STR
|
||||
END
|
||||
END
|
||||
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", VER_LANG_ID, VER_CHARSET_ID
|
||||
END
|
||||
END
|
||||
@ -33,17 +33,19 @@
|
||||
#include "cdownloader.h"
|
||||
#include <Windows.h>
|
||||
#include <Winhttp.h>
|
||||
|
||||
#define DNL_OK 0
|
||||
#define DNL_ABORT 1
|
||||
#define DNL_URL_ERR 2
|
||||
#define DNL_CONN_ERR 3
|
||||
#define DNL_OUT_MEM 4
|
||||
#define DNL_CREAT_ERR 5
|
||||
#define DNL_OTHER_ERR 6
|
||||
#include <future>
|
||||
|
||||
|
||||
int downloadToFile(const wstring &url, const wstring &filePath, std::atomic_bool &run, FnVoidInt &progress_callback)
|
||||
struct Connection {
|
||||
~Connection() {
|
||||
if (hRequest) WinHttpCloseHandle(hRequest);
|
||||
if (hConnect) WinHttpCloseHandle(hConnect);
|
||||
if (hSession) WinHttpCloseHandle(hSession);
|
||||
}
|
||||
HINTERNET hSession = NULL, hConnect = NULL, hRequest = NULL;
|
||||
};
|
||||
|
||||
static DWORD initConnection(const wstring &url, DWORD &dwFileSize, Connection &conn)
|
||||
{
|
||||
URL_COMPONENTS urlComp;
|
||||
ZeroMemory(&urlComp, sizeof(urlComp));
|
||||
@ -51,176 +53,208 @@ int downloadToFile(const wstring &url, const wstring &filePath, std::atomic_bool
|
||||
urlComp.dwHostNameLength = 1;
|
||||
urlComp.dwUrlPathLength = 1;
|
||||
if (!WinHttpCrackUrl(url.c_str(), (DWORD)url.length(), 0, &urlComp))
|
||||
return DNL_URL_ERR;
|
||||
return GetLastError();
|
||||
|
||||
wstring url_host(urlComp.lpszHostName, urlComp.dwHostNameLength);
|
||||
wstring url_path(urlComp.lpszUrlPath, urlComp.dwUrlPathLength);
|
||||
|
||||
int prev_percent = -1;
|
||||
DWORD dwProgress = 0;
|
||||
DWORD dwProgressMax = 0;
|
||||
DWORD dwSize = sizeof(DWORD);
|
||||
HANDLE hFile = INVALID_HANDLE_VALUE;
|
||||
conn.hSession = WinHttpOpen(L"WinHTTP Example/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
|
||||
if (!conn.hSession)
|
||||
return GetLastError();
|
||||
|
||||
HINTERNET hSession = WinHttpOpen(L"WinHTTP Example/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
|
||||
if (!hSession)
|
||||
return DNL_OTHER_ERR;
|
||||
//WinHttpSetStatusCallback(hSession, WinHttpCallback, WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS, 0);
|
||||
DWORD dwEnabledProtocols = WINHTTP_FLAG_SECURE_PROTOCOL_TLS1 | WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_1 | WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2;
|
||||
WinHttpSetOption(hSession, WINHTTP_OPTION_SECURE_PROTOCOLS, &dwEnabledProtocols, sizeof(DWORD));
|
||||
WinHttpSetOption(conn.hSession, WINHTTP_OPTION_SECURE_PROTOCOLS, &dwEnabledProtocols, sizeof(DWORD));
|
||||
|
||||
HINTERNET hConnect = WinHttpConnect(hSession, url_host.c_str(), INTERNET_DEFAULT_HTTPS_PORT, 0);
|
||||
if (!hConnect) {
|
||||
WinHttpCloseHandle(hSession);
|
||||
return DNL_CONN_ERR;
|
||||
}
|
||||
#ifdef IGNORE_CERTIFICATE_REQUIREMENTS
|
||||
DWORD dwSecurity = SECURITY_FLAG_IGNORE_UNKNOWN_CA | SECURITY_FLAG_IGNORE_CERT_CN_INVALID | SECURITY_FLAG_IGNORE_CERT_DATE_INVALID;
|
||||
WinHttpSetOption(conn.hSession, WINHTTP_OPTION_SECURITY_FLAGS, &dwSecurity, sizeof(DWORD));
|
||||
#endif
|
||||
|
||||
HINTERNET hRequest = WinHttpOpenRequest(hConnect, L"GET", url_path.c_str(), NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE);
|
||||
if (!hRequest) {
|
||||
WinHttpCloseHandle(hConnect);
|
||||
WinHttpCloseHandle(hSession);
|
||||
return DNL_CONN_ERR;
|
||||
}
|
||||
conn.hConnect = WinHttpConnect(conn.hSession, url_host.c_str(), INTERNET_DEFAULT_HTTPS_PORT, 0);
|
||||
if (!conn.hConnect)
|
||||
return GetLastError();
|
||||
|
||||
int result = DNL_OK;
|
||||
if (!WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0)) {
|
||||
result = DNL_OTHER_ERR;
|
||||
goto cleanup;
|
||||
}
|
||||
conn.hRequest = WinHttpOpenRequest(conn.hConnect, L"GET", url_path.c_str(), NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE);
|
||||
if (!conn.hRequest)
|
||||
return GetLastError();
|
||||
|
||||
if (!WinHttpReceiveResponse(hRequest, NULL)) {
|
||||
result = DNL_CONN_ERR;
|
||||
goto cleanup;
|
||||
}
|
||||
if (!WinHttpSendRequest(conn.hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0))
|
||||
return GetLastError();
|
||||
|
||||
if (!WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_CONTENT_LENGTH | WINHTTP_QUERY_FLAG_NUMBER, NULL, &dwProgressMax, &dwSize, WINHTTP_NO_HEADER_INDEX)) {
|
||||
result = DNL_CONN_ERR;
|
||||
goto cleanup;
|
||||
}
|
||||
if (!WinHttpReceiveResponse(conn.hRequest, NULL))
|
||||
return GetLastError();
|
||||
|
||||
hFile = CreateFile(filePath.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (hFile == INVALID_HANDLE_VALUE) {
|
||||
result = DNL_CREAT_ERR;
|
||||
goto cleanup;
|
||||
}
|
||||
DWORD dwSize = sizeof(DWORD);
|
||||
if (!WinHttpQueryHeaders(conn.hRequest, WINHTTP_QUERY_CONTENT_LENGTH | WINHTTP_QUERY_FLAG_NUMBER, NULL, &dwFileSize, &dwSize, WINHTTP_NO_HEADER_INDEX))
|
||||
return GetLastError();
|
||||
|
||||
do {
|
||||
if (!run) {
|
||||
result = DNL_ABORT;
|
||||
break;
|
||||
}
|
||||
|
||||
dwSize = 0;
|
||||
if (!WinHttpQueryDataAvailable(hRequest, &dwSize)) {
|
||||
result = DNL_CONN_ERR;
|
||||
break;
|
||||
}
|
||||
|
||||
LPSTR lpBuffer = new char[dwSize];
|
||||
if (!lpBuffer) {
|
||||
result = DNL_OUT_MEM;
|
||||
break;
|
||||
}
|
||||
|
||||
DWORD dwDownloaded = 0;
|
||||
if (!WinHttpReadData(hRequest, (LPVOID)lpBuffer, dwSize, &dwDownloaded)) {
|
||||
result = DNL_CONN_ERR;
|
||||
delete[] lpBuffer;
|
||||
break;
|
||||
}
|
||||
|
||||
DWORD dwBytesWritten = 0;
|
||||
BOOL write_res = WriteFile(hFile, lpBuffer, dwDownloaded, &dwBytesWritten, NULL);
|
||||
delete[] lpBuffer;
|
||||
if (!write_res || dwBytesWritten != dwDownloaded) {
|
||||
result = DNL_OUT_MEM;
|
||||
break;
|
||||
}
|
||||
|
||||
if (dwProgressMax != 0 && progress_callback) {
|
||||
dwProgress += dwDownloaded;
|
||||
int percent = static_cast<int>((100.0 * dwProgress) / dwProgressMax);
|
||||
if (percent != prev_percent) {
|
||||
progress_callback(percent);
|
||||
prev_percent = percent;
|
||||
}
|
||||
}
|
||||
|
||||
} while (dwSize > 0);
|
||||
|
||||
cleanup :
|
||||
if (hFile != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(hFile);
|
||||
if (result == DNL_ABORT)
|
||||
DeleteFile(filePath.c_str());
|
||||
}
|
||||
WinHttpCloseHandle(hRequest);
|
||||
WinHttpCloseHandle(hConnect);
|
||||
WinHttpCloseHandle(hSession);
|
||||
return result;
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
CDownloader::CDownloader()
|
||||
class CDownloaderPrivate
|
||||
{
|
||||
m_run = true;
|
||||
m_lock = false;
|
||||
public:
|
||||
CDownloaderPrivate()
|
||||
{}
|
||||
~CDownloaderPrivate()
|
||||
{}
|
||||
|
||||
DWORD downloadToFile()
|
||||
{
|
||||
DWORD dwSize = 0, dwProgress = 0, dwProgressMax = 0;
|
||||
Connection conn;
|
||||
DWORD result = initConnection(m_url, dwProgressMax, conn);
|
||||
if (result != ERROR_SUCCESS)
|
||||
return result;
|
||||
|
||||
HANDLE hFile = CreateFile(m_filePath.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (hFile == INVALID_HANDLE_VALUE)
|
||||
return GetLastError();
|
||||
|
||||
int prev_percent = -1;
|
||||
do {
|
||||
if (!m_run) {
|
||||
result = ERROR_CANCELLED;
|
||||
break;
|
||||
}
|
||||
|
||||
dwSize = 0;
|
||||
if (!WinHttpQueryDataAvailable(conn.hRequest, &dwSize)) {
|
||||
result = GetLastError();
|
||||
break;
|
||||
}
|
||||
|
||||
LPSTR lpBuffer = new char[dwSize];
|
||||
if (!lpBuffer) {
|
||||
result = ERROR_NOT_ENOUGH_MEMORY;
|
||||
break;
|
||||
}
|
||||
|
||||
DWORD dwDownloaded = 0;
|
||||
if (!WinHttpReadData(conn.hRequest, (LPVOID)lpBuffer, dwSize, &dwDownloaded)) {
|
||||
result = GetLastError();
|
||||
delete[] lpBuffer;
|
||||
break;
|
||||
}
|
||||
|
||||
DWORD dwBytesWritten = 0;
|
||||
BOOL write_res = WriteFile(hFile, lpBuffer, dwDownloaded, &dwBytesWritten, NULL);
|
||||
delete[] lpBuffer;
|
||||
if (!write_res) {
|
||||
result = GetLastError();
|
||||
break;
|
||||
}
|
||||
|
||||
if (dwBytesWritten != dwDownloaded) {
|
||||
result = ERROR_OUTOFMEMORY;
|
||||
break;
|
||||
}
|
||||
|
||||
if (dwProgressMax != 0 && m_progress_callback) {
|
||||
dwProgress += dwDownloaded;
|
||||
int percent = static_cast<int>((100.0 * dwProgress) / dwProgressMax);
|
||||
if (percent != prev_percent) {
|
||||
m_progress_callback(percent);
|
||||
prev_percent = percent;
|
||||
}
|
||||
}
|
||||
|
||||
} while (dwSize > 0);
|
||||
|
||||
CloseHandle(hFile);
|
||||
if (result == ERROR_CANCELLED)
|
||||
DeleteFile(m_filePath.c_str());
|
||||
return result;
|
||||
}
|
||||
FnVoidUlUl m_query_callback = nullptr;
|
||||
FnVoidUl m_complete_callback = nullptr;
|
||||
FnVoidInt m_progress_callback = nullptr;
|
||||
wstring m_url,
|
||||
m_filePath;
|
||||
std::future<void> m_future;
|
||||
std::atomic_bool m_run,
|
||||
m_lock;
|
||||
};
|
||||
|
||||
CDownloader::CDownloader() :
|
||||
pimpl(new CDownloaderPrivate)
|
||||
{
|
||||
pimpl->m_run = true;
|
||||
pimpl->m_lock = false;
|
||||
}
|
||||
|
||||
CDownloader::~CDownloader()
|
||||
{
|
||||
m_run = false;
|
||||
if (m_future.valid())
|
||||
m_future.wait();
|
||||
pimpl->m_run = false;
|
||||
if (pimpl->m_future.valid())
|
||||
pimpl->m_future.wait();
|
||||
delete pimpl, pimpl = nullptr;
|
||||
}
|
||||
|
||||
void CDownloader::queryContentLenght(const wstring &url)
|
||||
{
|
||||
if (url.empty() || pimpl->m_lock)
|
||||
return;
|
||||
|
||||
pimpl->m_lock = true;
|
||||
pimpl->m_future = std::async(std::launch::async, [=]() {
|
||||
DWORD dwFileSize = 0;
|
||||
Connection conn;
|
||||
DWORD error = initConnection(url, dwFileSize, conn);
|
||||
if (pimpl->m_query_callback)
|
||||
pimpl->m_query_callback(error, dwFileSize);
|
||||
pimpl->m_lock = false;
|
||||
});
|
||||
}
|
||||
|
||||
void CDownloader::downloadFile(const std::wstring &url, const std::wstring &filePath)
|
||||
{
|
||||
m_url.clear();
|
||||
m_filePath.clear();
|
||||
if (url.empty() || filePath.empty() || m_lock)
|
||||
pimpl->m_url.clear();
|
||||
pimpl->m_filePath.clear();
|
||||
if (url.empty() || filePath.empty() || pimpl->m_lock)
|
||||
return;
|
||||
|
||||
m_url = url;
|
||||
m_filePath = filePath;
|
||||
pimpl->m_url = url;
|
||||
pimpl->m_filePath = filePath;
|
||||
start();
|
||||
}
|
||||
|
||||
void CDownloader::start()
|
||||
{
|
||||
if (m_url.empty() || m_filePath.empty() || m_lock)
|
||||
if (pimpl->m_url.empty() || pimpl->m_filePath.empty() || pimpl->m_lock)
|
||||
return;
|
||||
|
||||
m_run = true;
|
||||
m_lock = true;
|
||||
m_future = std::async(std::launch::async, [=]() {
|
||||
int hr = downloadToFile(m_url, m_filePath, m_run, m_progress_callback);
|
||||
int error = (hr == DNL_OK) ? 0 :
|
||||
(hr == DNL_ABORT) ? 1 :
|
||||
(hr == DNL_OUT_MEM) ? -1 :
|
||||
(hr == DNL_CONN_ERR) ? -2 : -3;
|
||||
|
||||
if (m_complete_callback)
|
||||
m_complete_callback(error);
|
||||
m_lock = false;
|
||||
pimpl->m_run = true;
|
||||
pimpl->m_lock = true;
|
||||
pimpl->m_future = std::async(std::launch::async, [=]() {
|
||||
DWORD error = pimpl->downloadToFile();
|
||||
if (pimpl->m_complete_callback)
|
||||
pimpl->m_complete_callback(error);
|
||||
pimpl->m_lock = false;
|
||||
});
|
||||
}
|
||||
|
||||
void CDownloader::stop()
|
||||
{
|
||||
m_run = false;
|
||||
pimpl->m_run = false;
|
||||
}
|
||||
|
||||
wstring CDownloader::GetFilePath()
|
||||
{
|
||||
return m_filePath;
|
||||
return pimpl->m_filePath;
|
||||
}
|
||||
|
||||
void CDownloader::onComplete(FnVoidInt callback)
|
||||
void CDownloader::onQueryResponse(FnVoidUlUl callback)
|
||||
{
|
||||
m_complete_callback = callback;
|
||||
pimpl->m_query_callback = callback;
|
||||
}
|
||||
|
||||
void CDownloader::onComplete(FnVoidUl callback)
|
||||
{
|
||||
pimpl->m_complete_callback = callback;
|
||||
}
|
||||
|
||||
void CDownloader::onProgress(FnVoidInt callback)
|
||||
{
|
||||
m_progress_callback = callback;
|
||||
pimpl->m_progress_callback = callback;
|
||||
}
|
||||
|
||||
@ -35,35 +35,36 @@
|
||||
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <future>
|
||||
|
||||
typedef unsigned long ulong;
|
||||
typedef std::function<void(int)> FnVoidInt;
|
||||
typedef std::function<void(ulong)> FnVoidUl;
|
||||
typedef std::function<void(ulong,ulong)> FnVoidUlUl;
|
||||
|
||||
using std::wstring;
|
||||
|
||||
|
||||
class CDownloaderPrivate;
|
||||
|
||||
class CDownloader
|
||||
{
|
||||
public:
|
||||
CDownloader();
|
||||
~CDownloader();
|
||||
|
||||
void queryContentLenght(const wstring &url);
|
||||
void downloadFile(const wstring &url, const wstring &filePath);
|
||||
void start();
|
||||
void stop();
|
||||
wstring GetFilePath();
|
||||
|
||||
/* callback */
|
||||
void onComplete(FnVoidInt callback);
|
||||
void onQueryResponse(FnVoidUlUl callback);
|
||||
void onComplete(FnVoidUl callback);
|
||||
void onProgress(FnVoidInt callback);
|
||||
|
||||
private:
|
||||
FnVoidInt m_complete_callback = nullptr,
|
||||
m_progress_callback = nullptr;
|
||||
wstring m_url,
|
||||
m_filePath;
|
||||
std::future<void> m_future;
|
||||
std::atomic_bool m_run,
|
||||
m_lock;
|
||||
CDownloaderPrivate *pimpl = nullptr;
|
||||
};
|
||||
|
||||
#endif // CDOWNLOADER_H
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
#include <Windows.h>
|
||||
#include <CommCtrl.h>
|
||||
#include "application.h"
|
||||
#include "mainwindow.h"
|
||||
#include <locale>
|
||||
#include "resource.h"
|
||||
#include "utils.h"
|
||||
#include "baseutils.h"
|
||||
#include "translator.h"
|
||||
#include "cdownloader.h"
|
||||
#include "../../src/defines.h"
|
||||
#include "../../src/prop/defines_p.h"
|
||||
|
||||
@ -20,33 +20,19 @@
|
||||
#ifndef URL_INSTALL_X86_XP
|
||||
# define URL_INSTALL_X86_XP ""
|
||||
#endif
|
||||
#ifndef URL_INSTALL_X64_MSI
|
||||
# define URL_INSTALL_X64_MSI ""
|
||||
#endif
|
||||
#ifndef URL_INSTALL_X86_MSI
|
||||
# define URL_INSTALL_X86_MSI ""
|
||||
#endif
|
||||
#define _TR(str) Translator::tr(str).c_str()
|
||||
#define WINDOW_SIZE Size(768, 480)
|
||||
|
||||
|
||||
HANDLE hIcon = NULL;
|
||||
|
||||
struct UserData
|
||||
{
|
||||
CDownloader *dnl = nullptr;
|
||||
wstring *url = nullptr;
|
||||
wstring *file_name = nullptr;
|
||||
};
|
||||
|
||||
void startDownloadAndInstall(HWND hDlg, UserData *data);
|
||||
|
||||
INT_PTR CALLBACK DialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
int WINAPI _tWinMain(_In_ HINSTANCE hInst, _In_opt_ HINSTANCE hPrevInstance, _In_ LPTSTR lpCmdLine, _In_ int nCmdShow)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(hPrevInstance);
|
||||
std::locale::global(std::locale(""));
|
||||
LCID lcid = MAKELCID(GetUserDefaultUILanguage(), SORT_DEFAULT);
|
||||
Translator lang(lcid, IDT_TRANSLATIONS);
|
||||
HANDLE hMutex = CreateMutex(NULL, FALSE, _T(VER_PRODUCTNAME_STR));
|
||||
if (GetLastError() == ERROR_ALREADY_EXISTS) {
|
||||
NS_Utils::ShowMessage(_TR(MESSAGE_TEXT_ERR2));
|
||||
return 0;
|
||||
}
|
||||
int num_args = 0;
|
||||
if (LPTSTR *args = CommandLineToArgvW(lpCmdLine, &num_args)) {
|
||||
for (int i = 0; i < num_args; i++) {
|
||||
@ -56,185 +42,50 @@ int WINAPI _tWinMain(_In_ HINSTANCE hInst, _In_opt_ HINSTANCE hPrevInstance, _In
|
||||
}
|
||||
}
|
||||
LocalFree(args);
|
||||
}
|
||||
|
||||
SYSTEM_INFO info;
|
||||
GetSystemInfo(&info);
|
||||
|
||||
wstring url, fileName(_T(REG_APP_NAME));
|
||||
WinVer ver = NS_File::getWinVersion();
|
||||
if (info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) {
|
||||
url = (ver == WinVer::WinXP) ? _T(URL_INSTALL_X64_XP) : _T(URL_INSTALL_X64);
|
||||
fileName += (ver == WinVer::WinXP) ? _T("_x64_xp.exe") : _T("_x64.exe");
|
||||
} else
|
||||
if (info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) {
|
||||
url = (ver == WinVer::WinXP) ? _T(URL_INSTALL_X86_XP) : _T(URL_INSTALL_X86);
|
||||
fileName += (ver == WinVer::WinXP) ? _T("_x86_xp.exe") : _T("_x86.exe");
|
||||
} else {
|
||||
NS_Utils::ShowMessage(_TR(MESSAGE_TEXT_ERR1));
|
||||
}
|
||||
std::locale::global(std::locale(""));
|
||||
LCID lcid = MAKELCID(GetUserDefaultUILanguage(), SORT_DEFAULT);
|
||||
Translator lang(lcid, IDT_TRANSLATIONS);
|
||||
HANDLE hMutex = CreateMutex(NULL, FALSE, _T(VER_PRODUCTNAME_STR));
|
||||
if (GetLastError() == ERROR_ALREADY_EXISTS) {
|
||||
NS_Utils::ShowMessage(_TR(MSG_ERR_ALREADY_RUNNING));
|
||||
return 0;
|
||||
}
|
||||
|
||||
CDownloader dnl;
|
||||
UserData data;
|
||||
data.dnl = &dnl;
|
||||
data.url = &url;
|
||||
data.file_name = &fileName;
|
||||
|
||||
InitCommonControls();
|
||||
HWND hDlg = CreateDialogParam(hInst, MAKEINTRESOURCE(NS_Utils::IsRtlLanguage(lcid) ? IDD_DIALOG_RTL : IDD_DIALOG), NULL, DialogProc, (LPARAM)&data);
|
||||
ShowWindow(hDlg, nCmdShow);
|
||||
|
||||
BOOL ret;
|
||||
MSG msg = {0};
|
||||
while ((ret = GetMessage(&msg, hDlg, 0, 0)) != 0) {
|
||||
if (ret == -1)
|
||||
break;
|
||||
if (IsDialogMessage(hDlg, &msg)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
}
|
||||
CloseHandle(hMutex);
|
||||
return (int)msg.wParam;
|
||||
}
|
||||
|
||||
void startDownloadAndInstall(HWND hDlg, UserData *data)
|
||||
{
|
||||
HWND hLabelMsg = GetDlgItem(hDlg, IDC_LABEL_MESSAGE);
|
||||
if (hLabelMsg)
|
||||
SetWindowText(hLabelMsg, _TR(LABEL_MESSAGE_TEXT));
|
||||
|
||||
HWND hCheckSilent = GetDlgItem(hDlg, IDC_SILENT_CHECK);
|
||||
if (hCheckSilent) {
|
||||
wstring text(_T(" "));
|
||||
text.append(_TR(SILENT_CHECK_TEXT));
|
||||
SetWindowText(hCheckSilent, text.c_str());
|
||||
if (HWND hWnd = FindWindow(WINDOW_CLASS_NAME, NULL)) {
|
||||
wstring msg(_TR(MSG_ERR_CLOSE_APP));
|
||||
NS_Utils::Replace(msg, L"%1", _T(WINDOW_NAME));
|
||||
NS_Utils::ShowMessage(msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
if (hLabelMsg)
|
||||
SetWindowText(hLabelMsg, _TR(LABEL_MESSAGE_TEXT_ERR1));
|
||||
return;
|
||||
}
|
||||
if (data->url->empty()) {
|
||||
if (hLabelMsg)
|
||||
SetWindowText(hLabelMsg, _TR(LABEL_MESSAGE_TEXT_ERR6));
|
||||
return;
|
||||
}
|
||||
if (data->file_name->empty()) {
|
||||
if (hLabelMsg)
|
||||
SetWindowText(hLabelMsg, _TR(LABEL_MESSAGE_TEXT_ERR7));
|
||||
return;
|
||||
}
|
||||
|
||||
wstring msgText;
|
||||
if (hLabelMsg) {
|
||||
int len = GetWindowTextLength(hLabelMsg);
|
||||
if (len > 0) {
|
||||
LPTSTR buff = (LPTSTR)malloc((len + 1) * sizeof(TCHAR));
|
||||
if (buff) {
|
||||
GetWindowText(hLabelMsg, buff, len + 1);
|
||||
msgText = buff;
|
||||
free(buff);
|
||||
}
|
||||
}
|
||||
msgText += _T(" ") + (*data->file_name);
|
||||
SetWindowText(hLabelMsg, msgText.c_str());
|
||||
}
|
||||
|
||||
wstring path = NS_File::appPath() + _T("/") + (*data->file_name);
|
||||
HWND hProgress = GetDlgItem(hDlg, IDC_PROGRESS);
|
||||
data->dnl->onProgress([=](int percent) {
|
||||
if (IsWindow(hProgress))
|
||||
PostMessage(hProgress, PBM_SETPOS, percent, 0);
|
||||
});
|
||||
data->dnl->onComplete([=](int error) {
|
||||
if (error == 0) {
|
||||
if (IsWindow(hDlg))
|
||||
ShowWindow(hDlg, SW_HIDE);
|
||||
wstring args;
|
||||
if (IsWindow(hCheckSilent)) {
|
||||
LRESULT isChecked = SendMessage(hCheckSilent, BM_GETCHECK, 0, 0);
|
||||
if (isChecked == BST_CHECKED)
|
||||
args = _T("/SILENT");
|
||||
}
|
||||
if (!NS_File::runProcess(path, args)) {
|
||||
if (IsWindow(hDlg))
|
||||
ShowWindow(hDlg, SW_SHOW);
|
||||
if (IsWindow(hLabelMsg))
|
||||
SetWindowText(hLabelMsg, _TR(LABEL_MESSAGE_TEXT_ERR5));
|
||||
} else {
|
||||
if (IsWindow(hDlg))
|
||||
PostMessage(hDlg, WM_CLOSE, 0, 0);
|
||||
}
|
||||
if (NS_File::fileExists(path))
|
||||
NS_File::removeFile(path);
|
||||
} else
|
||||
if (error == -1) {
|
||||
if (IsWindow(hLabelMsg))
|
||||
SetWindowText(hLabelMsg, _TR(LABEL_MESSAGE_TEXT_ERR2));
|
||||
} else
|
||||
if (error == -2) {
|
||||
if (IsWindow(hLabelMsg))
|
||||
SetWindowText(hLabelMsg, _TR(LABEL_MESSAGE_TEXT_ERR3));
|
||||
wstring url_or_path, arch;
|
||||
bool app_installed = NS_Utils::IsAppInstalled(url_or_path, &arch);
|
||||
if (!app_installed) {
|
||||
if (NS_Utils::IsWin64()) {
|
||||
url_or_path = (Utils::getWinVersion() <= Utils::WinVer::WinVista) ? _T(URL_INSTALL_X64_XP) : _T(URL_INSTALL_X64);
|
||||
} else {
|
||||
if (IsWindow(hLabelMsg))
|
||||
SetWindowText(hLabelMsg, _TR(LABEL_MESSAGE_TEXT_ERR4));
|
||||
url_or_path = (Utils::getWinVersion() <= Utils::WinVer::WinVista) ? _T(URL_INSTALL_X86_XP) : _T(URL_INSTALL_X86);
|
||||
}
|
||||
}
|
||||
|
||||
Application app(hInst, lpCmdLine, nCmdShow);
|
||||
if (NS_Utils::IsRtlLanguage(lcid))
|
||||
app.setLayoutDirection(LayoutDirection::RightToLeft);
|
||||
int scrWidth = GetSystemMetrics(SM_CXSCREEN);
|
||||
int scrHeight = GetSystemMetrics(SM_CYSCREEN);
|
||||
int x = (scrWidth - WINDOW_SIZE.width) / 2;
|
||||
int y = (scrHeight - WINDOW_SIZE.height) / 2;
|
||||
MainWindow w(nullptr, Rect(x, y, WINDOW_SIZE.width, WINDOW_SIZE.height));
|
||||
w.onAboutToDestroy([&app]() {
|
||||
app.exit(0);
|
||||
});
|
||||
data->dnl->downloadFile(*data->url, path);
|
||||
}
|
||||
|
||||
INT_PTR CALLBACK DialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_INITDIALOG: {
|
||||
wstring text(_T(" "));
|
||||
text.append(_TR(CAPTION_TEXT));
|
||||
SetWindowText(hDlg, text.c_str());
|
||||
|
||||
HWND hwndIcon = GetDlgItem(hDlg, IDC_MAIN_ICON);
|
||||
hIcon = LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MAINICON), IMAGE_ICON, 64, 64, LR_DEFAULTCOLOR | LR_LOADTRANSPARENT);
|
||||
if (hIcon && hwndIcon)
|
||||
PostMessage(hwndIcon, STM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon);
|
||||
|
||||
HWND hLabelTitle = GetDlgItem(hDlg, IDC_LABEL_TITLE);
|
||||
if (hLabelTitle)
|
||||
SetWindowText(hLabelTitle, _TR(LABEL_TITLE_TEXT));
|
||||
|
||||
HWND hBtnCancel = GetDlgItem(hDlg, IDC_BUTTON_CANCEL);
|
||||
if (hBtnCancel)
|
||||
SetWindowText(hBtnCancel, _TR(BUTTON_CANCEL_TEXT));
|
||||
|
||||
startDownloadAndInstall(hDlg, (UserData*)lParam);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam)) {
|
||||
case IDC_BUTTON_CANCEL:
|
||||
PostMessage(hDlg, WM_CLOSE, 0, 0);
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_CLOSE:
|
||||
if (hIcon)
|
||||
DestroyIcon((HICON)hIcon);
|
||||
DestroyWindow(hDlg);
|
||||
return TRUE;
|
||||
|
||||
case WM_ACTIVATE:
|
||||
break;
|
||||
|
||||
case WM_DESTROY:
|
||||
PostQuitMessage(0);
|
||||
return TRUE;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
if (!app_installed)
|
||||
w.initInstallationMode(url_or_path);
|
||||
else
|
||||
w.initControlMode(arch);
|
||||
w.showAll();
|
||||
int exit_code = app.exec();
|
||||
CloseHandle(hMutex);
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
793
win-linux/extras/online-installer/src/mainwindow.cpp
Normal file
793
win-linux/extras/online-installer/src/mainwindow.cpp
Normal file
@ -0,0 +1,793 @@
|
||||
#include "mainwindow.h"
|
||||
#include "application.h"
|
||||
#include "utils.h"
|
||||
#include "checkbox.h"
|
||||
#include "button.h"
|
||||
#include "label.h"
|
||||
#include "boxlayout.h"
|
||||
#include "radiobutton.h"
|
||||
#include "progressbar.h"
|
||||
#include "metrics.h"
|
||||
#include "palette.h"
|
||||
#include "caption.h"
|
||||
#include "resource.h"
|
||||
#include "translator.h"
|
||||
#include "cdownloader.h"
|
||||
#include "baseutils.h"
|
||||
#include <Msi.h>
|
||||
#include <ShlObj.h>
|
||||
#include <Shlwapi.h>
|
||||
#include "../../src/defines.h"
|
||||
#include "../../src/prop/defines_p.h"
|
||||
|
||||
#ifndef URL_INSTALL_X64
|
||||
# define URL_INSTALL_X64 ""
|
||||
#endif
|
||||
#ifndef URL_INSTALL_X86
|
||||
# define URL_INSTALL_X86 ""
|
||||
#endif
|
||||
#ifndef URL_INSTALL_X64_XP
|
||||
# define URL_INSTALL_X64_XP ""
|
||||
#endif
|
||||
#ifndef URL_INSTALL_X86_XP
|
||||
# define URL_INSTALL_X86_XP ""
|
||||
#endif
|
||||
#ifndef URL_INSTALL_X64_MSI
|
||||
# define URL_INSTALL_X64_MSI ""
|
||||
#endif
|
||||
#ifndef URL_INSTALL_X86_MSI
|
||||
# define URL_INSTALL_X86_MSI ""
|
||||
#endif
|
||||
#define _TR(str) Translator::tr(str).c_str()
|
||||
|
||||
|
||||
template <class T>
|
||||
static void setSelectorStyle(T *sel) // style for CheckBox and RadioButton
|
||||
{
|
||||
sel->metrics()->setMetrics(Metrics::TextMarginLeft, 6);
|
||||
sel->palette()->setColor(Palette::Text, Palette::Disabled, 0x888888);
|
||||
sel->palette()->setColor(Palette::Text, Palette::Normal, 0x333333);
|
||||
sel->palette()->setColor(Palette::Text, Palette::Hover, 0x333333);
|
||||
sel->palette()->setColor(Palette::Text, Palette::Pressed, 0x333333);
|
||||
sel->palette()->setColor(Palette::Background, Palette::Disabled, 0xfefefe);
|
||||
sel->palette()->setColor(Palette::Background, Palette::Normal, 0xfefefe);
|
||||
sel->palette()->setColor(Palette::Background, Palette::Hover, 0xfefefe);
|
||||
sel->palette()->setColor(Palette::Background, Palette::Pressed, 0xfefefe);
|
||||
sel->palette()->setColor(Palette::Primitive, Palette::Disabled, 0x888888);
|
||||
sel->palette()->setColor(Palette::Primitive, Palette::Normal, 0x333333);
|
||||
sel->palette()->setColor(Palette::Primitive, Palette::Hover, 0x0055ff);
|
||||
sel->palette()->setColor(Palette::Primitive, Palette::Pressed, 0x0055ff);
|
||||
}
|
||||
|
||||
static void setButtonStyle(Button *btn)
|
||||
{
|
||||
btn->palette()->setColor(Palette::Text, Palette::Disabled, 0x888888);
|
||||
btn->palette()->setColor(Palette::Text, Palette::Normal, 0x333333);
|
||||
btn->palette()->setColor(Palette::Text, Palette::Hover, 0x333333);
|
||||
btn->palette()->setColor(Palette::Text, Palette::Pressed, 0x333333);
|
||||
btn->palette()->setColor(Palette::Background, Palette::Disabled, 0xeeeeee);
|
||||
btn->palette()->setColor(Palette::Background, Palette::Normal, 0xeeeeee);
|
||||
btn->palette()->setColor(Palette::Background, Palette::Hover, 0xe0e0e0);
|
||||
btn->palette()->setColor(Palette::Background, Palette::Pressed, 0xd0d0d0);
|
||||
btn->palette()->setColor(Palette::Border, Palette::Disabled, 0xbebebe);
|
||||
btn->palette()->setColor(Palette::Border, Palette::Normal, 0xbebebe);
|
||||
btn->palette()->setColor(Palette::Border, Palette::Hover, 0xbebebe);
|
||||
btn->palette()->setColor(Palette::Border, Palette::Pressed, 0xbebebe);
|
||||
btn->metrics()->setMetrics(Metrics::BorderWidth, 1);
|
||||
}
|
||||
|
||||
static void setProgressStyle(ProgressBar *bar)
|
||||
{
|
||||
bar->palette()->setColor(Palette::Background, Palette::Normal, 0xfefefe);
|
||||
bar->palette()->setColor(Palette::Base, Palette::Normal, 0xcccccc);
|
||||
bar->palette()->setColor(Palette::AlternateBase, Palette::Normal, 0x1e7aaa);
|
||||
}
|
||||
|
||||
static void setLabelStyle(Label *lb)
|
||||
{
|
||||
lb->palette()->setColor(Palette::Background, Palette::Normal, 0xfefefe);
|
||||
lb->palette()->setColor(Palette::Text, Palette::Normal, 0x888888);
|
||||
}
|
||||
|
||||
static void setControlLabelStyle(Label *lb)
|
||||
{
|
||||
lb->resize(50, 36);
|
||||
lb->palette()->setColor(Palette::Background, Palette::Normal, 0xfefefe);
|
||||
lb->palette()->setColor(Palette::Text, Palette::Normal, 0x333333);
|
||||
lb->metrics()->setMetrics(Metrics::TextAlignment, Metrics::AlignHLeft | Metrics::AlignVTop);
|
||||
}
|
||||
|
||||
MainWindow::MainWindow(Widget *parent, const Rect &rc) :
|
||||
Window(parent, rc),
|
||||
m_comntLbl(nullptr),
|
||||
m_versionLbl(nullptr),
|
||||
m_comntInfoLbl(nullptr),
|
||||
m_bar(nullptr),
|
||||
m_updRadio(nullptr),
|
||||
m_repRadio(nullptr),
|
||||
m_uninsRadio(nullptr),
|
||||
m_cancelBtn(nullptr),
|
||||
m_mode(Mode::Install),
|
||||
m_resize_conn(0),
|
||||
m_checkState(UpdateRadio),
|
||||
m_is_clear_checked(false),
|
||||
m_is_sttgs_checked(false),
|
||||
m_is_checked(false)
|
||||
{
|
||||
setWindowTitle(_TR(CAPTION));
|
||||
setResizable(false);
|
||||
// setIcon(IDI_MAINICON);
|
||||
palette()->setColor(Palette::Background, Palette::Normal, 0xfefefe);
|
||||
palette()->setColor(Palette::Border, Palette::Normal, 0x888888);
|
||||
if (Utils::getWinVersion() > Utils::WinXP && Utils::getWinVersion() < Utils::Win10)
|
||||
metrics()->setMetrics(Metrics::BorderWidth, 1);
|
||||
|
||||
Widget *cw = new Widget(this);
|
||||
cw->palette()->setColor(Palette::Background, Palette::Normal, 0xfefefe);
|
||||
setCentralWidget(cw);
|
||||
setContentsMargins(0,0,0,0);
|
||||
|
||||
BoxLayout *cenVlut = new BoxLayout(BoxLayout::Vertical);
|
||||
cenVlut->setContentMargins(0, 0, 0, 0);
|
||||
cenVlut->setSpacing(0);
|
||||
cw->setLayout(cenVlut);
|
||||
|
||||
/* Caption section*/
|
||||
Widget *topPanel = new Widget(cw);
|
||||
topPanel->resize(50,28);
|
||||
topPanel->palette()->setColor(Palette::Background, Palette::Normal, 0xfefefe);
|
||||
topPanel->setProperty(Widget::HSizeBehavior, Widget::Expanding);
|
||||
topPanel->setProperty(Widget::VSizeBehavior, Widget::Fixed);
|
||||
cenVlut->addWidget(topPanel);
|
||||
|
||||
BoxLayout *topHlut = new BoxLayout(BoxLayout::Horizontal);
|
||||
topHlut->setContentMargins(0, 0, 0, 0);
|
||||
topHlut->setSpacing(0);
|
||||
topPanel->setLayout(topHlut);
|
||||
|
||||
Caption *cap = new Caption(topPanel);
|
||||
cap->setResizingAvailable(false);
|
||||
cap->palette()->setColor(Palette::Background, Palette::Normal, 0xfefefe);
|
||||
cap->metrics()->setMetrics(Metrics::TextMarginLeft, 12);
|
||||
cap->metrics()->setMetrics(Metrics::TextAlignment, Metrics::AlignHLeft| Metrics::AlignVCenter);
|
||||
cap->resize(50,28);
|
||||
cap->setProperty(Widget::HSizeBehavior, Widget::Expanding);
|
||||
cap->setProperty(Widget::VSizeBehavior, Widget::Fixed);
|
||||
|
||||
Button *closeBtn = new Button(topPanel);
|
||||
closeBtn->resize(40,28);
|
||||
closeBtn->setProperty(Widget::HSizeBehavior, Widget::Fixed);
|
||||
closeBtn->setProperty(Widget::VSizeBehavior, Widget::Fixed);
|
||||
closeBtn->palette()->setColor(Palette::Background, Palette::Normal, 0xfefefe);
|
||||
closeBtn->palette()->setColor(Palette::Background, Palette::Hover, 0xe81123);
|
||||
closeBtn->palette()->setColor(Palette::Background, Palette::Pressed, 0x8b0a14);
|
||||
closeBtn->palette()->setColor(Palette::Background, Palette::Disabled, 0x2b2b2b);
|
||||
closeBtn->palette()->setColor(Palette::Primitive, Palette::Normal, 0x000000);
|
||||
closeBtn->metrics()->setMetrics(Metrics::PrimitiveWidth, 1);
|
||||
closeBtn->setStockIcon(Button::CloseIcon);
|
||||
closeBtn->setIconSize(10, 10);
|
||||
closeBtn->onClick([this]() {
|
||||
close();
|
||||
});
|
||||
topHlut->addWidget(cap);
|
||||
topHlut->addWidget(closeBtn);
|
||||
|
||||
/* Central section */
|
||||
m_cenPanel = new Widget(cw);
|
||||
m_cenPanel->palette()->setColor(Palette::Background, Palette::Normal, 0xfefefe);
|
||||
m_cenPanel->setProperty(Widget::HSizeBehavior, Widget::Expanding);
|
||||
m_cenPanel->setProperty(Widget::VSizeBehavior, Widget::Expanding);
|
||||
cenVlut->addWidget(m_cenPanel);
|
||||
|
||||
m_cenPanelVlut = new BoxLayout(BoxLayout::Vertical);
|
||||
m_cenPanelVlut->setContentMargins(6, 12, 6, 48);
|
||||
m_cenPanelVlut->setSpacing(6);
|
||||
m_cenPanel->setLayout(m_cenPanelVlut);
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
if (m_future.valid())
|
||||
m_future.wait();
|
||||
}
|
||||
|
||||
void MainWindow::initInstallationMode(const std::wstring &url)
|
||||
{
|
||||
m_mode = Mode::Install;
|
||||
/* Image section*/
|
||||
Label *wlcLbl = new Label(m_cenPanel);
|
||||
wlcLbl->resize(282, 200);
|
||||
wlcLbl->setImage(IDI_WELCOME, 282, 200);
|
||||
wlcLbl->palette()->setColor(Palette::Background, Palette::Normal, 0xfefefe);
|
||||
wlcLbl->setProperty(Widget::HSizeBehavior, Widget::Expanding);
|
||||
wlcLbl->setProperty(Widget::VSizeBehavior, Widget::Fixed);
|
||||
m_cenPanelVlut->addWidget(wlcLbl);
|
||||
|
||||
/* Check box section*/
|
||||
CheckBox *chkBox = new CheckBox(m_cenPanel, _TR(CHECK_SILENT));
|
||||
chkBox->setGeometry(m_cenPanel->size().width/2 - 43, 254, 180, 16);
|
||||
setSelectorStyle(chkBox);
|
||||
chkBox->onClick([chkBox, this]() {
|
||||
m_is_checked = chkBox->isChecked();
|
||||
});
|
||||
|
||||
/* Comment section */
|
||||
Label *comntLbl = new Label(m_cenPanel);
|
||||
comntLbl->setText(_TR(LABEL_WARN_CLOSE), true);
|
||||
comntLbl->setGeometry(0, m_cenPanel->size().height - 130, m_cenPanel->size().width, 48);
|
||||
setLabelStyle(comntLbl);
|
||||
|
||||
/* Install button section */
|
||||
Button *instlBtn = new Button(m_cenPanel);
|
||||
instlBtn->setText(_TR(BUTTON_INSTALL));
|
||||
instlBtn->setGeometry(m_cenPanel->size().width/2 - 50, m_cenPanel->size().height - 76, 100, 28);
|
||||
setButtonStyle(instlBtn);
|
||||
instlBtn->onClick([=]() {
|
||||
m_cenPanel->disconnect(m_resize_conn);
|
||||
chkBox->close();
|
||||
comntLbl->close();
|
||||
instlBtn->close();
|
||||
startInstall(url);
|
||||
});
|
||||
|
||||
m_resize_conn = m_cenPanel->onResize([chkBox, comntLbl, instlBtn](int w, int h) {
|
||||
chkBox->setGeometry(w/2 - 43, 254, 180, 16);
|
||||
comntLbl->setGeometry(0, h - 130, w, 48);
|
||||
instlBtn->setGeometry(w/2 - 50, h - 76, 100, 28);
|
||||
});
|
||||
}
|
||||
|
||||
void MainWindow::initControlMode(const std::wstring &_arch)
|
||||
{
|
||||
m_mode = Mode::Control;
|
||||
/* Comment section */
|
||||
m_versionLbl = new Label(m_cenPanel);
|
||||
setControlLabelStyle(m_versionLbl);
|
||||
m_versionLbl->setText(fillInstalledVerInfo());
|
||||
m_versionLbl->setProperty(Widget::HSizeBehavior, Widget::Expanding);
|
||||
m_versionLbl->setProperty(Widget::VSizeBehavior, Widget::Fixed);
|
||||
m_versionLbl->metrics()->setMetrics(Metrics::TextMarginLeft, 12);
|
||||
m_cenPanelVlut->setContentMargins(18, 6, 6, 6);
|
||||
m_cenPanelVlut->addWidget(m_versionLbl);
|
||||
|
||||
if (m_package == _TR(LABEL_UNKN_PACK) || m_ver == _TR(LABEL_UNKN_VER) || _arch.empty() || m_arch != _arch) {
|
||||
Label *errLbl = new Label(m_cenPanel);
|
||||
setControlLabelStyle(errLbl);
|
||||
errLbl->setText(_TR(LABEL_NO_OPTIONS));
|
||||
errLbl->setProperty(Widget::HSizeBehavior, Widget::Expanding);
|
||||
errLbl->setProperty(Widget::VSizeBehavior, Widget::Expanding);
|
||||
errLbl->metrics()->setMetrics(Metrics::TextMarginLeft, 24);
|
||||
m_cenPanelVlut->addWidget(errLbl);
|
||||
return;
|
||||
}
|
||||
createSelectionPage();
|
||||
}
|
||||
|
||||
bool MainWindow::event(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT *result)
|
||||
{
|
||||
switch (msg) {
|
||||
case WM_INVOKEMETHOD: {
|
||||
if (std::function<void()> *func = (std::function<void()>*)wParam) {
|
||||
if (*func)
|
||||
(*func)();
|
||||
delete func;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return Window::event(msg, wParam, lParam, result);
|
||||
}
|
||||
|
||||
void MainWindow::startInstall(const std::wstring &url)
|
||||
{
|
||||
/* Comment section */
|
||||
m_comntLbl = new Label(m_cenPanel);
|
||||
m_comntLbl->setText(_TR(LABEL_DOWNLOAD), true);
|
||||
m_comntLbl->setGeometry(0, m_cenPanel->size().height - 156, m_cenPanel->size().width, 24);
|
||||
m_comntLbl->metrics()->setMetrics(Metrics::FontHeight, 20);
|
||||
setLabelStyle(m_comntLbl);
|
||||
|
||||
m_comntInfoLbl = new Label(m_cenPanel);
|
||||
m_comntInfoLbl->setText(_TR(LABEL_ALMOST_DONE), true);
|
||||
m_comntInfoLbl->setGeometry(0, m_cenPanel->size().height - 112, m_cenPanel->size().width, 40);
|
||||
setLabelStyle(m_comntInfoLbl);
|
||||
|
||||
/* Progress section */
|
||||
m_bar = new ProgressBar(m_cenPanel);
|
||||
m_bar->setGeometry(0, m_cenPanel->size().height - 126, m_cenPanel->size().width, 5);
|
||||
setProgressStyle(m_bar);
|
||||
m_bar->metrics()->setMetrics(Metrics::IconMarginLeft, 108);
|
||||
m_bar->metrics()->setMetrics(Metrics::IconMarginRight, 108);
|
||||
|
||||
m_resize_conn = m_cenPanel->onResize([this](int w, int h) {
|
||||
m_comntLbl->setGeometry(0, h - 156, w, 24);
|
||||
m_comntInfoLbl->setGeometry(0, h - 112, w, 40);
|
||||
m_bar->setGeometry(0, m_cenPanel->size().height - 126, m_cenPanel->size().width, 5);
|
||||
});
|
||||
m_comntLbl->show();
|
||||
m_comntInfoLbl->show();
|
||||
m_bar->show();
|
||||
|
||||
wstring path = NS_File::generateTmpFileName(L".exe");
|
||||
startDownload(url, path, [=]() {
|
||||
wstring args;
|
||||
if (m_is_checked) {
|
||||
args = _T("/VERYSILENT");
|
||||
m_comntLbl->setText(_TR(LABEL_INSTALL), true);
|
||||
m_bar->pulse(true);
|
||||
} else {
|
||||
hide();
|
||||
}
|
||||
if (!NS_File::runProcess(path, args)) {
|
||||
if (!m_is_checked)
|
||||
show();
|
||||
m_bar->pulse(false);
|
||||
m_bar->setProgress(0);
|
||||
m_comntInfoLbl->setText(_TR(LABEL_ERR_RUNNING), true);
|
||||
} else {
|
||||
if (m_is_checked) {
|
||||
wstring app_path;
|
||||
if (NS_Utils::IsAppInstalled(app_path)) {
|
||||
m_cenPanel->disconnect(m_resize_conn);
|
||||
m_comntLbl->close();
|
||||
m_comntInfoLbl->close();
|
||||
m_bar->close();
|
||||
invokeMethod(&MainWindow::finishInstall, this, app_path);
|
||||
} else {
|
||||
m_bar->pulse(false);
|
||||
m_bar->setProgress(0);
|
||||
m_comntLbl->setText(_TR(LABEL_ERR_INSTALL), true);
|
||||
}
|
||||
} else {
|
||||
close();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void MainWindow::finishInstall(const std::wstring &app_path)
|
||||
{
|
||||
/* Check box section*/
|
||||
m_is_checked = false;
|
||||
CheckBox *chkBox = new CheckBox(m_cenPanel, _TR(CHECK_LAUNCH));
|
||||
chkBox->setGeometry(m_cenPanel->size().width/2 - 43, 254, 180, 16);
|
||||
setSelectorStyle(chkBox);
|
||||
chkBox->onClick([chkBox, this]() {
|
||||
m_is_checked = chkBox->isChecked();
|
||||
});
|
||||
|
||||
/* Comment section */
|
||||
wstring compl_text = _TR(LABEL_INSTALL_COMPL);
|
||||
NS_Utils::Replace(compl_text, L"%1", _T(WINDOW_NAME));
|
||||
Label *comntLbl = new Label(m_cenPanel);
|
||||
comntLbl->setText(compl_text, true);
|
||||
comntLbl->setGeometry(0, m_cenPanel->size().height - 130, m_cenPanel->size().width, 48);
|
||||
setLabelStyle(comntLbl);
|
||||
|
||||
/* Install button section */
|
||||
Button *closeBtn = new Button(m_cenPanel);
|
||||
closeBtn->setText(_TR(BUTTON_CLOSE));
|
||||
closeBtn->setGeometry(m_cenPanel->size().width/2 - 50, m_cenPanel->size().height - 76, 100, 28);
|
||||
setButtonStyle(closeBtn);
|
||||
closeBtn->onClick([=]() {
|
||||
if (m_is_checked)
|
||||
NS_File::runProcess(app_path + _T(APP_LAUNCH_NAME), L"", false);
|
||||
close();
|
||||
});
|
||||
|
||||
m_resize_conn = m_cenPanel->onResize([chkBox, comntLbl, closeBtn](int w, int h) {
|
||||
chkBox->setGeometry(w/2 - 43, 254, 180, 16);
|
||||
comntLbl->setGeometry(0, h - 130, w, 48);
|
||||
closeBtn->setGeometry(w/2 - 50, h - 76, 100, 28);
|
||||
});
|
||||
chkBox->show();
|
||||
comntLbl->show();
|
||||
closeBtn->show();
|
||||
}
|
||||
|
||||
void MainWindow::startUpdate()
|
||||
{
|
||||
wstring tmp_path = NS_File::toNativeSeparators(NS_File::generateTmpFileName(L"." + m_package));
|
||||
wstring url;
|
||||
if (m_package == L"msi") {
|
||||
url = (m_arch == L"x64") ? _T(URL_INSTALL_X64_MSI) : _T(URL_INSTALL_X86_MSI);
|
||||
} else {
|
||||
if (Utils::getWinVersion() <= Utils::WinVer::WinVista) {
|
||||
url = (m_arch == L"x64") ? _T(URL_INSTALL_X64_XP) : _T(URL_INSTALL_X86_XP);
|
||||
} else {
|
||||
url = (m_arch == L"x64") ? _T(URL_INSTALL_X64) : _T(URL_INSTALL_X86);
|
||||
}
|
||||
}
|
||||
|
||||
CDownloader *dnl = startDownload(url, tmp_path, [=]() {
|
||||
m_bar->pulse(true);
|
||||
wstring args = L"/c \"" + tmp_path;
|
||||
args += (m_package == L"msi") ? L" /qn\"" : L" /UPDATE /VERYSILENT\"";
|
||||
if (!NS_File::runProcess(L"cmd", args, true)) {
|
||||
m_bar->pulse(false);
|
||||
m_bar->setProgress(0);
|
||||
m_comntInfoLbl->setText(_TR(LABEL_ERR_RUNNING), true);
|
||||
} else {
|
||||
m_bar->pulse(false);
|
||||
m_bar->setProgress(100);
|
||||
m_comntLbl->setText(_TR(LABEL_UPDATE_COMPL));
|
||||
m_versionLbl->setText(fillInstalledVerInfo());
|
||||
}
|
||||
});
|
||||
|
||||
m_cancelBtn->onClick([=]() {
|
||||
dnl->stop();
|
||||
});
|
||||
}
|
||||
|
||||
void MainWindow::startRepair()
|
||||
{
|
||||
wstring tmp_path;
|
||||
if (m_package == L"msi") {
|
||||
wstring prodCode = NS_Utils::MsiProductCode(_T(WINDOW_NAME));
|
||||
if (prodCode.empty()) {
|
||||
m_comntInfoLbl->setText(_TR(LABEL_ERR_PROD_CODE), true);
|
||||
return;
|
||||
}
|
||||
wstring packageName = NS_Utils::MsiGetProperty(prodCode.c_str(), INSTALLPROPERTY_PACKAGENAME);
|
||||
if (packageName.empty()) {
|
||||
m_comntInfoLbl->setText(_TR(LABEL_ERR_PACK_NAME), true);
|
||||
return;
|
||||
}
|
||||
tmp_path = NS_File::toNativeSeparators(NS_File::tempPath() + _T("/") + packageName);
|
||||
} else {
|
||||
tmp_path = NS_File::toNativeSeparators(NS_File::generateTmpFileName(L"." + m_package));
|
||||
}
|
||||
|
||||
wstring url = L"https://github.com/%1/%2/releases/download/%3/%4";
|
||||
{
|
||||
wstring url_filename = L"DesktopEditors_" + m_arch;
|
||||
if (Utils::getWinVersion() <= Utils::WinVer::WinVista)
|
||||
url_filename.append(L"_xp");
|
||||
url_filename.append(L"." + m_package);
|
||||
|
||||
wstring url_ver = L"v" + m_ver;
|
||||
size_t pos = url_ver.find_last_of(L'.');
|
||||
if (pos != std::wstring::npos)
|
||||
url_ver = url_ver.substr(0, pos);
|
||||
|
||||
NS_Utils::Replace(url, L"%1", _T(REG_GROUP_KEY));
|
||||
NS_Utils::Replace(url, L"%2", _T(APP_NAME));
|
||||
NS_Utils::Replace(url, L"%3", url_ver);
|
||||
NS_Utils::Replace(url, L"%4", url_filename);
|
||||
}
|
||||
|
||||
CDownloader *dnl = startDownload(url, tmp_path, [=]() {
|
||||
m_bar->pulse(true);
|
||||
wstring cmd = (m_package == L"msi") ? L"msiexec" : L"cmd",
|
||||
args = (m_package == L"msi") ? L"/fvamus \"" : L"/c \"";
|
||||
args += tmp_path;
|
||||
args += (m_package == L"msi") ? L"\" /qn" : L" /VERYSILENT\"";
|
||||
if (!NS_File::runProcess(cmd, args, true)) {
|
||||
m_bar->pulse(false);
|
||||
m_bar->setProgress(0);
|
||||
m_comntInfoLbl->setText(_TR(LABEL_ERR_RUNNING), true);
|
||||
} else {
|
||||
if (m_is_clear_checked) {
|
||||
wstring dataPath = NS_File::appDataPath();
|
||||
if (!dataPath.empty())
|
||||
NS_File::removeDirRecursively(dataPath);
|
||||
}
|
||||
if (m_is_sttgs_checked) {
|
||||
wstring key(L"SOFTWARE\\");
|
||||
key.append(_T(REG_GROUP_KEY));
|
||||
SHDeleteKey(HKEY_CURRENT_USER, key.c_str());
|
||||
}
|
||||
m_bar->pulse(false);
|
||||
m_bar->setProgress(100);
|
||||
m_comntLbl->setText(_TR(LABEL_REPAIR_COMPL));
|
||||
}
|
||||
});
|
||||
|
||||
m_cancelBtn->onClick([=]() {
|
||||
dnl->stop();
|
||||
});
|
||||
}
|
||||
|
||||
void MainWindow::startUninstall()
|
||||
{
|
||||
m_cancelBtn->setDisabled(true);
|
||||
m_bar->pulse(true);
|
||||
wstring args = L"/c \"" + m_uninst_cmd;
|
||||
args += (m_package == L"msi") ? L" /qn\"" : L" /VERYSILENT\"";
|
||||
m_future = std::async(std::launch::async, [=]() {
|
||||
if (!NS_File::runProcess(L"cmd", args, true)) {
|
||||
m_bar->pulse(false);
|
||||
m_bar->setProgress(0);
|
||||
m_comntInfoLbl->setText(_TR(LABEL_ERR_UNINST));
|
||||
createCloseAndBackButtons();
|
||||
} else {
|
||||
if (m_is_checked) {
|
||||
wstring dataPath = NS_File::appDataPath();
|
||||
if (!dataPath.empty())
|
||||
NS_File::removeDirRecursively(dataPath);
|
||||
|
||||
wstring key(L"SOFTWARE\\");
|
||||
key.append(_T(REG_GROUP_KEY));
|
||||
SHDeleteKey(HKEY_CURRENT_USER, key.c_str());
|
||||
}
|
||||
m_bar->pulse(false);
|
||||
m_bar->setProgress(100);
|
||||
m_comntLbl->setText(_TR(LABEL_UNINST_COMPL));
|
||||
createCloseButton();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void MainWindow::createSelectionPage()
|
||||
{
|
||||
/* Check box section*/
|
||||
m_is_clear_checked = false;
|
||||
CheckBox *clrChkBox = new CheckBox(m_cenPanel, _TR(CHECK_CLR_DATA));
|
||||
clrChkBox->setDisabled(!(m_checkState & RepairRadio));
|
||||
clrChkBox->setChecked(m_checkState & ClrDataCheck);
|
||||
clrChkBox->setGeometry(79, 114, 450, 18);
|
||||
setSelectorStyle(clrChkBox);
|
||||
clrChkBox->onClick([=]() {
|
||||
m_is_clear_checked = clrChkBox->isChecked();
|
||||
m_checkState = (m_checkState & ~ClrDataCheck) | (m_is_clear_checked * ClrDataCheck);
|
||||
});
|
||||
|
||||
m_is_sttgs_checked = false;
|
||||
CheckBox *stnChkBox = new CheckBox(m_cenPanel, _TR(CHECK_CLR_STNGS));
|
||||
stnChkBox->setDisabled(!(m_checkState & RepairRadio));
|
||||
stnChkBox->setChecked(m_checkState & ClrStnCheck);
|
||||
stnChkBox->setGeometry(79, 146, 450, 18);
|
||||
setSelectorStyle(stnChkBox);
|
||||
stnChkBox->onClick([stnChkBox, this]() {
|
||||
m_is_sttgs_checked = stnChkBox->isChecked();
|
||||
m_checkState = (m_checkState & ~ClrStnCheck) | (m_is_sttgs_checked * ClrStnCheck);
|
||||
});
|
||||
|
||||
m_is_checked = false;
|
||||
CheckBox *clrAllChkBox = new CheckBox(m_cenPanel, _TR(CHECK_CLR_ALL));
|
||||
clrAllChkBox->setDisabled(!(m_checkState & UninstRadio));
|
||||
clrAllChkBox->setChecked(m_checkState & ClrAllCheck);
|
||||
clrAllChkBox->setGeometry(79, 216, 450, 18);
|
||||
setSelectorStyle(clrAllChkBox);
|
||||
clrAllChkBox->onClick([clrAllChkBox, this]() {
|
||||
m_is_checked = clrAllChkBox->isChecked();
|
||||
m_checkState = (m_checkState & ~ClrAllCheck) | (m_is_checked * ClrAllCheck);
|
||||
});
|
||||
|
||||
/* Update radio button section*/
|
||||
m_updRadio = new RadioButton(m_cenPanel, _TR(RADIO_UPDATE));
|
||||
m_updRadio->setChecked(m_checkState & UpdateRadio);
|
||||
m_updRadio->setGeometry(50, 48, 128, 18);
|
||||
setSelectorStyle(m_updRadio);
|
||||
m_updRadio->onClick([=]() {
|
||||
clrChkBox->setDisabled(true);
|
||||
stnChkBox->setDisabled(true);
|
||||
clrAllChkBox->setDisabled(true);
|
||||
if (m_repRadio->isChecked())
|
||||
m_repRadio->setChecked(false);
|
||||
if (m_uninsRadio->isChecked())
|
||||
m_uninsRadio->setChecked(false);
|
||||
m_checkState = (m_checkState | UpdateRadio) & ~(RepairRadio | UninstRadio);
|
||||
});
|
||||
|
||||
/* Repair radio button section*/
|
||||
m_repRadio = new RadioButton(m_cenPanel, _TR(RADIO_REPAIR));
|
||||
m_repRadio->setChecked(m_checkState & RepairRadio);
|
||||
m_repRadio->setGeometry(50, 82, 128, 18);
|
||||
setSelectorStyle(m_repRadio);
|
||||
m_repRadio->onClick([=]() {
|
||||
clrChkBox->setDisabled(false);
|
||||
stnChkBox->setDisabled(false);
|
||||
clrAllChkBox->setDisabled(true);
|
||||
if (m_updRadio->isChecked())
|
||||
m_updRadio->setChecked(false);
|
||||
if (m_uninsRadio->isChecked())
|
||||
m_uninsRadio->setChecked(false);
|
||||
m_checkState = (m_checkState | RepairRadio) & ~(UninstRadio | UpdateRadio);
|
||||
});
|
||||
|
||||
/* Uninstall radio button section*/
|
||||
m_uninsRadio = new RadioButton(m_cenPanel, _TR(RADIO_UNINST));
|
||||
m_uninsRadio->setChecked(m_checkState & UninstRadio);
|
||||
m_uninsRadio->setGeometry(50, 184, 128, 18);
|
||||
setSelectorStyle(m_uninsRadio);
|
||||
m_uninsRadio->onClick([=]() {
|
||||
clrChkBox->setDisabled(true);
|
||||
stnChkBox->setDisabled(true);
|
||||
clrAllChkBox->setDisabled(false);
|
||||
if (m_repRadio->isChecked())
|
||||
m_repRadio->setChecked(false);
|
||||
if (m_updRadio->isChecked())
|
||||
m_updRadio->setChecked(false);
|
||||
m_checkState = (m_checkState | UninstRadio) & ~(UpdateRadio | RepairRadio);
|
||||
});
|
||||
|
||||
/* Apply button section */
|
||||
Button *applyBtn = new Button(m_cenPanel);
|
||||
applyBtn->setText(_TR(BUTTON_APPLY));
|
||||
applyBtn->setGeometry(m_cenPanel->size().width - 100 - 12, m_cenPanel->size().height - 28 - 12, 100, 28);
|
||||
setButtonStyle(applyBtn);
|
||||
applyBtn->onClick([=]() {
|
||||
wstring msg = m_uninsRadio->isChecked() ? _TR(MSG_REMOVE) : m_repRadio->isChecked() ? _TR(MSG_REPAIR) : _TR(MSG_UPDATE);
|
||||
NS_Utils::Replace(msg, L"%1", _T(WINDOW_NAME));
|
||||
if (IDOK == MessageBox(nativeWindowHandle(), msg.c_str(), _TR(CAPTION), MB_ICONWARNING | MB_OKCANCEL | MB_DEFBUTTON2)) {
|
||||
m_cenPanel->disconnect(m_resize_conn);
|
||||
m_updRadio->close();
|
||||
m_repRadio->close();
|
||||
clrChkBox->close();
|
||||
stnChkBox->close();
|
||||
m_uninsRadio->close();
|
||||
clrAllChkBox->close();
|
||||
applyBtn->close();
|
||||
msg = m_uninsRadio->isChecked() ? _TR(LABEL_UNINSTLING) : m_repRadio->isChecked() ? _TR(LABEL_REPAIRING) : _TR(LABEL_UPDATING);
|
||||
createProgressPage(msg);
|
||||
if (m_uninsRadio->isChecked())
|
||||
startUninstall();
|
||||
else
|
||||
if (m_repRadio->isChecked())
|
||||
startRepair();
|
||||
else
|
||||
startUpdate();
|
||||
}
|
||||
});
|
||||
m_resize_conn = m_cenPanel->onResize([applyBtn](int w, int h) {
|
||||
applyBtn->setGeometry(w - 100 - 12, h - 28 - 12, 100, 28);
|
||||
});
|
||||
m_updRadio->show();
|
||||
m_repRadio->show();
|
||||
clrChkBox->show();
|
||||
stnChkBox->show();
|
||||
m_uninsRadio->show();
|
||||
clrAllChkBox->show();
|
||||
applyBtn->show();
|
||||
}
|
||||
|
||||
void MainWindow::createProgressPage(const std::wstring &text)
|
||||
{
|
||||
m_comntLbl = new Label(m_cenPanel);
|
||||
setControlLabelStyle(m_comntLbl);
|
||||
m_comntLbl->setText(text);
|
||||
m_comntLbl->metrics()->setMetrics(Metrics::TextMarginLeft, 12);
|
||||
m_comntLbl->setGeometry(30, 50, size().width - 30, 24);
|
||||
|
||||
m_comntInfoLbl = new Label(m_cenPanel);
|
||||
setControlLabelStyle(m_comntInfoLbl);
|
||||
m_comntInfoLbl->metrics()->setMetrics(Metrics::TextMarginLeft, 12);
|
||||
m_comntInfoLbl->setGeometry(30, 92, m_cenPanel->size().width - 30, 40);
|
||||
|
||||
/* Progress section */
|
||||
m_bar = new ProgressBar(m_cenPanel);
|
||||
m_bar->setGeometry(42, 80, 250, 5);
|
||||
setProgressStyle(m_bar);
|
||||
|
||||
m_cancelBtn = new Button(m_cenPanel);
|
||||
m_cancelBtn->setText(_TR(BUTTON_CANCEL));
|
||||
m_cancelBtn->setGeometry(m_cenPanel->size().width - 100 - 12, m_cenPanel->size().height - 28 - 12, 100, 28);
|
||||
setButtonStyle(m_cancelBtn);
|
||||
m_resize_conn = m_cenPanel->onResize([this](int w, int h) {
|
||||
m_cancelBtn->setGeometry(w - 100 - 12, h - 28 - 12, 100, 28);
|
||||
});
|
||||
|
||||
m_comntLbl->show();
|
||||
m_comntInfoLbl->show();
|
||||
m_bar->show();
|
||||
m_cancelBtn->show();
|
||||
}
|
||||
|
||||
void MainWindow::createCloseButton()
|
||||
{
|
||||
invokeMethod([=]() {
|
||||
m_cenPanel->disconnect(m_resize_conn);
|
||||
m_cancelBtn->close();
|
||||
Button *closeBtn = new Button(m_cenPanel);
|
||||
closeBtn->setText(_TR(BUTTON_CLOSE));
|
||||
closeBtn->setGeometry(m_cenPanel->size().width - 100 - 12, m_cenPanel->size().height - 28 - 12, 100, 28);
|
||||
setButtonStyle(closeBtn);
|
||||
closeBtn->onClick([=]() {
|
||||
m_cenPanel->disconnect(m_resize_conn);
|
||||
close();
|
||||
});
|
||||
m_resize_conn = m_cenPanel->onResize([closeBtn](int w, int h) {
|
||||
closeBtn->setGeometry(w - 100 - 12, h - 28 - 12, 100, 28);
|
||||
});
|
||||
closeBtn->show();
|
||||
});
|
||||
}
|
||||
|
||||
void MainWindow::createCloseAndBackButtons()
|
||||
{
|
||||
invokeMethod([=]() {
|
||||
m_cenPanel->disconnect(m_resize_conn);
|
||||
m_cancelBtn->close();
|
||||
Button *closeBtn = new Button(m_cenPanel);
|
||||
closeBtn->setText(_TR(BUTTON_CLOSE));
|
||||
closeBtn->setGeometry(m_cenPanel->size().width - 100 - 12, m_cenPanel->size().height - 28 - 12, 100, 28);
|
||||
setButtonStyle(closeBtn);
|
||||
closeBtn->onClick([=]() {
|
||||
m_cenPanel->disconnect(m_resize_conn);
|
||||
close();
|
||||
});
|
||||
|
||||
Button *backBtn = new Button(m_cenPanel);
|
||||
backBtn->setText(_TR(BUTTON_BACK));
|
||||
backBtn->setGeometry(m_cenPanel->size().width - 100 - 12 - 106, m_cenPanel->size().height - 28 - 12, 100, 28);
|
||||
setButtonStyle(backBtn);
|
||||
backBtn->onClick([=]() {
|
||||
m_cenPanel->disconnect(m_resize_conn);
|
||||
m_comntLbl->close();
|
||||
m_comntInfoLbl->close();
|
||||
m_bar->close();
|
||||
closeBtn->close();
|
||||
backBtn->close();
|
||||
createSelectionPage();
|
||||
});
|
||||
|
||||
m_resize_conn = m_cenPanel->onResize([closeBtn, backBtn](int w, int h) {
|
||||
closeBtn->setGeometry(w - 100 - 12, h - 28 - 12, 100, 28);
|
||||
backBtn->setGeometry(w - 100 - 12 - 106, h - 28 - 12, 100, 28);
|
||||
});
|
||||
|
||||
closeBtn->show();
|
||||
backBtn->show();
|
||||
});
|
||||
}
|
||||
|
||||
wstring MainWindow::fillInstalledVerInfo()
|
||||
{
|
||||
wstring text = _TR(LABEL_VERSION);
|
||||
NS_Utils::InstalledVerInfo(L"DisplayVersion", m_ver, m_arch);
|
||||
if (m_ver.empty())
|
||||
m_ver = _TR(LABEL_UNKN_VER);
|
||||
|
||||
NS_Utils::InstalledVerInfo(L"UninstallString", m_uninst_cmd, m_arch);
|
||||
m_package = (m_uninst_cmd.find(L"msiexec") != std::wstring::npos) ? L"msi" : (m_uninst_cmd.find(L".exe") != std::wstring::npos) ? L"exe" : _TR(LABEL_UNKN_PACK);
|
||||
|
||||
NS_Utils::Replace(text, L"%1", _T(WINDOW_NAME));
|
||||
NS_Utils::Replace(text, L"%2", m_ver);
|
||||
NS_Utils::Replace(text, L"%3", m_arch);
|
||||
NS_Utils::Replace(text, L"%4", m_package);
|
||||
return text;
|
||||
}
|
||||
|
||||
CDownloader* MainWindow::startDownload(const std::wstring &url, const std::wstring &path, const std::function<void()> &onComplete)
|
||||
{
|
||||
CDownloader *dnl = new CDownloader();
|
||||
dnl->onProgress([=](int percent) {
|
||||
m_bar->setProgress(percent);
|
||||
});
|
||||
dnl->onComplete([=](ulong error) {
|
||||
if (m_mode == Mode::Control)
|
||||
m_cancelBtn->setDisabled(true);
|
||||
if (error == ERROR_SUCCESS) {
|
||||
if (NS_File::verifyEmbeddedSignature(path)) {
|
||||
onComplete();
|
||||
} else {
|
||||
m_bar->setProgress(0);
|
||||
m_comntInfoLbl->setText(_TR(LABEL_NO_VER_AVAIL), true);
|
||||
}
|
||||
if (NS_File::fileExists(path))
|
||||
NS_File::removeFile(path);
|
||||
} else
|
||||
if (error == ERROR_CANCELLED) {
|
||||
m_comntInfoLbl->setText(_TR(LABEL_ERR_CANCELLED), true);
|
||||
} else {
|
||||
m_comntInfoLbl->setText(NS_Utils::GetLastErrorAsString(error), true);
|
||||
}
|
||||
|
||||
if (m_mode == Mode::Control)
|
||||
createCloseAndBackButtons();
|
||||
});
|
||||
dnl->downloadFile(url, path);
|
||||
onAboutToDestroy([=]() {
|
||||
delete dnl;
|
||||
});
|
||||
return dnl;
|
||||
}
|
||||
|
||||
template<typename Fn, typename... Args>
|
||||
void MainWindow::invokeMethod(Fn&& fn, Args&&... args)
|
||||
{
|
||||
std::function<void()> *func = new std::function<void()>(std::bind(std::forward<Fn>(fn), std::forward<Args>(args)...));
|
||||
PostMessage(m_hWnd, WM_INVOKEMETHOD, (WPARAM)func, 0);
|
||||
} // NOLINT
|
||||
67
win-linux/extras/online-installer/src/mainwindow.h
Normal file
67
win-linux/extras/online-installer/src/mainwindow.h
Normal file
@ -0,0 +1,67 @@
|
||||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
|
||||
#include "window.h"
|
||||
#include <future>
|
||||
|
||||
|
||||
class Label;
|
||||
class ProgressBar;
|
||||
class Widget;
|
||||
class BoxLayout;
|
||||
class RadioButton;
|
||||
class Button;
|
||||
class CDownloader;
|
||||
class MainWindow : public Window
|
||||
{
|
||||
public:
|
||||
MainWindow(Widget *parent, const Rect &rc);
|
||||
~MainWindow();
|
||||
|
||||
void initInstallationMode(const std::wstring &url);
|
||||
void initControlMode(const std::wstring &arch);
|
||||
|
||||
protected:
|
||||
virtual bool event(UINT, WPARAM, LPARAM, LRESULT*) override;
|
||||
|
||||
private:
|
||||
void startInstall(const std::wstring &url);
|
||||
void finishInstall(const std::wstring &app_path);
|
||||
void startUpdate();
|
||||
void startRepair();
|
||||
void startUninstall();
|
||||
void createSelectionPage();
|
||||
void createProgressPage(const std::wstring &text);
|
||||
void createCloseButton();
|
||||
void createCloseAndBackButtons();
|
||||
std::wstring fillInstalledVerInfo();
|
||||
CDownloader* startDownload(const std::wstring &url, const std::wstring &path, const std::function<void()> &onComplete);
|
||||
template<typename Fn, typename... Args>
|
||||
void invokeMethod(Fn&& fn, Args&&... args);
|
||||
|
||||
enum class Mode : BYTE {Install, Control};
|
||||
enum Selectors : BYTE {UpdateRadio = 1, RepairRadio = 2, UninstRadio = 4, ClrDataCheck = 8, ClrStnCheck = 16, ClrAllCheck = 32};
|
||||
std::future<void> m_future;
|
||||
std::wstring m_uninst_cmd,
|
||||
m_ver,
|
||||
m_arch,
|
||||
m_package;
|
||||
Label *m_comntLbl,
|
||||
*m_versionLbl,
|
||||
*m_comntInfoLbl;
|
||||
ProgressBar *m_bar;
|
||||
Widget *m_cenPanel;
|
||||
BoxLayout *m_cenPanelVlut;
|
||||
RadioButton *m_updRadio,
|
||||
*m_repRadio,
|
||||
*m_uninsRadio;
|
||||
Button *m_cancelBtn;
|
||||
Mode m_mode;
|
||||
int m_resize_conn;
|
||||
BYTE m_checkState;
|
||||
bool m_is_clear_checked,
|
||||
m_is_sttgs_checked,
|
||||
m_is_checked;
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
@ -1,29 +1,52 @@
|
||||
#include "version.h"
|
||||
|
||||
#define IDI_MAINICON 101
|
||||
#define IDD_DIALOG 102
|
||||
#define IDD_DIALOG_RTL 103
|
||||
|
||||
#define IDC_MAIN_ICON 1001
|
||||
#define IDC_LABEL_TITLE 1002
|
||||
#define IDC_LABEL_MESSAGE 1003
|
||||
#define IDC_PROGRESS 1004
|
||||
#define IDC_BUTTON_CANCEL 1005
|
||||
#define IDC_SILENT_CHECK 1006
|
||||
#define IDI_WELCOME 102
|
||||
|
||||
#define IDT_TRANSLATIONS 10001
|
||||
|
||||
#define CAPTION_TEXT VER_PRODUCTNAME_STR
|
||||
#define MESSAGE_TEXT_ERR1 "The application cannot continue because this architecture is not supported.\0"
|
||||
#define MESSAGE_TEXT_ERR2 "The application is already running.\0"
|
||||
#define LABEL_TITLE_TEXT "Preparing for installation\0"
|
||||
#define LABEL_MESSAGE_TEXT "Downloading a package\0"
|
||||
#define LABEL_MESSAGE_TEXT_ERR1 "An error occurred during initialization.\nPlease try restarting the app later.\0"
|
||||
#define LABEL_MESSAGE_TEXT_ERR2 "Package download failed: Not enough memory!\nPlease try restarting the app later.\0"
|
||||
#define LABEL_MESSAGE_TEXT_ERR3 "Package download failed: Server connection error!\nPlease try restarting the app later.\0"
|
||||
#define LABEL_MESSAGE_TEXT_ERR4 "Package download failed: Network error!\nPlease try restarting the app later.\0"
|
||||
#define LABEL_MESSAGE_TEXT_ERR5 "An error occurred while running the package.\nPlease try restarting the app later.\0"
|
||||
#define LABEL_MESSAGE_TEXT_ERR6 "An error occurred during initialization: Url not set.\0"
|
||||
#define LABEL_MESSAGE_TEXT_ERR7 "An error occurred during initialization: File name not specified.\0"
|
||||
#define BUTTON_CANCEL_TEXT "Cancel\0"
|
||||
#define SILENT_CHECK_TEXT "Silent Installation\0"
|
||||
#define APP_LAUNCH_NAME "\\DesktopEditors.exe"
|
||||
|
||||
#define CAPTION VER_PRODUCTNAME_STR
|
||||
#define MSG_ERR_ARCH "The application cannot continue because this architecture is not supported."
|
||||
#define MSG_ERR_ALREADY_RUNNING "The application is already running."
|
||||
#define MSG_ERR_CLOSE_APP "Setup has detected that %1 is currently running. Please close all instances of it."
|
||||
#define MSG_REMOVE "This will remove %1 and its components."
|
||||
#define MSG_REPAIR "This will repair the current version of %1."
|
||||
#define MSG_UPDATE "This will update %1 to the latest version available."
|
||||
#define LABEL_DOWNLOAD "Downloading"
|
||||
#define LABEL_INSTALL "Installing"
|
||||
#define LABEL_UPDATING "Updating"
|
||||
#define LABEL_REPAIRING "Repairing"
|
||||
#define LABEL_UNINSTLING "Uninstalling"
|
||||
#define LABEL_UPDATE_COMPL "Update complete!"
|
||||
#define LABEL_REPAIR_COMPL "Repairing completed!"
|
||||
#define LABEL_UNINST_COMPL "Uninstalling completed!"
|
||||
#define LABEL_VERSION "%1 %2 (%3 %4) is installed"
|
||||
#define LABEL_UNKN_VER "unknown version"
|
||||
#define LABEL_UNKN_PACK "unknown package"
|
||||
#define LABEL_NO_OPTIONS "No additional options available."
|
||||
#define LABEL_NO_VER_AVAIL "No version available"
|
||||
#define LABEL_WARN_CLOSE "This will install ONLYOFFICE Desktop Editors on your computer.\nIt is reccomended that you close all other applications before continuing."
|
||||
#define LABEL_ALMOST_DONE "Just a bit more and we're done"
|
||||
#define LABEL_INSTALL_COMPL "%1 has been successfully installed on your computer.\nTo run the application after closing this installer, select the check box."
|
||||
#define LABEL_ERR_PROD_CODE "Error while retrieving product code."
|
||||
#define LABEL_ERR_PACK_NAME "Error while retrieving package name."
|
||||
#define LABEL_ERR_INSTALL "An error occurred during installation."
|
||||
#define LABEL_ERR_UNINST "An error occurred during uninstalling."
|
||||
#define LABEL_ERR_COMMON "An error occurred:"
|
||||
#define LABEL_ERR_RUNNING "An error occurred while running the package.\nPlease try restarting the app later."
|
||||
#define LABEL_ERR_CANCELLED "Cancelled!"
|
||||
#define BUTTON_INSTALL "Install"
|
||||
#define BUTTON_CANCEL "Cancel"
|
||||
#define BUTTON_APPLY "Apply"
|
||||
#define BUTTON_CLOSE "Close"
|
||||
#define BUTTON_BACK "Back"
|
||||
#define RADIO_UPDATE "Update"
|
||||
#define RADIO_REPAIR "Repair"
|
||||
#define RADIO_UNINST "Uninstall"
|
||||
#define CHECK_SILENT "Silent Installation"
|
||||
#define CHECK_LAUNCH "Launch"
|
||||
#define CHECK_CLR_DATA "Clear cached data"
|
||||
#define CHECK_CLR_STNGS "Clear user settings"
|
||||
#define CHECK_CLR_ALL "Clear user settings and cached data"
|
||||
|
||||
@ -29,7 +29,7 @@ private:
|
||||
static wstring langName;
|
||||
static bool is_translations_valid;
|
||||
|
||||
enum TokenType {
|
||||
enum TokenType : unsigned char {
|
||||
TOKEN_BEGIN_DOCUMENT = 0,
|
||||
TOKEN_END_DOCUMENT,
|
||||
TOKEN_BEGIN_STRING_ID,
|
||||
|
||||
@ -0,0 +1,86 @@
|
||||
#include "abstractbutton.h"
|
||||
#include "palette.h"
|
||||
|
||||
|
||||
AbstractButton::AbstractButton(Widget *parent, const std::wstring &text) :
|
||||
Widget(parent, ObjectType::WidgetType),
|
||||
m_text(text)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
AbstractButton::~AbstractButton()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void AbstractButton::setText(const std::wstring &text)
|
||||
{
|
||||
m_text = text;
|
||||
update();
|
||||
}
|
||||
|
||||
int AbstractButton::onClick(const FnVoidVoid &callback)
|
||||
{
|
||||
m_click_callbacks[++m_connectionId] = callback;
|
||||
return m_connectionId;
|
||||
}
|
||||
|
||||
void AbstractButton::disconnect(int connectionId)
|
||||
{
|
||||
auto it = m_click_callbacks.find(connectionId);
|
||||
if (it != m_click_callbacks.end())
|
||||
m_click_callbacks.erase(it);
|
||||
}
|
||||
|
||||
bool AbstractButton::event(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT *result)
|
||||
{
|
||||
switch (msg) {
|
||||
case WM_LBUTTONDOWN: {
|
||||
if (!m_disabled) {
|
||||
palette()->setCurrentState(Palette::Pressed);
|
||||
repaint();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
case WM_LBUTTONUP: {
|
||||
if (!m_disabled) {
|
||||
palette()->setCurrentState(Palette::Hover);
|
||||
repaint();
|
||||
click();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_MOUSEENTER: {
|
||||
if (!m_disabled) {
|
||||
palette()->setCurrentState(Palette::Hover);
|
||||
repaint();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_MOUSELEAVE: {
|
||||
if (!m_disabled) {
|
||||
palette()->setCurrentState(Palette::Normal);
|
||||
repaint();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return Widget::event(msg, wParam, lParam, result);
|
||||
}
|
||||
|
||||
void AbstractButton::click()
|
||||
{
|
||||
if (underMouse()) {
|
||||
for (auto it = m_click_callbacks.begin(); it != m_click_callbacks.end(); it++) {
|
||||
if (it->second)
|
||||
(it->second)();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
#ifndef ABSTRACTBUTTON_H
|
||||
#define ABSTRACTBUTTON_H
|
||||
|
||||
#include "widget.h"
|
||||
#include <unordered_map>
|
||||
|
||||
|
||||
class AbstractButton : public Widget
|
||||
{
|
||||
public:
|
||||
AbstractButton(Widget *parent = nullptr, const std::wstring &text = L"");
|
||||
virtual ~AbstractButton();
|
||||
|
||||
void setText(const std::wstring &text);
|
||||
|
||||
/* callback */
|
||||
int onClick(const FnVoidVoid &callback);
|
||||
virtual void disconnect(int) override;
|
||||
|
||||
protected:
|
||||
virtual bool event(UINT, WPARAM, LPARAM, LRESULT*) override;
|
||||
virtual void click();
|
||||
|
||||
std::wstring m_text;
|
||||
|
||||
private:
|
||||
std::unordered_map<int, FnVoidVoid> m_click_callbacks;
|
||||
};
|
||||
|
||||
#endif // ABSTRACTBUTTON_H
|
||||
180
win-linux/extras/online-installer/src/uiclasses/application.cpp
Normal file
180
win-linux/extras/online-installer/src/uiclasses/application.cpp
Normal file
@ -0,0 +1,180 @@
|
||||
#include "application.h"
|
||||
#include "widget.h"
|
||||
#include "src/resource.h"
|
||||
#include <gdiplus.h>
|
||||
|
||||
|
||||
class Application::ApplicationPrivate
|
||||
{
|
||||
public:
|
||||
ApplicationPrivate();
|
||||
~ApplicationPrivate();
|
||||
|
||||
ULONG_PTR gdi_token;
|
||||
HINSTANCE hInstance;
|
||||
LayoutDirection layoutDirection;
|
||||
int windowId;
|
||||
ATOM registerClass(LPCWSTR className, HINSTANCE hInstance);
|
||||
static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
};
|
||||
|
||||
Application::ApplicationPrivate::ApplicationPrivate() :
|
||||
gdi_token(0),
|
||||
hInstance(nullptr),
|
||||
layoutDirection(LayoutDirection::LeftToRight),
|
||||
windowId(0)
|
||||
{
|
||||
Gdiplus::GdiplusStartupInput gdiplusStartupInput;
|
||||
Gdiplus::GdiplusStartup(&gdi_token, &gdiplusStartupInput, nullptr);
|
||||
}
|
||||
|
||||
Application::ApplicationPrivate::~ApplicationPrivate()
|
||||
{
|
||||
Gdiplus::GdiplusShutdown(gdi_token);
|
||||
}
|
||||
|
||||
ATOM Application::ApplicationPrivate::registerClass(LPCWSTR className, HINSTANCE hInstance)
|
||||
{
|
||||
WNDCLASSEX wcx;
|
||||
memset(&wcx, 0, sizeof(wcx));
|
||||
wcx.cbSize = sizeof(WNDCLASSEX);
|
||||
wcx.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
|
||||
wcx.hInstance = hInstance;
|
||||
wcx.lpfnWndProc = WndProc;
|
||||
wcx.cbClsExtra = 0;
|
||||
wcx.cbWndExtra = 0;
|
||||
// wcx.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MAINICON));
|
||||
// wcx.hIconSm = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MAINICON));
|
||||
wcx.lpszClassName = className;
|
||||
wcx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
|
||||
wcx.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
return RegisterClassEx(&wcx);
|
||||
}
|
||||
|
||||
LRESULT CALLBACK Application::ApplicationPrivate::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (msg == WM_CREATE) {
|
||||
if (CREATESTRUCT *cs = (CREATESTRUCT*)lParam) {
|
||||
if (Widget *wgt = (Widget*)cs->lpCreateParams) {
|
||||
wgt->setNativeWindowHandle(hWnd);
|
||||
SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)wgt);
|
||||
LRESULT result = 0;
|
||||
if (wgt->event(msg, wParam, lParam, &result))
|
||||
return result;
|
||||
}
|
||||
}
|
||||
} else
|
||||
if (Widget *wgt = (Widget*)GetWindowLongPtr(hWnd, GWLP_USERDATA)) {
|
||||
LRESULT result = 0;
|
||||
if (wgt->event(msg, wParam, lParam, &result))
|
||||
return result;
|
||||
}
|
||||
return DefWindowProc(hWnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
Application *Application::inst = nullptr;
|
||||
|
||||
Application::Application(HINSTANCE hInstance, PWSTR cmdline, int cmdshow) :
|
||||
Application()
|
||||
{
|
||||
d_ptr->hInstance = hInstance;
|
||||
if (!d_ptr->hInstance)
|
||||
d_ptr->hInstance = GetModuleHandle(NULL);
|
||||
inst = this;
|
||||
}
|
||||
|
||||
Application::Application() :
|
||||
Object(nullptr),
|
||||
d_ptr(new ApplicationPrivate)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Application *Application::instance()
|
||||
{
|
||||
return inst;
|
||||
}
|
||||
|
||||
HINSTANCE Application::moduleHandle()
|
||||
{
|
||||
return d_ptr->hInstance;
|
||||
}
|
||||
|
||||
void Application::setLayoutDirection(LayoutDirection layoutDirection)
|
||||
{
|
||||
d_ptr->layoutDirection = layoutDirection;
|
||||
}
|
||||
|
||||
Application::~Application()
|
||||
{
|
||||
delete d_ptr, d_ptr = nullptr;
|
||||
}
|
||||
|
||||
int Application::exec()
|
||||
{
|
||||
MSG msg;
|
||||
BOOL res;
|
||||
while ((res = GetMessage(&msg, NULL, 0, 0)) != 0 && res != -1) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
return (int)msg.wParam;
|
||||
}
|
||||
|
||||
void Application::exit(int code)
|
||||
{
|
||||
PostQuitMessage(code);
|
||||
}
|
||||
|
||||
void Application::registerWidget(Widget *wgt, ObjectType objType, const Rect &rc)
|
||||
{
|
||||
std::wstring className;
|
||||
DWORD style = WS_CLIPCHILDREN;
|
||||
DWORD exStyle = d_ptr->layoutDirection == LayoutDirection::RightToLeft ? WS_EX_LAYOUTRTL : 0;
|
||||
HWND hWndParent = wgt->parentWidget() ? wgt->parentWidget()->nativeWindowHandle() : HWND_DESKTOP;
|
||||
|
||||
switch (objType) {
|
||||
case ObjectType::WindowType:
|
||||
className = L"MainWindow " + std::to_wstring(++d_ptr->windowId);
|
||||
style |= WS_OVERLAPPEDWINDOW;
|
||||
exStyle |= WS_EX_APPWINDOW;
|
||||
break;
|
||||
|
||||
case ObjectType::DialogType:
|
||||
className = L"Dialog " + std::to_wstring(++d_ptr->windowId);
|
||||
style |= WS_CAPTION | WS_SYSMENU /*| DS_MODALFRAME*/;
|
||||
exStyle |= WS_EX_DLGMODALFRAME;
|
||||
break;
|
||||
|
||||
case ObjectType::PopupType:
|
||||
className = L"Popup " + std::to_wstring(++d_ptr->windowId);
|
||||
style |= WS_POPUP;
|
||||
exStyle |= WS_EX_TOOLWINDOW | WS_EX_LAYERED;
|
||||
break;
|
||||
|
||||
case ObjectType::WidgetType:
|
||||
default:
|
||||
className = L"Widget " + std::to_wstring(++d_ptr->windowId);
|
||||
style |= WS_CHILD;
|
||||
break;
|
||||
}
|
||||
|
||||
// if (wgt->parent()) {
|
||||
// if (wgt->parentWidget()->isCreated()) {
|
||||
// d_ptr->registerClass(className.c_str(), hInstance);
|
||||
// wgt->m_hWnd = CreateWindowEx(exStyle, className.c_str(), wgt->title().c_str(), style, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hWndParent, NULL, hInstance, NULL);
|
||||
// SetWindowLongPtr(wgt->m_hWnd, GWLP_USERDATA, (LONG_PTR)wgt);
|
||||
// } else {
|
||||
// wgt->connectOnCreate([=]() {
|
||||
// wgt->m_hWnd = CreateWindowEx(exStyle, className.c_str(), wgt->title().c_str(), style, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hWndParent, NULL, hInstance, NULL);
|
||||
// SetWindowLongPtr(wgt->m_hWnd, GWLP_USERDATA, (LONG_PTR)wgt);
|
||||
// });
|
||||
// }
|
||||
// } else {
|
||||
d_ptr->registerClass(className.c_str(), d_ptr->hInstance);
|
||||
CreateWindowEx(exStyle, className.c_str(), wgt->title().c_str(), style, rc.x, rc.y, rc.width, rc.height,
|
||||
hWndParent, NULL, d_ptr->hInstance, (LPVOID)wgt);
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,34 @@
|
||||
#ifndef APPLICATION_H
|
||||
#define APPLICATION_H
|
||||
|
||||
#include "object.h"
|
||||
#include "common.h"
|
||||
#include <Windows.h>
|
||||
|
||||
|
||||
class Widget;
|
||||
class Application : public Object
|
||||
{
|
||||
public:
|
||||
Application(HINSTANCE hInstance, PWSTR cmdline, int cmdshow);
|
||||
Application(const Application&) = delete;
|
||||
~Application();
|
||||
|
||||
Application& operator=(const Application&) = delete;
|
||||
static Application *instance();
|
||||
HINSTANCE moduleHandle();
|
||||
void setLayoutDirection(LayoutDirection);
|
||||
|
||||
int exec();
|
||||
void exit(int);
|
||||
|
||||
private:
|
||||
Application();
|
||||
friend class Widget;
|
||||
void registerWidget(Widget*, ObjectType, const Rect &rc);
|
||||
class ApplicationPrivate;
|
||||
ApplicationPrivate *d_ptr;
|
||||
static Application *inst;
|
||||
};
|
||||
|
||||
#endif // APPLICATION_H
|
||||
@ -0,0 +1,79 @@
|
||||
#include "baseutils.h"
|
||||
|
||||
|
||||
static int getLuma(COLORREF color)
|
||||
{
|
||||
return int(0.299 * GetRValue(color) + 0.587 * GetGValue(color) + 0.114 * GetBValue(color));
|
||||
}
|
||||
|
||||
Utils::WinVer Utils::getWinVersion()
|
||||
{
|
||||
static WinVer winVer = WinVer::Undef;
|
||||
if (winVer == WinVer::Undef) {
|
||||
if (HMODULE module = GetModuleHandleA("ntdll")) {
|
||||
NTSTATUS(WINAPI *RtlGetVersion)(LPOSVERSIONINFOEXW);
|
||||
*(FARPROC*)&RtlGetVersion = GetProcAddress(module, "RtlGetVersion");
|
||||
if (RtlGetVersion) {
|
||||
OSVERSIONINFOEXW os = {0};
|
||||
os.dwOSVersionInfoSize = sizeof(os);
|
||||
RtlGetVersion(&os);
|
||||
#define MjrVer os.dwMajorVersion
|
||||
#define MinVer os.dwMinorVersion
|
||||
#define BldVer os.dwBuildNumber
|
||||
winVer = MjrVer == 5L && (MinVer == 1L || MinVer == 2L) ? WinVer::WinXP :
|
||||
MjrVer == 6L && MinVer == 0L ? WinVer::WinVista :
|
||||
MjrVer == 6L && MinVer == 1L ? WinVer::Win7 :
|
||||
MjrVer == 6L && MinVer == 2L ? WinVer::Win8 :
|
||||
MjrVer == 6L && MinVer == 3L ? WinVer::Win8_1 :
|
||||
MjrVer == 10L && MinVer == 0L && BldVer < 22000 ? WinVer::Win10 :
|
||||
MjrVer == 10L && MinVer == 0L && BldVer >= 22000 ? WinVer::Win11 :
|
||||
MjrVer == 10L && MinVer > 0L ? WinVer::Win11 :
|
||||
MjrVer > 10L ? WinVer::Win11 : WinVer::Undef;
|
||||
}
|
||||
}
|
||||
}
|
||||
return winVer;
|
||||
}
|
||||
|
||||
COLORREF Utils::getColorizationColor(bool isActive, COLORREF topColor)
|
||||
{
|
||||
HKEY hKey;
|
||||
DWORD dwValue = 0;
|
||||
if (RegOpenKeyEx(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\DWM", 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
|
||||
DWORD dwType = REG_DWORD;
|
||||
DWORD dwSize = sizeof(DWORD);
|
||||
if (RegQueryValueEx(hKey, L"ColorPrevalence", nullptr, &dwType, (LPBYTE)&dwValue, &dwSize) == ERROR_SUCCESS) {
|
||||
}
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
if (isActive && dwValue != 0) {
|
||||
DWORD dwcolor = 0;
|
||||
BOOL opaque = TRUE;
|
||||
HRESULT(WINAPI *DwmGetColorizationColor)(DWORD*, BOOL*) = NULL;
|
||||
if (HMODULE module = LoadLibrary(L"dwmapi")) {
|
||||
*(FARPROC*)&DwmGetColorizationColor = GetProcAddress(module, "DwmGetColorizationColor");
|
||||
if (DwmGetColorizationColor && !SUCCEEDED(DwmGetColorizationColor(&dwcolor, &opaque))) {
|
||||
dwcolor = 0;
|
||||
}
|
||||
FreeLibrary(module);
|
||||
if (dwcolor)
|
||||
return RGB((dwcolor & 0xff0000) >> 16, (dwcolor & 0xff00) >> 8, dwcolor & 0xff);
|
||||
}
|
||||
}
|
||||
#define BORDER_ACTIVE_DARK RGB(0x2a, 0x2a, 0x2a) // Dark theme
|
||||
#define BORDER_INACTIVE_DARK RGB(0x3a, 0x3a, 0x3a)
|
||||
#define BORDER_ACTIVE_LIGHT_V1 RGB(0x58, 0x58, 0x58) // Light theme and colored background
|
||||
#define BORDER_ACTIVE_LIGHT_V2 RGB(0x77, 0x77, 0x77) // Light theme and white background
|
||||
#define BORDER_INACTIVE_LIGHT_V1 RGB(0x60, 0x60, 0x60)
|
||||
#define BORDER_INACTIVE_LIGHT_V2 RGB(0xaa, 0xaa, 0xaa)
|
||||
int luma = getLuma(topColor);
|
||||
COLORREF color = luma < 85 ? (isActive ? BORDER_ACTIVE_DARK : BORDER_INACTIVE_DARK) :
|
||||
luma < 170 ? (isActive ? BORDER_ACTIVE_LIGHT_V1 : BORDER_INACTIVE_LIGHT_V1) :
|
||||
(isActive ? BORDER_ACTIVE_LIGHT_V2 : BORDER_INACTIVE_LIGHT_V2);
|
||||
return color;
|
||||
}
|
||||
|
||||
bool Utils::isColorDark(COLORREF color)
|
||||
{
|
||||
return int(0.299 * GetRValue(color) + 0.587 * GetGValue(color) + 0.114 * GetBValue(color)) < 128;
|
||||
}
|
||||
17
win-linux/extras/online-installer/src/uiclasses/baseutils.h
Normal file
17
win-linux/extras/online-installer/src/uiclasses/baseutils.h
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef BASEUTILS_H
|
||||
#define BASEUTILS_H
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
|
||||
namespace Utils
|
||||
{
|
||||
enum WinVer : BYTE {
|
||||
Undef, WinXP, WinVista, Win7, Win8, Win8_1, Win10, Win11
|
||||
};
|
||||
WinVer getWinVersion();
|
||||
bool isColorDark(COLORREF color);
|
||||
COLORREF getColorizationColor(bool isActive = true, COLORREF topColor = 0x00ffffff);
|
||||
};
|
||||
|
||||
#endif // BASEUTILS_H
|
||||
211
win-linux/extras/online-installer/src/uiclasses/boxlayout.cpp
Normal file
211
win-linux/extras/online-installer/src/uiclasses/boxlayout.cpp
Normal file
@ -0,0 +1,211 @@
|
||||
#include "boxlayout.h"
|
||||
#include "widget.h"
|
||||
#include <cmath>
|
||||
|
||||
|
||||
BoxLayout::BoxLayout(Direction direction) :
|
||||
m_direction(direction)
|
||||
{
|
||||
m_margins = Margins(6,6,6,6);
|
||||
m_spacing = 6;
|
||||
}
|
||||
|
||||
BoxLayout::~BoxLayout()
|
||||
{
|
||||
for (auto it = m_destroy_conn.begin(); it != m_destroy_conn.end(); it++)
|
||||
it->first->disconnect(it->second);
|
||||
}
|
||||
|
||||
void BoxLayout::addWidget(Widget *wgt)
|
||||
{
|
||||
m_widgets.push_back(wgt);
|
||||
// int destroy_conn = wgt->onAboutToDestroy([=]() {
|
||||
// auto it = std::find(m_widgets.begin(), m_widgets.end(), wgt);
|
||||
// if (it != m_widgets.end())
|
||||
// m_widgets.erase(it);
|
||||
|
||||
// auto it_conn = m_destroy_conn.find(wgt);
|
||||
// if (it_conn != m_destroy_conn.end())
|
||||
// m_destroy_conn.erase(it_conn);
|
||||
// });
|
||||
// m_destroy_conn[wgt] = destroy_conn;
|
||||
}
|
||||
|
||||
void BoxLayout::setContentMargins(int left, int top, int right, int bottom)
|
||||
{
|
||||
m_margins = Margins(left, top, right, bottom);
|
||||
}
|
||||
|
||||
void BoxLayout::setSpacing(int spacing)
|
||||
{
|
||||
m_spacing = spacing;
|
||||
}
|
||||
|
||||
void BoxLayout::onResize(int w, int h)
|
||||
{
|
||||
int amount = m_widgets.size();
|
||||
if (amount > 0) {
|
||||
int x = m_margins.left;
|
||||
int y = m_margins.top;
|
||||
int sum_width = w - (m_margins.right + m_margins.left);
|
||||
int sum_height = h - (m_margins.bottom + m_margins.top);
|
||||
int num_fixed = 0;
|
||||
int sum_fixed_width_or_height = 0;
|
||||
int last_expanding = -1;
|
||||
if (m_direction == Horizontal) {
|
||||
sum_width -= (amount - 1) * m_spacing;
|
||||
for (int i = 0; i < amount; i++) {
|
||||
Widget::SizeBehavior sb = (Widget::SizeBehavior)m_widgets[i]->property(Widget::HSizeBehavior);
|
||||
if (sb == Widget::SizeBehavior::Fixed) {
|
||||
int _w = 0, _h = 0;
|
||||
m_widgets[i]->size(&_w, &_h);
|
||||
sum_fixed_width_or_height += _w;
|
||||
++num_fixed;
|
||||
} else
|
||||
if (sb == Widget::SizeBehavior::Expanding) {
|
||||
last_expanding = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (num_fixed != 0 && last_expanding != -1) {
|
||||
int sep_width = (int)std::round((float)(sum_width - sum_fixed_width_or_height)/(amount - num_fixed));
|
||||
for (int i = 0; i < amount; i++) {
|
||||
if (i == last_expanding)
|
||||
sep_width = (sum_width - sum_fixed_width_or_height) - (amount - num_fixed - 1)*sep_width;
|
||||
int _w = 0, _h = 0;
|
||||
m_widgets[i]->size(&_w, &_h);
|
||||
Widget::SizeBehavior hsb = (Widget::SizeBehavior)m_widgets[i]->property(Widget::HSizeBehavior);
|
||||
Widget::SizeBehavior vsb = (Widget::SizeBehavior)m_widgets[i]->property(Widget::VSizeBehavior);
|
||||
if (hsb == Widget::SizeBehavior::Fixed) {
|
||||
if (vsb == Widget::SizeBehavior::Fixed) {
|
||||
m_widgets[i]->move(x, y);
|
||||
} else
|
||||
if (vsb == Widget::SizeBehavior::Expanding) {
|
||||
m_widgets[i]->setGeometry(x, y, _w, sum_height);
|
||||
}
|
||||
x += _w + m_spacing;
|
||||
|
||||
} else
|
||||
if (hsb == Widget::SizeBehavior::Expanding) {
|
||||
if (vsb == Widget::SizeBehavior::Fixed) {
|
||||
m_widgets[i]->setGeometry(x, y, sep_width, _h);
|
||||
} else
|
||||
if (vsb == Widget::SizeBehavior::Expanding) {
|
||||
m_widgets[i]->setGeometry(x, y, sep_width, sum_height);
|
||||
}
|
||||
x += sep_width + m_spacing;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
int sep_width = (int)std::round((float)sum_width/amount);
|
||||
for (int i = 0; i < amount; i++) {
|
||||
if (i == amount - 1)
|
||||
sep_width = sum_width - i*sep_width;
|
||||
Widget::SizeBehavior hsb = (Widget::SizeBehavior)m_widgets[i]->property(Widget::HSizeBehavior);
|
||||
Widget::SizeBehavior vsb = (Widget::SizeBehavior)m_widgets[i]->property(Widget::VSizeBehavior);
|
||||
if (hsb == Widget::SizeBehavior::Fixed) {
|
||||
if (vsb == Widget::SizeBehavior::Fixed) {
|
||||
m_widgets[i]->move(x, y);
|
||||
} else
|
||||
if (vsb == Widget::SizeBehavior::Expanding) {
|
||||
int _w = 0, _h = 0;
|
||||
m_widgets[i]->size(&_w, &_h);
|
||||
m_widgets[i]->setGeometry(x, y, _w, sum_height);
|
||||
}
|
||||
|
||||
} else
|
||||
if (hsb == Widget::SizeBehavior::Expanding) {
|
||||
if (vsb == Widget::SizeBehavior::Fixed) {
|
||||
int _w = 0, _h = 0;
|
||||
m_widgets[i]->size(&_w, &_h);
|
||||
m_widgets[i]->setGeometry(x, y, sep_width, _h);
|
||||
} else
|
||||
if (vsb == Widget::SizeBehavior::Expanding) {
|
||||
m_widgets[i]->setGeometry(x, y, sep_width, sum_height);
|
||||
}
|
||||
}
|
||||
x += sep_width + m_spacing;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
sum_height -= (amount - 1) * m_spacing;
|
||||
for (int i = 0; i < amount; i++) {
|
||||
Widget::SizeBehavior sb = (Widget::SizeBehavior)m_widgets[i]->property(Widget::VSizeBehavior);
|
||||
if (sb == Widget::SizeBehavior::Fixed) {
|
||||
int _w = 0, _h = 0;
|
||||
m_widgets[i]->size(&_w, &_h);
|
||||
sum_fixed_width_or_height += _h;
|
||||
++num_fixed;
|
||||
} else
|
||||
if (sb == Widget::SizeBehavior::Expanding) {
|
||||
last_expanding = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (num_fixed != 0 && last_expanding != -1) {
|
||||
int sep_height = (int)std::round((float)(sum_height - sum_fixed_width_or_height)/(amount - num_fixed));
|
||||
for (int i = 0; i < amount; i++) {
|
||||
if (i == last_expanding)
|
||||
sep_height = (sum_height - sum_fixed_width_or_height) - (amount - num_fixed - 1)*sep_height;
|
||||
int _w = 0, _h = 0;
|
||||
m_widgets[i]->size(&_w, &_h);
|
||||
Widget::SizeBehavior hsb = (Widget::SizeBehavior)m_widgets[i]->property(Widget::HSizeBehavior);
|
||||
Widget::SizeBehavior vsb = (Widget::SizeBehavior)m_widgets[i]->property(Widget::VSizeBehavior);
|
||||
if (vsb == Widget::SizeBehavior::Fixed) {
|
||||
if (hsb == Widget::SizeBehavior::Fixed) {
|
||||
m_widgets[i]->move(x, y);
|
||||
} else
|
||||
if (hsb == Widget::SizeBehavior::Expanding) {
|
||||
m_widgets[i]->setGeometry(x, y, sum_width, _h);
|
||||
}
|
||||
y += _h + m_spacing;
|
||||
|
||||
} else
|
||||
if (vsb == Widget::SizeBehavior::Expanding) {
|
||||
if (hsb == Widget::SizeBehavior::Fixed) {
|
||||
m_widgets[i]->setGeometry(x, y, _w, sep_height);
|
||||
} else
|
||||
if (hsb == Widget::SizeBehavior::Expanding) {
|
||||
m_widgets[i]->setGeometry(x, y, sum_width, sep_height);
|
||||
}
|
||||
y += sep_height + m_spacing;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
int sep_height = (int)std::round((float)sum_height/amount);
|
||||
for (int i = 0; i < amount; i++) {
|
||||
if (i == amount - 1)
|
||||
sep_height = sum_height - i*sep_height;
|
||||
Widget::SizeBehavior hsb = (Widget::SizeBehavior)m_widgets[i]->property(Widget::HSizeBehavior);
|
||||
Widget::SizeBehavior vsb = (Widget::SizeBehavior)m_widgets[i]->property(Widget::VSizeBehavior);
|
||||
if (vsb == Widget::SizeBehavior::Fixed) {
|
||||
if (hsb == Widget::SizeBehavior::Fixed) {
|
||||
m_widgets[i]->move(x, y);
|
||||
} else
|
||||
if (hsb == Widget::SizeBehavior::Expanding) {
|
||||
int _w = 0, _h = 0;
|
||||
m_widgets[i]->size(&_w, &_h);
|
||||
m_widgets[i]->setGeometry(x, y, sum_width, _h);
|
||||
}
|
||||
|
||||
} else
|
||||
if (vsb == Widget::SizeBehavior::Expanding) {
|
||||
if (hsb == Widget::SizeBehavior::Fixed) {
|
||||
int _w = 0, _h = 0;
|
||||
m_widgets[i]->size(&_w, &_h);
|
||||
m_widgets[i]->setGeometry(x, y, _w, sep_height);
|
||||
} else
|
||||
if (hsb == Widget::SizeBehavior::Expanding) {
|
||||
m_widgets[i]->setGeometry(x, y, sum_width, sep_height);
|
||||
}
|
||||
}
|
||||
y += sep_height + m_spacing;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
33
win-linux/extras/online-installer/src/uiclasses/boxlayout.h
Normal file
33
win-linux/extras/online-installer/src/uiclasses/boxlayout.h
Normal file
@ -0,0 +1,33 @@
|
||||
#ifndef BOXLAYOUT_H
|
||||
#define BOXLAYOUT_H
|
||||
|
||||
#include "layout.h"
|
||||
#include <unordered_map>
|
||||
|
||||
|
||||
class BoxLayout : public Layout
|
||||
{
|
||||
public:
|
||||
enum Direction : unsigned char {
|
||||
Horizontal,
|
||||
Vertical
|
||||
};
|
||||
BoxLayout(Direction);
|
||||
~BoxLayout();
|
||||
|
||||
virtual void addWidget(Widget *wgt) override;
|
||||
virtual void setContentMargins(int, int, int, int);
|
||||
virtual void setSpacing(int);
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
virtual void onResize(int w, int h) override;
|
||||
std::unordered_map<Widget*, int> m_destroy_conn;
|
||||
std::vector<Widget*> m_widgets;
|
||||
Direction m_direction;
|
||||
int m_spacing;
|
||||
int m_total_fixed_size;
|
||||
};
|
||||
|
||||
#endif // BOXLAYOUT_H
|
||||
197
win-linux/extras/online-installer/src/uiclasses/button.cpp
Normal file
197
win-linux/extras/online-installer/src/uiclasses/button.cpp
Normal file
@ -0,0 +1,197 @@
|
||||
#include "button.h"
|
||||
#include "baseutils.h"
|
||||
#include "drawningengine.h"
|
||||
#include "metrics.h"
|
||||
#include "palette.h"
|
||||
#include <windowsx.h>
|
||||
|
||||
|
||||
static bool isArrangingAllowed() {
|
||||
BOOL arranging = FALSE;
|
||||
SystemParametersInfoA(SPI_GETWINARRANGING, 0, &arranging, 0);
|
||||
return (arranging == TRUE);
|
||||
}
|
||||
|
||||
Button::Button(Widget *parent, const std::wstring &text) :
|
||||
AbstractButton(parent, text),
|
||||
m_hIcon(nullptr),
|
||||
m_hMetaFile(nullptr),
|
||||
m_stockIcon(StockIcon::None),
|
||||
supportSnapLayouts(false),
|
||||
snapLayoutAllowed(false),
|
||||
snapLayoutTimerIsSet(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Button::~Button()
|
||||
{
|
||||
if (m_hIcon) {
|
||||
DestroyIcon(m_hIcon);
|
||||
m_hIcon = nullptr;
|
||||
}
|
||||
if (m_hMetaFile) {
|
||||
//delete m_hMetaFile;
|
||||
DeleteEnhMetaFile(m_hMetaFile);
|
||||
m_hMetaFile = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void Button::setIcon(const std::wstring &path, int w, int h)
|
||||
{
|
||||
if (m_hIcon) {
|
||||
DestroyIcon(m_hIcon);
|
||||
m_hIcon = nullptr;
|
||||
}
|
||||
metrics()->setMetrics(Metrics::IconWidth, w);
|
||||
metrics()->setMetrics(Metrics::IconHeight, h);
|
||||
m_hIcon = (HICON)LoadImage(NULL, path.c_str(), IMAGE_ICON, w, h, LR_LOADFROMFILE | LR_DEFAULTCOLOR | LR_SHARED);
|
||||
update();
|
||||
}
|
||||
|
||||
void Button::setIcon(int id, int w, int h)
|
||||
{
|
||||
if (m_hIcon) {
|
||||
DestroyIcon(m_hIcon);
|
||||
m_hIcon = nullptr;
|
||||
}
|
||||
metrics()->setMetrics(Metrics::IconWidth, w);
|
||||
metrics()->setMetrics(Metrics::IconHeight, h);
|
||||
HMODULE hInst = GetModuleHandle(NULL);
|
||||
m_hIcon = (HICON)LoadImage(hInst, MAKEINTRESOURCE(id), IMAGE_ICON, w, h, LR_COPYFROMRESOURCE | LR_DEFAULTCOLOR | LR_SHARED);
|
||||
update();
|
||||
}
|
||||
|
||||
void Button::setEMFIcon(const std::wstring &path, int w, int h)
|
||||
{
|
||||
if (m_hMetaFile) {
|
||||
//delete m_hMetaFile;
|
||||
DeleteEnhMetaFile(m_hMetaFile);
|
||||
m_hMetaFile = nullptr;
|
||||
}
|
||||
metrics()->setMetrics(Metrics::IconWidth, w);
|
||||
metrics()->setMetrics(Metrics::IconHeight, h);
|
||||
m_hMetaFile = GetEnhMetaFile(path.c_str());
|
||||
//m_hMetaFile = new Metafile(path.c_str());
|
||||
update();
|
||||
}
|
||||
|
||||
void Button::setEMFIcon(int id, int w, int h)
|
||||
{
|
||||
if (m_hMetaFile) {
|
||||
//delete m_hMetaFile;
|
||||
DeleteEnhMetaFile(m_hMetaFile);
|
||||
m_hMetaFile = nullptr;
|
||||
}
|
||||
metrics()->setMetrics(Metrics::IconWidth, w);
|
||||
metrics()->setMetrics(Metrics::IconHeight, h);
|
||||
HMODULE hInst = GetModuleHandle(NULL);
|
||||
if (HRSRC hRes = FindResource(hInst, MAKEINTRESOURCE(id), RT_RCDATA)) {
|
||||
if (HGLOBAL hResData = LoadResource(hInst, hRes)) {
|
||||
if (LPVOID pData = LockResource(hResData)) {
|
||||
DWORD dataSize = SizeofResource(hInst, hRes);
|
||||
if (dataSize > 0)
|
||||
m_hMetaFile = SetEnhMetaFileBits(dataSize, (BYTE*)pData);
|
||||
}
|
||||
FreeResource(hResData);
|
||||
}
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
void Button::setIconSize(int w, int h)
|
||||
{
|
||||
metrics()->setMetrics(Metrics::IconWidth, w);
|
||||
metrics()->setMetrics(Metrics::IconHeight, h);
|
||||
update();
|
||||
}
|
||||
|
||||
void Button::setSupportSnapLayouts()
|
||||
{
|
||||
if (Utils::getWinVersion() > Utils::WinVer::Win10) {
|
||||
snapLayoutAllowed = isArrangingAllowed();
|
||||
supportSnapLayouts = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Button::setStockIcon(StockIcon stockIcon)
|
||||
{
|
||||
m_stockIcon = stockIcon;
|
||||
update();
|
||||
}
|
||||
|
||||
bool Button::event(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT *result)
|
||||
{
|
||||
switch (msg) {
|
||||
case WM_PAINT: {
|
||||
RECT rc;
|
||||
GetClientRect(m_hWnd, &rc);
|
||||
|
||||
engine()->Begin(this, m_hWnd, &rc);
|
||||
engine()->FillBackground();
|
||||
// engine()->DrawRoundedRect();
|
||||
if (metrics()->value(Metrics::BorderWidth) != 0)
|
||||
engine()->DrawBorder();
|
||||
if (m_hIcon)
|
||||
engine()->DrawIcon(m_hIcon);
|
||||
if (m_hMetaFile)
|
||||
engine()->DrawEmfIcon(m_hMetaFile);
|
||||
if (!m_text.empty())
|
||||
engine()->DrawText(rc, m_text);
|
||||
|
||||
if (m_stockIcon == StockIcon::CloseIcon)
|
||||
engine()->DrawStockCloseIcon();
|
||||
else
|
||||
if (m_stockIcon == StockIcon::RestoreIcon)
|
||||
engine()->DrawStockRestoreIcon();
|
||||
else
|
||||
if (m_stockIcon == StockIcon::MinimizeIcon)
|
||||
engine()->DrawStockMinimizeIcon();
|
||||
else
|
||||
if (m_stockIcon == StockIcon::MaximizeIcon)
|
||||
engine()->DrawStockMaximizeIcon();
|
||||
|
||||
engine()->End();
|
||||
|
||||
*result = FALSE;
|
||||
return true;
|
||||
}
|
||||
|
||||
case WM_NCHITTEST: {
|
||||
if (supportSnapLayouts && snapLayoutAllowed) {
|
||||
if (!snapLayoutTimerIsSet) {
|
||||
snapLayoutTimerIsSet = true;
|
||||
palette()->setCurrentState(Palette::Hover);
|
||||
SetTimer(m_hWnd, SNAP_LAYOUTS_TIMER_ID, 100, NULL);
|
||||
repaint();
|
||||
}
|
||||
*result = HTMAXBUTTON;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
case WM_TIMER: {
|
||||
if (wParam == SNAP_LAYOUTS_TIMER_ID) {
|
||||
if (!underMouse()) {
|
||||
KillTimer(m_hWnd, wParam);
|
||||
snapLayoutTimerIsSet = false;
|
||||
palette()->setCurrentState(Palette::Normal);
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_CAPTURECHANGED: {
|
||||
if (Utils::getWinVersion() > Utils::WinVer::Win10) {
|
||||
click();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return AbstractButton::event(msg, wParam, lParam, result);
|
||||
}
|
||||
45
win-linux/extras/online-installer/src/uiclasses/button.h
Normal file
45
win-linux/extras/online-installer/src/uiclasses/button.h
Normal file
@ -0,0 +1,45 @@
|
||||
#ifndef BUTTON_H
|
||||
#define BUTTON_H
|
||||
|
||||
#include "abstractbutton.h"
|
||||
#include <gdiplus.h>
|
||||
|
||||
|
||||
class Button : public AbstractButton
|
||||
{
|
||||
public:
|
||||
Button(Widget *parent = nullptr, const std::wstring &text = L"");
|
||||
virtual ~Button();
|
||||
|
||||
enum StockIcon : BYTE {
|
||||
None,
|
||||
MinimizeIcon,
|
||||
MaximizeIcon,
|
||||
RestoreIcon,
|
||||
CloseIcon
|
||||
};
|
||||
|
||||
void setIcon(const std::wstring &path, int w, int h);
|
||||
void setIcon(int id, int w, int h);
|
||||
void setEMFIcon(const std::wstring &path, int w, int h);
|
||||
void setEMFIcon(int id, int w, int h);
|
||||
void setIconSize(int w, int h);
|
||||
void setSupportSnapLayouts();
|
||||
void setStockIcon(StockIcon stockIcon);
|
||||
|
||||
/* callback */
|
||||
|
||||
protected:
|
||||
virtual bool event(UINT, WPARAM, LPARAM, LRESULT*) override;
|
||||
|
||||
private:
|
||||
HICON m_hIcon;
|
||||
HENHMETAFILE m_hMetaFile;
|
||||
//Gdiplus::Metafile *m_hMetaFile;
|
||||
int m_stockIcon;
|
||||
bool supportSnapLayouts,
|
||||
snapLayoutAllowed;
|
||||
bool snapLayoutTimerIsSet;
|
||||
};
|
||||
|
||||
#endif // BUTTON_H
|
||||
117
win-linux/extras/online-installer/src/uiclasses/caption.cpp
Normal file
117
win-linux/extras/online-installer/src/uiclasses/caption.cpp
Normal file
@ -0,0 +1,117 @@
|
||||
#include "caption.h"
|
||||
#include "baseutils.h"
|
||||
#include "metrics.h"
|
||||
#include "drawningengine.h"
|
||||
#include <windowsx.h>
|
||||
|
||||
#define RESIZE_AREA_PART 0.14
|
||||
|
||||
|
||||
Caption::Caption(Widget *parent) :
|
||||
Label(parent),
|
||||
m_isResizingAvailable(true)
|
||||
{
|
||||
m_hwndRoot = GetAncestor(m_hWnd, GA_ROOT);
|
||||
}
|
||||
|
||||
Caption::~Caption()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Caption::setResizingAvailable(bool isResizingAvailable)
|
||||
{
|
||||
m_isResizingAvailable = isResizingAvailable;
|
||||
}
|
||||
|
||||
bool Caption::event(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT *result)
|
||||
{
|
||||
switch (msg) {
|
||||
case WM_PAINT: {
|
||||
RECT rc;
|
||||
GetClientRect(m_hWnd, &rc);
|
||||
|
||||
engine()->Begin(this, m_hWnd, &rc);
|
||||
engine()->FillBackground();
|
||||
// DrawRoundedRect();
|
||||
if (metrics()->value(Metrics::BorderWidth) != 0)
|
||||
engine()->DrawBorder();
|
||||
if (!m_title.empty())
|
||||
engine()->DrawText(rc, m_title);
|
||||
|
||||
engine()->End();
|
||||
|
||||
*result = FALSE;
|
||||
return true;
|
||||
}
|
||||
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_NCLBUTTONDOWN: {
|
||||
if (isResizingAvailable()) {
|
||||
int y = GET_Y_LPARAM(lParam);
|
||||
if (HCURSOR hCursor = LoadCursor(NULL, isPointInResizeArea(y) ? IDC_SIZENS : IDC_ARROW))
|
||||
SetCursor(hCursor);
|
||||
}
|
||||
if (postMsg(WM_NCLBUTTONDOWN)) {
|
||||
*result = TRUE;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
case WM_LBUTTONDBLCLK: {
|
||||
if (postMsg(WM_NCLBUTTONDBLCLK)) {
|
||||
*result = TRUE;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
case WM_MOUSEMOVE:
|
||||
case WM_NCMOUSEMOVE: {
|
||||
if (isResizingAvailable()) {
|
||||
int y = GET_Y_LPARAM(lParam);
|
||||
if (HCURSOR hCursor = LoadCursor(NULL, isPointInResizeArea(y) ? IDC_SIZENS : IDC_ARROW))
|
||||
SetCursor(hCursor);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_MOUSEENTER: {
|
||||
//palette()->setCurrentState(Palette::Hover);
|
||||
repaint();
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_MOUSELEAVE: {
|
||||
//palette()->setCurrentState(Palette::Normal);
|
||||
repaint();
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return Widget::event(msg, wParam, lParam, result);
|
||||
}
|
||||
|
||||
bool Caption::isResizingAvailable()
|
||||
{
|
||||
return m_isResizingAvailable && Utils::getWinVersion() >= Utils::WinVer::Win10 && !IsZoomed(m_hwndRoot);
|
||||
}
|
||||
|
||||
bool Caption::isPointInResizeArea(int posY)
|
||||
{
|
||||
int w = 0, h = 0;
|
||||
size(&w, &h);
|
||||
return posY <= RESIZE_AREA_PART * h;
|
||||
}
|
||||
|
||||
bool Caption::postMsg(DWORD cmd) {
|
||||
POINT pt;
|
||||
::GetCursorPos(&pt);
|
||||
ScreenToClient(m_hWnd, &pt);
|
||||
::ReleaseCapture();
|
||||
::PostMessage(m_hwndRoot, cmd, isResizingAvailable() && isPointInResizeArea(pt.y) ? HTTOP : HTCAPTION, POINTTOPOINTS(pt));
|
||||
return true;
|
||||
}
|
||||
30
win-linux/extras/online-installer/src/uiclasses/caption.h
Normal file
30
win-linux/extras/online-installer/src/uiclasses/caption.h
Normal file
@ -0,0 +1,30 @@
|
||||
#ifndef CAPTION_H
|
||||
#define CAPTION_H
|
||||
|
||||
#include "label.h"
|
||||
#include <Windows.h>
|
||||
|
||||
|
||||
class Caption : public Label
|
||||
{
|
||||
public:
|
||||
Caption(Widget *parent = nullptr);
|
||||
~Caption();
|
||||
|
||||
void setResizingAvailable(bool);
|
||||
|
||||
/* callback */
|
||||
|
||||
protected:
|
||||
virtual bool event(UINT, WPARAM, LPARAM, LRESULT*) override;
|
||||
|
||||
private:
|
||||
bool isResizingAvailable();
|
||||
bool isPointInResizeArea(int posY);
|
||||
bool postMsg(DWORD cmd);
|
||||
|
||||
HWND m_hwndRoot;
|
||||
bool m_isResizingAvailable;
|
||||
};
|
||||
|
||||
#endif // CAPTION_H
|
||||
59
win-linux/extras/online-installer/src/uiclasses/checkbox.cpp
Normal file
59
win-linux/extras/online-installer/src/uiclasses/checkbox.cpp
Normal file
@ -0,0 +1,59 @@
|
||||
#include "checkbox.h"
|
||||
#include "drawningengine.h"
|
||||
#include "metrics.h"
|
||||
#include <windowsx.h>
|
||||
|
||||
|
||||
CheckBox::CheckBox(Widget *parent, const std::wstring &text) :
|
||||
AbstractButton(parent, text),
|
||||
m_checked(false)
|
||||
{
|
||||
metrics()->setMetrics(Metrics::TextAlignment, Metrics::AlignHLeft | Metrics::AlignVCenter);
|
||||
}
|
||||
|
||||
CheckBox::~CheckBox()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CheckBox::setChecked(bool checked)
|
||||
{
|
||||
m_checked = checked;
|
||||
update();
|
||||
}
|
||||
|
||||
bool CheckBox::isChecked()
|
||||
{
|
||||
return m_checked;
|
||||
}
|
||||
|
||||
bool CheckBox::event(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT *result)
|
||||
{
|
||||
switch (msg) {
|
||||
case WM_PAINT: {
|
||||
RECT rc;
|
||||
GetClientRect(m_hWnd, &rc);
|
||||
|
||||
engine()->Begin(this, m_hWnd, &rc);
|
||||
engine()->DrawCheckBox(m_text, m_checked);
|
||||
if (metrics()->value(Metrics::BorderWidth) != 0)
|
||||
engine()->DrawBorder();
|
||||
|
||||
engine()->End();
|
||||
|
||||
*result = FALSE;
|
||||
return true;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return AbstractButton::event(msg, wParam, lParam, result);
|
||||
}
|
||||
|
||||
void CheckBox::click()
|
||||
{
|
||||
m_checked = !m_checked;
|
||||
update();
|
||||
AbstractButton::click();
|
||||
}
|
||||
26
win-linux/extras/online-installer/src/uiclasses/checkbox.h
Normal file
26
win-linux/extras/online-installer/src/uiclasses/checkbox.h
Normal file
@ -0,0 +1,26 @@
|
||||
#ifndef CHECKBOX_H
|
||||
#define CHECKBOX_H
|
||||
|
||||
#include "abstractbutton.h"
|
||||
|
||||
|
||||
class CheckBox : public AbstractButton
|
||||
{
|
||||
public:
|
||||
CheckBox(Widget *parent = nullptr, const std::wstring &text = L"");
|
||||
virtual ~CheckBox();
|
||||
|
||||
void setChecked(bool checked);
|
||||
bool isChecked();
|
||||
|
||||
/* callback */
|
||||
|
||||
protected:
|
||||
virtual bool event(UINT, WPARAM, LPARAM, LRESULT*) override;
|
||||
virtual void click() override;
|
||||
|
||||
private:
|
||||
bool m_checked;
|
||||
};
|
||||
|
||||
#endif // CHECKBOX_H
|
||||
81
win-linux/extras/online-installer/src/uiclasses/common.cpp
Normal file
81
win-linux/extras/online-installer/src/uiclasses/common.cpp
Normal file
@ -0,0 +1,81 @@
|
||||
#include "common.h"
|
||||
|
||||
|
||||
Margins::Margins() :
|
||||
left(0), top(0), right(0), bottom(0)
|
||||
{}
|
||||
|
||||
Margins::Margins(int l, int t, int r, int b) :
|
||||
left(l), top(t), right(r), bottom(b)
|
||||
{}
|
||||
|
||||
Margins::Margins(const Margins &mrg)
|
||||
{
|
||||
left = mrg.left;
|
||||
top = mrg.top;
|
||||
right = mrg.right;
|
||||
bottom = mrg.bottom;
|
||||
}
|
||||
|
||||
Margins& Margins::operator=(const Margins &mrg)
|
||||
{
|
||||
if (this == &mrg)
|
||||
return *this;
|
||||
left = mrg.left;
|
||||
top = mrg.top;
|
||||
right = mrg.right;
|
||||
bottom = mrg.bottom;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
Rect::Rect() :
|
||||
x(0), y(0), width(0), height(0)
|
||||
{}
|
||||
|
||||
Rect::Rect(int x, int y, int w, int h) :
|
||||
x(x), y(y), width(w), height(h)
|
||||
{}
|
||||
|
||||
Rect::Rect(const Rect &rc)
|
||||
{
|
||||
x = rc.x;
|
||||
y = rc.y;
|
||||
width = rc.width;
|
||||
height = rc.height;
|
||||
}
|
||||
|
||||
Rect& Rect::operator=(const Rect &rc)
|
||||
{
|
||||
if (this == &rc)
|
||||
return *this;
|
||||
x = rc.x;
|
||||
y = rc.y;
|
||||
width = rc.width;
|
||||
height = rc.height;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
Size::Size() :
|
||||
width(0), height(0)
|
||||
{}
|
||||
|
||||
Size::Size(int w, int h) :
|
||||
width(w), height(h)
|
||||
{}
|
||||
|
||||
Size::Size(const Size &sz)
|
||||
{
|
||||
width = sz.width;
|
||||
height = sz.height;
|
||||
}
|
||||
|
||||
Size& Size::operator=(const Size &sz)
|
||||
{
|
||||
if (this == &sz)
|
||||
return *this;
|
||||
width = sz.width;
|
||||
height = sz.height;
|
||||
return *this;
|
||||
}
|
||||
37
win-linux/extras/online-installer/src/uiclasses/common.h
Normal file
37
win-linux/extras/online-installer/src/uiclasses/common.h
Normal file
@ -0,0 +1,37 @@
|
||||
#ifndef COMMON_H
|
||||
#define COMMON_H
|
||||
|
||||
|
||||
struct Margins {
|
||||
Margins();
|
||||
Margins(int, int, int, int);
|
||||
Margins(const Margins&);
|
||||
Margins& operator=(const Margins&);
|
||||
|
||||
int left, top, right, bottom;
|
||||
};
|
||||
|
||||
struct Rect {
|
||||
Rect();
|
||||
Rect(int, int, int, int);
|
||||
Rect(const Rect &rc);
|
||||
Rect& operator=(const Rect &rc);
|
||||
|
||||
int x, y, width, height;
|
||||
};
|
||||
|
||||
struct Size {
|
||||
Size();
|
||||
Size(int, int);
|
||||
Size(const Size&);
|
||||
Size& operator=(const Size&);
|
||||
|
||||
int width, height;
|
||||
};
|
||||
|
||||
enum LayoutDirection : unsigned char {
|
||||
LeftToRight = 0,
|
||||
RightToLeft
|
||||
};
|
||||
|
||||
#endif // COMMON_H
|
||||
@ -0,0 +1,17 @@
|
||||
#ifndef COMMONDEFINES_H
|
||||
#define COMMONDEFINES_H
|
||||
|
||||
#include <functional>
|
||||
|
||||
#define SNAP_LAYOUTS_TIMER_ID 0x1f000000
|
||||
#define PROGRESS_PULSE_TIMER_ID 0x2f000000
|
||||
|
||||
#define WM_MOUSEENTER (WM_APP + 1)
|
||||
#define WM_INVOKEMETHOD (WM_APP + 2)
|
||||
|
||||
typedef std::function<void(void)> FnVoidVoid;
|
||||
typedef std::function<void(int)> FnVoidInt;
|
||||
typedef std::function<void(int, int)> FnVoidIntInt;
|
||||
typedef std::function<void(bool*)> FnVoidBoolPtr;
|
||||
|
||||
#endif // COMMONDEFINES_H
|
||||
76
win-linux/extras/online-installer/src/uiclasses/dialog.cpp
Normal file
76
win-linux/extras/online-installer/src/uiclasses/dialog.cpp
Normal file
@ -0,0 +1,76 @@
|
||||
#include "dialog.h"
|
||||
#include "metrics.h"
|
||||
#include "palette.h"
|
||||
#include "drawningengine.h"
|
||||
|
||||
|
||||
Dialog::Dialog(Widget *parent, const Rect &rc) :
|
||||
Widget(parent, ObjectType::DialogType, rc)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Dialog::~Dialog()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool Dialog::event(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT *result)
|
||||
{
|
||||
switch (msg) {
|
||||
case WM_SHOWWINDOW: {
|
||||
if (wParam) {
|
||||
if (Widget *parent = parentWidget())
|
||||
EnableWindow(parent->nativeWindowHandle(), FALSE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_PAINT: {
|
||||
RECT rc;
|
||||
GetClientRect(m_hWnd, &rc);
|
||||
|
||||
engine()->Begin(this, m_hWnd);
|
||||
engine()->FillBackground(rc);
|
||||
//engine()->DrawRoundedRect(rc);
|
||||
if (metrics()->value(Metrics::BorderWidth) != 0)
|
||||
engine()->DrawBorder(rc);
|
||||
// if (!m_title.empty())
|
||||
// engine()->DrawText(rc, m_title);
|
||||
|
||||
|
||||
engine()->End();
|
||||
|
||||
*result = FALSE;
|
||||
return true;
|
||||
}
|
||||
|
||||
case WM_MOUSEENTER: {
|
||||
palette()->setCurrentState(Palette::Hover);
|
||||
repaint();
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_NCMOUSELEAVE:
|
||||
case WM_MOUSELEAVE: {
|
||||
palette()->setCurrentState(Palette::Normal);
|
||||
repaint();
|
||||
break;
|
||||
}
|
||||
|
||||
/*case WM_NCHITTEST: {
|
||||
*result = HTCAPTION;
|
||||
return true;
|
||||
}*/
|
||||
|
||||
case WM_CLOSE: {
|
||||
if (Widget *parent = parentWidget())
|
||||
EnableWindow(parent->nativeWindowHandle(), TRUE);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return Widget::event(msg, wParam, lParam, result);
|
||||
}
|
||||
25
win-linux/extras/online-installer/src/uiclasses/dialog.h
Normal file
25
win-linux/extras/online-installer/src/uiclasses/dialog.h
Normal file
@ -0,0 +1,25 @@
|
||||
#ifndef DIALOG_H
|
||||
#define DIALOG_H
|
||||
|
||||
#include "widget.h"
|
||||
#include <Windows.h>
|
||||
|
||||
#define DEFAULT_DLG_RECT Rect(100,100,800,600)
|
||||
|
||||
|
||||
class Dialog : public Widget
|
||||
{
|
||||
public:
|
||||
Dialog(Widget *parent = nullptr, const Rect &rc = DEFAULT_DLG_RECT);
|
||||
virtual ~Dialog();
|
||||
|
||||
/* callback */
|
||||
|
||||
protected:
|
||||
virtual bool event(UINT, WPARAM, LPARAM, LRESULT*) override;
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
#endif // DIALOG_H
|
||||
@ -0,0 +1,33 @@
|
||||
#include "drawingsurface.h"
|
||||
#include "drawningengine.h"
|
||||
#include "metrics.h"
|
||||
#include "palette.h"
|
||||
|
||||
|
||||
DrawningSurface::DrawningSurface() :
|
||||
m_metrics(new Metrics),
|
||||
m_palette(new Palette)
|
||||
{
|
||||
m_engine = DrawingEngine::instance();
|
||||
}
|
||||
|
||||
DrawningSurface::~DrawningSurface()
|
||||
{
|
||||
delete m_palette, m_palette = nullptr;
|
||||
delete m_metrics, m_metrics = nullptr;
|
||||
}
|
||||
|
||||
Metrics *DrawningSurface::metrics()
|
||||
{
|
||||
return m_metrics;
|
||||
}
|
||||
|
||||
Palette *DrawningSurface::palette()
|
||||
{
|
||||
return m_palette;
|
||||
}
|
||||
|
||||
DrawingEngine *DrawningSurface::engine()
|
||||
{
|
||||
return m_engine;
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
#ifndef DRAWNINGSURFACE_H
|
||||
#define DRAWNINGSURFACE_H
|
||||
|
||||
|
||||
class Metrics;
|
||||
class Palette;
|
||||
class DrawingEngine;
|
||||
class DrawningSurface
|
||||
{
|
||||
public:
|
||||
DrawningSurface();
|
||||
virtual ~DrawningSurface();
|
||||
|
||||
Metrics *metrics();
|
||||
Palette *palette();
|
||||
|
||||
protected:
|
||||
DrawingEngine *engine();
|
||||
|
||||
private:
|
||||
Metrics *m_metrics;
|
||||
Palette *m_palette;
|
||||
DrawingEngine *m_engine;
|
||||
};
|
||||
|
||||
#endif // DRAWNINGSURFACE_H
|
||||
@ -0,0 +1,570 @@
|
||||
#include "drawningengine.h"
|
||||
#include "drawingsurface.h"
|
||||
#include "palette.h"
|
||||
#include "metrics.h"
|
||||
#include <gdiplusheaders.h>
|
||||
|
||||
|
||||
static Gdiplus::Color ColorFromColorRef(COLORREF rgb)
|
||||
{
|
||||
Gdiplus::Color color;
|
||||
color.SetFromCOLORREF(rgb);
|
||||
return color;
|
||||
}
|
||||
|
||||
static void RoundedPath(Gdiplus::GraphicsPath &ph, int x, int y, int width, int height, int rad)
|
||||
{
|
||||
ph.AddArc(x, y, rad * 2, rad * 2, 180, 90);
|
||||
ph.AddLine(x + rad, y, x + width - rad, y);
|
||||
ph.AddArc(x + width - rad * 2, y, rad * 2, rad * 2, 270, 90);
|
||||
ph.AddLine(x + width, y + rad, x + width, y + height - rad);
|
||||
ph.AddArc(x + width - rad * 2, y + height - rad * 2, rad * 2, rad * 2, 0, 90);
|
||||
ph.AddLine(x + width - rad, y + height, x + rad, y + height);
|
||||
ph.AddArc(x, y + height - rad * 2, rad * 2, rad * 2, 90, 90);
|
||||
ph.AddLine(x, y + height - rad, x, y + rad);
|
||||
ph.CloseFigure();
|
||||
}
|
||||
|
||||
DrawingEngine::DrawingEngine() :
|
||||
m_ds(nullptr),
|
||||
m_ps(nullptr),
|
||||
m_hwnd(nullptr),
|
||||
m_hdc(nullptr),
|
||||
m_memDC(nullptr),
|
||||
m_memBmp(nullptr),
|
||||
m_oldBmp(nullptr),
|
||||
m_graphics(nullptr)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
DrawingEngine* DrawingEngine::instance()
|
||||
{
|
||||
static DrawingEngine inst;
|
||||
return &inst;
|
||||
}
|
||||
|
||||
DrawingEngine::~DrawingEngine()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
DrawningSurface *DrawingEngine::surface()
|
||||
{
|
||||
return m_ds;
|
||||
}
|
||||
|
||||
void DrawingEngine::Begin(DrawningSurface *ds, HWND hwnd, RECT *rc)
|
||||
{
|
||||
if (m_ds) {
|
||||
printf("Engine is buisy...\n");
|
||||
fflush(stdout);
|
||||
return;
|
||||
}
|
||||
m_ds = ds;
|
||||
m_rc = rc;
|
||||
m_hwnd = hwnd;
|
||||
m_ps = new PAINTSTRUCT;
|
||||
m_hdc = BeginPaint(hwnd, m_ps);
|
||||
}
|
||||
|
||||
void DrawingEngine::FillBackground() const
|
||||
{
|
||||
HBRUSH bkgBrush = CreateSolidBrush(m_ds->palette()->color(Palette::Background));
|
||||
HBRUSH oldBkgBrush = (HBRUSH)SelectObject(m_hdc, bkgBrush);
|
||||
FillRect(m_hdc, m_rc, bkgBrush);
|
||||
SelectObject(m_hdc, oldBkgBrush);
|
||||
DeleteObject(bkgBrush);
|
||||
}
|
||||
|
||||
// void DrawingEngine::DrawRoundedRect()
|
||||
// {
|
||||
// int x = m_rc->left + m_ds->metrics()->value(Metrics::BorderWidth) - 1;
|
||||
// int y = m_rc->top + m_ds->metrics()->value(Metrics::BorderWidth) - 1;
|
||||
// int width = m_rc->right - m_rc->left - m_ds->metrics()->value(Metrics::BorderWidth) * 2 + 1;
|
||||
// int height = m_rc->bottom - m_rc->top - m_ds->metrics()->value(Metrics::BorderWidth) * 2 + 1;
|
||||
// int rad = m_ds->metrics()->value(Metrics::BorderRadius);
|
||||
|
||||
// m_memDC = CreateCompatibleDC(m_hdc);
|
||||
// m_memBmp = CreateCompatibleBitmap(m_hdc, m_rc->right - m_rc->left, m_rc->bottom - m_rc->top);
|
||||
// m_oldBmp = (HBITMAP)SelectObject(m_memDC, m_memBmp);
|
||||
|
||||
// m_graphics = new Gdiplus::Graphics(m_memDC);
|
||||
// m_graphics->SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
|
||||
// m_graphics->Clear(ColorFromColorRef(m_ds->palette()->color(Palette::Background)));
|
||||
|
||||
// Gdiplus::GraphicsPath ph;
|
||||
// RoundedPath(ph, x, y, width, height, rad);
|
||||
|
||||
// Gdiplus::SolidBrush brush(ColorFromColorRef(m_ds->palette()->color(Palette::Base)));
|
||||
// m_graphics->FillPath(&brush, &ph);
|
||||
|
||||
// if (m_ds->metrics()->value(Metrics::BorderWidth) != 0) {
|
||||
// Gdiplus::Pen pen(ColorFromColorRef(m_ds->palette()->color(Palette::Border)), m_ds->metrics()->value(Metrics::BorderWidth));
|
||||
// m_graphics->DrawPath(&pen, &ph);
|
||||
// }
|
||||
|
||||
// BitBlt(m_hdc, m_rc->left, m_rc->top, m_rc->right - m_rc->left, m_rc->bottom - m_rc->top, m_memDC, 0, 0, SRCCOPY);
|
||||
|
||||
// delete m_graphics;
|
||||
// m_graphics = nullptr;
|
||||
// SelectObject(m_memDC, m_oldBmp);
|
||||
// m_oldBmp = nullptr;
|
||||
// DeleteObject(m_memBmp);
|
||||
// m_memBmp = nullptr;
|
||||
// DeleteDC(m_memDC);
|
||||
// m_memDC = nullptr;
|
||||
// }
|
||||
|
||||
void DrawingEngine::DrawBorder() const
|
||||
{
|
||||
HPEN hPen = CreatePen(PS_SOLID, m_ds->metrics()->value(Metrics::BorderWidth), m_ds->palette()->color(Palette::Border));
|
||||
HPEN oldPen = (HPEN)SelectObject(m_hdc, hPen);
|
||||
MoveToEx(m_hdc, m_rc->left, m_rc->top, NULL);
|
||||
LineTo(m_hdc, m_rc->right - 1, m_rc->top);
|
||||
LineTo(m_hdc, m_rc->right - 1, m_rc->bottom - 1);
|
||||
LineTo(m_hdc, m_rc->left, m_rc->bottom - 1);
|
||||
LineTo(m_hdc, m_rc->left, m_rc->top);
|
||||
SelectObject(m_hdc, oldPen);
|
||||
DeleteObject(hPen);
|
||||
}
|
||||
|
||||
void DrawingEngine::DrawTopBorder(int brdWidth, COLORREF brdColor) const
|
||||
{
|
||||
HPEN pen = CreatePen(PS_SOLID, brdWidth, brdColor);
|
||||
HPEN oldPen = (HPEN)SelectObject(m_hdc, pen);
|
||||
MoveToEx(m_hdc, m_rc->left, m_rc->top, NULL);
|
||||
LineTo(m_hdc, m_rc->right, m_rc->top);
|
||||
SelectObject(m_hdc, oldPen);
|
||||
DeleteObject(pen);
|
||||
}
|
||||
|
||||
void DrawingEngine::DrawIcon(HICON hIcon) const
|
||||
{
|
||||
int x = m_rc->left + (m_rc->right - m_rc->left - m_ds->metrics()->value(Metrics::IconWidth)) / 2;
|
||||
int y = m_rc->top + (m_rc->bottom - m_rc->top - m_ds->metrics()->value(Metrics::IconHeight)) / 2;
|
||||
DrawIconEx(m_hdc, x, y, hIcon, m_ds->metrics()->value(Metrics::IconWidth), m_ds->metrics()->value(Metrics::IconHeight), 0, NULL, DI_NORMAL);
|
||||
}
|
||||
|
||||
void DrawingEngine::DrawEmfIcon(HENHMETAFILE hIcon) const
|
||||
{
|
||||
int x = m_rc->left + (m_rc->right - m_rc->left - m_ds->metrics()->value(Metrics::IconWidth)) / 2;
|
||||
int y = m_rc->top + (m_rc->bottom - m_rc->top - m_ds->metrics()->value(Metrics::IconHeight)) / 2;
|
||||
RECT _rc{x, y, x + m_ds->metrics()->value(Metrics::IconWidth), y + m_ds->metrics()->value(Metrics::IconHeight)};
|
||||
SetGraphicsMode(m_hdc, GM_ADVANCED);
|
||||
SetPolyFillMode(m_hdc, WINDING);
|
||||
SetStretchBltMode(m_hdc, HALFTONE);
|
||||
SetBrushOrgEx(m_hdc, 0, 0, nullptr);
|
||||
PlayEnhMetaFile(m_hdc, hIcon, &_rc);
|
||||
// Gdiplus::Graphics gr(m_hdc);
|
||||
// gr.SetInterpolationMode(Gdiplus::InterpolationModeBilinear);
|
||||
// gr.SetPixelOffsetMode(Gdiplus::PixelOffsetModeHighQuality);
|
||||
// gr.SetSmoothingMode(Gdiplus::SmoothingMode::SmoothingModeAntiAlias);
|
||||
// int x = m_rc->left + (m_rc->right - m_rc->left - m_ds->metrics()->value(Metrics::IconWidth)) / 2;
|
||||
// int y = m_rc->top + (m_rc->bottom - m_rc->top - m_ds->metrics()->value(Metrics::IconHeight)) / 2;
|
||||
// Gdiplus::Metafile mf(hIcon);
|
||||
// mf.ConvertToEmfPlus(&gr, NULL , Gdiplus::EmfTypeEmfPlusOnly, NULL);
|
||||
// gr.DrawImage(&mf, x, y, m_ds->metrics()->value(Metrics::IconWidth), m_ds->metrics()->value(Metrics::IconHeight));
|
||||
}
|
||||
|
||||
void DrawingEngine::DrawImage(Gdiplus::Bitmap *hBmp) const
|
||||
{
|
||||
int x = m_rc->left + (m_rc->right - m_rc->left - m_ds->metrics()->value(Metrics::IconWidth)) / 2;
|
||||
int y = m_rc->top + (m_rc->bottom - m_rc->top - m_ds->metrics()->value(Metrics::IconHeight)) / 2;
|
||||
Gdiplus::Graphics gr(m_hdc);
|
||||
gr.SetInterpolationMode(Gdiplus::InterpolationModeBilinear);
|
||||
gr.SetPixelOffsetMode(Gdiplus::PixelOffsetModeHighQuality);
|
||||
gr.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
|
||||
gr.DrawImage(hBmp, x, y, m_ds->metrics()->value(Metrics::IconWidth), m_ds->metrics()->value(Metrics::IconHeight));
|
||||
}
|
||||
|
||||
void DrawingEngine::DrawStockCloseIcon()
|
||||
{
|
||||
HPEN hPen = CreatePen(PS_SOLID, m_ds->metrics()->value(Metrics::PrimitiveWidth), m_ds->palette()->color(Palette::Primitive));
|
||||
HPEN oldPen = (HPEN)SelectObject(m_hdc, hPen);
|
||||
int x = m_rc->left + (m_rc->right - m_rc->left)/2;
|
||||
int y = m_rc->top + (m_rc->bottom - m_rc->top)/2;
|
||||
MoveToEx(m_hdc, x, y, NULL);
|
||||
LineTo(m_hdc, x + m_ds->metrics()->value(Metrics::IconWidth)/2, y + m_ds->metrics()->value(Metrics::IconHeight)/2);
|
||||
MoveToEx(m_hdc, x, y, NULL);
|
||||
LineTo(m_hdc, x + m_ds->metrics()->value(Metrics::IconWidth)/2, y - m_ds->metrics()->value(Metrics::IconHeight)/2);
|
||||
MoveToEx(m_hdc, x, y, NULL);
|
||||
LineTo(m_hdc, x - m_ds->metrics()->value(Metrics::IconWidth)/2, y + m_ds->metrics()->value(Metrics::IconHeight)/2);
|
||||
MoveToEx(m_hdc, x, y, NULL);
|
||||
LineTo(m_hdc, x - m_ds->metrics()->value(Metrics::IconWidth)/2, y - m_ds->metrics()->value(Metrics::IconHeight)/2);
|
||||
SelectObject(m_hdc, oldPen);
|
||||
DeleteObject(hPen);
|
||||
}
|
||||
|
||||
void DrawingEngine::DrawStockMinimizeIcon()
|
||||
{
|
||||
HPEN hPen = CreatePen(PS_SOLID, m_ds->metrics()->value(Metrics::PrimitiveWidth), m_ds->palette()->color(Palette::Primitive));
|
||||
HPEN oldPen = (HPEN)SelectObject(m_hdc, hPen);
|
||||
int x = m_rc->left + (m_rc->right - m_rc->left - m_ds->metrics()->value(Metrics::IconWidth)) / 2;
|
||||
int y = m_rc->top + (m_rc->bottom - m_rc->top - m_ds->metrics()->value(Metrics::IconHeight)) / 2;
|
||||
MoveToEx(m_hdc, x, y + m_ds->metrics()->value(Metrics::IconHeight)/2, NULL);
|
||||
LineTo(m_hdc, x + m_ds->metrics()->value(Metrics::IconWidth), y + m_ds->metrics()->value(Metrics::IconHeight)/2);
|
||||
SelectObject(m_hdc, oldPen);
|
||||
DeleteObject(hPen);
|
||||
}
|
||||
|
||||
void DrawingEngine::DrawStockMaximizeIcon()
|
||||
{
|
||||
HPEN hPen = CreatePen(PS_SOLID, m_ds->metrics()->value(Metrics::PrimitiveWidth), m_ds->palette()->color(Palette::Primitive));
|
||||
HPEN oldPen = (HPEN)SelectObject(m_hdc, hPen);
|
||||
int x = m_rc->left + (m_rc->right - m_rc->left - m_ds->metrics()->value(Metrics::IconWidth)) / 2;
|
||||
int y = m_rc->top + (m_rc->bottom - m_rc->top - m_ds->metrics()->value(Metrics::IconHeight)) / 2;
|
||||
int quarterw = m_ds->metrics()->value(Metrics::IconWidth)/4;
|
||||
int restw = m_ds->metrics()->value(Metrics::IconWidth) - quarterw;
|
||||
int quarterh = m_ds->metrics()->value(Metrics::IconHeight)/4;
|
||||
int resth = m_ds->metrics()->value(Metrics::IconHeight) - quarterh;
|
||||
MoveToEx(m_hdc, x, y + quarterh, NULL);
|
||||
LineTo(m_hdc, x + restw - 1, y + quarterh);
|
||||
LineTo(m_hdc, x + restw - 1, y + m_ds->metrics()->value(Metrics::IconHeight) - 1);
|
||||
LineTo(m_hdc, x, y + m_ds->metrics()->value(Metrics::IconHeight) - 1);
|
||||
LineTo(m_hdc, x, y + quarterh + m_ds->metrics()->value(Metrics::PrimitiveWidth) - 1);
|
||||
MoveToEx(m_hdc, x + quarterw, y + quarterh, NULL);
|
||||
LineTo(m_hdc, x + quarterw, y);
|
||||
LineTo(m_hdc, x + m_ds->metrics()->value(Metrics::IconWidth) - 1, y);
|
||||
LineTo(m_hdc, x + m_ds->metrics()->value(Metrics::IconWidth) - 1, y + resth - 1);
|
||||
LineTo(m_hdc, x + restw - 1, y + resth - 1);
|
||||
SelectObject(m_hdc, oldPen);
|
||||
DeleteObject(hPen);
|
||||
}
|
||||
|
||||
void DrawingEngine::DrawStockRestoreIcon()
|
||||
{
|
||||
HPEN hPen = CreatePen(PS_SOLID, m_ds->metrics()->value(Metrics::PrimitiveWidth), m_ds->palette()->color(Palette::Primitive));
|
||||
HPEN oldPen = (HPEN)SelectObject(m_hdc, hPen);
|
||||
int x = m_rc->left + (m_rc->right - m_rc->left - m_ds->metrics()->value(Metrics::IconWidth)) / 2;
|
||||
int y = m_rc->top + (m_rc->bottom - m_rc->top - m_ds->metrics()->value(Metrics::IconHeight)) / 2;
|
||||
MoveToEx(m_hdc, x, y, NULL);
|
||||
LineTo(m_hdc, x + m_ds->metrics()->value(Metrics::IconWidth) - 1, y);
|
||||
LineTo(m_hdc, x + m_ds->metrics()->value(Metrics::IconWidth) - 1, y + m_ds->metrics()->value(Metrics::IconHeight) - 1);
|
||||
LineTo(m_hdc, x, y + m_ds->metrics()->value(Metrics::IconHeight) - 1);
|
||||
LineTo(m_hdc, x, y + m_ds->metrics()->value(Metrics::PrimitiveWidth) - 1);
|
||||
SelectObject(m_hdc, oldPen);
|
||||
DeleteObject(hPen);
|
||||
}
|
||||
|
||||
void DrawingEngine::DrawCheckBox(const std::wstring &text, bool checked)
|
||||
{
|
||||
int x = m_rc->left;
|
||||
int y = m_rc->top + (m_rc->bottom - m_rc->top - m_ds->metrics()->value(Metrics::IconHeight)) / 2;
|
||||
|
||||
m_memDC = CreateCompatibleDC(m_hdc);
|
||||
m_memBmp = CreateCompatibleBitmap(m_hdc, m_rc->right - m_rc->left, m_rc->bottom - m_rc->top);
|
||||
m_oldBmp = (HBITMAP)SelectObject(m_memDC, m_memBmp);
|
||||
|
||||
SetLayout(m_memDC, LAYOUT_BITMAPORIENTATIONPRESERVED);
|
||||
m_graphics = new Gdiplus::Graphics(m_memDC);
|
||||
m_graphics->SetSmoothingMode(Gdiplus::SmoothingModeDefault);
|
||||
m_graphics->Clear(ColorFromColorRef(m_ds->palette()->color(Palette::Background)));
|
||||
|
||||
Gdiplus::Pen pen(ColorFromColorRef(m_ds->palette()->color(Palette::Primitive)), m_ds->metrics()->value(Metrics::PrimitiveWidth));
|
||||
Gdiplus::Rect rc(x, y, m_ds->metrics()->value(Metrics::IconWidth) - 1, m_ds->metrics()->value(Metrics::IconHeight) - 1);
|
||||
m_graphics->DrawRectangle(&pen, rc);
|
||||
if (checked) {
|
||||
Gdiplus::PointF pts[3] = {
|
||||
Gdiplus::PointF(float(x + 2), float(y + m_ds->metrics()->value(Metrics::IconHeight)/2 - 1)),
|
||||
Gdiplus::PointF(float(x + m_ds->metrics()->value(Metrics::IconWidth)/2 - 2), float(y + m_ds->metrics()->value(Metrics::IconHeight) - 5)),
|
||||
Gdiplus::PointF(float(x + m_ds->metrics()->value(Metrics::IconWidth) - 3), float(y + 4))
|
||||
};
|
||||
m_graphics->DrawLines(&pen, pts, 3);
|
||||
}
|
||||
if (!text.empty()) {
|
||||
RECT rc;
|
||||
SetRect(&rc, m_rc->left + m_ds->metrics()->value(Metrics::IconWidth), m_rc->top, m_rc->right, m_rc->bottom);
|
||||
m_graphics->SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
|
||||
LayeredDrawText(rc, text);
|
||||
}
|
||||
BitBlt(m_hdc, m_rc->left, m_rc->top, m_rc->right - m_rc->left, m_rc->bottom - m_rc->top, m_memDC, 0, 0, SRCCOPY);
|
||||
|
||||
delete m_graphics;
|
||||
m_graphics = nullptr;
|
||||
SelectObject(m_memDC, m_oldBmp);
|
||||
m_oldBmp = nullptr;
|
||||
DeleteObject(m_memBmp);
|
||||
m_memBmp = nullptr;
|
||||
DeleteDC(m_memDC);
|
||||
m_memDC = nullptr;
|
||||
// HPEN hPen = CreatePen(PS_SOLID, m_ds->metrics()->value(Metrics::PrimitiveWidth), m_ds->palette()->color(Palette::Primitive));
|
||||
// HPEN oldPen = (HPEN)SelectObject(m_hdc, hPen);
|
||||
// int x = m_rc->left;
|
||||
// int y = m_rc->top + (m_rc->bottom - m_rc->top - m_ds->metrics()->value(Metrics::IconHeight)) / 2;
|
||||
// MoveToEx(m_hdc, x, y, NULL);
|
||||
// LineTo(m_hdc, x + m_ds->metrics()->value(Metrics::IconWidth) - 1, y);
|
||||
// LineTo(m_hdc, x + m_ds->metrics()->value(Metrics::IconWidth) - 1, y + m_ds->metrics()->value(Metrics::IconHeight) - 1);
|
||||
// LineTo(m_hdc, x, y + m_ds->metrics()->value(Metrics::IconHeight) - 1);
|
||||
// LineTo(m_hdc, x, y + m_ds->metrics()->value(Metrics::PrimitiveWidth) - 1);
|
||||
// if (checked) {
|
||||
// MoveToEx(m_hdc, x + 2, y + m_ds->metrics()->value(Metrics::IconHeight)/2 - 1, NULL);
|
||||
// LineTo(m_hdc, x + m_ds->metrics()->value(Metrics::IconWidth)/2 - 2, y + m_ds->metrics()->value(Metrics::IconHeight) - 5);
|
||||
// LineTo(m_hdc, x + m_ds->metrics()->value(Metrics::IconWidth) - 2, y + 3);
|
||||
// }
|
||||
// SelectObject(m_hdc, oldPen);
|
||||
// DeleteObject(hPen);
|
||||
}
|
||||
|
||||
void DrawingEngine::DrawRadioButton(const std::wstring &text, bool checked)
|
||||
{
|
||||
int x = m_rc->left;
|
||||
int y = m_rc->top + (m_rc->bottom - m_rc->top - m_ds->metrics()->value(Metrics::IconHeight)) / 2;
|
||||
|
||||
m_memDC = CreateCompatibleDC(m_hdc);
|
||||
m_memBmp = CreateCompatibleBitmap(m_hdc, m_rc->right - m_rc->left, m_rc->bottom - m_rc->top);
|
||||
m_oldBmp = (HBITMAP)SelectObject(m_memDC, m_memBmp);
|
||||
|
||||
SetLayout(m_memDC, LAYOUT_BITMAPORIENTATIONPRESERVED);
|
||||
m_graphics = new Gdiplus::Graphics(m_memDC);
|
||||
m_graphics->SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
|
||||
m_graphics->Clear(ColorFromColorRef(m_ds->palette()->color(Palette::Background)));
|
||||
|
||||
Gdiplus::Pen pen(ColorFromColorRef(m_ds->palette()->color(Palette::Primitive)), m_ds->metrics()->value(Metrics::PrimitiveWidth));
|
||||
m_graphics->DrawEllipse(&pen, x, y, m_ds->metrics()->value(Metrics::IconHeight) - 1, m_ds->metrics()->value(Metrics::IconHeight) - 1);
|
||||
if (checked) {
|
||||
Gdiplus::SolidBrush chunkBrush(ColorFromColorRef(m_ds->palette()->color(Palette::Primitive)));
|
||||
m_graphics->FillEllipse(&chunkBrush, x + 2, y + 2, m_ds->metrics()->value(Metrics::IconHeight) - 4 - 1, m_ds->metrics()->value(Metrics::IconHeight) - 4 - 1);
|
||||
}
|
||||
if (!text.empty()) {
|
||||
RECT rc;
|
||||
SetRect(&rc, m_rc->left + m_ds->metrics()->value(Metrics::IconWidth), m_rc->top, m_rc->right, m_rc->bottom);
|
||||
LayeredDrawText(rc, text);
|
||||
}
|
||||
BitBlt(m_hdc, m_rc->left, m_rc->top, m_rc->right - m_rc->left, m_rc->bottom - m_rc->top, m_memDC, 0, 0, SRCCOPY);
|
||||
|
||||
delete m_graphics;
|
||||
m_graphics = nullptr;
|
||||
SelectObject(m_memDC, m_oldBmp);
|
||||
m_oldBmp = nullptr;
|
||||
DeleteObject(m_memBmp);
|
||||
m_memBmp = nullptr;
|
||||
DeleteDC(m_memDC);
|
||||
m_memDC = nullptr;
|
||||
}
|
||||
|
||||
void DrawingEngine::DrawProgressBar(int progress, int pulse_pos)
|
||||
{
|
||||
int x = m_rc->left + m_ds->metrics()->value(Metrics::BorderWidth) + m_ds->metrics()->value(Metrics::IconMarginLeft);
|
||||
int y = m_rc->top + m_ds->metrics()->value(Metrics::BorderWidth) + m_ds->metrics()->value(Metrics::IconMarginTop);
|
||||
int width = m_rc->right - m_rc->left - m_ds->metrics()->value(Metrics::BorderWidth) * 2 -
|
||||
m_ds->metrics()->value(Metrics::IconMarginRight) - m_ds->metrics()->value(Metrics::IconMarginLeft) - 1;
|
||||
int height = m_rc->bottom - m_rc->top - m_ds->metrics()->value(Metrics::BorderWidth) * 2 -
|
||||
m_ds->metrics()->value(Metrics::IconMarginBottom) - m_ds->metrics()->value(Metrics::IconMarginTop) - 1;
|
||||
int rad = m_ds->metrics()->value(Metrics::BorderRadius);
|
||||
|
||||
m_memDC = CreateCompatibleDC(m_hdc);
|
||||
m_memBmp = CreateCompatibleBitmap(m_hdc, m_rc->right - m_rc->left, m_rc->bottom - m_rc->top);
|
||||
m_oldBmp = (HBITMAP)SelectObject(m_memDC, m_memBmp);
|
||||
|
||||
m_graphics = new Gdiplus::Graphics(m_memDC);
|
||||
m_graphics->SetSmoothingMode(Gdiplus::SmoothingModeHighSpeed);
|
||||
m_graphics->Clear(ColorFromColorRef(m_ds->palette()->color(Palette::Background)));
|
||||
|
||||
Gdiplus::GraphicsPath ph;
|
||||
RoundedPath(ph, x, y, width, height, rad);
|
||||
|
||||
Gdiplus::SolidBrush prgBrush(ColorFromColorRef(m_ds->palette()->color(Palette::Base)));
|
||||
m_graphics->FillPath(&prgBrush, &ph);
|
||||
{
|
||||
int _x = x, _width;
|
||||
if (pulse_pos != -1) {
|
||||
_width = width/5;
|
||||
_x = x + (int)round(double((width - _width) * pulse_pos)/100);
|
||||
} else {
|
||||
if (progress < 0)
|
||||
progress = 0;
|
||||
else
|
||||
if (progress > 100)
|
||||
progress = 100;
|
||||
_width = (int)round(double(width * progress)/100);
|
||||
}
|
||||
Gdiplus::GraphicsPath _ph;
|
||||
RoundedPath(_ph, _x, y, _width, height, rad);
|
||||
|
||||
Gdiplus::SolidBrush chunkBrush(ColorFromColorRef(m_ds->palette()->color(Palette::AlternateBase)));
|
||||
m_graphics->FillPath(&chunkBrush, &_ph);
|
||||
}
|
||||
|
||||
if (m_ds->metrics()->value(Metrics::BorderWidth) != 0) {
|
||||
Gdiplus::Pen pen(ColorFromColorRef(m_ds->palette()->color(Palette::Border)), m_ds->metrics()->value(Metrics::BorderWidth));
|
||||
m_graphics->DrawPath(&pen, &ph);
|
||||
}
|
||||
|
||||
BitBlt(m_hdc, m_rc->left, m_rc->top, m_rc->right - m_rc->left, m_rc->bottom - m_rc->top, m_memDC, 0, 0, SRCCOPY);
|
||||
|
||||
delete m_graphics;
|
||||
m_graphics = nullptr;
|
||||
SelectObject(m_memDC, m_oldBmp);
|
||||
m_oldBmp = nullptr;
|
||||
DeleteObject(m_memBmp);
|
||||
m_memBmp = nullptr;
|
||||
DeleteDC(m_memDC);
|
||||
m_memDC = nullptr;
|
||||
}
|
||||
|
||||
void DrawingEngine::DrawText(const RECT &rc, const std::wstring &text, bool multiline) const
|
||||
{
|
||||
HFONT hFont = CreateFontW(m_ds->metrics()->value(Metrics::FontHeight), m_ds->metrics()->value(Metrics::FontWidth), 0, 0, FW_NORMAL,
|
||||
0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, DEFAULT_PITCH, TEXT("Segoe UI"));
|
||||
HFONT hOldFont = (HFONT) SelectObject(m_hdc, hFont);
|
||||
SetBkMode(m_hdc, TRANSPARENT);
|
||||
SetTextColor(m_hdc, m_ds->palette()->color(Palette::Text));
|
||||
RECT _rc{rc.left + m_ds->metrics()->value(Metrics::TextMarginLeft), rc.top + m_ds->metrics()->value(Metrics::TextMarginTop),
|
||||
rc.right + m_ds->metrics()->value(Metrics::TextMarginRight), rc.bottom + m_ds->metrics()->value(Metrics::TextMarginBottom)};
|
||||
UINT fmt = multiline ? 0 : DT_SINGLELINE;
|
||||
UINT algn = m_ds->metrics()->value(Metrics::TextAlignment);
|
||||
if (algn & Metrics::AlignHLeft)
|
||||
fmt |= DT_LEFT;
|
||||
if (algn & Metrics::AlignHCenter)
|
||||
fmt |= DT_CENTER;
|
||||
if (algn & Metrics::AlignHRight)
|
||||
fmt |= DT_RIGHT;
|
||||
if (algn & Metrics::AlignVTop)
|
||||
fmt |= DT_TOP;
|
||||
if (algn & Metrics::AlignVCenter)
|
||||
fmt |= DT_VCENTER;
|
||||
if (algn & Metrics::AlignVBottom)
|
||||
fmt |= DT_BOTTOM;
|
||||
::DrawText(m_hdc, text.c_str(), text.length(), &_rc, fmt);
|
||||
SelectObject(m_hdc, hOldFont);
|
||||
SetBkMode(m_hdc, OPAQUE);
|
||||
DeleteObject(hFont);
|
||||
}
|
||||
|
||||
void DrawingEngine::End()
|
||||
{
|
||||
EndPaint(m_hwnd, m_ps);
|
||||
delete m_ps;
|
||||
m_ps = nullptr;
|
||||
m_hdc = nullptr;
|
||||
m_hwnd = nullptr;
|
||||
m_rc = nullptr;
|
||||
m_ds = nullptr;
|
||||
}
|
||||
|
||||
// void DrawingEngine::LayeredBegin(DrawningSurface *ds, HWND hwnd, RECT *rc)
|
||||
// {
|
||||
// if (m_ds) {
|
||||
// printf("Engine is buisy....\n");
|
||||
// fflush(stdout);
|
||||
// return;
|
||||
// }
|
||||
// m_ds = ds;
|
||||
// m_rc = rc;
|
||||
// m_hwnd = hwnd;
|
||||
// m_hdc = GetDC(m_hwnd);
|
||||
// m_memDC = CreateCompatibleDC(m_hdc);
|
||||
// m_memBmp = CreateCompatibleBitmap(m_hdc, rc->right - rc->left, rc->bottom - rc->top);
|
||||
// m_oldBmp = (HBITMAP)SelectObject(m_memDC, m_memBmp);
|
||||
|
||||
// m_graphics = new Gdiplus::Graphics(m_memDC);
|
||||
// m_graphics->SetSmoothingMode(Gdiplus::SmoothingMode::SmoothingModeAntiAlias);
|
||||
// // gr->SetCompositingMode(Gdiplus::CompositingMode::CompositingModeSourceOver);
|
||||
// // gr->SetInterpolationMode(Gdiplus::InterpolationModeHighQuality);
|
||||
// }
|
||||
|
||||
// void DrawingEngine::LayeredDrawRoundedRect() const
|
||||
// {
|
||||
// int x = m_rc->left + m_ds->metrics()->value(Metrics::ShadowWidth) + m_ds->metrics()->value(Metrics::BorderWidth) - 1;
|
||||
// int y = m_rc->top + m_ds->metrics()->value(Metrics::ShadowWidth) + m_ds->metrics()->value(Metrics::BorderWidth) - 1;
|
||||
// int width = m_rc->right - m_rc->left - (m_ds->metrics()->value(Metrics::ShadowWidth) + m_ds->metrics()->value(Metrics::BorderWidth)) * 2 + 1;
|
||||
// int height = m_rc->bottom - m_rc->top - (m_ds->metrics()->value(Metrics::ShadowWidth) + m_ds->metrics()->value(Metrics::BorderWidth)) * 2 + 1;
|
||||
|
||||
// int rad = m_ds->metrics()->value(Metrics::BorderRadius);
|
||||
// Gdiplus::GraphicsPath ph;
|
||||
// RoundedPath(ph, x, y, width, height, rad);
|
||||
|
||||
// if (m_ds->metrics()->value(Metrics::BorderWidth) != 0) {
|
||||
// Gdiplus::Pen pen(ColorFromColorRef(m_ds->palette()->color(Palette::Border)), m_ds->metrics()->value(Metrics::BorderWidth));
|
||||
// m_graphics->DrawPath(&pen, &ph);
|
||||
// }
|
||||
// Gdiplus::SolidBrush brush(ColorFromColorRef(m_ds->palette()->color(Palette::Background)));
|
||||
// m_graphics->FillPath(&brush, &ph);
|
||||
// }
|
||||
|
||||
void DrawingEngine::LayeredDrawText(RECT &rc, const std::wstring &text) const
|
||||
{
|
||||
// Gdiplus::FontFamily fntFam(L"Segoe UI");
|
||||
// Gdiplus::Font font(&fntFam, m_ds->metrics()->value(Metrics::FontHeight), Gdiplus::FontStyleRegular, Gdiplus::Unit::UnitPixel);
|
||||
HFONT hFont = CreateFontW(m_ds->metrics()->value(Metrics::FontHeight), m_ds->metrics()->value(Metrics::FontWidth), 0, 0, FW_NORMAL,
|
||||
0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, DEFAULT_PITCH, TEXT("Segoe UI"));
|
||||
LOGFONTW logFont = {0};
|
||||
GetObject(hFont, sizeof(LOGFONTW), &logFont);
|
||||
Gdiplus::Font font(m_memDC, &logFont);
|
||||
DeleteObject(hFont);
|
||||
Gdiplus::RectF rcF(rc.left + m_ds->metrics()->value(Metrics::TextMarginLeft), rc.top + m_ds->metrics()->value(Metrics::TextMarginTop),
|
||||
rc.right + m_ds->metrics()->value(Metrics::TextMarginRight) - rc.left - m_ds->metrics()->value(Metrics::TextMarginLeft),
|
||||
rc.bottom + m_ds->metrics()->value(Metrics::TextMarginBottom) - rc.top - m_ds->metrics()->value(Metrics::TextMarginTop));
|
||||
Gdiplus::StringAlignment h_algn, v_algn;
|
||||
UINT algn = m_ds->metrics()->value(Metrics::TextAlignment);
|
||||
if (algn & Metrics::AlignHLeft)
|
||||
h_algn = Gdiplus::StringAlignmentNear;
|
||||
if (algn & Metrics::AlignHCenter)
|
||||
h_algn = Gdiplus::StringAlignmentCenter;
|
||||
if (algn & Metrics::AlignHRight)
|
||||
h_algn = Gdiplus::StringAlignmentFar;
|
||||
if (algn & Metrics::AlignVTop)
|
||||
v_algn = Gdiplus::StringAlignmentNear;
|
||||
if (algn & Metrics::AlignVCenter)
|
||||
v_algn = Gdiplus::StringAlignmentCenter;
|
||||
if (algn & Metrics::AlignVBottom)
|
||||
v_algn = Gdiplus::StringAlignmentFar;
|
||||
Gdiplus::StringFormat strFmt;
|
||||
strFmt.SetAlignment(h_algn);
|
||||
strFmt.SetLineAlignment(v_algn);
|
||||
Gdiplus::SolidBrush brush(ColorFromColorRef(m_ds->palette()->color(Palette::Text)));
|
||||
m_graphics->DrawString(text.c_str(), -1, &font, rcF, &strFmt, &brush);
|
||||
}
|
||||
|
||||
// void DrawingEngine::LayeredDrawShadow(int shadowWidth, int rad)
|
||||
// {
|
||||
// #define SHADOW_TRANSPATENCY 0x26
|
||||
// for (int i = 0; i < shadowWidth; i++) {
|
||||
// int x = m_rc->left + i;
|
||||
// int y = m_rc->top + i;
|
||||
// int width = m_rc->right - m_rc->left - i * 2 - 1;
|
||||
// int height = m_rc->bottom - m_rc->top - i * 2 - 1;
|
||||
|
||||
// Gdiplus::GraphicsPath ph;
|
||||
// RoundedPath(ph, x, y, width, height, rad);
|
||||
|
||||
// int alpha = shadowWidth > 1 ? SHADOW_TRANSPATENCY * (i * i) / ((shadowWidth - 1) * (shadowWidth - 1)) : SHADOW_TRANSPATENCY;
|
||||
// Gdiplus::Pen pen(Gdiplus::Color(alpha, 0, 0, 0), 1);
|
||||
// m_graphics->DrawPath(&pen, &ph);
|
||||
// }
|
||||
// }
|
||||
|
||||
// void DrawingEngine::LayeredUpdate(BYTE alpha)
|
||||
// {
|
||||
// RECT wrc;
|
||||
// GetWindowRect(m_hwnd, &wrc);
|
||||
// HDC scrDC = GetDC(NULL);
|
||||
// POINT ptSrc = {0, 0};
|
||||
// POINT ptDst = {wrc.left, wrc.top};
|
||||
// SIZE szDst = {wrc.right - wrc.left, wrc.bottom - wrc.top};
|
||||
// BLENDFUNCTION bf;
|
||||
// bf.AlphaFormat = AC_SRC_ALPHA;
|
||||
// bf.BlendFlags = 0;
|
||||
// bf.BlendOp = AC_SRC_OVER;
|
||||
// bf.SourceConstantAlpha = alpha;
|
||||
// UpdateLayeredWindow(m_hwnd, scrDC, &ptDst, &szDst, m_memDC, &ptSrc, 0, &bf, ULW_ALPHA);
|
||||
// ReleaseDC(NULL, scrDC);
|
||||
// }
|
||||
|
||||
// void DrawingEngine::LayeredEnd()
|
||||
// {
|
||||
// delete m_graphics;
|
||||
// m_graphics = nullptr;
|
||||
// SelectObject(m_memDC, m_oldBmp);
|
||||
// m_oldBmp = nullptr;
|
||||
// DeleteObject(m_memBmp);
|
||||
// m_memBmp = nullptr;
|
||||
// DeleteDC(m_memDC);
|
||||
// m_memDC = nullptr;
|
||||
// ReleaseDC(m_hwnd, m_hdc);
|
||||
// m_hdc = nullptr;
|
||||
// m_hwnd = nullptr;
|
||||
// m_rc = nullptr;
|
||||
// m_ds = nullptr;
|
||||
// }
|
||||
@ -0,0 +1,59 @@
|
||||
#ifndef DRAWNINGENGINE_H
|
||||
#define DRAWNINGENGINE_H
|
||||
|
||||
#include <Windows.h>
|
||||
#include <gdiplus.h>
|
||||
#include <string>
|
||||
|
||||
|
||||
class DrawningSurface;
|
||||
class DrawingEngine
|
||||
{
|
||||
public:
|
||||
DrawingEngine(const DrawingEngine&) = delete;
|
||||
DrawingEngine& operator=(const DrawingEngine&) = delete;
|
||||
static DrawingEngine *instance();
|
||||
|
||||
|
||||
DrawningSurface *surface();
|
||||
void Begin(DrawningSurface*, HWND, RECT *rc);
|
||||
void FillBackground() const;
|
||||
// void DrawRoundedRect();
|
||||
void DrawBorder() const;
|
||||
void DrawTopBorder(int, COLORREF) const;
|
||||
void DrawIcon(HICON hIcon) const;
|
||||
void DrawEmfIcon(HENHMETAFILE hIconc) const;
|
||||
void DrawImage(Gdiplus::Bitmap *hBmp) const;
|
||||
void DrawStockCloseIcon();
|
||||
void DrawStockMinimizeIcon();
|
||||
void DrawStockMaximizeIcon();
|
||||
void DrawStockRestoreIcon();
|
||||
void DrawCheckBox(const std::wstring &text, bool checked = false);
|
||||
void DrawRadioButton(const std::wstring &text, bool checked = false);
|
||||
void DrawProgressBar(int progress, int pulse_pos);
|
||||
void DrawText(const RECT &rc, const std::wstring &text, bool multiline = false) const;
|
||||
void End();
|
||||
|
||||
// void LayeredBegin(DrawningSurface*, HWND, RECT *rc);
|
||||
// void LayeredDrawRoundedRect() const;
|
||||
void LayeredDrawText(RECT &rc, const std::wstring &text) const;
|
||||
// void LayeredDrawShadow(int shadowWidth, int rad);
|
||||
// void LayeredUpdate(BYTE alpha);
|
||||
// void LayeredEnd();
|
||||
|
||||
private:
|
||||
DrawingEngine();
|
||||
~DrawingEngine();
|
||||
|
||||
DrawningSurface *m_ds;
|
||||
RECT *m_rc;
|
||||
PAINTSTRUCT *m_ps;
|
||||
HWND m_hwnd;
|
||||
HDC m_hdc;
|
||||
HDC m_memDC;
|
||||
HBITMAP m_memBmp;
|
||||
HBITMAP m_oldBmp;
|
||||
Gdiplus::Graphics *m_graphics;
|
||||
};
|
||||
|
||||
#endif // DRAWNINGENGINE_H
|
||||
185
win-linux/extras/online-installer/src/uiclasses/label.cpp
Normal file
185
win-linux/extras/online-installer/src/uiclasses/label.cpp
Normal file
@ -0,0 +1,185 @@
|
||||
#include "label.h"
|
||||
#include "metrics.h"
|
||||
#include "drawningengine.h"
|
||||
|
||||
|
||||
Label::Label(Widget *parent) :
|
||||
Widget(parent, ObjectType::WidgetType),
|
||||
m_hIcon(nullptr),
|
||||
m_hMetaFile(nullptr),
|
||||
m_hBmp(nullptr),
|
||||
m_multiline(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Label::~Label()
|
||||
{
|
||||
if (m_hIcon) {
|
||||
DestroyIcon(m_hIcon);
|
||||
m_hIcon = nullptr;
|
||||
}
|
||||
if (m_hMetaFile) {
|
||||
//delete m_hMetaFile;
|
||||
DeleteEnhMetaFile(m_hMetaFile);
|
||||
m_hMetaFile = nullptr;
|
||||
}
|
||||
if (m_hBmp) {
|
||||
delete m_hBmp, m_hBmp = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void Label::setText(const std::wstring &text, bool multiline)
|
||||
{
|
||||
m_text = text;
|
||||
m_multiline = multiline;
|
||||
update();
|
||||
}
|
||||
|
||||
void Label::setIcon(const std::wstring &path, int w, int h)
|
||||
{
|
||||
if (m_hIcon) {
|
||||
DestroyIcon(m_hIcon);
|
||||
m_hIcon = nullptr;
|
||||
}
|
||||
metrics()->setMetrics(Metrics::IconWidth, w);
|
||||
metrics()->setMetrics(Metrics::IconHeight, h);
|
||||
m_hIcon = (HICON)LoadImage(NULL, path.c_str(), IMAGE_ICON, w, h, LR_LOADFROMFILE | LR_DEFAULTCOLOR | LR_SHARED);
|
||||
update();
|
||||
}
|
||||
|
||||
void Label::setIcon(int id, int w, int h)
|
||||
{
|
||||
if (m_hIcon) {
|
||||
DestroyIcon(m_hIcon);
|
||||
m_hIcon = nullptr;
|
||||
}
|
||||
metrics()->setMetrics(Metrics::IconWidth, w);
|
||||
metrics()->setMetrics(Metrics::IconHeight, h);
|
||||
HMODULE hInst = GetModuleHandle(NULL);
|
||||
m_hIcon = (HICON)LoadImage(hInst, MAKEINTRESOURCE(id), IMAGE_ICON, w, h, LR_COPYFROMRESOURCE | LR_DEFAULTCOLOR | LR_SHARED);
|
||||
update();
|
||||
}
|
||||
|
||||
void Label::setEMFIcon(const std::wstring &path, int w, int h)
|
||||
{
|
||||
if (m_hMetaFile) {
|
||||
//delete m_hMetaFile;
|
||||
DeleteEnhMetaFile(m_hMetaFile);
|
||||
m_hMetaFile = nullptr;
|
||||
}
|
||||
metrics()->setMetrics(Metrics::IconWidth, w);
|
||||
metrics()->setMetrics(Metrics::IconHeight, h);
|
||||
m_hMetaFile = GetEnhMetaFile(path.c_str());
|
||||
//m_hMetaFile = new Metafile(path.c_str());
|
||||
update();
|
||||
}
|
||||
|
||||
void Label::setEMFIcon(int id, int w, int h)
|
||||
{
|
||||
if (m_hMetaFile) {
|
||||
//delete m_hMetaFile;
|
||||
DeleteEnhMetaFile(m_hMetaFile);
|
||||
m_hMetaFile = nullptr;
|
||||
}
|
||||
metrics()->setMetrics(Metrics::IconWidth, w);
|
||||
metrics()->setMetrics(Metrics::IconHeight, h);
|
||||
HMODULE hInst = GetModuleHandle(NULL);
|
||||
if (HRSRC hRes = FindResource(hInst, MAKEINTRESOURCE(id), RT_RCDATA)) {
|
||||
if (HGLOBAL hResData = LoadResource(hInst, hRes)) {
|
||||
if (LPVOID pData = LockResource(hResData)) {
|
||||
DWORD dataSize = SizeofResource(hInst, hRes);
|
||||
if (dataSize > 0)
|
||||
m_hMetaFile = SetEnhMetaFileBits(dataSize, (BYTE*)pData);
|
||||
}
|
||||
FreeResource(hResData);
|
||||
}
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
void Label::setImage(int id, int w, int h)
|
||||
{
|
||||
if (m_hBmp) {
|
||||
delete m_hBmp, m_hBmp = nullptr;
|
||||
}
|
||||
metrics()->setMetrics(Metrics::IconWidth, w);
|
||||
metrics()->setMetrics(Metrics::IconHeight, h);
|
||||
HMODULE hInst = GetModuleHandle(NULL);
|
||||
if (HRSRC hRes = FindResource(hInst, MAKEINTRESOURCE(id), L"PNG")) {
|
||||
if (HGLOBAL hResData = LoadResource(hInst, hRes)) {
|
||||
if (LPVOID pData = LockResource(hResData)) {
|
||||
DWORD dataSize = SizeofResource(hInst, hRes);
|
||||
if (dataSize > 0) {
|
||||
if (HGLOBAL hGlobal = GlobalAlloc(GHND, dataSize)) {
|
||||
if (LPVOID pBuffer = GlobalLock(hGlobal)) {
|
||||
memcpy(pBuffer, pData, dataSize);
|
||||
IStream *pStream = nullptr;
|
||||
HRESULT hr = CreateStreamOnHGlobal(hGlobal, TRUE, &pStream);
|
||||
if (SUCCEEDED(hr)) {
|
||||
m_hBmp = new Gdiplus::Bitmap(pStream);
|
||||
pStream->Release();
|
||||
}
|
||||
GlobalUnlock(hGlobal);
|
||||
}
|
||||
GlobalFree(hGlobal);
|
||||
}
|
||||
}
|
||||
}
|
||||
FreeResource(hResData);
|
||||
}
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
void Label::setIconSize(int w, int h)
|
||||
{
|
||||
metrics()->setMetrics(Metrics::IconWidth, w);
|
||||
metrics()->setMetrics(Metrics::IconHeight, h);
|
||||
update();
|
||||
}
|
||||
|
||||
bool Label::event(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT *result)
|
||||
{
|
||||
switch (msg) {
|
||||
case WM_PAINT: {
|
||||
RECT rc;
|
||||
GetClientRect(m_hWnd, &rc);
|
||||
|
||||
engine()->Begin(this, m_hWnd, &rc);
|
||||
engine()->FillBackground();
|
||||
// DrawRoundedRect();
|
||||
if (metrics()->value(Metrics::BorderWidth) != 0)
|
||||
engine()->DrawBorder();
|
||||
if (m_hBmp)
|
||||
engine()->DrawImage(m_hBmp);
|
||||
if (m_hIcon)
|
||||
engine()->DrawIcon(m_hIcon);
|
||||
if (m_hMetaFile)
|
||||
engine()->DrawEmfIcon(m_hMetaFile);
|
||||
if (!m_text.empty())
|
||||
engine()->DrawText(rc, m_text, m_multiline);
|
||||
|
||||
engine()->End();
|
||||
|
||||
*result = FALSE;
|
||||
return true;
|
||||
}
|
||||
|
||||
// case WM_MOUSEENTER: {
|
||||
// palette()->setCurrentState(Palette::Hover);
|
||||
// repaint();
|
||||
// break;
|
||||
// }
|
||||
|
||||
// case WM_MOUSELEAVE: {
|
||||
// palette()->setCurrentState(Palette::Normal);
|
||||
// repaint();
|
||||
// break;
|
||||
// }
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return Widget::event(msg, wParam, lParam, result);
|
||||
}
|
||||
35
win-linux/extras/online-installer/src/uiclasses/label.h
Normal file
35
win-linux/extras/online-installer/src/uiclasses/label.h
Normal file
@ -0,0 +1,35 @@
|
||||
#ifndef LABEL_H
|
||||
#define LABEL_H
|
||||
|
||||
#include "widget.h"
|
||||
#include <Windows.h>
|
||||
#include <gdiplus.h>
|
||||
|
||||
|
||||
class Label : public Widget
|
||||
{
|
||||
public:
|
||||
Label(Widget *parent = nullptr);
|
||||
virtual ~Label();
|
||||
|
||||
void setText(const std::wstring &text, bool multiline = false);
|
||||
void setIcon(const std::wstring &path, int w, int h);
|
||||
void setIcon(int id, int w, int h);
|
||||
void setEMFIcon(const std::wstring &path, int w, int h);
|
||||
void setEMFIcon(int id, int w, int h);
|
||||
void setImage(int id, int w, int h);
|
||||
void setIconSize(int w, int h);
|
||||
/* callback */
|
||||
|
||||
protected:
|
||||
virtual bool event(UINT, WPARAM, LPARAM, LRESULT*) override;
|
||||
|
||||
private:
|
||||
std::wstring m_text;
|
||||
HICON m_hIcon;
|
||||
HENHMETAFILE m_hMetaFile;
|
||||
Gdiplus::Bitmap *m_hBmp;
|
||||
bool m_multiline;
|
||||
};
|
||||
|
||||
#endif // LABEL_H
|
||||
12
win-linux/extras/online-installer/src/uiclasses/layout.cpp
Normal file
12
win-linux/extras/online-installer/src/uiclasses/layout.cpp
Normal file
@ -0,0 +1,12 @@
|
||||
#include "layout.h"
|
||||
|
||||
|
||||
Layout::Layout(Object *parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Layout::~Layout()
|
||||
{
|
||||
|
||||
}
|
||||
27
win-linux/extras/online-installer/src/uiclasses/layout.h
Normal file
27
win-linux/extras/online-installer/src/uiclasses/layout.h
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef LAYOUT_H
|
||||
#define LAYOUT_H
|
||||
|
||||
#include "object.h"
|
||||
#include "layoutitem.h"
|
||||
#include "common.h"
|
||||
// #include <vector>
|
||||
|
||||
|
||||
|
||||
class Layout : public LayoutItem
|
||||
{
|
||||
public:
|
||||
Layout(Object *parent = nullptr);
|
||||
virtual ~Layout();
|
||||
|
||||
virtual void addWidget(Widget *wgt) = 0;
|
||||
|
||||
protected:
|
||||
Margins m_margins;
|
||||
|
||||
private:
|
||||
friend class Widget;
|
||||
virtual void onResize(int w, int h) = 0;
|
||||
};
|
||||
|
||||
#endif // LAYOUT_H
|
||||
@ -0,0 +1,22 @@
|
||||
#include "layoutitem.h"
|
||||
|
||||
|
||||
LayoutItem::LayoutItem()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
LayoutItem::~LayoutItem()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Widget *LayoutItem::widget()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Layout *LayoutItem::layout()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
20
win-linux/extras/online-installer/src/uiclasses/layoutitem.h
Normal file
20
win-linux/extras/online-installer/src/uiclasses/layoutitem.h
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef LAYOUTITEM_H
|
||||
#define LAYOUTITEM_H
|
||||
|
||||
|
||||
class Widget;
|
||||
class Layout;
|
||||
|
||||
class LayoutItem
|
||||
{
|
||||
public:
|
||||
LayoutItem();
|
||||
~LayoutItem();
|
||||
|
||||
virtual Widget *widget();
|
||||
virtual Layout *layout();
|
||||
|
||||
protected:
|
||||
};
|
||||
|
||||
#endif // LAYOUTITEM_H
|
||||
40
win-linux/extras/online-installer/src/uiclasses/metrics.cpp
Normal file
40
win-linux/extras/online-installer/src/uiclasses/metrics.cpp
Normal file
@ -0,0 +1,40 @@
|
||||
#include "metrics.h"
|
||||
|
||||
|
||||
Metrics::Metrics()
|
||||
{
|
||||
metrics[BorderWidth] = 0;
|
||||
metrics[BorderRadius] = 0;
|
||||
metrics[IconWidth] = 16;
|
||||
metrics[IconHeight] = 16;
|
||||
metrics[IconMarginLeft] = 0;
|
||||
metrics[IconMarginRight] = 0;
|
||||
metrics[IconMarginTop] = 0;
|
||||
metrics[IconMarginBottom] = 0;
|
||||
metrics[IconAlignment] = Alignment::AlignCenter;
|
||||
metrics[FontWidth] = 0;
|
||||
metrics[FontHeight] = 18;
|
||||
metrics[PrimitiveWidth] = 1;
|
||||
metrics[ShadowWidth] = 10;
|
||||
metrics[ShadowRadius] = 10;
|
||||
metrics[TextMarginLeft] = 0;
|
||||
metrics[TextMarginTop] = 0;
|
||||
metrics[TextMarginRight] = 0;
|
||||
metrics[TextMarginBottom] = 0;
|
||||
metrics[TextAlignment] = Alignment::AlignCenter;
|
||||
}
|
||||
|
||||
Metrics::~Metrics()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int Metrics::value(Role role)
|
||||
{
|
||||
return metrics[role];
|
||||
}
|
||||
|
||||
void Metrics::setMetrics(Role role, int value)
|
||||
{
|
||||
metrics[role] = value;
|
||||
}
|
||||
53
win-linux/extras/online-installer/src/uiclasses/metrics.h
Normal file
53
win-linux/extras/online-installer/src/uiclasses/metrics.h
Normal file
@ -0,0 +1,53 @@
|
||||
#ifndef METRICS_H
|
||||
#define METRICS_H
|
||||
|
||||
|
||||
class Metrics
|
||||
{
|
||||
public:
|
||||
Metrics();
|
||||
~Metrics();
|
||||
|
||||
enum Alignment : unsigned char {
|
||||
AlignHLeft = 1,
|
||||
AlignHCenter = 2,
|
||||
AlignHRight = 4,
|
||||
AlignVTop = 8,
|
||||
AlignVCenter = 16,
|
||||
AlignVBottom = 32,
|
||||
AlignCenter = AlignHCenter | AlignVCenter
|
||||
};
|
||||
|
||||
enum Role : unsigned char {
|
||||
BorderWidth,
|
||||
BorderRadius,
|
||||
IconWidth,
|
||||
IconHeight,
|
||||
IconMarginLeft,
|
||||
IconMarginTop,
|
||||
IconMarginRight,
|
||||
IconMarginBottom,
|
||||
IconAlignment,
|
||||
FontWidth,
|
||||
FontHeight,
|
||||
PrimitiveWidth,
|
||||
ShadowWidth,
|
||||
ShadowRadius,
|
||||
TextMarginLeft,
|
||||
TextMarginTop,
|
||||
TextMarginRight,
|
||||
TextMarginBottom,
|
||||
TextAlignment,
|
||||
METRICS_COUNT
|
||||
};
|
||||
|
||||
void setMetrics(Role, int);
|
||||
int value(Role);
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
int metrics[METRICS_COUNT];
|
||||
};
|
||||
|
||||
#endif // METRICS_H
|
||||
40
win-linux/extras/online-installer/src/uiclasses/object.cpp
Normal file
40
win-linux/extras/online-installer/src/uiclasses/object.cpp
Normal file
@ -0,0 +1,40 @@
|
||||
#include "object.h"
|
||||
|
||||
|
||||
int Object::m_connectionId = 0;
|
||||
|
||||
Object::Object(Object *parent) :
|
||||
m_parent(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Object::~Object()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Object *Object::parent()
|
||||
{
|
||||
return m_parent;
|
||||
}
|
||||
|
||||
void Object::setParent(Object *parent)
|
||||
{
|
||||
m_parent = parent;
|
||||
}
|
||||
|
||||
void Object::setObjectName(const std::wstring &object_name)
|
||||
{
|
||||
m_object_name = object_name;
|
||||
}
|
||||
|
||||
std::wstring Object::objectName()
|
||||
{
|
||||
return m_object_name;
|
||||
}
|
||||
|
||||
void Object::disconnect(int connectionId)
|
||||
{
|
||||
|
||||
}
|
||||
35
win-linux/extras/online-installer/src/uiclasses/object.h
Normal file
35
win-linux/extras/online-installer/src/uiclasses/object.h
Normal file
@ -0,0 +1,35 @@
|
||||
#ifndef OBJECT_H
|
||||
#define OBJECT_H
|
||||
|
||||
#include <string>
|
||||
|
||||
|
||||
class Object
|
||||
{
|
||||
public:
|
||||
Object(Object *parent = nullptr);
|
||||
virtual ~Object();
|
||||
|
||||
enum ObjectType : unsigned char {
|
||||
ApplicationType,
|
||||
WindowType,
|
||||
DialogType,
|
||||
WidgetType,
|
||||
PopupType
|
||||
};
|
||||
|
||||
Object *parent();
|
||||
void setParent(Object*);
|
||||
void setObjectName(const std::wstring&);
|
||||
std::wstring objectName();
|
||||
virtual void disconnect(int);
|
||||
|
||||
protected:
|
||||
static int m_connectionId;
|
||||
|
||||
private:
|
||||
Object *m_parent;
|
||||
std::wstring m_object_name;
|
||||
};
|
||||
|
||||
#endif // OBJECT_H
|
||||
59
win-linux/extras/online-installer/src/uiclasses/palette.cpp
Normal file
59
win-linux/extras/online-installer/src/uiclasses/palette.cpp
Normal file
@ -0,0 +1,59 @@
|
||||
#include "palette.h"
|
||||
|
||||
|
||||
Palette::Palette()
|
||||
{
|
||||
palette[Background][Disabled] = 0x21252b;
|
||||
palette[Background][Normal] = 0x21252b;
|
||||
palette[Background][Hover] = 0x34383f;
|
||||
palette[Background][Pressed] = 0x30343c;
|
||||
palette[Border][Disabled] = 0x21252b;
|
||||
palette[Border][Normal] = 0x21252b;
|
||||
palette[Border][Hover] = 0x34383f;
|
||||
palette[Border][Pressed] = 0x30343c;
|
||||
palette[Base][Disabled] = 0x0000ff;
|
||||
palette[Base][Normal] = 0x0000ff;
|
||||
palette[Base][Hover] = 0x0000ff;
|
||||
palette[Base][Pressed] = 0x0000ff;
|
||||
palette[AlternateBase][Disabled] = 0xff0000;
|
||||
palette[AlternateBase][Normal] = 0xff0000;
|
||||
palette[AlternateBase][Hover] = 0xff0000;
|
||||
palette[AlternateBase][Pressed] = 0xff0000;
|
||||
palette[Text][Disabled] = 0xeeeeee;
|
||||
palette[Text][Normal] = 0xeeeeee;
|
||||
palette[Text][Hover] = 0xaaaaaa;
|
||||
palette[Text][Pressed] = 0xaaaaaa;
|
||||
palette[Primitive][Disabled] = 0xeeeeee;
|
||||
palette[Primitive][Normal] = 0xeeeeee;
|
||||
palette[Primitive][Hover] = 0xeeeeee;
|
||||
palette[Primitive][Pressed] = 0xeeeeee;
|
||||
|
||||
setCurrentState(Normal);
|
||||
}
|
||||
|
||||
Palette::~Palette()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
COLORREF Palette::color(Role role)
|
||||
{
|
||||
return RGB((currentColors[role] & 0xff0000) >> 16, (currentColors[role] & 0xff00) >> 8, currentColors[role] & 0xff);
|
||||
}
|
||||
|
||||
void Palette::setColor(Role role, State state, DWORD color)
|
||||
{
|
||||
palette[role][state] = color;
|
||||
currentColors[role] = palette[role][currentState];
|
||||
}
|
||||
|
||||
void Palette::setCurrentState(State state)
|
||||
{
|
||||
currentColors[Background] = palette[Background][state];
|
||||
currentColors[Border] = palette[Border][state];
|
||||
currentColors[Base] = palette[Base][state];
|
||||
currentColors[AlternateBase] = palette[AlternateBase][state];
|
||||
currentColors[Text] = palette[Text][state];
|
||||
currentColors[Primitive] = palette[Primitive][state];
|
||||
currentState = state;
|
||||
}
|
||||
41
win-linux/extras/online-installer/src/uiclasses/palette.h
Normal file
41
win-linux/extras/online-installer/src/uiclasses/palette.h
Normal file
@ -0,0 +1,41 @@
|
||||
#ifndef PALETTE_H
|
||||
#define PALETTE_H
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
|
||||
class Palette
|
||||
{
|
||||
public:
|
||||
Palette();
|
||||
~Palette();
|
||||
|
||||
enum Role : BYTE {
|
||||
Background = 0,
|
||||
Border,
|
||||
Base,
|
||||
AlternateBase,
|
||||
Text,
|
||||
Primitive,
|
||||
PALETTE_ROLE_COUNT
|
||||
};
|
||||
|
||||
enum State : BYTE {
|
||||
Disabled = 0,
|
||||
Normal,
|
||||
Hover,
|
||||
Pressed,
|
||||
PALETTE_STATE_COUNT
|
||||
};
|
||||
|
||||
COLORREF color(Role);
|
||||
void setColor(Role, State, DWORD);
|
||||
void setCurrentState(State);
|
||||
|
||||
private:
|
||||
DWORD palette[PALETTE_ROLE_COUNT][PALETTE_STATE_COUNT];
|
||||
DWORD currentColors[PALETTE_ROLE_COUNT];
|
||||
State currentState;
|
||||
};
|
||||
|
||||
#endif // PALETTE_H
|
||||
110
win-linux/extras/online-installer/src/uiclasses/progressbar.cpp
Normal file
110
win-linux/extras/online-installer/src/uiclasses/progressbar.cpp
Normal file
@ -0,0 +1,110 @@
|
||||
#include "progressbar.h"
|
||||
#include "drawningengine.h"
|
||||
|
||||
#define DEFAULT_PULSE_STEP 1
|
||||
|
||||
|
||||
ProgressBar::ProgressBar(Widget *parent) :
|
||||
Widget(parent, ObjectType::WidgetType),
|
||||
m_progress(0),
|
||||
m_pulse_pos(-1),
|
||||
m_pulse_direction(1),
|
||||
m_pulse_step(DEFAULT_PULSE_STEP)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ProgressBar::~ProgressBar()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ProgressBar::setProgress(int progress)
|
||||
{
|
||||
m_progress = progress;
|
||||
update();
|
||||
}
|
||||
|
||||
void ProgressBar::pulse(bool enable)
|
||||
{
|
||||
m_pulse_pos = enable ? 0 : -1;
|
||||
m_pulse_direction = 1;
|
||||
if (enable) {
|
||||
timeBeginPeriod(1);
|
||||
SetTimer(m_hWnd, PROGRESS_PULSE_TIMER_ID, 17, NULL);
|
||||
} else {
|
||||
KillTimer(m_hWnd, PROGRESS_PULSE_TIMER_ID);
|
||||
timeEndPeriod(1);
|
||||
}
|
||||
}
|
||||
|
||||
void ProgressBar::setPulseStep(int step)
|
||||
{
|
||||
if (step < 1)
|
||||
step = 1;
|
||||
else
|
||||
if (step > 50)
|
||||
step = 50;
|
||||
m_pulse_step = step;
|
||||
}
|
||||
|
||||
bool ProgressBar::event(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT *result)
|
||||
{
|
||||
switch (msg) {
|
||||
// case WM_LBUTTONDOWN: {
|
||||
// palette()->setCurrentState(Palette::Pressed);
|
||||
// repaint();
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// case WM_LBUTTONUP: {
|
||||
// palette()->setCurrentState(Palette::Hover);
|
||||
// repaint();
|
||||
// break;
|
||||
// }
|
||||
// case WM_MOUSEENTER: {
|
||||
// palette()->setCurrentState(Palette::Hover);
|
||||
// repaint();
|
||||
// break;
|
||||
// }
|
||||
|
||||
// case WM_MOUSELEAVE:
|
||||
// case WM_NCMOUSELEAVE: {
|
||||
// palette()->setCurrentState(Palette::Normal);
|
||||
// repaint();
|
||||
// break;
|
||||
// }
|
||||
|
||||
case WM_PAINT: {
|
||||
RECT rc;
|
||||
GetClientRect(m_hWnd, &rc);
|
||||
|
||||
engine()->Begin(this, m_hWnd, &rc);
|
||||
engine()->DrawProgressBar(m_progress, m_pulse_pos);
|
||||
engine()->End();
|
||||
|
||||
*result = FALSE;
|
||||
return true;
|
||||
}
|
||||
|
||||
case WM_TIMER: {
|
||||
if (wParam == PROGRESS_PULSE_TIMER_ID) {
|
||||
m_pulse_pos += m_pulse_direction * m_pulse_step;
|
||||
if (m_pulse_pos >= 100) {
|
||||
m_pulse_pos = 100;
|
||||
m_pulse_direction = -1;
|
||||
} else
|
||||
if (m_pulse_pos <= 0) {
|
||||
m_pulse_pos = 0;
|
||||
m_pulse_direction = 1;
|
||||
}
|
||||
update();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return Widget::event(msg, wParam, lParam, result);
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
#ifndef PROGRESSBAR_H
|
||||
#define PROGRESSBAR_H
|
||||
|
||||
#include "widget.h"
|
||||
//#include <gdiplus.h>
|
||||
|
||||
|
||||
class ProgressBar : public Widget
|
||||
{
|
||||
public:
|
||||
ProgressBar(Widget *parent = nullptr);
|
||||
virtual ~ProgressBar();
|
||||
|
||||
void setProgress(int progress);
|
||||
void pulse(bool);
|
||||
void setPulseStep(int);
|
||||
|
||||
/* callback */
|
||||
|
||||
protected:
|
||||
virtual bool event(UINT, WPARAM, LPARAM, LRESULT*) override;
|
||||
|
||||
private:
|
||||
int m_progress,
|
||||
m_pulse_pos,
|
||||
m_pulse_direction,
|
||||
m_pulse_step;
|
||||
};
|
||||
|
||||
#endif // PROGRESSBAR_H
|
||||
@ -0,0 +1,59 @@
|
||||
#include "radiobutton.h"
|
||||
#include "drawningengine.h"
|
||||
#include "metrics.h"
|
||||
#include <windowsx.h>
|
||||
|
||||
|
||||
RadioButton::RadioButton(Widget *parent, const std::wstring &text) :
|
||||
AbstractButton(parent, text),
|
||||
m_checked(false)
|
||||
{
|
||||
metrics()->setMetrics(Metrics::TextAlignment, Metrics::AlignHLeft | Metrics::AlignVCenter);
|
||||
}
|
||||
|
||||
RadioButton::~RadioButton()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void RadioButton::setChecked(bool checked)
|
||||
{
|
||||
m_checked = checked;
|
||||
update();
|
||||
}
|
||||
|
||||
bool RadioButton::isChecked()
|
||||
{
|
||||
return m_checked;
|
||||
}
|
||||
|
||||
bool RadioButton::event(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT *result)
|
||||
{
|
||||
switch (msg) {
|
||||
case WM_PAINT: {
|
||||
RECT rc;
|
||||
GetClientRect(m_hWnd, &rc);
|
||||
|
||||
engine()->Begin(this, m_hWnd, &rc);
|
||||
engine()->DrawRadioButton(m_text, m_checked);
|
||||
if (metrics()->value(Metrics::BorderWidth) != 0)
|
||||
engine()->DrawBorder();
|
||||
|
||||
engine()->End();
|
||||
|
||||
*result = FALSE;
|
||||
return true;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return AbstractButton::event(msg, wParam, lParam, result);
|
||||
}
|
||||
|
||||
void RadioButton::click()
|
||||
{
|
||||
m_checked = true;
|
||||
update();
|
||||
AbstractButton::click();
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
#ifndef RADIOBUTTON_H
|
||||
#define RADIOBUTTON_H
|
||||
|
||||
#include "abstractbutton.h"
|
||||
|
||||
|
||||
class RadioButton : public AbstractButton
|
||||
{
|
||||
public:
|
||||
RadioButton(Widget *parent = nullptr, const std::wstring &text = L"");
|
||||
virtual ~RadioButton();
|
||||
|
||||
void setChecked(bool checked);
|
||||
bool isChecked();
|
||||
|
||||
/* callback */
|
||||
|
||||
protected:
|
||||
virtual bool event(UINT, WPARAM, LPARAM, LRESULT*) override;
|
||||
virtual void click() override;
|
||||
|
||||
private:
|
||||
bool m_checked;
|
||||
};
|
||||
|
||||
#endif // RADIOBUTTON_H
|
||||
414
win-linux/extras/online-installer/src/uiclasses/widget.cpp
Normal file
414
win-linux/extras/online-installer/src/uiclasses/widget.cpp
Normal file
@ -0,0 +1,414 @@
|
||||
#include "widget.h"
|
||||
#include "application.h"
|
||||
#include "metrics.h"
|
||||
#include "palette.h"
|
||||
#include "drawningengine.h"
|
||||
#include <CommCtrl.h>
|
||||
|
||||
|
||||
static bool isAllocOnHeap(void *addr) {
|
||||
if (HANDLE procHeap = GetProcessHeap()) {
|
||||
if (HeapLock(procHeap)) {
|
||||
bool res = false;
|
||||
PROCESS_HEAP_ENTRY entry = {0};
|
||||
while (HeapWalk(procHeap, &entry)) {
|
||||
if ((entry.wFlags & PROCESS_HEAP_REGION) && addr >= (void*)entry.Region.lpFirstBlock && addr <= (void*)entry.Region.lpLastBlock) {
|
||||
res = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!HeapUnlock(procHeap))
|
||||
res = false;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Widget::Widget(Widget *parent) :
|
||||
Widget(parent, ObjectType::WidgetType)
|
||||
{}
|
||||
|
||||
Widget::Widget(Widget *parent, HWND hwnd) :
|
||||
Object(parent),
|
||||
DrawningSurface(),
|
||||
m_hWnd(hwnd),
|
||||
m_layout(nullptr),
|
||||
m_disabled(false),
|
||||
m_is_created(false),
|
||||
m_is_destroyed(false),
|
||||
m_is_class_destroyed(false),
|
||||
m_mouse_entered(false)
|
||||
{
|
||||
LONG style = ::GetWindowLong(m_hWnd, GWL_STYLE) | WS_CHILD;
|
||||
::SetWindowLong(m_hWnd, GWL_STYLE, style);
|
||||
m_properties[Properties::HSizeBehavior] = SizeBehavior::Expanding;
|
||||
m_properties[Properties::VSizeBehavior] = SizeBehavior::Expanding;
|
||||
SetParent(hwnd, parent->nativeWindowHandle());
|
||||
}
|
||||
|
||||
Widget::Widget(Widget *parent, ObjectType type, const Rect &rc) :
|
||||
Object(parent),
|
||||
DrawningSurface(),
|
||||
m_hWnd(nullptr),
|
||||
m_layout(nullptr),
|
||||
m_disabled(false),
|
||||
m_is_created(false),
|
||||
m_is_destroyed(false),
|
||||
m_is_class_destroyed(false),
|
||||
m_mouse_entered(false)
|
||||
{
|
||||
m_properties[Properties::HSizeBehavior] = SizeBehavior::Expanding;
|
||||
m_properties[Properties::VSizeBehavior] = SizeBehavior::Expanding;
|
||||
Application::instance()->registerWidget(this, type, rc);
|
||||
}
|
||||
|
||||
Widget::~Widget()
|
||||
{
|
||||
m_is_class_destroyed = true;
|
||||
if (m_layout) {
|
||||
if (isAllocOnHeap(m_layout))
|
||||
delete m_layout;
|
||||
m_layout = nullptr;
|
||||
}
|
||||
if (!m_is_destroyed)
|
||||
DestroyWindow(m_hWnd);
|
||||
}
|
||||
|
||||
void Widget::setGeometry(int x, int y, int width, int height)
|
||||
{
|
||||
SetWindowPos(m_hWnd, NULL, x, y, width, height, SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOOWNERZORDER /*| SWP_NOSENDCHANGING*/);
|
||||
}
|
||||
|
||||
void Widget::setDisabled(bool disable)
|
||||
{
|
||||
m_disabled = disable;
|
||||
palette()->setCurrentState(disable ? Palette::Disabled : Palette::Normal);
|
||||
update();
|
||||
}
|
||||
|
||||
void Widget::close()
|
||||
{
|
||||
PostMessage(m_hWnd, WM_CLOSE, 0, 0);
|
||||
}
|
||||
|
||||
void Widget::move(int x, int y)
|
||||
{
|
||||
SetWindowPos(m_hWnd, NULL, x, y, 0, 0, SWP_NOSIZE | SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOOWNERZORDER /*| SWP_NOSENDCHANGING*/);
|
||||
}
|
||||
|
||||
void Widget::resize(int w, int h)
|
||||
{
|
||||
SetWindowPos(m_hWnd, NULL, 0, 0, w, h, SWP_NOMOVE | SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOOWNERZORDER /*| SWP_NOSENDCHANGING*/);
|
||||
}
|
||||
|
||||
Widget *Widget::parentWidget()
|
||||
{
|
||||
return dynamic_cast<Widget*>(parent());
|
||||
}
|
||||
|
||||
std::wstring Widget::title()
|
||||
{
|
||||
return m_title;
|
||||
}
|
||||
|
||||
Size Widget::size()
|
||||
{
|
||||
RECT rc;
|
||||
GetClientRect(m_hWnd, &rc);
|
||||
return Size(rc.right - rc.left, rc.bottom - rc.top);
|
||||
}
|
||||
|
||||
void Widget::size(int *width, int *height)
|
||||
{
|
||||
RECT rc;
|
||||
GetClientRect(m_hWnd, &rc);
|
||||
*width = rc.right - rc.left;
|
||||
*height = rc.bottom - rc.top;
|
||||
}
|
||||
|
||||
void Widget::setWindowTitle(const std::wstring &title)
|
||||
{
|
||||
m_title = title;
|
||||
SetWindowText(m_hWnd, title.c_str());
|
||||
}
|
||||
|
||||
void Widget::setProperty(Properties property, int val)
|
||||
{
|
||||
m_properties[property] = val;
|
||||
}
|
||||
|
||||
void Widget::show()
|
||||
{
|
||||
ShowWindow(m_hWnd, SW_SHOW);
|
||||
UpdateWindow(m_hWnd);
|
||||
}
|
||||
|
||||
void Widget::hide()
|
||||
{
|
||||
ShowWindow(m_hWnd, SW_HIDE);
|
||||
}
|
||||
|
||||
void Widget::repaint()
|
||||
{
|
||||
if (IsWindowVisible(m_hWnd))
|
||||
RedrawWindow(m_hWnd, NULL, NULL, RDW_INVALIDATE | RDW_NOERASE | RDW_INTERNALPAINT | RDW_UPDATENOW);
|
||||
}
|
||||
|
||||
void Widget::update()
|
||||
{
|
||||
if (IsWindowVisible(m_hWnd))
|
||||
RedrawWindow(m_hWnd, NULL, NULL, RDW_INVALIDATE | RDW_NOERASE | RDW_INTERNALPAINT);
|
||||
}
|
||||
|
||||
void Widget::setLayout(Layout *layout)
|
||||
{
|
||||
if (m_layout) {
|
||||
// TODO: error: trying to add a layout when the widget contains a layout
|
||||
} else {
|
||||
m_layout = layout;
|
||||
}
|
||||
}
|
||||
|
||||
bool Widget::isCreated()
|
||||
{
|
||||
return m_is_created;
|
||||
}
|
||||
|
||||
bool Widget::underMouse()
|
||||
{
|
||||
POINT pt;
|
||||
GetCursorPos(&pt);
|
||||
return WindowFromPoint(pt) == m_hWnd;
|
||||
}
|
||||
|
||||
int Widget::property(Properties property)
|
||||
{
|
||||
return m_properties[property];
|
||||
}
|
||||
|
||||
Layout *Widget::layout()
|
||||
{
|
||||
return m_layout;
|
||||
}
|
||||
|
||||
HWND Widget::nativeWindowHandle()
|
||||
{
|
||||
return m_hWnd;
|
||||
}
|
||||
|
||||
Widget *Widget::widgetFromHwnd(Widget *parent, HWND hwnd)
|
||||
{
|
||||
return new Widget(parent, hwnd);
|
||||
}
|
||||
|
||||
int Widget::onResize(const FnVoidIntInt &callback)
|
||||
{
|
||||
m_resize_callbacks[++m_connectionId] = callback;
|
||||
return m_connectionId;
|
||||
}
|
||||
|
||||
int Widget::onMove(const FnVoidIntInt &callback)
|
||||
{
|
||||
m_move_callbacks[++m_connectionId] = callback;
|
||||
return m_connectionId;
|
||||
}
|
||||
|
||||
int Widget::onAboutToDestroy(const FnVoidVoid &callback)
|
||||
{
|
||||
m_destroy_callbacks[++m_connectionId] = callback;
|
||||
return m_connectionId;
|
||||
}
|
||||
|
||||
int Widget::onCreate(const FnVoidVoid &callback)
|
||||
{
|
||||
m_create_callbacks[++m_connectionId] = callback;
|
||||
return m_connectionId;
|
||||
}
|
||||
|
||||
int Widget::onClose(const FnVoidBoolPtr &callback)
|
||||
{
|
||||
m_close_callbacks[++m_connectionId] = callback;
|
||||
return m_connectionId;
|
||||
}
|
||||
|
||||
void Widget::disconnect(int connectionId)
|
||||
{
|
||||
{
|
||||
auto it = m_resize_callbacks.find(connectionId);
|
||||
if (it != m_resize_callbacks.end()) {
|
||||
m_resize_callbacks.erase(it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
{
|
||||
auto it = m_move_callbacks.find(connectionId);
|
||||
if (it != m_move_callbacks.end()) {
|
||||
m_move_callbacks.erase(it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
{
|
||||
auto it = m_destroy_callbacks.find(connectionId);
|
||||
if (it != m_destroy_callbacks.end()) {
|
||||
m_destroy_callbacks.erase(it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
{
|
||||
auto it = m_create_callbacks.find(connectionId);
|
||||
if (it != m_create_callbacks.end()) {
|
||||
m_create_callbacks.erase(it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
{
|
||||
auto it = m_close_callbacks.find(connectionId);
|
||||
if (it != m_close_callbacks.end()) {
|
||||
m_close_callbacks.erase(it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Widget::event(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT *result)
|
||||
{
|
||||
switch (msg) {
|
||||
case WM_ACTIVATE:
|
||||
break;
|
||||
|
||||
case WM_CREATE: {
|
||||
m_is_created = true;
|
||||
for (auto it = m_create_callbacks.begin(); it != m_create_callbacks.end(); it++)
|
||||
if (it->second)
|
||||
(it->second)();
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_SIZE:
|
||||
if (m_layout)
|
||||
m_layout->onResize(LOWORD(lParam), HIWORD(lParam));
|
||||
for (auto it = m_resize_callbacks.begin(); it != m_resize_callbacks.end(); it++)
|
||||
if (it->second)
|
||||
(it->second)(LOWORD(lParam), HIWORD(lParam));
|
||||
break;
|
||||
|
||||
case WM_MOVE:
|
||||
for (auto it = m_move_callbacks.begin(); it != m_move_callbacks.end(); it++)
|
||||
if (it->second)
|
||||
(it->second)(LOWORD(lParam), HIWORD(lParam));
|
||||
break;
|
||||
|
||||
case WM_PAINT: {
|
||||
RECT rc;
|
||||
GetClientRect(m_hWnd, &rc);
|
||||
engine()->Begin(this, m_hWnd, &rc);
|
||||
engine()->FillBackground();
|
||||
if (metrics()->value(Metrics::BorderWidth) != 0)
|
||||
engine()->DrawBorder();
|
||||
//DrawRoundedRect();
|
||||
engine()->End();
|
||||
*result = FALSE;
|
||||
return true;
|
||||
}
|
||||
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_NCLBUTTONDOWN: {
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_ERASEBKGND: {
|
||||
*result = FALSE;
|
||||
return true;
|
||||
}
|
||||
|
||||
case WM_LBUTTONDBLCLK: {
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_LBUTTONUP: {
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_MOUSEMOVE: {
|
||||
if (!m_mouse_entered) {
|
||||
m_mouse_entered = true;
|
||||
PostMessage(m_hWnd, WM_MOUSEENTER, 0, 0);
|
||||
}
|
||||
// add here impl onMouseMove
|
||||
TRACKMOUSEEVENT tme;
|
||||
tme.cbSize = sizeof(tme);
|
||||
tme.hwndTrack = m_hWnd;
|
||||
tme.dwFlags = TME_LEAVE /*| TME_HOVER*/;
|
||||
tme.dwHoverTime = HOVER_DEFAULT;
|
||||
_TrackMouseEvent(&tme);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_NCMOUSEMOVE: {
|
||||
if (!m_mouse_entered) {
|
||||
m_mouse_entered = true;
|
||||
PostMessage(m_hWnd, WM_MOUSEENTER, 0, 0);
|
||||
}
|
||||
// add here impl onMouseMove
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_MOUSEHOVER:
|
||||
case WM_NCMOUSEHOVER: {
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_MOUSEENTER: {
|
||||
// palette()->setCurrentState(Palette::Hover);
|
||||
// repaint();
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_MOUSELEAVE:
|
||||
case WM_NCMOUSELEAVE: {
|
||||
if (m_mouse_entered) {
|
||||
m_mouse_entered = false;
|
||||
}
|
||||
// palette()->setCurrentState(Palette::Normal);
|
||||
// repaint();
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_CLOSE: {
|
||||
bool accept = true;
|
||||
for (auto it = m_close_callbacks.begin(); it != m_close_callbacks.end(); it++)
|
||||
if (it->second)
|
||||
(it->second)(&accept);
|
||||
if (accept)
|
||||
DestroyWindow(m_hWnd);
|
||||
*result = TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
case WM_DESTROY: {
|
||||
m_is_destroyed = true;
|
||||
for (auto it = m_destroy_callbacks.begin(); it != m_destroy_callbacks.end(); it++)
|
||||
if (it->second)
|
||||
(it->second)();
|
||||
|
||||
if (!m_is_class_destroyed) {
|
||||
if (isAllocOnHeap(this)) {
|
||||
SetWindowLongPtr(m_hWnd, GWLP_USERDATA, 0);
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Widget::setNativeWindowHandle(HWND hWnd)
|
||||
{
|
||||
m_hWnd = hWnd;
|
||||
}
|
||||
89
win-linux/extras/online-installer/src/uiclasses/widget.h
Normal file
89
win-linux/extras/online-installer/src/uiclasses/widget.h
Normal file
@ -0,0 +1,89 @@
|
||||
#ifndef WIDGET_H
|
||||
#define WIDGET_H
|
||||
|
||||
#include "object.h"
|
||||
#include "drawingsurface.h"
|
||||
#include "layout.h"
|
||||
#include "commondefines.h"
|
||||
#include <unordered_map>
|
||||
#include <Windows.h>
|
||||
|
||||
|
||||
class Widget : public Object, public DrawningSurface
|
||||
{
|
||||
public:
|
||||
Widget(Widget *parent = nullptr);
|
||||
virtual ~Widget();
|
||||
|
||||
enum Properties : BYTE {
|
||||
HSizeBehavior,
|
||||
VSizeBehavior,
|
||||
PROPERTIES_COUNT
|
||||
};
|
||||
|
||||
enum SizeBehavior : BYTE {
|
||||
Fixed,
|
||||
Expanding,
|
||||
//Preferred
|
||||
};
|
||||
|
||||
virtual void setGeometry(int, int, int, int);
|
||||
void setDisabled(bool);
|
||||
void close();
|
||||
void move(int, int);
|
||||
void resize(int, int);
|
||||
Widget* parentWidget();
|
||||
std::wstring title();
|
||||
Size size();
|
||||
void size(int*, int*);
|
||||
void setWindowTitle(const std::wstring &title);
|
||||
void setProperty(Properties, int);
|
||||
void show();
|
||||
void hide();
|
||||
void repaint();
|
||||
void update();
|
||||
void setLayout(Layout *lut);
|
||||
bool isCreated();
|
||||
bool underMouse();
|
||||
int property(Properties);
|
||||
Layout* layout();
|
||||
HWND nativeWindowHandle();
|
||||
static Widget* widgetFromHwnd(Widget *parent, HWND);
|
||||
|
||||
/* callback */
|
||||
int onResize(const FnVoidIntInt &callback);
|
||||
int onMove(const FnVoidIntInt &callback);
|
||||
int onAboutToDestroy(const FnVoidVoid &callback);
|
||||
int onCreate(const FnVoidVoid &callback);
|
||||
int onClose(const FnVoidBoolPtr &callback);
|
||||
|
||||
virtual void disconnect(int) override;
|
||||
|
||||
protected:
|
||||
friend class Application;
|
||||
Widget(Widget *parent, HWND);
|
||||
Widget(Widget *parent, ObjectType type, const Rect &rc = Rect(CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT));
|
||||
virtual bool event(UINT, WPARAM, LPARAM, LRESULT*);
|
||||
|
||||
HWND m_hWnd;
|
||||
Layout *m_layout;
|
||||
std::wstring m_title;
|
||||
bool m_disabled;
|
||||
|
||||
private:
|
||||
void setNativeWindowHandle(HWND);
|
||||
|
||||
int m_properties[PROPERTIES_COUNT];
|
||||
std::unordered_map<int, FnVoidIntInt> m_resize_callbacks,
|
||||
m_move_callbacks;
|
||||
std::unordered_map<int, FnVoidVoid> m_create_callbacks,
|
||||
m_destroy_callbacks;
|
||||
std::unordered_map<int, FnVoidBoolPtr> m_close_callbacks;
|
||||
|
||||
bool m_is_created,
|
||||
m_is_destroyed,
|
||||
m_is_class_destroyed,
|
||||
m_mouse_entered;
|
||||
};
|
||||
|
||||
#endif // WIDGET_H
|
||||
544
win-linux/extras/online-installer/src/uiclasses/window.cpp
Normal file
544
win-linux/extras/online-installer/src/uiclasses/window.cpp
Normal file
@ -0,0 +1,544 @@
|
||||
#include "window.h"
|
||||
#include "baseutils.h"
|
||||
#include "palette.h"
|
||||
#include "metrics.h"
|
||||
#include "drawningengine.h"
|
||||
#include <windowsx.h>
|
||||
|
||||
#define DCX_USESTYLE 0x00010000
|
||||
#define NC_AREA_WIDTH 3
|
||||
#define MAIN_WINDOW_BORDER_WIDTH 1
|
||||
|
||||
using WinVer = Utils::WinVer;
|
||||
|
||||
|
||||
static BOOL CALLBACK EnumChildProc(_In_ HWND hwnd, _In_ LPARAM lParam)
|
||||
{
|
||||
ShowWindow(hwnd, SW_SHOW);
|
||||
UpdateWindow(hwnd);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static double GetLogicalDpi(HWND hWnd)
|
||||
{
|
||||
if (HMODULE module = GetModuleHandleA("user32")) {
|
||||
UINT(WINAPI *_GetDpiForWindow)(HWND) = NULL;
|
||||
*(FARPROC*)&_GetDpiForWindow = GetProcAddress(module, "GetDpiForWindow");
|
||||
if (_GetDpiForWindow)
|
||||
return _GetDpiForWindow(hWnd)/96;
|
||||
}
|
||||
HDC hdc = GetDC(NULL);
|
||||
double dpi = (double)GetDeviceCaps(hdc, LOGPIXELSX)/96;
|
||||
ReleaseDC(NULL, hdc);
|
||||
return dpi;
|
||||
}
|
||||
|
||||
static Rect availableGeometry(HWND hwnd)
|
||||
{
|
||||
Rect rc;
|
||||
if (HMONITOR monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST)) {
|
||||
MONITORINFOEX monInfo;
|
||||
ZeroMemory(&monInfo, sizeof(monInfo));
|
||||
monInfo.cbSize = sizeof(MONITORINFOEX);
|
||||
if (GetMonitorInfo(monitor, &monInfo))
|
||||
rc = Rect(monInfo.rcWork.left, monInfo.rcWork.top, monInfo.rcWork.right - monInfo.rcWork.left, monInfo.rcWork.bottom - monInfo.rcWork.top);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void GetFrameMetricsForDpi(FRAME &frame, double dpi, bool maximized = false)
|
||||
{
|
||||
WinVer ver = Utils::getWinVersion();
|
||||
int row = ver == WinVer::WinXP ? 0 :
|
||||
ver <= WinVer::Win7 ? 1 :
|
||||
ver <= WinVer::Win8_1 ? 2 :
|
||||
ver <= WinVer::Win10 ? 3 : 4;
|
||||
|
||||
int column = dpi <= 1.0 ? 0 :
|
||||
dpi <= 1.25 ? 1 :
|
||||
dpi <= 1.5 ? 2 :
|
||||
dpi <= 1.75 ? 3 :
|
||||
dpi <= 2.0 ? 4 :
|
||||
dpi <= 2.25 ? 5 :
|
||||
dpi <= 2.5 ? 6 :
|
||||
dpi <= 3.0 ? 7 :
|
||||
dpi <= 3.5 ? 8 :
|
||||
dpi <= 4.0 ? 9 :
|
||||
dpi <= 4.5 ? 10 :
|
||||
dpi <= 5.0 ? 11 : 12;
|
||||
|
||||
const int left[5][13] = { // Left margin for scales 100-500%
|
||||
{0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2}, // WinXp: for NC width 3px
|
||||
{7, 8, 10, 11, 12, 13, 15, 17, 20, 22, 25, 27, 32}, // WinVista - Win7
|
||||
{7, 8, 10, 11, 12, 13, 15, 17, 20, 22, 25, 27, 32}, // Win8 - Win8.1
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Win10
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} // Win11
|
||||
};
|
||||
frame.left = left[row][column];
|
||||
|
||||
const int top[5][13] = { // Top margin for scales 100-500%
|
||||
{0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2}, // WinXp: for NC width 3px
|
||||
{7, 8, 10, 11, 12, 13, 15, 17, 20, 22, 25, 27, 32}, // WinVista - Win7
|
||||
{7, 8, 10, 11, 12, 13, 15, 17, 20, 22, 25, 27, 32}, // Win8 - Win8.1
|
||||
{31, 38, 45, 52, 58, 65, 72, 85, 99, 112, 126, 139, 167}, // Win10
|
||||
{30, 37, 43, 50, 56, 63, 69, 82, 95, 108, 121, 134, 161} // Win11
|
||||
};
|
||||
frame.top = top[row][column];
|
||||
|
||||
if (!maximized)
|
||||
return;
|
||||
|
||||
const int left_ofs[5][13] = { // Left offset for scales 100-500%
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // WinXp
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // WinVista - Win7
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Win8 - Win8.1
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Win10
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} // Win11
|
||||
};
|
||||
frame.left -= left_ofs[row][column];
|
||||
|
||||
const int top_ofs[5][13] = { // Top offset for scales 100-500%
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // WinXp
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // WinVista - Win7
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Win8 - Win8.1
|
||||
{8, 9, 11, 12, 13, 14, 16, 18, 21, 24, 27, 30, 36}, // Win10
|
||||
{7, 8, 9, 10, 11, 12, 13, 15, 17, 19, 21, 23, 28} // Win11
|
||||
};
|
||||
frame.top -= top_ofs[row][column];
|
||||
}
|
||||
|
||||
static bool isTaskbarAutoHideOn()
|
||||
{
|
||||
APPBARDATA ABData;
|
||||
ABData.cbSize = sizeof(ABData);
|
||||
return (SHAppBarMessage(ABM_GETSTATE, &ABData) & ABS_AUTOHIDE) != 0;
|
||||
}
|
||||
|
||||
static bool isThemeActive()
|
||||
{
|
||||
static BOOL(WINAPI *IsThemeActive)() = NULL;
|
||||
if (!IsThemeActive) {
|
||||
if (HMODULE module = GetModuleHandleA("uxtheme"))
|
||||
*(FARPROC*)&IsThemeActive = GetProcAddress(module, "IsThemeActive");
|
||||
}
|
||||
return IsThemeActive ? (bool)IsThemeActive() : true;
|
||||
}
|
||||
|
||||
Window::Window(Widget *parent, const Rect &rc) :
|
||||
Widget(parent, ObjectType::WindowType, rc),
|
||||
m_centralWidget(nullptr),
|
||||
m_contentMargins(0,0,0,0),
|
||||
m_resAreaWidth(0),
|
||||
m_state(-1),
|
||||
m_borderless(true),
|
||||
m_isResizable(true),
|
||||
m_scaleChanged(false),
|
||||
m_init_size(rc.width, rc.height)
|
||||
{
|
||||
//setLayout(new BoxLayout(BoxLayout::Vertical));
|
||||
m_isThemeActive = isThemeActive();
|
||||
m_isTaskbarAutoHideOn = isTaskbarAutoHideOn();
|
||||
m_borderless = true;//isCustomWindowStyle();
|
||||
|
||||
if (m_borderless && Utils::getWinVersion() < WinVer::Win10) {
|
||||
LONG style = ::GetWindowLong(m_hWnd, GWL_STYLE) | WS_OVERLAPPEDWINDOW;
|
||||
::SetWindowLong(m_hWnd, GWL_STYLE, style & ~WS_CAPTION);
|
||||
}
|
||||
m_isMaximized = IsZoomed(m_hWnd);
|
||||
m_dpi = GetLogicalDpi(m_hWnd);
|
||||
GetFrameMetricsForDpi(m_frame, m_dpi, m_isMaximized);
|
||||
|
||||
if (m_borderless && Utils::getWinVersion() == WinVer::Win10) {
|
||||
SystemParametersInfo(SPI_GETBORDER, 0, &m_brdWidth, 0);
|
||||
m_brdColor = Utils::getColorizationColor(true, RGB(0xfe, 0xfe, 0xfe));
|
||||
}
|
||||
SetWindowPos(m_hWnd, NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
|
||||
}
|
||||
|
||||
Window::~Window()
|
||||
{
|
||||
//if (m_layout)
|
||||
// delete m_layout, m_layout = nullptr;
|
||||
}
|
||||
|
||||
void Window::setCentralWidget(Widget *wgt)
|
||||
{
|
||||
m_centralWidget = wgt;
|
||||
}
|
||||
|
||||
void Window::setContentsMargins(int left, int top, int right, int bottom)
|
||||
{
|
||||
m_contentMargins = Margins(left, top, right, bottom);
|
||||
if (IsWindowVisible(m_hWnd))
|
||||
SetWindowPos(m_hWnd, NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
|
||||
}
|
||||
|
||||
void Window::setResizable(bool isResizable)
|
||||
{
|
||||
if (m_isResizable != isResizable) {
|
||||
m_isResizable = isResizable;
|
||||
LONG style = ::GetWindowLong(m_hWnd, GWL_STYLE);
|
||||
::SetWindowLong(m_hWnd, GWL_STYLE, m_isResizable ? style | WS_MAXIMIZEBOX : style & ~WS_MAXIMIZEBOX);
|
||||
}
|
||||
}
|
||||
|
||||
void Window::showAll()
|
||||
{
|
||||
ShowWindow(m_hWnd, SW_SHOW);
|
||||
UpdateWindow(m_hWnd);
|
||||
EnumChildWindows(m_hWnd, EnumChildProc, 0);
|
||||
}
|
||||
|
||||
void Window::showNormal()
|
||||
{
|
||||
ShowWindow(m_hWnd, SW_RESTORE);
|
||||
}
|
||||
|
||||
void Window::showMinimized()
|
||||
{
|
||||
ShowWindow(m_hWnd, SW_SHOWMINIMIZED);
|
||||
}
|
||||
|
||||
void Window::showMaximized()
|
||||
{
|
||||
ShowWindow(m_hWnd, SW_SHOWMAXIMIZED);
|
||||
}
|
||||
|
||||
void Window::setIcon(int id)
|
||||
{
|
||||
HMODULE hInstance = GetModuleHandle(NULL);
|
||||
HICON hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(id));
|
||||
SendMessage(m_hWnd, WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
|
||||
SendMessage(m_hWnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
|
||||
}
|
||||
|
||||
bool Window::isMinimized()
|
||||
{
|
||||
WINDOWPLACEMENT wpl;
|
||||
wpl.length = sizeof(wpl);
|
||||
if (GetWindowPlacement(m_hWnd, &wpl))
|
||||
return wpl.showCmd == SW_SHOWMINIMIZED;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Window::isMaximized()
|
||||
{
|
||||
WINDOWPLACEMENT wpl;
|
||||
wpl.length = sizeof(wpl);
|
||||
if (GetWindowPlacement(m_hWnd, &wpl))
|
||||
return wpl.showCmd == SW_SHOWMAXIMIZED;
|
||||
return false;
|
||||
}
|
||||
|
||||
Widget *Window::centralWidget()
|
||||
{
|
||||
return m_centralWidget;
|
||||
}
|
||||
|
||||
int Window::onStateChanged(const FnVoidInt &callback)
|
||||
{
|
||||
m_state_callbacks[++m_connectionId] = callback;
|
||||
return m_connectionId;
|
||||
}
|
||||
|
||||
void Window::disconnect(int connectionId)
|
||||
{
|
||||
auto it = m_state_callbacks.find(connectionId);
|
||||
if (it != m_state_callbacks.end())
|
||||
m_state_callbacks.erase(it);
|
||||
}
|
||||
|
||||
bool Window::event(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT *result)
|
||||
{
|
||||
switch (msg) {
|
||||
case WM_DPICHANGED: {
|
||||
m_dpi = (double)HIWORD(wParam)/96;
|
||||
RECT *prc = (RECT*)lParam;
|
||||
GetFrameMetricsForDpi(m_frame, m_dpi, m_isMaximized);
|
||||
SetWindowPos(m_hWnd, NULL, prc->left, prc->top, prc->right - prc->left, prc->bottom - prc->top, SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_NCMOUSEMOVE:
|
||||
case WM_MOUSEMOVE: {
|
||||
//int x = GET_X_LPARAM(lParam);
|
||||
//int y = GET_Y_LPARAM(lParam);
|
||||
//printf("Window Move Event: %d x %d \t %lld\n", x, y, (long long)this);
|
||||
//fflush(stdout);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_MOUSEHOVER:
|
||||
case WM_NCMOUSEHOVER: {
|
||||
//int x = GET_X_LPARAM(lParam);
|
||||
//int y = GET_Y_LPARAM(lParam);
|
||||
//printf("Window Hover Event: %d x %d \t %lld\n", x, y, (long long)this);
|
||||
//fflush(stdout);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_PAINT: {
|
||||
RECT rc;
|
||||
GetClientRect(m_hWnd, &rc);
|
||||
engine()->Begin(this, m_hWnd, &rc);
|
||||
engine()->FillBackground();
|
||||
if (metrics()->value(Metrics::BorderWidth) != 0)
|
||||
engine()->DrawBorder();
|
||||
if (m_brdWidth != 0)
|
||||
engine()->DrawTopBorder(m_brdWidth, m_brdColor);
|
||||
engine()->End();
|
||||
*result = FALSE;
|
||||
return true;
|
||||
}
|
||||
|
||||
case WM_NCPAINT: {
|
||||
if (Utils::getWinVersion() > WinVer::Win7 || !m_borderless)
|
||||
return false;
|
||||
if (HDC hdc = ::GetDCEx(m_hWnd, 0, DCX_WINDOW | DCX_USESTYLE)) {
|
||||
RECT rcc, rcw;
|
||||
::GetClientRect(m_hWnd, &rcc);
|
||||
::GetWindowRect(m_hWnd, &rcw);
|
||||
POINT pt;
|
||||
pt.x = rcw.left;
|
||||
pt.y = rcw.top;
|
||||
::MapWindowPoints(0, m_hWnd, (LPPOINT)&rcw, (sizeof(RECT)/sizeof(POINT)));
|
||||
::OffsetRect(&rcc, -rcw.left, -rcw.top);
|
||||
::OffsetRect(&rcw, -rcw.left, -rcw.top);
|
||||
HRGN rgntemp = NULL;
|
||||
if (wParam == NULLREGION || wParam == ERROR) {
|
||||
::ExcludeClipRect(hdc, rcc.left, rcc.top, rcc.right, rcc.bottom);
|
||||
} else {
|
||||
rgntemp = ::CreateRectRgn(rcc.left + pt.x, rcc.top + pt.y, rcc.right + pt.x, rcc.bottom + pt.y);
|
||||
if (::CombineRgn(rgntemp, (HRGN)wParam, rgntemp, RGN_DIFF) == NULLREGION) {
|
||||
// nothing to paint
|
||||
}
|
||||
::OffsetRgn(rgntemp, -pt.x, -pt.y);
|
||||
::ExtSelectClipRgn(hdc, rgntemp, RGN_AND);
|
||||
}
|
||||
HBRUSH hbrushBkg = ::CreateSolidBrush(palette()->color(Palette::Background));
|
||||
::FillRect(hdc, &rcw, hbrushBkg);
|
||||
::DeleteObject(hbrushBkg);
|
||||
|
||||
// HRGN hrgn = CreateRectRgn(0, 0, 0, 0);
|
||||
// GetWindowRgn(msg->hwnd, hrgn);
|
||||
HBRUSH hbrushBrd = ::CreateSolidBrush(palette()->color(Palette::Border));
|
||||
::FrameRect(hdc, &rcw, hbrushBrd); // Drawing NC border when using ~WS_CAPTION
|
||||
// ::FrameRgn(hdc, hrgn, hbrushBrd, 1, 1); // Drawing NC border when using WS_CAPTION
|
||||
::DeleteObject(hbrushBrd);
|
||||
// ::DeleteObject(hrgn);
|
||||
|
||||
::ReleaseDC(m_hWnd, hdc);
|
||||
if (rgntemp != 0)
|
||||
::DeleteObject(rgntemp);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
case WM_NCCALCSIZE: {
|
||||
if (!m_borderless || !wParam)
|
||||
return false;
|
||||
NCCALCSIZE_PARAMS *params = (NCCALCSIZE_PARAMS*)lParam;
|
||||
if (!m_isThemeActive) {
|
||||
*result = m_isMaximized ? 0 : DefWindowProc(m_hWnd, WM_NCCALCSIZE, wParam, lParam);
|
||||
return true;
|
||||
}
|
||||
LRESULT res = DefWindowProc(m_hWnd, WM_NCCALCSIZE, wParam, lParam);
|
||||
params->rgrc[0].left -= m_frame.left;
|
||||
params->rgrc[0].top -= m_frame.top;
|
||||
params->rgrc[0].right += m_frame.left;
|
||||
params->rgrc[0].bottom += m_frame.left;
|
||||
if (m_isMaximized && m_isTaskbarAutoHideOn && (Utils::getWinVersion() >= WinVer::Win10))
|
||||
params->rgrc[0].bottom -= 2;
|
||||
*result = res;
|
||||
return true;
|
||||
}
|
||||
|
||||
case WM_NCHITTEST: {
|
||||
if (m_isResizable) {
|
||||
if (m_borderless) {
|
||||
RECT rect;
|
||||
GetWindowRect(m_hWnd, &rect);
|
||||
long x = GET_X_LPARAM(lParam);
|
||||
long y = GET_Y_LPARAM(lParam);
|
||||
if (x <= rect.left + m_resAreaWidth) {
|
||||
if (y <= rect.top + m_resAreaWidth)
|
||||
*result = HTTOPLEFT;
|
||||
else
|
||||
if (y > rect.top + m_resAreaWidth && y < rect.bottom - m_resAreaWidth)
|
||||
*result = HTLEFT;
|
||||
else
|
||||
if (y >= rect.bottom - m_resAreaWidth)
|
||||
*result = HTBOTTOMLEFT;
|
||||
} else
|
||||
if (x > rect.left + m_resAreaWidth && x < rect.right - m_resAreaWidth) {
|
||||
if (y <= rect.top + m_resAreaWidth)
|
||||
*result = HTTOP;
|
||||
else
|
||||
if (y >= rect.bottom - m_resAreaWidth)
|
||||
*result = HTBOTTOM;
|
||||
} else
|
||||
if (x >= rect.right - m_resAreaWidth) {
|
||||
if (y <= rect.top + m_resAreaWidth)
|
||||
*result = HTTOPRIGHT;
|
||||
else
|
||||
if (y > rect.top + m_resAreaWidth && y < rect.bottom - m_resAreaWidth)
|
||||
*result = HTRIGHT;
|
||||
else
|
||||
if (y >= rect.bottom - m_resAreaWidth)
|
||||
*result = HTBOTTOMRIGHT;
|
||||
}
|
||||
return *result != 0;
|
||||
}
|
||||
} else {
|
||||
LRESULT hit = DefWindowProc(m_hWnd, msg, wParam, lParam);
|
||||
if (hit == HTBOTTOM || hit == HTLEFT || hit == HTRIGHT || hit == HTTOP ||
|
||||
hit == HTBOTTOMLEFT || hit == HTBOTTOMRIGHT || hit == HTTOPLEFT || hit == HTTOPRIGHT) {
|
||||
*result = HTCLIENT;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
case WM_NCACTIVATE: {
|
||||
if (m_borderless) {
|
||||
if (Utils::getWinVersion() > WinVer::WinXP && Utils::getWinVersion() < WinVer::Win10) {
|
||||
// Prevent drawing of inactive system frame (needs ~WS_CAPTION or temporary ~WS_VISIBLE to work)
|
||||
*result = DefWindowProc(m_hWnd, WM_NCACTIVATE, wParam, -1);
|
||||
return true;
|
||||
} else
|
||||
if (Utils::getWinVersion() == WinVer::Win10) {
|
||||
m_brdColor = Utils::getColorizationColor(LOWORD(wParam), RGB(0xfe, 0xfe, 0xfe));
|
||||
// POINT pt = {2,2};
|
||||
// ClientToScreen(m_hWnd, &pt);
|
||||
// HWND chld = WindowFromPoint(pt);
|
||||
// if (chld) {
|
||||
// HDC dc = GetDC(chld);
|
||||
// int x = pt.x, y = pt.y;
|
||||
// COLORREF color = GetPixel(dc, x, y);
|
||||
// ReleaseDC(chld, dc);
|
||||
|
||||
// int _red = GetRValue(color);
|
||||
// int _green = GetGValue(color);
|
||||
// int _blue = GetBValue(color);
|
||||
|
||||
// printf("Red: 0x%02x\n", _red);
|
||||
// printf("Green: 0x%02x\n", _green);
|
||||
// printf("Blue: 0x%02x\n", _blue);
|
||||
// fflush(stdout);
|
||||
// }
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
case WM_GETMINMAXINFO: {
|
||||
bool isMaximized = (bool)IsZoomed(m_hWnd);
|
||||
if (m_isMaximized != isMaximized) {
|
||||
m_isMaximized = isMaximized;
|
||||
GetFrameMetricsForDpi(m_frame, m_dpi, isMaximized);
|
||||
if (m_borderless && Utils::getWinVersion() == WinVer::Win10) {
|
||||
if (isMaximized) {
|
||||
m_brdWidth = 0;
|
||||
} else {
|
||||
SystemParametersInfo(SPI_GETBORDER, 0, &m_brdWidth, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!m_isResizable) {
|
||||
MINMAXINFO* minMaxInfo = (MINMAXINFO*)lParam;
|
||||
minMaxInfo->ptMinTrackSize.x = m_init_size.width;
|
||||
minMaxInfo->ptMinTrackSize.y = m_init_size.height;
|
||||
minMaxInfo->ptMaxTrackSize.x = m_init_size.width;
|
||||
minMaxInfo->ptMaxTrackSize.y = m_init_size.height;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_THEMECHANGED: {
|
||||
bool _isThemeActive = isThemeActive();
|
||||
if (m_isThemeActive != _isThemeActive)
|
||||
m_isThemeActive = _isThemeActive;
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_SETTINGCHANGE: {
|
||||
// if (wParam == SPI_SETWINARRANGING) {
|
||||
// if (Utils::getWinVersion() > Utils::WinVer::Win10)
|
||||
// SendMessage((HWND)m_boxTitleBtns->winId(), WM_SETTINGCHANGE, 0, 0);
|
||||
// }
|
||||
// printf(" Settings...\n");
|
||||
// fflush(stdout);
|
||||
// snapLayoutAllowed = isArrangingAllowed();
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_SIZING: {
|
||||
// if (m_borderless)
|
||||
// RedrawWindow(m_hWnd, NULL, NULL, RDW_INVALIDATE | RDW_NOERASE | RDW_INTERNALPAINT);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_SIZE: {
|
||||
switch (wParam) {
|
||||
case SIZE_MAXIMIZED:
|
||||
case SIZE_MINIMIZED:
|
||||
case SIZE_RESTORED: {
|
||||
if (m_state != (int)wParam) {
|
||||
m_state = (int)wParam;
|
||||
for (auto it = m_state_callbacks.begin(); it != m_state_callbacks.end(); it++)
|
||||
if (it->second)
|
||||
(it->second)(m_state);
|
||||
|
||||
if (m_borderless) {
|
||||
if (m_isMaximized) {
|
||||
if (Utils::getWinVersion() < WinVer::Win10) {
|
||||
m_resAreaWidth = 0;
|
||||
Rect rc = availableGeometry(m_hWnd);
|
||||
int offset = 0;
|
||||
if (Utils::getWinVersion() == WinVer::WinXP) {
|
||||
if (isTaskbarAutoHideOn())
|
||||
offset += NC_AREA_WIDTH + 1;
|
||||
if (m_isThemeActive) {
|
||||
rc.x += -NC_AREA_WIDTH;
|
||||
rc.y += -NC_AREA_WIDTH;
|
||||
rc.width += 2*NC_AREA_WIDTH;
|
||||
rc.height += 2*NC_AREA_WIDTH;
|
||||
}
|
||||
} else
|
||||
if (Utils::getWinVersion() > WinVer::WinXP && isTaskbarAutoHideOn())
|
||||
offset += 2;
|
||||
SetWindowPos(m_hWnd, NULL, rc.x, rc.y, rc.width, rc.height - offset, SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING);
|
||||
}
|
||||
} else {
|
||||
if (Utils::getWinVersion() < WinVer::Win10) {
|
||||
m_resAreaWidth = (int)round(MAIN_WINDOW_BORDER_WIDTH * m_dpi);
|
||||
if (Utils::getWinVersion() == WinVer::WinXP)
|
||||
m_resAreaWidth -= NC_AREA_WIDTH;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_centralWidget) {
|
||||
int top_offset = 0;
|
||||
if (m_borderless && !m_isMaximized && Utils::getWinVersion() == Utils::WinVer::Win10)
|
||||
top_offset = m_brdWidth;
|
||||
m_centralWidget->setGeometry(m_contentMargins.left + m_resAreaWidth, m_contentMargins.top + top_offset + m_resAreaWidth,
|
||||
LOWORD(lParam) - m_contentMargins.right - m_contentMargins.left - 2*m_resAreaWidth,
|
||||
HIWORD(lParam) - m_contentMargins.bottom - m_contentMargins.top - top_offset - 2*m_resAreaWidth);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return Widget::event(msg, wParam, lParam, result);
|
||||
}
|
||||
67
win-linux/extras/online-installer/src/uiclasses/window.h
Normal file
67
win-linux/extras/online-installer/src/uiclasses/window.h
Normal file
@ -0,0 +1,67 @@
|
||||
#ifndef WINDOW_H
|
||||
#define WINDOW_H
|
||||
|
||||
#include "widget.h"
|
||||
|
||||
#define DEFAULT_WINDOW_RECT Rect(100,100,1368,768)
|
||||
|
||||
|
||||
struct FRAME {
|
||||
FRAME() : left(0), top(0)
|
||||
{}
|
||||
FRAME(FRAME &frame) {
|
||||
left = frame.left;
|
||||
top = frame.top;
|
||||
}
|
||||
int left, top;
|
||||
};
|
||||
|
||||
class Window : public Widget
|
||||
{
|
||||
public:
|
||||
Window(Widget *parent = nullptr, const Rect &rc = DEFAULT_WINDOW_RECT);
|
||||
virtual ~Window();
|
||||
|
||||
void setCentralWidget(Widget*);
|
||||
void setContentsMargins(int, int, int, int);
|
||||
void setResizable(bool);
|
||||
void showAll();
|
||||
void showNormal();
|
||||
void showMinimized();
|
||||
void showMaximized();
|
||||
void setIcon(int);
|
||||
void setLayout(Layout*) = delete;
|
||||
bool isMinimized();
|
||||
bool isMaximized();
|
||||
Widget *centralWidget();
|
||||
Layout *layout() = delete;
|
||||
|
||||
/* callback */
|
||||
int onStateChanged(const FnVoidInt &callback);
|
||||
|
||||
virtual void disconnect(int) override;
|
||||
|
||||
protected:
|
||||
virtual bool event(UINT, WPARAM, LPARAM, LRESULT*) override;
|
||||
|
||||
private:
|
||||
Widget *m_centralWidget;
|
||||
Margins m_contentMargins;
|
||||
COLORREF m_brdColor;
|
||||
int m_brdWidth,
|
||||
m_resAreaWidth,
|
||||
m_state;
|
||||
double m_dpi;
|
||||
FRAME m_frame;
|
||||
bool m_borderless,
|
||||
m_isResizable,
|
||||
m_isMaximized,
|
||||
m_isThemeActive,
|
||||
m_isTaskbarAutoHideOn,
|
||||
m_scaleChanged;
|
||||
Size m_init_size;
|
||||
|
||||
std::unordered_map<int, FnVoidInt> m_state_callbacks;
|
||||
};
|
||||
|
||||
#endif // WINDOW_H
|
||||
@ -31,34 +31,57 @@
|
||||
*/
|
||||
|
||||
#include "utils.h"
|
||||
#include "baseutils.h"
|
||||
#include "resource.h"
|
||||
#include "translator.h"
|
||||
#include <Windows.h>
|
||||
#include <shlwapi.h>
|
||||
#include <fstream>
|
||||
#include <regex>
|
||||
#include <algorithm>
|
||||
#include <Softpub.h>
|
||||
#include <TlHelp32.h>
|
||||
#include <sstream>
|
||||
#include <Msi.h>
|
||||
#include <ShlObj.h>
|
||||
// #include <sstream>
|
||||
#include "../../src/defines.h"
|
||||
#include "../../src/prop/defines_p.h"
|
||||
|
||||
#define _TR(str) Translator::tr(str).c_str()
|
||||
#define APP_REG_PATH "\\" REG_GROUP_KEY "\\" REG_APP_NAME
|
||||
#define BIT123_LAYOUTRTL 0x08000000
|
||||
#ifndef LOCALE_IREADINGLAYOUT
|
||||
# define LOCALE_IREADINGLAYOUT 0x70
|
||||
#endif
|
||||
|
||||
|
||||
static void RegQueryStringValue(HKEY rootKey, LPCWSTR subkey, REGSAM advFlags, LPCWSTR value, wstring &result)
|
||||
{
|
||||
HKEY hKey;
|
||||
if (RegOpenKeyExW(rootKey, subkey, 0, KEY_READ | advFlags, &hKey) == ERROR_SUCCESS) {
|
||||
DWORD type = REG_SZ, cbData = 0;
|
||||
if (SHGetValue(hKey, L"", value, &type, NULL, &cbData) == ERROR_SUCCESS) {
|
||||
wchar_t *pvData = (wchar_t*)malloc(cbData);
|
||||
if (SHGetValue(hKey, L"", value, &type, (void*)pvData, &cbData) == ERROR_SUCCESS)
|
||||
result = pvData;
|
||||
free(pvData);
|
||||
}
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
}
|
||||
|
||||
namespace NS_Utils
|
||||
{
|
||||
wstring GetLastErrorAsString()
|
||||
wstring GetLastErrorAsString(DWORD _errID)
|
||||
{
|
||||
DWORD errID = ::GetLastError();
|
||||
DWORD errID = _errID != 0 ? _errID : ::GetLastError();
|
||||
if (errID == 0)
|
||||
return _T("");
|
||||
|
||||
LPTSTR msgBuff = NULL;
|
||||
size_t size = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL, errID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&msgBuff, 0, NULL);
|
||||
wstring msg(msgBuff, (int)size);
|
||||
wstring msg = _TR(LABEL_ERR_COMMON) + wstring(L" ") + std::to_wstring(errID);
|
||||
if (size > 0)
|
||||
msg.append(L"\n" + wstring(msgBuff, (int)size));
|
||||
LocalFree(msgBuff);
|
||||
return msg;
|
||||
}
|
||||
@ -68,13 +91,13 @@ namespace NS_Utils
|
||||
if (showError)
|
||||
str += _T(" ") + GetLastErrorAsString();
|
||||
wstring caption(_T(" "));
|
||||
caption.append(_TR(CAPTION_TEXT));
|
||||
caption.append(_TR(CAPTION));
|
||||
MessageBox(NULL, str.c_str(), caption.c_str(), MB_ICONERROR | MB_SERVICE_NOTIFICATION_NT3X | MB_SETFOREGROUND);
|
||||
}
|
||||
|
||||
bool IsRtlLanguage(unsigned long lcid)
|
||||
{
|
||||
if (NS_File::getWinVersion() >= WinVer::Win7) {
|
||||
if (Utils::getWinVersion() >= Utils::WinVer::Win7) {
|
||||
DWORD layout = 0;
|
||||
if (GetLocaleInfo(lcid, LOCALE_IREADINGLAYOUT | LOCALE_RETURN_NUMBER, (LPWSTR)&layout, sizeof(layout)/sizeof(WCHAR)) > 0)
|
||||
return layout == 1;
|
||||
@ -85,15 +108,123 @@ namespace NS_Utils
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsWin64()
|
||||
{
|
||||
#ifdef _WIN64
|
||||
return true;
|
||||
#else
|
||||
BOOL wow64 = FALSE;
|
||||
return IsWow64Process(GetCurrentProcess(), &wow64) && wow64;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool IsAppInstalled(wstring &path, wstring *arch)
|
||||
{
|
||||
std::vector<REGSAM> flags{0};
|
||||
if (NS_Utils::IsWin64()) {
|
||||
#ifdef _WIN64
|
||||
flags.push_back(KEY_WOW64_32KEY);
|
||||
#else
|
||||
flags.push_back(KEY_WOW64_64KEY);
|
||||
#endif
|
||||
}
|
||||
wstring subkey(L"Software");
|
||||
subkey += _T(APP_REG_PATH);
|
||||
for (auto &flag : flags) {
|
||||
RegQueryStringValue(HKEY_LOCAL_MACHINE, subkey.c_str(), flag, L"AppPath", path);
|
||||
if (!path.empty() /*&& NS_File::fileExists(path + _T(APP_LAUNCH_NAME))*/) {
|
||||
if (arch) {
|
||||
#ifdef _WIN64
|
||||
*arch = (flag == 0) ? L"x64" : L"x86";
|
||||
#else
|
||||
*arch = (flag == 0) ? L"x86" : L"x64";
|
||||
#endif
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void InstalledVerInfo(LPCWSTR value, wstring &name, wstring &arch)
|
||||
{
|
||||
if (!name.empty())
|
||||
name.clear();
|
||||
std::vector<REGSAM> flags{0};
|
||||
if (NS_Utils::IsWin64()) {
|
||||
#ifdef _WIN64
|
||||
flags.push_back(KEY_WOW64_32KEY);
|
||||
#else
|
||||
flags.push_back(KEY_WOW64_64KEY);
|
||||
#endif
|
||||
}
|
||||
for (auto &flag : flags) {
|
||||
wstring subkey(L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\");
|
||||
subkey += _T(WINDOW_NAME);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
RegQueryStringValue(HKEY_LOCAL_MACHINE, subkey.c_str(), flag, value, name);
|
||||
if (!name.empty()) {
|
||||
if (arch.empty()) {
|
||||
#ifdef _WIN64
|
||||
arch = (flag == 0) ? L"x64" : L"x86";
|
||||
#else
|
||||
arch = (flag == 0) ? L"x86" : L"x64";
|
||||
#endif
|
||||
}
|
||||
return;
|
||||
}
|
||||
subkey += L"_is1";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Replace(wstring &str, const wstring &from, const wstring &to) {
|
||||
if (from.empty())
|
||||
return;
|
||||
size_t start_pos = 0;
|
||||
while((start_pos = str.find(from, start_pos)) != std::wstring::npos) {
|
||||
str.replace(start_pos, from.length(), to);
|
||||
start_pos += to.length();
|
||||
}
|
||||
}
|
||||
|
||||
wstring MsiGetProperty(LPCWSTR prodCode, LPCWSTR propName)
|
||||
{
|
||||
DWORD buffSize = 0;
|
||||
UINT res = MsiGetProductInfoW(prodCode, propName, NULL, &buffSize);
|
||||
if ((res == ERROR_MORE_DATA || res == ERROR_SUCCESS) && buffSize > 0) {
|
||||
++buffSize;
|
||||
wchar_t *value = new wchar_t[buffSize];
|
||||
if (MsiGetProductInfoW(prodCode, propName, value, &buffSize) == ERROR_SUCCESS) {
|
||||
wstring propValue = value;
|
||||
delete[] value;
|
||||
return propValue;
|
||||
}
|
||||
delete[] value;
|
||||
}
|
||||
return wstring();
|
||||
}
|
||||
|
||||
wstring MsiProductCode(const wstring &prodName)
|
||||
{
|
||||
DWORD ind = 0;
|
||||
WCHAR prodCode[39];
|
||||
while (MsiEnumProductsEx(NULL, NULL, MSIINSTALLCONTEXT_MACHINE, ind++, prodCode, NULL, NULL, NULL) == ERROR_SUCCESS) {
|
||||
if (MsiGetProperty(prodCode, INSTALLPROPERTY_PRODUCTNAME) == prodName)
|
||||
return prodCode;
|
||||
}
|
||||
return wstring();
|
||||
}
|
||||
}
|
||||
|
||||
namespace NS_File
|
||||
{
|
||||
bool runProcess(const wstring &fileName, const wstring &args, bool runAsAdmin)
|
||||
bool runProcess(const wstring &fileName, const wstring &args, bool runAsAdmin, bool wait)
|
||||
{
|
||||
SHELLEXECUTEINFO shExInfo = {0};
|
||||
shExInfo.cbSize = sizeof(shExInfo);
|
||||
shExInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_NO_CONSOLE | SEE_MASK_FLAG_NO_UI;
|
||||
shExInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_NO_CONSOLE /*| SEE_MASK_FLAG_NO_UI*/;
|
||||
shExInfo.hwnd = NULL;
|
||||
shExInfo.lpVerb = runAsAdmin ? _T("runas") : _T("open");
|
||||
shExInfo.lpFile = fileName.c_str();
|
||||
@ -102,7 +233,8 @@ namespace NS_File
|
||||
shExInfo.nShow = SW_HIDE;
|
||||
shExInfo.hInstApp = NULL;
|
||||
if (ShellExecuteEx(&shExInfo)) {
|
||||
WaitForSingleObject(shExInfo.hProcess, INFINITE);
|
||||
if (wait)
|
||||
WaitForSingleObject(shExInfo.hProcess, INFINITE);
|
||||
CloseHandle(shExInfo.hProcess);
|
||||
return true;
|
||||
}
|
||||
@ -144,14 +276,35 @@ namespace NS_File
|
||||
return DeleteFile(filePath.c_str()) != 0;
|
||||
}
|
||||
|
||||
bool removeDirRecursively(const wstring &dir)
|
||||
{
|
||||
WCHAR pFrom[_MAX_PATH + 1] = {0};
|
||||
swprintf_s(pFrom, sizeof(pFrom)/sizeof(WCHAR), L"%s%c", dir.c_str(), L'\0');
|
||||
SHFILEOPSTRUCT fop = {
|
||||
NULL,
|
||||
FO_DELETE,
|
||||
pFrom,
|
||||
NULL,
|
||||
FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT,
|
||||
FALSE,
|
||||
0,
|
||||
NULL
|
||||
};
|
||||
return SHFileOperation(&fop) == 0;
|
||||
}
|
||||
|
||||
wstring fromNativeSeparators(const wstring &path)
|
||||
{
|
||||
return std::regex_replace(path, std::wregex(_T("\\\\")), _T("/"));
|
||||
wstring _path(path);
|
||||
std::replace(_path.begin(), _path.end(), L'\\', L'/');
|
||||
return _path;
|
||||
}
|
||||
|
||||
wstring toNativeSeparators(const wstring &path)
|
||||
{
|
||||
return std::regex_replace(path, std::wregex(_T("\\/")), _T("\\"));
|
||||
wstring _path(path);
|
||||
std::replace(_path.begin(), _path.end(), L'/', L'\\');
|
||||
return _path;
|
||||
}
|
||||
|
||||
wstring parentPath(const wstring &path)
|
||||
@ -160,12 +313,12 @@ namespace NS_File
|
||||
return (delim == wstring::npos) ? _T("") : path.substr(0, delim);
|
||||
}
|
||||
|
||||
// wstring tempPath()
|
||||
// {
|
||||
// TCHAR buff[MAX_PATH] = {0};
|
||||
// DWORD res = ::GetTempPath(MAX_PATH, buff);
|
||||
// return (res != 0) ? fromNativeSeparators(parentPath(buff)) : _T("");
|
||||
// }
|
||||
wstring tempPath()
|
||||
{
|
||||
TCHAR buff[MAX_PATH] = {0};
|
||||
DWORD res = ::GetTempPath(MAX_PATH, buff);
|
||||
return (res != 0) ? fromNativeSeparators(parentPath(buff)) : _T("");
|
||||
}
|
||||
|
||||
wstring appPath()
|
||||
{
|
||||
@ -174,57 +327,56 @@ namespace NS_File
|
||||
return (res != 0) ? fromNativeSeparators(parentPath(buff)) : _T("");
|
||||
}
|
||||
|
||||
WinVer getWinVersion()
|
||||
wstring generateTmpFileName(const wstring &ext)
|
||||
{
|
||||
static WinVer winVer = WinVer::Undef;
|
||||
if (winVer == WinVer::Undef) {
|
||||
if (HMODULE module = GetModuleHandleA("ntdll")) {
|
||||
NTSTATUS(WINAPI *RtlGetVersion)(LPOSVERSIONINFOEXW);
|
||||
*(FARPROC*)&RtlGetVersion = GetProcAddress(module, "RtlGetVersion");
|
||||
if (RtlGetVersion) {
|
||||
OSVERSIONINFOEXW os = {0};
|
||||
os.dwOSVersionInfoSize = sizeof(os);
|
||||
RtlGetVersion(&os);
|
||||
winVer = os.dwMajorVersion == 5L && (os.dwMinorVersion == 1L || os.dwMinorVersion == 2L) ? WinVer::WinXP :
|
||||
os.dwMajorVersion == 6L && os.dwMinorVersion == 0L ? WinVer::WinVista :
|
||||
os.dwMajorVersion == 6L && os.dwMinorVersion == 1L ? WinVer::Win7 :
|
||||
os.dwMajorVersion == 6L && os.dwMinorVersion == 2L ? WinVer::Win8 :
|
||||
os.dwMajorVersion == 6L && os.dwMinorVersion == 3L ? WinVer::Win8_1 :
|
||||
os.dwMajorVersion == 10L && os.dwMinorVersion == 0L && os.dwBuildNumber < 22000 ? WinVer::Win10 :
|
||||
os.dwMajorVersion == 10L && os.dwMinorVersion == 0L && os.dwBuildNumber >= 22000 ? WinVer::Win11 :
|
||||
os.dwMajorVersion == 10L && os.dwMinorVersion > 0L ? WinVer::Win11 :
|
||||
os.dwMajorVersion > 10L ? WinVer::Win11 : WinVer::Undef;
|
||||
}
|
||||
}
|
||||
}
|
||||
return winVer;
|
||||
wstring uuid_tstr;
|
||||
UUID uuid = {0};
|
||||
RPC_WSTR wszUuid = NULL;
|
||||
if (UuidCreate(&uuid) == RPC_S_OK && UuidToStringW(&uuid, &wszUuid) == RPC_S_OK) {
|
||||
uuid_tstr = ((wchar_t*)wszUuid);
|
||||
RpcStringFreeW(&wszUuid);
|
||||
} else
|
||||
uuid_tstr = L"00000000-0000-0000-0000-000000000000";
|
||||
return NS_File::tempPath() + _T("/") + _T(FILE_PREFIX) + uuid_tstr + ext;
|
||||
}
|
||||
|
||||
// bool verifyEmbeddedSignature(const wstring &fileName)
|
||||
// {
|
||||
// WINTRUST_FILE_INFO fileInfo;
|
||||
// ZeroMemory(&fileInfo, sizeof(fileInfo));
|
||||
// fileInfo.cbStruct = sizeof(WINTRUST_FILE_INFO);
|
||||
// fileInfo.pcwszFilePath = fileName.c_str();
|
||||
// fileInfo.hFile = NULL;
|
||||
// fileInfo.pgKnownSubject = NULL;
|
||||
bool verifyEmbeddedSignature(const wstring &fileName)
|
||||
{
|
||||
WINTRUST_FILE_INFO wfi;
|
||||
ZeroMemory(&wfi, sizeof(wfi));
|
||||
wfi.cbStruct = sizeof(WINTRUST_FILE_INFO);
|
||||
wfi.pcwszFilePath = fileName.c_str();
|
||||
wfi.hFile = NULL;
|
||||
wfi.pgKnownSubject = NULL;
|
||||
|
||||
// GUID guidAction = WINTRUST_ACTION_GENERIC_VERIFY_V2;
|
||||
// WINTRUST_DATA winTrustData;
|
||||
// ZeroMemory(&winTrustData, sizeof(winTrustData));
|
||||
// winTrustData.cbStruct = sizeof(WINTRUST_DATA);
|
||||
// winTrustData.pPolicyCallbackData = NULL;
|
||||
// winTrustData.pSIPClientData = NULL;
|
||||
// winTrustData.dwUIChoice = WTD_UI_NONE;
|
||||
// winTrustData.fdwRevocationChecks = WTD_REVOKE_NONE;
|
||||
// winTrustData.dwUnionChoice = WTD_CHOICE_FILE;
|
||||
// winTrustData.dwStateAction = WTD_STATEACTION_VERIFY;
|
||||
// winTrustData.hWVTStateData = NULL;
|
||||
// winTrustData.pwszURLReference = NULL;
|
||||
// winTrustData.dwUIContext = 0;
|
||||
// winTrustData.pFile = &fileInfo;
|
||||
// return WinVerifyTrust(NULL, &guidAction, &winTrustData) == ERROR_SUCCESS;
|
||||
// }
|
||||
GUID guidAction = WINTRUST_ACTION_GENERIC_VERIFY_V2;
|
||||
WINTRUST_DATA wtd;
|
||||
ZeroMemory(&wtd, sizeof(wtd));
|
||||
wtd.cbStruct = sizeof(WINTRUST_DATA);
|
||||
wtd.pPolicyCallbackData = NULL;
|
||||
wtd.pSIPClientData = NULL;
|
||||
wtd.dwUIChoice = WTD_UI_NONE;
|
||||
wtd.fdwRevocationChecks = WTD_REVOKE_NONE;
|
||||
wtd.dwUnionChoice = WTD_CHOICE_FILE;
|
||||
wtd.dwStateAction = WTD_STATEACTION_VERIFY;
|
||||
wtd.hWVTStateData = NULL;
|
||||
wtd.pwszURLReference = NULL;
|
||||
wtd.dwUIContext = 0;
|
||||
wtd.pFile = &wfi;
|
||||
return WinVerifyTrust(NULL, &guidAction, &wtd) == ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
wstring appDataPath()
|
||||
{
|
||||
TCHAR buff[MAX_PATH] = {0};
|
||||
if (SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_LOCAL_APPDATA, NULL, SHGFP_TYPE_CURRENT, buff))) {
|
||||
wstring path(buff);
|
||||
path.append(_T(APP_REG_PATH));
|
||||
path.append(_T("\\data"));
|
||||
return path;
|
||||
}
|
||||
return _T("");
|
||||
}
|
||||
}
|
||||
|
||||
namespace NS_Logger
|
||||
|
||||
@ -33,14 +33,12 @@
|
||||
#ifndef UTILS_H
|
||||
#define UTILS_H
|
||||
|
||||
#include <Windows.h>
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <tchar.h>
|
||||
|
||||
using std::string;
|
||||
using std::wstring;
|
||||
using std::to_wstring;
|
||||
using std::list;
|
||||
|
||||
#define DEFAULT_ERROR_MESSAGE _T("An error occurred: ") + \
|
||||
wstring(_T(__FUNCTION__)) + _T(" Line: ") + to_wstring(__LINE__)
|
||||
@ -48,30 +46,34 @@ using std::list;
|
||||
_T(" ") + NS_Utils::GetLastErrorAsString()
|
||||
|
||||
|
||||
enum class WinVer : unsigned char {
|
||||
Undef, WinXP, WinVista, Win7, Win8, Win8_1, Win10, Win11
|
||||
};
|
||||
|
||||
namespace NS_Utils
|
||||
{
|
||||
wstring GetLastErrorAsString();
|
||||
wstring GetLastErrorAsString(DWORD errID = 0);
|
||||
void ShowMessage(wstring str, bool showError = false);
|
||||
bool IsRtlLanguage(unsigned long lcid);
|
||||
bool IsWin64();
|
||||
bool IsAppInstalled(wstring &path, wstring *arch = nullptr);
|
||||
void InstalledVerInfo(LPCWSTR value, wstring &name, wstring &arch);
|
||||
void Replace(wstring &str, const wstring &from, const wstring &to);
|
||||
wstring MsiGetProperty(LPCWSTR prodCode, LPCWSTR propName);
|
||||
wstring MsiProductCode(const wstring &prodName);
|
||||
}
|
||||
|
||||
namespace NS_File
|
||||
{
|
||||
bool runProcess(const wstring &fileName, const wstring &args, bool runAsAdmin = false);
|
||||
//bool isProcessRunning(const wstring &fileName);
|
||||
bool runProcess(const wstring &fileName, const wstring &args, bool runAsAdmin = false, bool wait = true);
|
||||
// bool isProcessRunning(const wstring &fileName);
|
||||
bool fileExists(const wstring &filePath);
|
||||
bool removeFile(const wstring &filePath);
|
||||
bool removeDirRecursively(const wstring &dir);
|
||||
wstring fromNativeSeparators(const wstring &path);
|
||||
wstring toNativeSeparators(const wstring &path);
|
||||
wstring parentPath(const wstring &path);
|
||||
//wstring tempPath();
|
||||
wstring tempPath();
|
||||
wstring appPath();
|
||||
WinVer getWinVersion();
|
||||
//bool verifyEmbeddedSignature(const wstring &fileName);
|
||||
wstring appDataPath();
|
||||
wstring generateTmpFileName(const wstring &ext);
|
||||
bool verifyEmbeddedSignature(const wstring &fileName);
|
||||
}
|
||||
|
||||
namespace NS_Logger
|
||||
|
||||
Reference in New Issue
Block a user