Repository: ad2017gd/RainbowTaskbar
Branch: main
Commit: 5ee0f34e91e4
Files: 163
Total size: 675.4 KB
Directory structure:
gitextract_i3_ujbve/
├── .editorconfig
├── .github/
│ └── ISSUE_TEMPLATE/
│ ├── bug_report.md
│ ├── feature_request.md
│ └── other-issue.md
├── .gitignore
├── LICENSE
├── MSIXPkg2/
│ ├── MSIXPkg2.wapproj
│ └── Package.appxmanifest
├── README.md
├── RainbowTaskbar/
│ ├── App.xaml
│ ├── App.xaml.cs
│ ├── AssemblyInfo.cs
│ ├── Configuration/
│ │ ├── Config.cs
│ │ ├── Instruction/
│ │ │ ├── DefaultPresets.cs
│ │ │ ├── Instruction.cs
│ │ │ ├── InstructionConfig.cs
│ │ │ ├── InstructionGroup.cs
│ │ │ ├── InstructionPreset.cs
│ │ │ └── Instructions/
│ │ │ ├── BorderRadiusInstruction.cs
│ │ │ ├── ClearLayerInstruction.cs
│ │ │ ├── ColorInstruction.cs
│ │ │ ├── DelayInstruction.cs
│ │ │ ├── ImageInstruction.cs
│ │ │ ├── ShapeInstruction.cs
│ │ │ ├── TextInstruction.cs
│ │ │ └── TransparencyInstruction.cs
│ │ └── Web/
│ │ └── WebConfig.cs
│ ├── Drawing/
│ │ ├── CanvasManager.cs
│ │ └── LayerManager.cs
│ ├── Editor/
│ │ ├── DebugWindow.xaml
│ │ ├── DebugWindow.xaml.cs
│ │ ├── EditorViewModel.cs
│ │ ├── EditorWindow.xaml
│ │ ├── EditorWindow.xaml.cs
│ │ └── Pages/
│ │ ├── About.xaml
│ │ ├── About.xaml.cs
│ │ ├── Browse.xaml
│ │ ├── Browse.xaml.cs
│ │ ├── Configs.xaml
│ │ ├── Configs.xaml.cs
│ │ ├── Controls/
│ │ │ ├── ConfigListItemControl.xaml
│ │ │ ├── ConfigListItemControl.xaml.cs
│ │ │ ├── InstructionContextMenu.xaml
│ │ │ ├── InstructionContextMenu.xaml.cs
│ │ │ ├── InstructionControls/
│ │ │ │ ├── BorderRadiusInstructionControl.xaml
│ │ │ │ ├── BorderRadiusInstructionControl.xaml.cs
│ │ │ │ ├── ClearLayerInstructionControl.xaml
│ │ │ │ ├── ClearLayerInstructionControl.xaml.cs
│ │ │ │ ├── ColorInstructionControl.xaml
│ │ │ │ ├── ColorInstructionControl.xaml.cs
│ │ │ │ ├── Converters/
│ │ │ │ │ ├── ColorConverter.cs
│ │ │ │ │ ├── DivideHalf.cs
│ │ │ │ │ ├── FileExists.cs
│ │ │ │ │ └── FloatToPercentage.cs
│ │ │ │ ├── DelayInstructionControl.xaml
│ │ │ │ ├── DelayInstructionControl.xaml.cs
│ │ │ │ ├── ImageInstructionControl.xaml
│ │ │ │ ├── ImageInstructionControl.xaml.cs
│ │ │ │ ├── ShapeInstructionControl.xaml
│ │ │ │ ├── ShapeInstructionControl.xaml.cs
│ │ │ │ ├── TextInstructionControl.xaml
│ │ │ │ ├── TextInstructionControl.xaml.cs
│ │ │ │ ├── TransparencyInstructionControl.xaml
│ │ │ │ └── TransparencyInstructionControl.xaml.cs
│ │ │ ├── IssueControl.xaml
│ │ │ ├── IssueControl.xaml.cs
│ │ │ ├── LoginControl.xaml
│ │ │ ├── LoginControl.xaml.cs
│ │ │ ├── ResultListItemControl.xaml
│ │ │ ├── ResultListItemControl.xaml.cs
│ │ │ ├── UnsafeImage.cs
│ │ │ └── WebControls/
│ │ │ ├── AddPropertyDialogControl.xaml
│ │ │ └── AddPropertyDialogControl.xaml.cs
│ │ ├── Edit/
│ │ │ ├── EditInfo.xaml
│ │ │ ├── EditInfo.xaml.cs
│ │ │ ├── EditPage.cs
│ │ │ ├── InstructionEditPage.xaml
│ │ │ ├── InstructionEditPage.xaml.cs
│ │ │ ├── ViewComments.xaml
│ │ │ ├── ViewComments.xaml.cs
│ │ │ ├── ViewInfo.xaml
│ │ │ ├── ViewInfo.xaml.cs
│ │ │ ├── WebEditPage.xaml
│ │ │ ├── WebEditPage.xaml.cs
│ │ │ └── WebView2Fixed.cs
│ │ ├── EmptyPageBadFix.xaml
│ │ ├── EmptyPageBadFix.xaml.cs
│ │ ├── EmptyPageBadFix2.xaml
│ │ ├── EmptyPageBadFix2.xaml.cs
│ │ ├── Home.xaml
│ │ ├── Home.xaml.cs
│ │ ├── Settings.xaml
│ │ └── Settings.xaml.cs
│ ├── ExplorerTAP/
│ │ └── ExplorerTAP.cs
│ ├── FodyWeavers.xml
│ ├── HTTPAPI/
│ │ └── WorkshopAPI.cs
│ ├── Helpers/
│ │ ├── AutoUpdate.cs
│ │ ├── Cache.cs
│ │ ├── DPIUtil.cs
│ │ ├── HiddenWebViewHost.xaml
│ │ ├── HiddenWebViewHost.xaml.cs
│ │ ├── JsonColorConverter.cs
│ │ ├── Taskbar.cs
│ │ └── Window.cs
│ ├── Interpolation/
│ │ └── ColorInterpolation.cs
│ ├── Languages/
│ │ ├── Localization.cs
│ │ ├── Translators.cs
│ │ ├── en_US.xaml
│ │ ├── en_US.xaml.cs
│ │ ├── fr_FR.xaml
│ │ ├── fr_FR.xaml.cs
│ │ ├── ro_RO.xaml
│ │ ├── ro_RO.xaml.cs
│ │ ├── zh_CN.cs
│ │ └── zh_CN.xaml
│ ├── Preferences/
│ │ └── Settings.cs
│ ├── Properties/
│ │ ├── Resources.Designer.cs
│ │ ├── Resources.resx
│ │ ├── Settings.Designer.cs
│ │ ├── Settings.settings
│ │ └── launchSettings.json
│ ├── RainbowTaskbar.csproj
│ ├── Taskbar.xaml
│ ├── Taskbar.xaml.cs
│ ├── TaskbarViewModel.cs
│ ├── TrayWindow.xaml
│ ├── TrayWindow.xaml.cs
│ ├── V2Legacy/
│ │ └── Configuration/
│ │ ├── Config.cs
│ │ ├── Instruction.cs
│ │ ├── InstructionPreset.cs
│ │ └── Instructions/
│ │ ├── BorderRadiusInstruction.cs
│ │ ├── ClearLayerInstruction.cs
│ │ ├── ColorInstruction.cs
│ │ ├── DelayInstruction.cs
│ │ ├── ImageInstruction.cs
│ │ ├── ShapeInstruction.cs
│ │ ├── TextInstruction.cs
│ │ └── TransparencyInstruction.cs
│ └── msix.build.props
├── RainbowTaskbar.sln
├── RainbowTaskbarDLL/
│ ├── AppearanceServiceAPI.cpp
│ ├── AppearanceServiceAPI.h
│ ├── ArmFix/
│ │ └── RpcProxy.h
│ ├── ErrorDebug.h
│ ├── Factory.h
│ ├── IUnused.h
│ ├── IUnused.idl
│ ├── RainbowTaskbarDLL.def
│ ├── RainbowTaskbarDLL.idl
│ ├── RainbowTaskbarDLL.vcxproj
│ ├── RainbowTaskbarDLL.vcxproj.filters
│ ├── TAP.cpp
│ ├── TAP.h
│ ├── Taskbar.h
│ ├── VisualTreeWatch.cpp
│ ├── VisualTreeWatch.h
│ ├── csharpinterop.cpp
│ ├── dllmain.cpp
│ ├── framework.h
│ ├── packages.config
│ └── winrt.h
├── SetupARM64.iss
└── SetupX64.iss
================================================
FILE CONTENTS
================================================
================================================
FILE: .editorconfig
================================================
[*]
charset = utf-8-bom
end_of_line = crlf
trim_trailing_whitespace = false
insert_final_newline = false
indent_style = space
indent_size = 4
# Microsoft .NET properties
csharp_new_line_before_members_in_object_initializers = false
csharp_new_line_before_open_brace = none
csharp_preferred_modifier_order = public, private, protected, internal, new, static, abstract, virtual, sealed, readonly, override, extern, unsafe, volatile, async:suggestion
csharp_space_after_cast = true
csharp_style_expression_bodied_accessors = true:suggestion
csharp_style_expression_bodied_methods = true:none
csharp_style_expression_bodied_properties = false:suggestion
csharp_style_var_elsewhere = true:suggestion
csharp_style_var_for_built_in_types = true:suggestion
csharp_style_var_when_type_is_apparent = true:suggestion
dotnet_naming_rule.constants_rule.import_to_resharper = as_predefined
dotnet_naming_rule.constants_rule.severity = warning
dotnet_naming_rule.constants_rule.style = upper_camel_case_style
dotnet_naming_rule.constants_rule.symbols = constants_symbols
dotnet_naming_rule.public_fields_rule.import_to_resharper = as_predefined
dotnet_naming_rule.public_fields_rule.severity = warning
dotnet_naming_rule.public_fields_rule.style = lower_camel_case_style
dotnet_naming_rule.public_fields_rule.symbols = public_fields_symbols
dotnet_naming_rule.static_readonly_rule.import_to_resharper = as_predefined
dotnet_naming_rule.static_readonly_rule.severity = warning
dotnet_naming_rule.static_readonly_rule.style = upper_camel_case_style
dotnet_naming_rule.static_readonly_rule.symbols = static_readonly_symbols
dotnet_naming_rule.unity_serialized_field_rule.import_to_resharper = True
dotnet_naming_rule.unity_serialized_field_rule.resharper_description = Unity serialized field
dotnet_naming_rule.unity_serialized_field_rule.resharper_guid = 5f0fdb63-c892-4d2c-9324-15c80b22a7ef
dotnet_naming_rule.unity_serialized_field_rule.severity = warning
dotnet_naming_rule.unity_serialized_field_rule.style = lower_camel_case_style
dotnet_naming_rule.unity_serialized_field_rule.symbols = unity_serialized_field_symbols
dotnet_naming_style.lower_camel_case_style.capitalization = camel_case
dotnet_naming_style.upper_camel_case_style.capitalization = pascal_case
dotnet_naming_symbols.constants_symbols.applicable_accessibilities = public, internal, protected, protected_internal, private_protected
dotnet_naming_symbols.constants_symbols.applicable_kinds = field
dotnet_naming_symbols.constants_symbols.required_modifiers = const
dotnet_naming_symbols.public_fields_symbols.applicable_accessibilities = public, internal, protected, protected_internal, private_protected
dotnet_naming_symbols.public_fields_symbols.applicable_kinds = field
dotnet_naming_symbols.static_readonly_symbols.applicable_accessibilities = public, internal, protected, protected_internal, private_protected
dotnet_naming_symbols.static_readonly_symbols.applicable_kinds = field
dotnet_naming_symbols.static_readonly_symbols.required_modifiers = static, readonly
dotnet_naming_symbols.unity_serialized_field_symbols.applicable_accessibilities = *
dotnet_naming_symbols.unity_serialized_field_symbols.applicable_kinds =
dotnet_naming_symbols.unity_serialized_field_symbols.resharper_applicable_kinds = unity_serialised_field
dotnet_naming_symbols.unity_serialized_field_symbols.resharper_required_modifiers = instance
dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary:none
dotnet_style_parentheses_in_other_binary_operators = never_if_unnecessary:none
dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary:none
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
dotnet_style_predefined_type_for_member_access = true:suggestion
dotnet_style_qualification_for_event = false:suggestion
dotnet_style_qualification_for_field = false:suggestion
dotnet_style_qualification_for_method = false:suggestion
dotnet_style_qualification_for_property = false:suggestion
dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggestion
# ReSharper properties
resharper_apply_auto_detected_rules = false
resharper_autodetect_indent_settings = true
resharper_csharp_empty_block_style = together_same_line
resharper_csharp_stick_comment = false
resharper_indent_braces_inside_statement_conditions = false
resharper_local_function_body = expression_body
resharper_show_autodetect_configure_formatting_tip = false
resharper_space_within_single_line_array_initializer_braces = false
resharper_use_indent_from_vs = false
# ReSharper inspection severities
resharper_arrange_redundant_parentheses_highlighting = hint
resharper_arrange_this_qualifier_highlighting = hint
resharper_arrange_type_member_modifiers_highlighting = hint
resharper_arrange_type_modifiers_highlighting = hint
resharper_built_in_type_reference_style_for_member_access_highlighting = hint
resharper_built_in_type_reference_style_highlighting = hint
resharper_redundant_base_qualifier_highlighting = warning
resharper_suggest_var_or_type_built_in_types_highlighting = hint
resharper_suggest_var_or_type_elsewhere_highlighting = hint
resharper_suggest_var_or_type_simple_types_highlighting = hint
resharper_web_config_module_not_resolved_highlighting = warning
resharper_web_config_type_not_resolved_highlighting = warning
resharper_web_config_wrong_module_highlighting = warning
[{*.har,*.inputactions,*.jsb2,*.jsb3,*.json,.babelrc,.eslintrc,.stylelintrc,bowerrc,jest.config}]
indent_style = space
indent_size = 2
[*.{appxmanifest,asax,ascx,aspx,axaml,build,cg,cginc,compute,cs,cshtml,dtd,fs,fsi,fsscript,fsx,hlsl,hlsli,hlslinc,master,ml,mli,nuspec,paml,razor,resw,resx,shader,skin,usf,ush,vb,xaml,xamlx,xoml,xsd}]
indent_style = space
indent_size = 4
tab_width = 4
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a bug report
title: "[BUG] "
labels: bug
assignees: ad2017gd
---
**Describe the bug**
*A clear and concise description of what the bug is.*
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
...
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Windows version and/or build**
... (can be a screenshot of winver.exe)
**RainbowTaskbar version**
...
================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: enhancement
assignees: ad2017gd
---
**Describe your feature request.**
...
================================================
FILE: .github/ISSUE_TEMPLATE/other-issue.md
================================================
---
name: Other issue
about: ONLY USE IF NOT A BUG REPORT/FEATURE REQUEST!
title: ''
labels: ''
assignees: ad2017gd
---
================================================
FILE: .gitignore
================================================
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# ASP.NET Scaffolding
ScaffoldingReadMe.txt
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.tlog
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Coverlet is a free, cross platform Code Coverage Tool
coverage*.json
coverage*.xml
coverage*.info
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio 6 auto-generated project file (contains which files were open etc.)
*.vbp
# Visual Studio 6 workspace and project file (working project files containing files to include in project)
*.dsw
*.dsp
# Visual Studio 6 technical files
*.ncb
*.aps
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# Visual Studio History (VSHistory) files
.vshistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd
# VS Code files for those working on multiple tools
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
*.code-workspace
# Local History for Visual Studio Code
.history/
# Windows Installer files from build outputs
*.cab
*.msi
*.msix
*.msm
*.msp
# JetBrains Rider
*.sln.iml
.idea/*
/RainbowTaskbar/RainbowTaskbar - Backup.csproj
/vcpkg_installed
/Output
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2023 ad2017gd
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: MSIXPkg2/MSIXPkg2.wapproj
================================================
15.0
Debug
x86
Release (MSIX)
AnyCPU
Release (MSIX)
ARM
Release (MSIX)
ARM64
Release (MSIX)
x64
Release (MSIX)
x86
Release
x86
Debug
x64
Release
x64
Debug
ARM
Release
ARM
Debug
ARM64
Release
ARM64
Debug
AnyCPU
Release
AnyCPU
$(MSBuildExtensionsPath)\Microsoft\DesktopBridge\
eeaf81a9-bb63-40d9-a733-7f25d2313df5
10.0.26100.0
10.0.17763.0
net8.0-windows17763.0
en-US
True
$(NoWarn);NU1702
..\RainbowTaskbar\RainbowTaskbar.csproj
x64
False
18A14CD3EECA6DA0643255C7613892FF281EC8AA
SHA256
False
False
0
True
False
Always
Always
Always
Always
Always
Always
Always
Always
Always
Always
Always
Always
Always
Always
Always
Designer
================================================
FILE: MSIXPkg2/Package.appxmanifest
================================================
RainbowTaskbar.
ad2017
Images\StoreLogo.png
================================================
FILE: README.md
================================================
[
* ](#microsoft-store)
[
](https://apps.microsoft.com/detail/9nn78x0674xw)
[
](https://github.com/ad2017gd/RainbowTaskbar/releases/download/3.2.2/setup-x64.exe)
[
](https://paypal.me/ad2k17)
Useful tool for Windows taskbar customization. Supports web configurations or instruction-like configurations that feature color effects, transitions, blur, images, text, rounded corners, shapes, transparency. Now rewritten in .NET 8!
Conflicts with TranslucentTB! Close it before running RainbowTaskbar
https://www.youtube.com/watch?v=HvbapfQLOZs
# Getting started
First off, grab yourself the hottest new release at https://github.com/ad2017gd/RainbowTaskbar/releases.
RainbowTaskbar is a portable app, so there's no installing required. There are setups available, but they only install a single file and create a nice shortcut for you. If not already installed, you will be prompted to install the **.NET 8** runtime.
After launching the app for the first time, the editor will automatically open. You can find other users' presets in the Browse tab, or you can create your own.

Have fun using RainbowTaskbar!
# Documentation
https://rnb.ad2017.dev/web/docs
TODO
# Thank you for 100 stars
A sincere thank you to all the users of RainbowTaskbar! Since the first release of this program in 2021, I would have never expected it to have as many users as it has now.
RainbowTaskbar has really been a passion project of mine all this time. It all started thanks to my friend telling me about the fact that, at the time, there weren't any really good
taskbar customization software (actually there were and still are but none would fit my personalization needs).
The first version of RainbowTaskbar was written in C, which was a pretty bad idea. I didn't realise at the time, but the UI was also pretty much garbage. However, when I saw
open source software websites reposting my tool, it really gave me the motivation to still work on this program.
Thanks to my other friend, [zCri](https://github.com/zCri), we both rewrote RainbowTaskbar to the (then) current v2 .NET version (now v3!), which allowed me to implement even more
features with cleaner UI.
After the rewrite, RainbowTaskbar received even more attention from people, which also made me continue updating it. However, all the attention has also led to some
copies of this software being sold on markets such as the Microsoft Store by other people, stripping it of all the credits.
If you wish to support me in the future development of this app and, perhaps, other apps, you can [buy RainbowTaskbar from the Microsoft Store](https://www.microsoft.com/store/productId/9NN78X0674XW)
which is actually published by me, or by donating on [PayPal](https://paypal.me/ad2k17). I thank you once again for using this software.
# License
See `LICENSE` for more information.
# Notes
## Microsoft Store
*The Microsoft Store version of this software is provided as a means for donations. This software is free and open-source. You can download it for free in the releases tab or by clicking the download button next to the Microsoft Store page button.
================================================
FILE: RainbowTaskbar/App.xaml
================================================
================================================
FILE: RainbowTaskbar/App.xaml.cs
================================================
using H.Pipes;
using H.Pipes.AccessControl;
using Microsoft.Web.WebView2.WinForms;
using Microsoft.Win32;
using PropertyChanged;
using RainbowTaskbar.Configuration;
using RainbowTaskbar.Configuration.Instruction;
using RainbowTaskbar.Configuration.Web;
using RainbowTaskbar.Drawing;
using RainbowTaskbar.Editor;
using RainbowTaskbar.Helpers;
using RainbowTaskbar.HTTPAPI;
using RainbowTaskbar.Languages;
using RainbowTaskbar.Preferences;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Pipes;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Security.AccessControl;
using System.Security.Principal;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization.Metadata;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Threading;
using System.Xml;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using Localization = RainbowTaskbar.Languages.Localization;
namespace RainbowTaskbar;
///
/// Interaction logic for App.xaml
///
public partial class App : Application {
[DllImport("KERNEL32.DLL", EntryPoint = "SetProcessWorkingSetSize", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool SetProcessWorkingSetSize(IntPtr pProcess, int dwMinimumWorkingSetSize, int dwMaximumWorkingSetSize);
[DllImport("KERNEL32.DLL", EntryPoint = "GetCurrentProcess", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr GetCurrentProcess();
[StructLayout(LayoutKind.Sequential)]
struct Point {
public int X;
public int Y;
}
[StructLayout(LayoutKind.Sequential)]
struct MOUSEHOOKSTRUCT {
public Point pt;
public IntPtr hwnd;
public uint wHitTestCode;
public IntPtr dwExtraInfo;
}
public delegate int MouseProc(int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("user32", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
public static extern int SetWindowsHookEx(int idHook, MouseProc lpfn, int hInstance, int threadId);
[DllImport("user32", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
public static extern int CallNextHookEx(int idHook, int nCode, IntPtr wParam, IntPtr lParam);
static int mouseHookId = -1;
static MouseProc callback = new MouseProc(HookCallback);
const int WH_MOUSE_LL = 14;
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
[StructLayout(LayoutKind.Sequential)]
public struct POINT {
public int X;
public int Y;
}
[DllImport("user32.dll")]
static extern bool ScreenToClient(IntPtr hWnd, ref POINT lpPoint);
static DateTime last = DateTime.MinValue;
[DllImport("user32.dll", EntryPoint = "RealChildWindowFromPoint", SetLastError = false)]
public static extern IntPtr RealChildWindowFromPoint(IntPtr hwndParent, int x, int y);
[DllImport("user32.dll", SetLastError = true)]
static extern bool UnhookWindowsHookEx(IntPtr hhk);
public static IntPtr FindLastChildAtPoint(IntPtr parent, int x, int y) {
IntPtr neww = RealChildWindowFromPoint(parent, x, y);
if (neww != 0 && neww != parent) return FindLastChildAtPoint(neww, x, y);
else return parent;
}
static DateTime lastMove = DateTime.MinValue;
private static int HookCallback(int nCode, IntPtr wParam, IntPtr lParam) {
var mhs = Marshal.PtrToStructure(lParam);
if (nCode >= 0) {
App.Current.Dispatcher.BeginInvoke(() => {
try {
if (App.Settings.SelectedConfig is InstructionConfig) return;
if (wParam == 0x0201 && trayWindow.TrayIcon.ContextMenu.IsOpen || wParam == 0x0204) return;
if (wParam == 0x0200 /* MOUSEMOVE */) {
if (DateTime.Now - lastMove > TimeSpan.FromMilliseconds(8)) {
lastMove = DateTime.Now;
}
else return;
}
var farLeft = (int) (App.taskbars.Count > 0 ? App.taskbars.Min(x => x.Left) : 0);
App.taskbars.ForEach(x => {
if (x.webView is null) return;
// passing WM_LBUTTONDOWN interferes with tray icon, too bad
var pn = System.Windows.Forms.Control.MousePosition;
var scale = x.windowHelper.scale;
if (!new System.Drawing.Rectangle(new((int) (x.Left * scale), (int) (x.Top * scale)), new((int) (x.ActualWidth * scale), (int) (x.ActualHeight * scale))).Contains(pn)) return;
POINT p = new POINT { X = (int) (pn.X), Y = (int) (pn.Y) };
IntPtr cch = FindLastChildAtPoint(x.webView.Handle, 0, 0);
ScreenToClient(App.Settings.GraphicsRepeat ? cch : x.windowHelper.HWND, ref p);
if (!App.Settings.GraphicsRepeat) p.X += (int) x.Left - farLeft;
PostMessage(cch, (uint) wParam, 0x0000, (IntPtr) (((uint) (p.Y) << 16) | ((((ushort) (p.X)) & 0xFFFF))));
});
} catch { }
});
}
return CallNextHookEx(mouseHookId, nCode, wParam, lParam);
}
public static List taskbars = new();
public static bool monacoExtracted = false;
public static EditorWindow editor = null;
public static TrayWindow trayWindow = (TrayWindow) Current.MainWindow;
public static Mutex mutex = new(true, "RainbowTaskbar Mutex");
public static Localization localization;
public static EditorViewModel editorViewModel = new();
public static bool firstRun = false;
public static string rainbowTaskbarDir = Path.Join(Environment.GetEnvironmentVariable("AppData"), "RainbowTaskbar");
public static string configDir = Path.Join(rainbowTaskbarDir, "configurations");
public static string monacoDir = Path.Join(rainbowTaskbarDir, "monaco");
public static LayerManager layers = null;
public static Random rnd = new();
public static HiddenWebViewHost hiddenWebViewHost = null;
public static Microsoft.Web.WebView2.Wpf.WebView2 webView { get => hiddenWebViewHost?.webView_; }
public static Mutex webViewReady = new Mutex();
public static int farLeft;
public static List AllConfigsFromFiles() {
List configs = new();
if(!Directory.Exists(configDir)) Directory.CreateDirectory(configDir);
foreach (string f in Directory.EnumerateFiles(configDir)) {
try {
Config cfg = Config.FromFile(f);
cfg.fileName = f;
configs.Add(cfg);
} catch { }
}
return configs;
}
public static ObservableCollection Configs { get; set; } = new ObservableCollection(AllConfigsFromFiles().OrderBy(x => x.Created).Reverse());
public static Settings Settings { get; set; } = Settings.FromFile();
public static void LaunchEditor() {
if (editor == null) {
editor = new EditorWindow();
}
editor.Show();
editor.WindowState = WindowState.Normal;
editor.Activate();
editor.BringIntoView();
editor.Focus();
}
public App() {
localization = new Localization();
}
public new static void Exit() {
if(trayWindow is not null) trayWindow.TrayIcon.Dispose();
StopHook();
ExplorerTAP.ExplorerTAP.Reset();
taskbars.ForEach(t => {
t.taskbarHelper.Radius = 0;
t.taskbarHelper.UpdateRadius();
t.Close();
t.taskbarHelper.SetAlpha(1);
TaskbarHelper.SendMessage(t.taskbarHelper.HWND, TaskbarHelper.WM_DWMCOMPOSITIONCHANGED, 1, null);
t.taskbarHelper.Style = TaskbarHelper.TaskbarStyle.ForceDefault;
t.taskbarHelper.SetBlur();
// win11 fix
});
Current.Dispatcher.Invoke(() => { Current.Shutdown(); });
}
[StructLayout(LayoutKind.Sequential)]
struct MSG {
public IntPtr hwnd;
public uint message;
public IntPtr wParam;
public IntPtr lParam;
public uint time;
public System.Drawing.Point pt;
}
[DllImport("user32.dll")]
static extern bool GetMessage(out MSG lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax);
[DllImport("user32.dll")]
static extern bool TranslateMessage(ref MSG lpMsg);
[DllImport("user32.dll")]
static extern IntPtr DispatchMessage(ref MSG lpMsg);
[DllImport("user32.dll", SetLastError = true)]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
public static void StartHook() {
Task.Run(() => {
Thread.CurrentThread.Priority = ThreadPriority.AboveNormal;
if (mouseHookId != -1) return;
mouseHookId = SetWindowsHookEx(WH_MOUSE_LL, callback, 0, 0);
MSG msg;
while (GetMessage(out msg, IntPtr.Zero, 0, 0)) {
TranslateMessage(ref msg);
DispatchMessage(ref msg);
}
});
}
public static void StopHook() {
UnhookWindowsHookEx(mouseHookId);
mouseHookId = -1;
}
private static bool isappfullscreen = false;
public static bool IsAppFullscreen { get => isappfullscreen; set {
isappfullscreen = value;
if(value) {
App.taskbars.ForEach(x => x.Hide());
} else {
App.taskbars.ForEach(x => x.Show());
}
} }
public static bool IsAppMicrosoftStore { get => IsMicrosoftStore(); }
public static bool IsMicrosoftStore() {
return System.Environment.ProcessPath.ToLower().StartsWith(@"c:\program files\windowsapps");
}
private void Application_Startup(object sender, StartupEventArgs e) {
var exceptionCount = 0;
AppDomain.CurrentDomain.UnhandledException += (_, e) => {
if (++exceptionCount >= 3) return;
Exception err = (Exception) e.ExceptionObject;
if(App.Settings is not null && App.Settings.workshopAPI is not null && App.Settings.ReportExceptions) {
App.Settings.workshopAPI.ReportException(err);
}
MessageBox.Show(err.Message + "\n" + err.StackTrace, "RainbowTaskbar - Unhandled exception", MessageBoxButton.OK, MessageBoxImage.Error);
Exit();
};
if (mutex.WaitOne(TimeSpan.Zero, true)) {
if (e.Args.Length > 0 && e.Args[0] == "shell") {
Task.Run(() => {
Thread.Sleep(500);
Process.Start(Environment.ProcessPath, Environment.GetCommandLineArgs());
});
}
Task.Run(async () => {
await using var pipe = new PipeServer("RainbowTaskbar Pipe");
pipe.AddAccessRules(new PipeAccessRule("Everyone", PipeAccessRights.FullControl, AccessControlType.Allow));
pipe.MessageReceived += (sender, args) => {
if (args.Message == "OpenEditor")
Dispatcher.Invoke(() => {
LaunchEditor();
});
if (args.Message.StartsWith("Shell=")) {
var uri = new Uri(args.Message.Split("Shell=")[1]);
Dispatcher.Invoke(() => {
LaunchEditor();
});
if (uri.Host == "config") {
var configs = App.Settings.workshopAPI.SearchConfigsAsync(uri.AbsolutePath.Substring(1), Editor.Pages.SortBy.Match).Result;
if(configs.Result && configs.Results.Count == 1) {
var config = configs.Parse().ElementAt(0);
config.CachedBase64Thumbnail = App.Settings.workshopAPI.DownloadThumbnailBase64(config).Result;
config.LoadImage();
Dispatcher.Invoke(() => {
App.editor.OpenConfig(config);
});
}
}
}
};
await pipe.StartAsync();
await Task.Delay(Timeout.InfiniteTimeSpan);
});
if (!Settings.GraphicsRepeat) {
webViewReady.WaitOne();
//App.webView = new();
}
App.localization.Switch(Settings.language);
if (Settings.CheckUpdate && !IsMicrosoftStore()) AutoUpdate.CheckForUpdate();
// port old config bleh
var oldconfigpath = Environment.ExpandEnvironmentVariables("%appdata%/rnbconf.xml");
var nwoldconfigpath = Environment.ExpandEnvironmentVariables("%appdata%/rnbconf.bak.xml");
if (File.Exists(oldconfigpath)) {
var res = MessageBox.Show(App.localization.Get("msgbox_migrate"), "RainbowTaskbar", MessageBoxButton.YesNo);
if (res == MessageBoxResult.Yes) {
File.WriteAllText(oldconfigpath, File.ReadAllText(oldconfigpath).Replace("RainbowTaskbar.Configuration", "RainbowTaskbar.V2Legacy.Configuration"));
using var fileStream = new FileStream(oldconfigpath, FileMode.OpenOrCreate);
using var reader = XmlDictionaryReader.CreateTextReader(fileStream, new XmlDictionaryReaderQuotas());
var serializerSettings = new DataContractSerializerSettings {
PreserveObjectReferences = true
};
var serializer = new DataContractSerializer(typeof(V2Legacy.Configuration.Config), serializerSettings);
var cfg = serializer.ReadObject(reader) as V2Legacy.Configuration.Config;
var curcfg = InstructionConfig.FromLegacyConfig(cfg);
curcfg.ToFile();
App.Configs.Add(curcfg);
foreach (var preset in cfg.Presets) {
var portcfg = InstructionConfig.FromLegacyPreset(preset);
portcfg.ToFile();
App.Configs.Add(portcfg);
}
reader.Close();
fileStream.Close();
File.Delete(oldconfigpath);
} else {
File.Delete(oldconfigpath);
}
}
Settings.workshopAPI = new WorkshopAPI() {};
Settings.OnLoginKeyChanged();
if (Settings.FirstStart) {
Settings.FirstStart = false;
Settings.ToFile();
firstRun = true;
}
//TODO:remove this its for debugfging
// LaunchEditor();
if (Settings.WebTouchThrough) StartHook();
if (App.Settings.Version < Assembly.GetExecutingAssembly().GetName().Version) {
if (App.Settings.Version > new Version("1.0")) {
// Valid update
if (App.Settings.Version <= new Version("3.1.3") && App.IsMicrosoftStore()) {
App.Settings.RunAtStartup = true;
}
}
App.Settings.Version = Assembly.GetExecutingAssembly().GetName().Version;
App.Settings.SaveChanged();
}
Task.Run(() => {
ExplorerTAP.ExplorerTAP.TryInject();
App.Current.Dispatcher.Invoke(() => {
taskbars = FindAllTaskbars();
SetupTaskbars();
Taskbar.SetupLayers();
Taskbar.SetupWebViews();
if(App.Settings.SelectedConfig is not null) App.Settings.SelectedConfig.Start();
Settings.OnGlobalOpacityChanged();
if (firstRun == true) {
Task.Run(() => {
Thread.Sleep(1000); // amazing coding
Dispatcher.Invoke(() => LaunchEditor());
});
}
// todo: add back?
// API.Start();
});
});
}
else {
var shell = false;
var shellMessage = "";
foreach (string s in e.Args) {
if(shell == true) {
shellMessage = s;
}
if(s == "shell") {
shell = true;
}
}
var pipe = new PipeClient("RainbowTaskbar Pipe");
pipe.ConnectAsync().Wait();
if (shell) {
pipe.WriteAsync("Shell="+shellMessage).Wait();
} else {
pipe.WriteAsync("OpenEditor").Wait();
}
pipe.DisconnectAsync().Wait();
Environment.Exit(0);
}
}
public delegate bool EnumWindowsProc(IntPtr hWnd, int lParam);
[DllImport("user32.dll")]
private static extern int EnumWindows(EnumWindowsProc proc, int lParam);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
public static List FindAllTaskbars() {
List tsk = new List();
var nw = new Taskbar(TaskbarHelper.FindWindow("Shell_TrayWnd", null));
nw.Show();
tsk.Add(nw);
EnumWindows(new EnumWindowsProc((hWnd, lParam) =>
{
StringBuilder className = new StringBuilder(255);
GetClassName(hWnd, className, 255);
if (className.ToString() == "Shell_SecondaryTrayWnd") {
var newWindow = new Taskbar(hWnd, true);
newWindow.Show();
tsk.Add(newWindow);
}
return true;
}), 0);
return tsk;
}
public static void SetupTaskbars() {
taskbars.MinBy(t => t.Left).taskbarHelper.first = true;
taskbars.MaxBy(t => t.Left).taskbarHelper.last = true;
taskbars.ForEach(t => {
t.taskbarHelper.UpdateRadius();
int fals = 1;
TaskbarHelper.DwmSetWindowAttribute(new WindowInteropHelper(t).EnsureHandle(), TaskbarHelper.DWMWINDOWATTRIBUTE.ExcludedFromPeek, ref fals, sizeof(int));
});
Task.Run(() => {
if (!ExplorerTAP.ExplorerTAP.NeedsTAP()) return;
var hwnd = TaskbarHelper.FindWindow("Shell_TrayWnd", null);
while(hwnd != IntPtr.Zero) {
Thread.Sleep(150);
hwnd = TaskbarHelper.FindWindow("Shell_TrayWnd", null);
}
ExplorerTAP.ExplorerTAP.IsInjected = false;
do {
hwnd = TaskbarHelper.FindWindow("Shell_TrayWnd", null);
Thread.Sleep(150);
} while (hwnd == IntPtr.Zero);
while (!ExplorerTAP.ExplorerTAP.NeedsTAP()) {
Thread.Sleep(150);
}
Thread.Sleep(2000);
ExplorerTAP.ExplorerTAP.TryInject();
while (!ExplorerTAP.ExplorerTAP.IsInjected) {
Thread.Sleep(150);
}
ReloadTaskbars();
});
}
public static void ReloadTaskbars(bool startConfig = true) =>
Current.Dispatcher.Invoke(() => {
if (App.hiddenWebViewHost is not null) {
if (App.hiddenWebViewHost.webView_ is not null) {
App.hiddenWebViewHost.webView_.Dispose();
App.hiddenWebViewHost.webView_ = null;
}
App.hiddenWebViewHost.Close();
App.hiddenWebViewHost = null;
}
if (!App.Settings.GraphicsRepeat) {
webViewReady.WaitOne();
App.hiddenWebViewHost = new();
}
taskbars.ForEach(taskbar => {
if(taskbar.webView_ is not null) taskbar.webView_.Dispose();
taskbar.webView_ = null;
taskbar.windowHelper.RemoveDuplicate();
taskbar.Close();
});
if(Config.currentlyRunning is not null) Config.currentlyRunning.Stop().Wait(500);
Config.currentlyRunning = null;
taskbars = FindAllTaskbars();
SetupTaskbars();
Taskbar.SetupLayers();
Taskbar.SetupWebViews();
Task.Run(() => {
Thread.Sleep(100);
App.Current.Dispatcher.Invoke(() => Taskbar.SoftReset(startConfig));
});
});
}
================================================
FILE: RainbowTaskbar/AssemblyInfo.cs
================================================
using System.Windows;
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]
================================================
FILE: RainbowTaskbar/Configuration/Config.cs
================================================
using RainbowTaskbar.Configuration.Instruction;
using RainbowTaskbar.Configuration.Instruction.Instructions;
using RainbowTaskbar.Configuration.Web;
using RainbowTaskbar.Helpers;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Media.Imaging;
namespace RainbowTaskbar.Configuration {
public enum ConfigPublishStatus {
NotPublished,
PreviouslyPublished,
Published
}
[JsonDerivedType(typeof(InstructionConfigData), typeDiscriminator: "c")]
[JsonDerivedType(typeof(WebConfigData), typeDiscriminator: "w")]
[Serializable]
public abstract class ConfigData {
}
[JsonDerivedType(typeof(InstructionConfig), typeDiscriminator: "c")]
[JsonDerivedType(typeof(WebConfig), typeDiscriminator: "w")]
[Serializable]
public abstract class Config : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
public string Name { get; set; } = App.localization?.Get("untitled") ?? "Untitled";
public string Description { get; set; } = "";
public string? PublishedID { get; set; }
public string? PreviousPublishedID { get; set; }
public string? CachedPublisherUsername { get; set; }
public string? CachedBase64Thumbnail { get; set; }
[JsonIgnore]
public int? CachedLikeCount { get; set; }
[JsonIgnore]
public int? CachedCommentCount { get; set; }
public string LocalID { get; set; }
public DateTime Created { get; set; } = DateTime.Now;
public DateTime Updated { get; set; } = DateTime.Now;
public DateTime Published { get; set; } = DateTime.MinValue;
[JsonIgnore]
public bool ChangedSincePublish { get => Updated > Published; }
[JsonIgnore]
public ConfigPublishStatus PublishStatus { get => PublishedID is not null ? (ChangedSincePublish ? ConfigPublishStatus.PreviouslyPublished : ConfigPublishStatus.Published) : ConfigPublishStatus.NotPublished; }
public static Config currentlyRunning;
public ConfigData ConfigData { get; set; }
[JsonIgnore]
public static JsonSerializerOptions SerializerOptions { get; set; } = new JsonSerializerOptions { Converters = { new JsonColorConverter() } };
[JsonIgnore]
public string ConfigType { get => this.GetType().Name; }
[JsonIgnore]
public string fileName = null;
public void InitNew() {
LocalID = Guid.NewGuid().ToString();
}
public static Config FromFile(string file) {
if (!File.Exists(file)) return null;
Config cfg = JsonSerializer.Deserialize(File.ReadAllText(file), SerializerOptions);
cfg.fileName = file;
return cfg;
}
public void ToFile() {
if (fileName is null)
fileName = Path.Join(App.configDir, LocalID + ".json");
File.WriteAllText(fileName,
JsonSerializer.Serialize(this, SerializerOptions));
}
public Config Copy() {
return JsonSerializer.Deserialize(JsonSerializer.Serialize(this, SerializerOptions), SerializerOptions);
}
public void DeleteFile() {
if (File.Exists(fileName)) File.Delete(fileName);
}
static bool stopping = false;
public virtual Task Start() {
if (stopping) return Task.FromResult(false);
return Task.Run(() => {
stopping = true;
if (currentlyRunning is not null) currentlyRunning.Stop().Wait(300);
stopping = false;
App.Current.Dispatcher.Invoke(() => {
var inst = new TransparencyInstruction() {
Type = TransparencyInstruction.TransparencyInstructionType.All, Opacity = 1
};
var inst2 = new TransparencyInstruction() {
Type = TransparencyInstruction.TransparencyInstructionType.TaskbarElements, Opacity = 1
};
App.taskbars.ForEach(x => { inst.Execute(x); inst2.Execute(x); });
currentlyRunning = this;
});
return true;
});
}
public abstract Task Stop();
public BitmapImage? LoadImage() {
if (CachedBase64Thumbnail is null) return null;
try {
byte[] imageBytes = Convert.FromBase64String(CachedBase64Thumbnail);
var bImg = new BitmapImage();
using (var stream = new MemoryStream(imageBytes, 0, imageBytes.Length)) {
bImg.BeginInit();
bImg.CacheOption = BitmapCacheOption.OnLoad;
bImg.StreamSource = stream;
bImg.EndInit();
bImg.Freeze();
}
return bImg;
}
catch { return null; }
}
}
}
================================================
FILE: RainbowTaskbar/Configuration/Instruction/DefaultPresets.cs
================================================
using RainbowTaskbar.Configuration.Instruction.Instructions;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
namespace RainbowTaskbar.Configuration.Instruction;
public static class DefaultPresets {
public static readonly InstructionPreset Rainbow = new() {
Name = "Rainbow",
RunOnceGroup = new InstructionGroup() {
Instructions = {
new BorderRadiusInstruction {
Radius = 16
},
new TransparencyInstruction {
Type = TransparencyInstruction.TransparencyInstructionType.Style,
Style = TransparencyInstruction.TransparencyInstructionStyle.Transparent
},
new TransparencyInstruction {
Type = TransparencyInstruction.TransparencyInstructionType.RainbowTaskbar,
Opacity = 0.8
},
}
},
LoopGroups = new BindingList(new InstructionGroup[] {
new InstructionGroup {
Instructions = new BindingList {
new ColorInstruction {
Time = 1,
Color1 = Color.FromArgb(255, 255, 0, 0),
Color2 = Color.FromArgb(255, 255, 154, 0),
Effect = ColorInstruction.ColorInstructionEffect.FadeGradient,
Time2 = 500
},
new ColorInstruction {
Time = 1,
Color1 = Color.FromArgb(255, 255, 154, 0),
Color2 = Color.FromArgb(255, 208, 222, 33),
Effect = ColorInstruction.ColorInstructionEffect.FadeGradient,
Time2 = 500
},
new ColorInstruction {
Time = 1,
Color1 = Color.FromArgb(255, 208, 222, 33),
Color2 = Color.FromArgb(255, 79, 220, 74),
Effect = ColorInstruction.ColorInstructionEffect.FadeGradient,
Time2 = 500
},
new ColorInstruction {
Time = 1,
Color1 = Color.FromArgb(255, 79, 220, 74),
Color2 = Color.FromArgb(255, 63, 218, 216),
Effect = ColorInstruction.ColorInstructionEffect.FadeGradient,
Time2 = 500
},
new ColorInstruction {
Time = 1,
Color1 = Color.FromArgb(255, 63, 218, 216),
Color2 = Color.FromArgb(255, 47, 201, 226),
Effect = ColorInstruction.ColorInstructionEffect.FadeGradient,
Time2 = 500
},
new ColorInstruction {
Time = 1,
Color1 = Color.FromArgb(255, 47, 201, 226),
Color2 = Color.FromArgb(255, 28, 127, 238),
Effect = ColorInstruction.ColorInstructionEffect.FadeGradient,
Time2 = 500
},
new ColorInstruction {
Time = 1,
Color1 = Color.FromArgb(255, 28, 127, 238),
Color2 = Color.FromArgb(255, 95, 21, 242),
Effect = ColorInstruction.ColorInstructionEffect.FadeGradient,
Time2 = 500
},
new ColorInstruction {
Time = 1,
Color1 = Color.FromArgb(255, 95, 21, 242),
Color2 = Color.FromArgb(255, 186, 12, 248),
Effect = ColorInstruction.ColorInstructionEffect.FadeGradient,
Time2 = 500
},
new ColorInstruction {
Time = 1,
Color1 = Color.FromArgb(255, 186, 12, 248),
Color2 = Color.FromArgb(255, 251, 7, 217),
Effect = ColorInstruction.ColorInstructionEffect.FadeGradient,
Time2 = 500
},
new ColorInstruction {
Time = 1,
Color1 = Color.FromArgb(255, 251, 7, 217),
Color2 = Color.FromArgb(255, 255, 0, 0),
Effect = ColorInstruction.ColorInstructionEffect.FadeGradient,
Time2 = 500
}
}
}
})
};
public static readonly InstructionPreset Chill = new() {
Name = "Chill",
RunOnceGroup = new InstructionGroup() {
Instructions = {
new TransparencyInstruction {
Type = TransparencyInstruction.TransparencyInstructionType.Style,
Style = TransparencyInstruction.TransparencyInstructionStyle.Transparent
},
new TransparencyInstruction {
Type = TransparencyInstruction.TransparencyInstructionType.RainbowTaskbar,
Opacity = 0.9
},
}
},
LoopGroups = new BindingList(new InstructionGroup[] {
new InstructionGroup {
Instructions = new BindingList {
new ColorInstruction {
Time = 5000,
Color1 = Color.RoyalBlue,
Color2 = Color.DarkBlue,
Effect = ColorInstruction.ColorInstructionEffect.FadeGradient,
Transition = ColorInstruction.ColorInstructionTransition.Cubic,
Time2 = 3000
},
new ColorInstruction {
Time = 5000,
Color1 = Color.DarkBlue,
Color2 = Color.RoyalBlue,
Effect = ColorInstruction.ColorInstructionEffect.FadeGradient,
Transition = ColorInstruction.ColorInstructionTransition.Cubic,
Time2 = 3000
}
}
}
})
};
public static readonly InstructionPreset Unknown = new() {
Name = "Unknown",
RunOnceGroup = new InstructionGroup() {
Instructions = {
new TransparencyInstruction {
Type = TransparencyInstruction.TransparencyInstructionType.Style,
Style = TransparencyInstruction.TransparencyInstructionStyle.Transparent
},
new TransparencyInstruction {
Type = TransparencyInstruction.TransparencyInstructionType.RainbowTaskbar,
Opacity = 0.9
},
}
},
LoopGroups = new BindingList(new InstructionGroup[] {
new InstructionGroup {
Instructions = new BindingList {
new ColorInstruction {
Time = 1001,
Randomize = true,
Effect = ColorInstruction.ColorInstructionEffect.FadeGradient,
Transition = ColorInstruction.ColorInstructionTransition.Linear,
Time2 = 1000
},
new TransparencyInstruction {
Type = TransparencyInstruction.TransparencyInstructionType.Style,
Style = TransparencyInstruction.TransparencyInstructionStyle.Transparent
},
new TransparencyInstruction {
Type = TransparencyInstruction.TransparencyInstructionType.Style,
Style = TransparencyInstruction.TransparencyInstructionStyle.Transparent
},
new TransparencyInstruction {
Type = TransparencyInstruction.TransparencyInstructionType.Style,
Style = TransparencyInstruction.TransparencyInstructionStyle.Transparent
},
new TransparencyInstruction {
Type = TransparencyInstruction.TransparencyInstructionType.Style,
Style = TransparencyInstruction.TransparencyInstructionStyle.Transparent
},
new TransparencyInstruction {
Type = TransparencyInstruction.TransparencyInstructionType.Style,
Style = TransparencyInstruction.TransparencyInstructionStyle.Transparent
},
new TransparencyInstruction {
Type = TransparencyInstruction.TransparencyInstructionType.Style,
Style = TransparencyInstruction.TransparencyInstructionStyle.Transparent
},
new TransparencyInstruction {
Type = TransparencyInstruction.TransparencyInstructionType.Style,
Style = TransparencyInstruction.TransparencyInstructionStyle.Transparent
},
new TransparencyInstruction {
Type = TransparencyInstruction.TransparencyInstructionType.Style,
Style = TransparencyInstruction.TransparencyInstructionStyle.Transparent
},
new TransparencyInstruction {
Type = TransparencyInstruction.TransparencyInstructionType.Style,
Style = TransparencyInstruction.TransparencyInstructionStyle.Transparent
},
new TransparencyInstruction {
Type = TransparencyInstruction.TransparencyInstructionType.Style,
Style = TransparencyInstruction.TransparencyInstructionStyle.Transparent
},
new TransparencyInstruction {
Type = TransparencyInstruction.TransparencyInstructionType.Style,
Style = TransparencyInstruction.TransparencyInstructionStyle.Transparent
},
new TransparencyInstruction {
Type = TransparencyInstruction.TransparencyInstructionType.Style,
Style = TransparencyInstruction.TransparencyInstructionStyle.Transparent
},
new TransparencyInstruction {
Type = TransparencyInstruction.TransparencyInstructionType.Style,
Style = TransparencyInstruction.TransparencyInstructionStyle.Transparent
},
new TransparencyInstruction {
Type = TransparencyInstruction.TransparencyInstructionType.Style,
Style = TransparencyInstruction.TransparencyInstructionStyle.Transparent
},
new TransparencyInstruction {
Type = TransparencyInstruction.TransparencyInstructionType.Style,
Style = TransparencyInstruction.TransparencyInstructionStyle.Transparent
},
new TransparencyInstruction {
Type = TransparencyInstruction.TransparencyInstructionType.Style,
Style = TransparencyInstruction.TransparencyInstructionStyle.Transparent
},
new TransparencyInstruction {
Type = TransparencyInstruction.TransparencyInstructionType.Style,
Style = TransparencyInstruction.TransparencyInstructionStyle.Transparent
},
new TransparencyInstruction {
Type = TransparencyInstruction.TransparencyInstructionType.Style,
Style = TransparencyInstruction.TransparencyInstructionStyle.Transparent
}
}
},
new InstructionGroup {
Instructions = new BindingList {
new TransparencyInstruction {
Type = TransparencyInstruction.TransparencyInstructionType.Style,
Style = TransparencyInstruction.TransparencyInstructionStyle.Transparent
},
new TransparencyInstruction {
Type = TransparencyInstruction.TransparencyInstructionType.Style,
Style = TransparencyInstruction.TransparencyInstructionStyle.Transparent
}
}
}
})
};
public static readonly InstructionPreset HighContrast = new() {
Name = "High contrast",
RunOnceGroup = new InstructionGroup() {
Instructions = {
new TransparencyInstruction {
Type = TransparencyInstruction.TransparencyInstructionType.Style,
Style = TransparencyInstruction.TransparencyInstructionStyle.Transparent
},
new ShapeInstruction {
Shape = ShapeInstruction.ShapeInstructionShapes.Rectangle,
Fill = Color.Transparent,
Line = Color.FromArgb(0, 255, 0),
Layer = 1,
LineSize = 4,
FitTaskbars = true
},
new ColorInstruction {
Time = 1001,
Color1 = Color.Black,
Effect = ColorInstruction.ColorInstructionEffect.Solid,
}
}
}
};
public static readonly InstructionPreset ModernChill = new() {
Name = "Modern Blue Chill",
RunOnceGroup = new InstructionGroup() {
Instructions = {
new BorderRadiusInstruction {
Radius = 16
},
new TransparencyInstruction {
Type = TransparencyInstruction.TransparencyInstructionType.Style,
Style = TransparencyInstruction.TransparencyInstructionStyle.Transparent
},
new TransparencyInstruction {
Type = TransparencyInstruction.TransparencyInstructionType.RainbowTaskbar,
Opacity = 0.9
},
new TransparencyInstruction {
Type = TransparencyInstruction.TransparencyInstructionType.Layer,
Opacity = 0.8,
Layer = 0,
},
}
},
LoopGroups = new BindingList(new InstructionGroup[] {
new InstructionGroup {
Instructions = new BindingList {
new ShapeInstruction {
FitTaskbars = true,
DrawOnce = true,
Shape = ShapeInstruction.ShapeInstructionShapes.Rectangle,
LineSize = 2,
Line = Color.FromArgb(255,0, 200, 255),
Fill = Color.Transparent,
Layer = 1
},
new ColorInstruction {
Effect = ColorInstruction.ColorInstructionEffect.FadeGradient,
Transition = ColorInstruction.ColorInstructionTransition.Sine,
Time = 3000,
Color1 = Color.FromArgb(255, 0, 136, 196),
Color2 = Color.Black,
Angle = 0,
Time2 = 5000,
Layer = 0,
Randomize = false
},
new ColorInstruction {
Effect = ColorInstruction.ColorInstructionEffect.FadeGradient,
Transition = ColorInstruction.ColorInstructionTransition.Sine,
Time = 3000,
Color1 = Color.Black,
Color2 = Color.FromArgb(255, 0, 136, 196),
Angle = 0,
Time2 = 5000,
Layer = 0,
Randomize = false
}
}
}
})
};
public static readonly InstructionPreset ModernChill2 = new() {
Name = "Modern Red Chill",
RunOnceGroup = new InstructionGroup() {
Instructions = {
new BorderRadiusInstruction {
Radius = 16
},
new TransparencyInstruction {
Type = TransparencyInstruction.TransparencyInstructionType.Style,
Style = TransparencyInstruction.TransparencyInstructionStyle.Transparent
},
new TransparencyInstruction {
Type = TransparencyInstruction.TransparencyInstructionType.RainbowTaskbar,
Opacity = 0.9
},
new TransparencyInstruction {
Type = TransparencyInstruction.TransparencyInstructionType.Layer,
Opacity = 0.8,
Layer = 0,
},
}
},
LoopGroups = new BindingList(new InstructionGroup[] {
new InstructionGroup {
Instructions = new BindingList {
new ShapeInstruction {
FitTaskbars = true,
DrawOnce = true,
Shape = ShapeInstruction.ShapeInstructionShapes.Rectangle,
LineSize = 2,
Line = Color.FromArgb(255,255, 61, 0),
Fill = Color.Transparent,
Layer = 1
},
new ColorInstruction {
Effect = ColorInstruction.ColorInstructionEffect.FadeGradient,
Transition = ColorInstruction.ColorInstructionTransition.Sine,
Time = 3000,
Color1 = Color.FromArgb(255, 176, 0, 0),
Color2 = Color.Black,
Angle = 0,
Time2 = 5000,
Layer = 0,
Randomize = false
},
new ColorInstruction {
Effect = ColorInstruction.ColorInstructionEffect.FadeGradient,
Transition = ColorInstruction.ColorInstructionTransition.Sine,
Time = 3000,
Color1 = Color.Black,
Color2 = Color.FromArgb(255, 176, 0, 0),
Angle = 0,
Time2 = 5000,
Layer = 0,
Randomize = false
}
}
}
})
};
public static readonly InstructionPreset Translucent = new() {
Name = "Translucent",
RunOnceGroup = new InstructionGroup() {
Instructions = {
new TransparencyInstruction {
Type = TransparencyInstruction.TransparencyInstructionType.Style,
Style = TransparencyInstruction.TransparencyInstructionStyle.Transparent
}
}
},
};
public static readonly InstructionPreset Blurred = new() {
Name = "Blurred",
RunOnceGroup = new InstructionGroup() {
Instructions = {
new TransparencyInstruction {
Type = TransparencyInstruction.TransparencyInstructionType.Style,
Style = TransparencyInstruction.TransparencyInstructionStyle.Blur
}
}
},
};
public static readonly InstructionPreset Vaporwave = new() {
Name = "Vaporwave",
RunOnceGroup = new InstructionGroup() {
Instructions = {
new TransparencyInstruction {
Type = TransparencyInstruction.TransparencyInstructionType.Style,
Style = TransparencyInstruction.TransparencyInstructionStyle.Transparent
},
new TransparencyInstruction {
Type = TransparencyInstruction.TransparencyInstructionType.Layer,
Opacity = 0.6,
Layer = 0,
},
}
},
LoopGroups = new BindingList(new InstructionGroup[] {
new InstructionGroup {
Instructions = new BindingList {
new ShapeInstruction {
FitTaskbars = true,
DrawOnce = true,
Shape = ShapeInstruction.ShapeInstructionShapes.Rectangle,
LineSize = 2,
Line = Color.FromArgb(255, 159,198, 255),
Fill = Color.Transparent,
Layer = 1
},
new TextInstruction {
DrawOnce = true,
Text = " レーンボー・タスクバー レーンボー・タスクバー レーンボー・タスクバー レーンボー・タスクバー レーンボー・タスクバー レーンボー・タスクバー レーンボー・タスクバー レーンボー・タスクバー レーンボー・タスクバー レーンボー・タスクバー ",
Center = true,
Y = 6,
Font = "Arial",
Size = 32,
Color = Color.FromArgb(63,220,247,255),
Layer = 1
},
new TextInstruction {
DrawOnce = true,
Text = "◓ ◓ ◓ ◓ ◓ ◓ ◓ ◓ ◓ ◓ ◓ ◓ ◓ ◓ ◓ ◓ ◓ ◓ ◓ ◓ ◓ ◓ ◓ ◓ ◓",
X = 4,
Y = 6,
Font = "Arial",
Size = 32,
Color = Color.FromArgb(127,255,110,172),
Layer = 1
},
new TextInstruction {
DrawOnce = true,
Text = "◓ ◒ ◓ ◒ ◓ ◒ ◓ ◒ ◓ ◒ ◓ ◒ ◓ ◒ ◓ ◒ ◓ ◒ ◓ ◒ ◓ ◒ ◓ ◒ ◓",
X = 6,
Y = 8,
Font = "Arial",
Size = 32,
Color = Color.FromArgb(127,255,214,110),
Layer = 1
},
new TextInstruction {
DrawOnce = true,
Text = "ツ ツ ツ ツ ツ ツ ツ ツ ツ ツ ツ ツ ツ ツ ツ ツ ツ ツ ツ ツ ツ ツ ツ ツ ツ ツ ",
Center = true,
Y = 29,
Font = "Arial",
Size = 16,
Color = Color.FromArgb(200,110,255,182),
Layer = 1
},
new ColorInstruction {
Effect = ColorInstruction.ColorInstructionEffect.FadeGradient,
Transition = ColorInstruction.ColorInstructionTransition.Linear,
Time = 0,
Color1 = Color.FromArgb(255, 100, 112, 216),
Color2 = Color.FromArgb(255, 0, 185, 255),
Angle = 0,
Time2 = 1500,
Layer = 0,
Randomize = false
},
new ColorInstruction {
Effect = ColorInstruction.ColorInstructionEffect.FadeGradient,
Transition = ColorInstruction.ColorInstructionTransition.Linear,
Time = 0,
Color1 = Color.FromArgb(255, 0, 185, 255),
Color2 = Color.FromArgb(255, 255, 0, 158),
Angle = 0,
Time2 = 1500,
Layer = 0,
Randomize = false
},
new ColorInstruction {
Effect = ColorInstruction.ColorInstructionEffect.FadeGradient,
Transition = ColorInstruction.ColorInstructionTransition.Linear,
Time = 0,
Color1 = Color.FromArgb(255, 255, 0, 158),
Color2 = Color.FromArgb(255, 100, 112, 216),
Angle = 0,
Time2 = 1500,
Layer = 0,
Randomize = false
}
}
}
})
};
public static readonly List Presets = new List() {
Translucent, Blurred, Rainbow, Chill,
HighContrast, ModernChill,ModernChill2,
Vaporwave, Unknown
};
}
================================================
FILE: RainbowTaskbar/Configuration/Instruction/Instruction.cs
================================================
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
using System.Threading;
using FastMember;
using RainbowTaskbar.Configuration.Instruction.Instructions;
using RainbowTaskbar.Configuration.Web;
namespace RainbowTaskbar.Configuration.Instruction;
[JsonDerivedType(typeof(BorderRadiusInstruction), typeDiscriminator: "b")]
[JsonDerivedType(typeof(ClearLayerInstruction), typeDiscriminator: "c")]
[JsonDerivedType(typeof(ColorInstruction), typeDiscriminator: "cl")]
[JsonDerivedType(typeof(DelayInstruction), typeDiscriminator: "d")]
[JsonDerivedType(typeof(ImageInstruction), typeDiscriminator: "i")]
[JsonDerivedType(typeof(ShapeInstruction), typeDiscriminator: "s")]
[JsonDerivedType(typeof(TextInstruction), typeDiscriminator: "t")]
[JsonDerivedType(typeof(TransparencyInstruction), typeDiscriminator: "tr")]
public abstract class Instruction : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
public static IEnumerable InstructionTypes { get; set; } = GetKnownInstructionTypes();
public static IEnumerable DisplayableInstructionTypes {
get => InstructionTypes.Skip(1);
}
[JsonIgnore]
public abstract string Description { get; }
[JsonIgnore]
public string Name {
get {
return App.localization.Name(GetType().Name.ToLower());
}
}
[JsonIgnore]
public string TypeName {
get {
return GetType().Name;
}
}
public static IEnumerable GetKnownInstructionTypes() {
if (InstructionTypes == null)
InstructionTypes = Assembly.GetExecutingAssembly().GetTypes()
.Where(type => typeof(Instruction).IsAssignableFrom(type)).ToList();
return InstructionTypes;
}
public bool Execute(Taskbar window) => Execute(window, CancellationToken.None);
public abstract bool Execute(Taskbar window, CancellationToken token);
// TODO: Json or remove this idk
//public abstract JObject ToJSON();
/*
public static Instruction FromJSON(Type type, JObject json) {
dynamic inst = type.GetConstructor(Array.Empty()).Invoke(null) as Instruction;
foreach (var prop in json.Properties())
if (prop.Name != "Name" && prop.Name != "Position") {
var wrapped = ObjectAccessor.Create(inst);
if (prop.Name.StartsWith("Color"))
wrapped[prop.Name] = ColorTranslator.FromHtml(prop.Value.Value());
else
if (wrapped[prop.Name] is not null)
wrapped[prop.Name] = Convert.ChangeType(prop.Value, wrapped[prop.Name].GetType());
else
wrapped[prop.Name] = prop.Value;
}
return inst;
}
*/
}
================================================
FILE: RainbowTaskbar/Configuration/Instruction/InstructionConfig.cs
================================================
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Dynamic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Text.RegularExpressions;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media.Animation;
using System.Xml;
using PropertyChanged;
using RainbowTaskbar.HTTPAPI;
using System.Diagnostics;
using RainbowTaskbar.Configuration.Instruction.Instructions;
using System.Text.Json.Serialization;
namespace RainbowTaskbar.Configuration.Instruction;
[Serializable]
public class InstructionConfigData : ConfigData, INotifyPropertyChanged {
private static readonly int SupportedConfigVersion = 0;
public int ConfigFileVersion { get; set; } = SupportedConfigVersion;
public InstructionGroup RunOnceGroup { get; set; } = new();
[OnChangedMethod(nameof(SetupPropertyChanged))]
public BindingList LoopGroups { get; set; } = new BindingList();
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
// PropertyChanged bullshit
private void SetupPropertyChanged() {
LoopGroups.ListChanged += (_, _) => OnPropertyChanged(nameof(Instructions));
}
// ------------------------
public InstructionConfigData() {
SetupPropertyChanged();
}
}
[Serializable]
public class InstructionConfig : Config {
public CancellationTokenSource cts = new CancellationTokenSource();
public InstructionConfigData Data { get => ConfigData as InstructionConfigData; set => ConfigData = value; }
public InstructionConfig() {
ConfigData = new InstructionConfigData();
Data.RunOnceGroup = new InstructionGroup();
}
public override async Task Start() {
if(!(await base.Start())) return false;
App.taskbars.ForEach(x => {
x.ClassicGrid.Visibility = System.Windows.Visibility.Visible;
x.WebGrid.Visibility = System.Windows.Visibility.Collapsed;
});
Task.Run(() => StartGroupTasks());
return true;
}
public override Task Stop() {
return Task.WhenAll(StopGroupTasks());
}
public List StopGroupTasks() {
var tasks = new List();
if(cts is not null) {
cts.Cancel();
cts = null;
}
if(Data.RunOnceGroup.Task is not null) tasks.Add(Data.RunOnceGroup.Task);
foreach(var group in Data.LoopGroups) {
if(group.Task is not null) tasks.Add(group.Task);
}
return tasks;
}
public void StartGroupTasks() {
Stop().Wait();
cts = new CancellationTokenSource();
Data.RunOnceGroup.StartOnceTask(cts.Token);
Data.RunOnceGroup.Task.Wait(cts.Token);
foreach (var group in Data.LoopGroups) {
group.StartLoopTask(cts.Token);
}
}
public static BindingList LegacyInstructionsToV2(BindingList instructions) {
var cfg = new BindingList();
foreach (var inst in instructions) {
if (inst is V2Legacy.Configuration.Instructions.BorderRadiusInstruction binst) {
cfg.Add(new BorderRadiusInstruction() {
Radius = binst.Radius,
});
}
if (inst is V2Legacy.Configuration.Instructions.ClearLayerInstruction cinst) {
cfg.Add(new ClearLayerInstruction() {
Layer = cinst.Layer,
});
}
if (inst is V2Legacy.Configuration.Instructions.ColorInstruction clinst) {
cfg.Add(new ColorInstruction() {
Angle = clinst.Angle,
Color1 = clinst.Color1,
Color2 = clinst.Color2,
Effect = (ColorInstruction.ColorInstructionEffect) clinst.Effect,
Randomize = clinst.Randomize,
Layer = clinst.Layer,
Time = clinst.Time,
Time2 = clinst.Time2,
Transition = (ColorInstruction.ColorInstructionTransition) clinst.Transition
});
}
if (inst is V2Legacy.Configuration.Instructions.DelayInstruction dinst) {
cfg.Add(new DelayInstruction() {
Time = dinst.Time,
});
}
if (inst is V2Legacy.Configuration.Instructions.ImageInstruction iinst) {
cfg.Add(new ImageInstruction() {
DrawOnce = iinst.DrawOnce,
Height = iinst.Height,
Layer = iinst.Layer,
Width = iinst.Width,
Opacity = iinst.Opacity,
Path = iinst.Path,
X = iinst.X,
Y = iinst.Y
});
}
if (inst is V2Legacy.Configuration.Instructions.ShapeInstruction sinst) {
cfg.Add(new ShapeInstruction() {
DrawOnce = sinst.DrawOnce,
Shape = (ShapeInstruction.ShapeInstructionShapes) sinst.Shape,
Fill = sinst.Fill,
FitTaskbars = sinst.FitTaskbars,
Layer = sinst.Layer,
Line = sinst.Line,
LineSize = sinst.LineSize,
Radius = sinst.Radius,
X2 = sinst.X2,
Y2 = sinst.Y2,
X = sinst.X,
Y = sinst.Y
});
}
if (inst is V2Legacy.Configuration.Instructions.TextInstruction tinst) {
cfg.Add(new TextInstruction() {
Size = tinst.Size,
Center = tinst.Center,
Color = tinst.Color,
DrawOnce = tinst.DrawOnce,
Font = tinst.Font,
Layer = tinst.Layer,
Text = tinst.Text,
X = tinst.X,
Y = tinst.Y,
});
}
if (inst is V2Legacy.Configuration.Instructions.TransparencyInstruction trinst) {
cfg.Add(new TransparencyInstruction() {
Layer = trinst.Layer,
Style = (TransparencyInstruction.TransparencyInstructionStyle) trinst.Style,
Opacity = trinst.Opacity,
Type = (TransparencyInstruction.TransparencyInstructionType) trinst.Type
});
}
}
return cfg;
}
public static InstructionConfig FromLegacyConfig(V2Legacy.Configuration.Config config) {
var cfg = new InstructionConfig();
cfg.InitNew();
var cfgData = (InstructionConfigData)cfg.ConfigData;
cfgData.LoopGroups.Add(new());
cfgData.LoopGroups[0].Instructions = LegacyInstructionsToV2(config.Instructions);
cfg.Name = "(MIGRATED) Current";
return cfg;
}
public static InstructionConfig FromLegacyPreset(V2Legacy.Configuration.InstructionPreset preset) {
var cfg = new InstructionConfig();
cfg.InitNew();
var cfgData = (InstructionConfigData) cfg.ConfigData;
cfgData.LoopGroups.Add(new());
cfgData.LoopGroups[0].Instructions = LegacyInstructionsToV2(preset.Instructions);
cfg.Name = "(MIGRATED) " + preset.Name;
return cfg;
}
}
================================================
FILE: RainbowTaskbar/Configuration/Instruction/InstructionGroup.cs
================================================
using PropertyChanged;
using RainbowTaskbar.HTTPAPI;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
namespace RainbowTaskbar.Configuration.Instruction {
public class InstructionGroup : INotifyPropertyChanged {
[OnChangedMethod(nameof(SetupPropertyChanged))]
public BindingList Instructions { get; set; } = new BindingList();
[JsonIgnore]
public Task Task { get; set; } = null;
private int groupStep = 0;
public event PropertyChangedEventHandler PropertyChanged;
private void SetupPropertyChanged() {
Instructions.ListChanged += (_, _) => OnPropertyChanged(nameof(Instructions));
}
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
public InstructionGroup() {
SetupPropertyChanged();
}
public bool RunOnceTask(CancellationToken token) {
bool slept = false;
for (groupStep = 0;
groupStep < Instructions.Count && !token.IsCancellationRequested;
groupStep++) {
try {
var tasks = new List();
App.taskbars.ForEach(taskbar => {
tasks.Add(Task.Run(() => {
if (groupStep < Instructions.Count && Instructions[groupStep].Execute(taskbar, token)) slept = true;
}));
});
Task.WaitAll(tasks.ToArray(), token);
}
catch (Exception e) {
if (e.GetType() == typeof(OperationCanceledException) || e.InnerException is not null && e.InnerException.GetType() == typeof(TaskCanceledException)) {
return slept;
}
MessageBox.Show(
$"The \"{Instructions[groupStep].Description}\" instruction at index {groupStep} (starting from 0) threw an exception, it will be removed from the instruction group.\n${e.Message}",
"RainbowTaskbar", MessageBoxButton.OK, MessageBoxImage.Error);
Application.Current.Dispatcher.Invoke(() => {
Instructions.RemoveAt(groupStep);
App.Settings.SelectedConfig.ToFile();
App.ReloadTaskbars();
});
return slept;
}
}
return slept;
}
public void LoopTask(CancellationToken token) {
while (!token.IsCancellationRequested) {
var slept = RunOnceTask(token);
if (!slept) break;
}
}
public void StartOnceTask(CancellationToken token) {
Task = Task.Run(() => RunOnceTask(token));
}
public void StartLoopTask(CancellationToken token) {
Task = Task.Run(() => LoopTask(token));
}
}
}
================================================
FILE: RainbowTaskbar/Configuration/Instruction/InstructionPreset.cs
================================================
using System.ComponentModel;
using System.Runtime.Serialization;
namespace RainbowTaskbar.Configuration.Instruction;
public class InstructionPreset {
public string Name { get; set; }
public InstructionGroup RunOnceGroup { get; set; } = new InstructionGroup();
public BindingList LoopGroups { get; set; } = new BindingList();
}
================================================
FILE: RainbowTaskbar/Configuration/Instruction/Instructions/BorderRadiusInstruction.cs
================================================
using System.Dynamic;
using System.Runtime.Serialization;
using System.Threading;
namespace RainbowTaskbar.Configuration.Instruction.Instructions;
internal class BorderRadiusInstruction : Instruction {
public int Radius { get; set; } = 0;
public override string Description {
get {
return App.localization.InstructionFormat(this, Radius);
}
}
public override bool Execute(Taskbar window, CancellationToken _) {
window.taskbarHelper.Radius = Radius;
window.windowHelper.Radius = Radius;
window.taskbarHelper.UpdateRadius();
return false;
}
/*
public override JObject ToJSON() {
dynamic data = new ExpandoObject();
data.Name = GetType().Name;
data.Radius = Radius;
return JObject.FromObject(data);
}
*/
}
================================================
FILE: RainbowTaskbar/Configuration/Instruction/Instructions/ClearLayerInstruction.cs
================================================
using System.Dynamic;
using System.Linq;
using System.Runtime.Serialization;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
namespace RainbowTaskbar.Configuration.Instruction.Instructions;
internal class ClearLayerInstruction : Instruction {
public int Layer { get; set; } = 0;
public override string Description {
get {
return App.localization.InstructionFormat(this, Layer);
}
}
public override bool Execute(Taskbar window, CancellationToken token) {
window.Dispatcher.Invoke(() => {
window.canvasManager.layers.MakeIfNeeded(Layer);
window.canvasManager.layers.renderTargets[Layer].Clear();
}, System.Windows.Threading.DispatcherPriority.Normal, token);
return false;
}
/*
public override JObject ToJSON() {
dynamic data = new ExpandoObject();
data.Name = GetType().Name;
data.Layer = Layer;
return JObject.FromObject(data);
}
*/
}
================================================
FILE: RainbowTaskbar/Configuration/Instruction/Instructions/ColorInstruction.cs
================================================
using System.Drawing;
using System.Dynamic;
using System.Runtime.Serialization;
using System.Threading;
using System.Windows.Media;
using RainbowTaskbar.Interpolation;
using Color = System.Drawing.Color;
using Brush = System.Windows.Media.Brush;
using RainbowTaskbar.Languages;
namespace RainbowTaskbar.Configuration.Instruction.Instructions;
internal class ColorInstruction : Instruction {
public override string Description {
get {
if (Randomize) {
return App.localization.InstructionFormatSuffix(this, "randomized", Effect.ToStringLocalized());
}
else if (Effect == ColorInstructionEffect.Gradient || Effect == ColorInstructionEffect.FadeGradient) {
return App.localization.InstructionFormatSuffix(this, "gradient", Effect.ToStringLocalized(), ColorTranslator.ToHtml(Color1), ColorTranslator.ToHtml(Color2));
}
else {
return App.localization.InstructionFormatSuffix(this, "solid", Effect.ToStringLocalized(), ColorTranslator.ToHtml(Color1));
}
}
}
public enum ColorInstructionEffect {
Solid,
Fade,
Gradient,
FadeGradient
}
public enum ColorInstructionTransition {
Linear,
Sine,
Cubic,
Exponential,
Back
}
public int Time { get; set; } = 1;
public Color Color1 { get; set; } = Color.FromArgb(0, 0, 0);
public ColorInstructionEffect Effect { get; set; }
public Color Color2 { get; set; } = Color.FromArgb(0, 0, 0);
public int Time2 { get; set; } = 1;
public ColorInstructionTransition Transition { get; set; }
public double Angle { get; set; } = 0;
public int Layer { get; set; } = 0;
public bool Randomize { get; set; } = false;
public bool Has2Colors { get => Effect == ColorInstructionEffect.FadeGradient || Effect == ColorInstructionEffect.Gradient; }
/*
public override JObject ToJSON() {
dynamic data = new ExpandoObject();
data.Name = GetType().Name;
data.Time = Time;
data.Effect = Effect;
data.Transition = Transition;
data.Time2 = Time2;
data.Angle = Angle;
data.Layer = Layer;
data.Randomize = Randomize;
data.Color1 = ColorExtension.HexConverter(Color1);
data.Color2 = ColorExtension.HexConverter(Color2);
return JObject.FromObject(data);
}
*/
public override bool Execute(Taskbar window, CancellationToken token) {
var OldBrush = window.canvasManager.layers.brushes[Layer];
if (Randomize) {
Color1 = Color.FromArgb(255, App.rnd.Next(0, 255), App.rnd.Next(0, 255), App.rnd.Next(0, 255));
Color2 = Color.FromArgb(255, App.rnd.Next(0, 255), App.rnd.Next(0, 255), App.rnd.Next(0, 255));
}
switch (Effect) {
case ColorInstructionEffect.Solid:
window.Dispatcher.Invoke(() => {
var Brush = new SolidColorBrush(Color1.ToMediaColor());
window.canvasManager.layers.DrawRect(Layer, Brush);
}, System.Windows.Threading.DispatcherPriority.Normal, token);
token.WaitHandle.WaitOne(Time);
break;
case ColorInstructionEffect.Gradient:
window.Dispatcher.Invoke(() => {
var Brush = new LinearGradientBrush(Color1.ToMediaColor(), Color2.ToMediaColor(), Angle);
window.canvasManager.layers.DrawRect(Layer, Brush);
}, System.Windows.Threading.DispatcherPriority.Normal, token);
token.WaitHandle.WaitOne(Time);
break;
case ColorInstructionEffect.FadeGradient:
if (OldBrush is SolidColorBrush) {
var Brush = (SolidColorBrush) OldBrush;
System.Windows.Media.Color OColor;
window.Dispatcher.Invoke(() => { OColor = Brush.Color; }, System.Windows.Threading.DispatcherPriority.Normal, token);
var j = 1;
while (j++ < Time2 / App.Settings.InterpolationQuality) {
var Color1Interpolated = ColorInterpolation.Interpolate(OColor.ToDrawingColor(), Color1,
(ColorInterpolation.INTERPOLATE_FUNCTION) Transition, (double) j / (Time2 / App.Settings.InterpolationQuality));
var Color2Interpolated = ColorInterpolation.Interpolate(OColor.ToDrawingColor(), Color2,
(ColorInterpolation.INTERPOLATE_FUNCTION) Transition, (double) j / (Time2 / App.Settings.InterpolationQuality));
window.Dispatcher.Invoke(() => {
var Brush = new LinearGradientBrush(Color1Interpolated.ToMediaColor(),
Color2Interpolated.ToMediaColor(), Angle);
window.canvasManager.layers.DrawRect(Layer, Brush);
}, System.Windows.Threading.DispatcherPriority.Normal, token);
token.WaitHandle.WaitOne(Time2 / (Time2 / App.Settings.InterpolationQuality));
}
}
else {
var Brush = (LinearGradientBrush) OldBrush;
System.Windows.Media.Color OColor1;
System.Windows.Media.Color OColor2;
window.Dispatcher.Invoke(() => {
OColor1 = Brush.GradientStops[0].Color;
OColor2 = Brush.GradientStops[1].Color;
}, System.Windows.Threading.DispatcherPriority.Normal, token);
var j = 1;
while (j++ < Time2 / App.Settings.InterpolationQuality) {
var Color1Interpolated = ColorInterpolation.Interpolate(OColor1.ToDrawingColor(), Color1,
(ColorInterpolation.INTERPOLATE_FUNCTION) Transition, (double) j / (Time2 / App.Settings.InterpolationQuality));
var Color2Interpolated = ColorInterpolation.Interpolate(OColor2.ToDrawingColor(), Color2,
(ColorInterpolation.INTERPOLATE_FUNCTION) Transition, (double) j / (Time2 / App.Settings.InterpolationQuality));
window.Dispatcher.Invoke(() => {
var Brush = new LinearGradientBrush(Color1Interpolated.ToMediaColor(),
Color2Interpolated.ToMediaColor(), Angle);
window.canvasManager.layers.DrawRect(Layer, Brush);
}, System.Windows.Threading.DispatcherPriority.Normal, token);
token.WaitHandle.WaitOne(Time2 / (Time2 / App.Settings.InterpolationQuality));
}
}
token.WaitHandle.WaitOne(Time);
break;
case ColorInstructionEffect.Fade:
if (OldBrush is SolidColorBrush) {
var Brush = (SolidColorBrush) OldBrush;
System.Windows.Media.Color OColor;
window.Dispatcher.Invoke(() => { OColor = Brush.Color; }, System.Windows.Threading.DispatcherPriority.Normal, token);
var j = 1;
while (j++ < Time2 / App.Settings.InterpolationQuality) {
var Color1Interpolated = ColorInterpolation.Interpolate(OColor.ToDrawingColor(), Color1,
(ColorInterpolation.INTERPOLATE_FUNCTION) Transition, (double) j / (Time2 / App.Settings.InterpolationQuality));
window.Dispatcher.Invoke(() => {
var Brush = new SolidColorBrush(Color1Interpolated.ToMediaColor());
window.canvasManager.layers.DrawRect(Layer, Brush);
}, System.Windows.Threading.DispatcherPriority.Normal, token);
token.WaitHandle.WaitOne(Time2 / (Time2 / App.Settings.InterpolationQuality));
}
}
else {
var Brush = (LinearGradientBrush) OldBrush;
System.Windows.Media.Color OColor1;
System.Windows.Media.Color OColor2;
window.Dispatcher.Invoke(() => {
OColor1 = Brush.GradientStops[0].Color;
OColor2 = Brush.GradientStops[1].Color;
}, System.Windows.Threading.DispatcherPriority.Normal, token);
var j = 1;
while (j++ < Time2 / App.Settings.InterpolationQuality) {
var Color1Interpolated = ColorInterpolation.Interpolate(OColor1.ToDrawingColor(), Color1,
(ColorInterpolation.INTERPOLATE_FUNCTION) Transition, (double) j / (Time2 / App.Settings.InterpolationQuality));
var Color2Interpolated = ColorInterpolation.Interpolate(OColor2.ToDrawingColor(), Color1,
(ColorInterpolation.INTERPOLATE_FUNCTION) Transition, (double) j / (Time2 / App.Settings.InterpolationQuality));
window.Dispatcher.Invoke(() => {
var Brush = new LinearGradientBrush(Color1Interpolated.ToMediaColor(),
Color2Interpolated.ToMediaColor(), Angle);
window.canvasManager.layers.DrawRect(Layer, Brush);
}, System.Windows.Threading.DispatcherPriority.Normal, token);
token.WaitHandle.WaitOne(Time2 / (Time2 / App.Settings.InterpolationQuality));
}
}
token.WaitHandle.WaitOne(Time);
break;
}
return true;
}
}
================================================
FILE: RainbowTaskbar/Configuration/Instruction/Instructions/DelayInstruction.cs
================================================
using System.Dynamic;
using System.Runtime.Serialization;
using System.Threading;
namespace RainbowTaskbar.Configuration.Instruction.Instructions;
internal class DelayInstruction : Instruction {
public int Time { get; set; } = 1;
public override string Description {
get {
return App.localization.InstructionFormat(this, Time);
}
}
public override bool Execute(Taskbar window, CancellationToken token) {
token.WaitHandle.WaitOne(Time);
return true;
}
/*
public override JObject ToJSON() {
dynamic data = new ExpandoObject();
data.Name = GetType().Name;
data.Time = Time;
return JObject.FromObject(data);
}
*/
}
================================================
FILE: RainbowTaskbar/Configuration/Instruction/Instructions/ImageInstruction.cs
================================================
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Dynamic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace RainbowTaskbar.Configuration.Instruction.Instructions;
internal class ImageInstruction : Instruction {
public bool drawn = false;
public int Layer { get; set; } = 0;
public string Path { get; set; } = "";
public int X { get; set; } = 0;
public int Y { get; set; } = 0;
public int Width { get; set; } = 0;
public int Height { get; set; } = 0;
public double Opacity { get; set; } = 1;
public bool DrawOnce { get; set; } = false;
public override string Description {
get {
return App.localization.InstructionFormat(this, System.IO.Path.GetFileName(Path));
}
}
/*
public override JObject ToJSON() {
dynamic data = new ExpandoObject();
data.Name = GetType().Name;
data.Layer = Layer;
data.Path = Path;
data.X = X;
data.Y = Y;
data.Width = Width;
data.Height = Height;
data.Opacity = Opacity;
data.DrawOnce = DrawOnce;
return JObject.FromObject(data);
}
*/
public override bool Execute(Taskbar window, CancellationToken token) {
if (Path == "") return false;
if (DrawOnce && drawn) return false;
window.Dispatcher.Invoke(() => {
var bmp = new Bitmap(Path);
var ms = new MemoryStream();
bmp.Save(ms, ImageFormat.Png);
var image = new BitmapImage();
image.BeginInit();
ms.Seek(0, SeekOrigin.Begin);
image.StreamSource = ms;
image.EndInit();
window.canvasManager.layers.DrawImage(Layer, new Rect(X, Y, Width == 0 ? bmp.Width : Width, Height == 0 ? bmp.Height : Height), image);
}, System.Windows.Threading.DispatcherPriority.Normal, token);
if (DrawOnce) {
drawn = true;
}
return false;
}
}
================================================
FILE: RainbowTaskbar/Configuration/Instruction/Instructions/ShapeInstruction.cs
================================================
using System;
using System.Dynamic;
using System.Globalization;
using System.Linq;
using System.Runtime.Serialization;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows.Shapes;
using RainbowTaskbar.Interpolation;
using RainbowTaskbar.Languages;
namespace RainbowTaskbar.Configuration.Instruction.Instructions;
public class ShapeInstruction : Instruction {
public bool drawn = false;
public int Layer { get; set; } = 0;
public ShapeInstructionShapes Shape { get; set; } = ShapeInstructionShapes.Line;
public int X { get; set; } = 0;
public int Y { get; set; } = 0;
public int X2 { get; set; } = 0;
public int Y2 { get; set; } = 0;
private Taskbar _tsk;
private int x2 {
get {
if (FitTaskbars) {
return App.Settings.GraphicsRepeat ? _tsk.canvasManager.layers.width : App.layers.width;
}
else {
return X2;
}
}
}
private int y2 {
get {
if (FitTaskbars) {
return App.Settings.GraphicsRepeat ? _tsk.canvasManager.layers.height : App.layers.height;
}
else {
return Y2;
}
}
}
public bool DrawOnce { get; set; } = false;
public System.Drawing.Color Fill { get; set; } = System.Drawing.Color.FromArgb(255, 0, 0, 0);
public System.Drawing.Color Line { get; set; } = System.Drawing.Color.FromArgb(255, 0, 0, 0);
public int LineSize { get; set; } = 1;
public int Radius { get; set; } = 0;
private int radius {
get {
if (FitTaskbars) {
return _tsk.taskbarHelper.Radius + 1;
}
else {
return Radius;
}
}
}
public bool FitTaskbars { get; set; } = false;
public override string Description {
get {
var name = Shape == ShapeInstructionShapes.Rectangle && Radius > 0 ? App.localization.Get("enum_roundedrect") : Shape.ToStringLocalized();
return App.localization.InstructionFormat(this, name);
}
}
public override bool Execute(Taskbar window, CancellationToken token) {
_tsk = window;
if (DrawOnce && drawn) {
return false;
}
switch (Shape) {
case ShapeInstructionShapes.Line: {
var geometry = new LineGeometry(new Point(X, Y), new Point(x2, y2));
geometry.Freeze();
window.Dispatcher.Invoke(() =>
window.canvasManager.layers.DrawShape(Layer, geometry, null, new Pen(new SolidColorBrush(Line.ToMediaColor()), LineSize))
, System.Windows.Threading.DispatcherPriority.Normal, token);
break;
}
case ShapeInstructionShapes.Rectangle: {
var geometry = new RectangleGeometry(new Rect(new Point(X, Y), new Point(x2, y2)));
geometry.RadiusX = radius / 2.0; geometry.RadiusY = radius / 2.0;
geometry.Freeze();
window.Dispatcher.Invoke(() =>
window.canvasManager.layers.DrawShape(Layer, geometry, new SolidColorBrush(Fill.ToMediaColor()), new Pen(new SolidColorBrush(Line.ToMediaColor()), LineSize))
, System.Windows.Threading.DispatcherPriority.Normal, token);
break;
}
case ShapeInstructionShapes.Ellipse: {
var geometry = new EllipseGeometry(new Rect(new Point(X, Y), new Point(x2, y2)));
geometry.Freeze();
window.Dispatcher.Invoke(() =>
window.canvasManager.layers.DrawShape(Layer, geometry, new SolidColorBrush(Fill.ToMediaColor()), new Pen(new SolidColorBrush(Line.ToMediaColor()), LineSize))
, System.Windows.Threading.DispatcherPriority.Normal, token);
break;
}
}
if (DrawOnce) {
drawn = true;
}
return false;
}
public enum ShapeInstructionShapes {
Line,
Rectangle,
Ellipse
}
/*
public override JObject ToJSON() {
dynamic data = new ExpandoObject();
data.Name = GetType().Name;
data.Layer = Layer;
data.Shape = Shape;
data.X = X;
data.Y = Y;
data.X2 = X2;
data.Y2 = Y2;
data.FitTaskbars = FitTaskbars;
data.Fill = ColorExtension.HexConverter(Fill);
data.Line = ColorExtension.HexConverter(Line);
data.LineSize = LineSize;
data.DrawOnce = DrawOnce;
return JObject.FromObject(data);
}
*/
}
================================================
FILE: RainbowTaskbar/Configuration/Instruction/Instructions/TextInstruction.cs
================================================
using System.Dynamic;
using System.Runtime.Serialization;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using RainbowTaskbar.Interpolation;
using Color = System.Drawing.Color;
namespace RainbowTaskbar.Configuration.Instruction.Instructions;
internal class TextInstruction : Instruction {
public bool drawn = false;
public int Layer { get; set; } = 1;
public string Text { get; set; } = "";
public int X { get; set; } = 0;
public int Y { get; set; } = 0;
public string Font { get; set; } = "Arial";
public int Size { get; set; } = 32;
public bool DrawOnce { get; set; } = false;
public Color Color { get; set; } = Color.Black;
public bool Center { get; set; } = false;
public override string Description {
get {
return App.localization.InstructionFormat(this, Text);
}
}
/*
public override JObject ToJSON() {
dynamic data = new ExpandoObject();
data.Name = GetType().Name;
data.Layer = Layer;
data.Text = Text;
data.X = X;
data.Y = Y;
data.Font = Font;
data.Size = Size;
data.Color = ColorExtension.HexConverter(Color);
data.DrawOnce = DrawOnce;
data.Center = Center;
return JObject.FromObject(data);
}*/
public override bool Execute(Taskbar window, CancellationToken token) {
if (drawn && DrawOnce) {
return false;
}
window.Dispatcher.Invoke(() =>
window.canvasManager.layers.DrawText(Layer, Text, X, Y, Size, Font, new SolidColorBrush(Color.ToMediaColor()), Center)
, System.Windows.Threading.DispatcherPriority.Normal, token);
if (DrawOnce) drawn = true;
return false;
}
}
================================================
FILE: RainbowTaskbar/Configuration/Instruction/Instructions/TransparencyInstruction.cs
================================================
using System;
using System.Dynamic;
using System.Runtime.Serialization;
using System.Threading;
using System.Windows.Controls;
using RainbowTaskbar.Helpers;
using RainbowTaskbar.Languages;
namespace RainbowTaskbar.Configuration.Instruction.Instructions;
public class TransparencyInstruction : Instruction {
public enum TransparencyInstructionStyle {
Default,
Blur,
Transparent
}
public enum TransparencyInstructionType {
Taskbar,
RainbowTaskbar,
All,
Style,
Layer,
TaskbarElements
}
public TransparencyInstructionType Type { get; set; }
public double Opacity { get; set; } = 1;
public double TaskbarOpacity { get => App.Settings.GlobalOpacity == -1 ? Opacity : App.Settings.GlobalOpacity; }
public TransparencyInstructionStyle Style { get; set; }
public int Layer { get; set; }
public override string Description {
get {
/*return Type == TransparencyInstructionType.Style ? $"Taskbar style - {Style.ToString()}" :
(Type == TransparencyInstructionType.Layer ? $"Layer {Layer} - {Math.Round(Opacity * 100)}% opacity" :
$"{Type.ToString()} - {Math.Round(Opacity * 100)}% opacity");*/
if (Type == TransparencyInstructionType.Style) {
return App.localization.InstructionFormatSuffix(this, "style", Style.ToStringLocalized());
}
else if (Type == TransparencyInstructionType.Layer) {
return App.localization.InstructionFormatSuffix(this, "layer", Layer, Math.Round(Opacity * 100));
}
else {
return App.localization.InstructionFormatSuffix(this, "opacity", Type.ToStringLocalized(), Math.Round(Opacity * 100));
}
}
}
/*
public override JObject ToJSON() {
dynamic data = new ExpandoObject();
data.Name = GetType().Name;
data.Opacity = Opacity;
data.Layer = Layer;
data.Style = Style;
data.Type = Type;
return JObject.FromObject(data);
}
*/
public override bool Execute(Taskbar window, CancellationToken token) {
switch (Type) {
case TransparencyInstructionType.Taskbar:
window.taskbarHelper.SetAlpha(TaskbarOpacity);
break;
case TransparencyInstructionType.RainbowTaskbar:
window.Dispatcher.Invoke(() => {
if (window.Opacity != Opacity) window.Opacity = Opacity;
}, System.Windows.Threading.DispatcherPriority.Normal, token);
break;
case TransparencyInstructionType.All:
window.Dispatcher.Invoke(() => {
if (window.Opacity != Opacity) window.Opacity = Opacity;
}, System.Windows.Threading.DispatcherPriority.Normal, token);
window.taskbarHelper.SetAlpha(TaskbarOpacity);
break;
case TransparencyInstructionType.Style:
switch (Style) {
case TransparencyInstructionStyle.Default:
if (window.taskbarHelper.Style != TaskbarHelper.TaskbarStyle.Default)
window.taskbarHelper.Style = TaskbarHelper.TaskbarStyle.ForceDefault;
break;
case TransparencyInstructionStyle.Blur:
window.taskbarHelper.Style = TaskbarHelper.TaskbarStyle.Blur;
break;
case TransparencyInstructionStyle.Transparent:
window.taskbarHelper.Style = TaskbarHelper.TaskbarStyle.Transparent;
break;
}
ExplorerTAP.ExplorerTAP.SetAppearanceType(Style);
break;
case TransparencyInstructionType.Layer:
window.Dispatcher.Invoke(() =>
window.canvasManager.canvases[Layer].Opacity = Opacity
, System.Windows.Threading.DispatcherPriority.Normal, token);
break;
case TransparencyInstructionType.TaskbarElements:
ExplorerTAP.ExplorerTAP.SetTaskbarElementsOpacity(Opacity);
break;
}
return false;
}
}
================================================
FILE: RainbowTaskbar/Configuration/Web/WebConfig.cs
================================================
using Microsoft.Web.WebView2.Core;
using Microsoft.Web.WebView2.Wpf;
using RainbowTaskbar.Helpers;
using RainbowTaskbar.Interpolation;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows.Threading;
namespace RainbowTaskbar.Configuration.Web {
public enum WebConfigUserSettingDataType {
String,
Number,
Color,
Boolean
}
[Serializable]
public class WebConfigUserSetting {
public string Name { get; set; } = App.localization?.Get("defpropname") ?? "New property";
public string Key { get; set; } = App.localization?.Get("defpropkey") ?? "property_1";
public string _value { get; set; } = string.Empty;
// probably should have used a converter but i gave up trying
[JsonIgnore]
public string ValueJS {
get {
switch (DataType) {
case WebConfigUserSettingDataType.Boolean: {
var suc = bool.TryParse(_value, out bool res);
return suc ? res.ToString().ToLower() : "false";
}
case WebConfigUserSettingDataType.Number: {
var suc = double.TryParse(_value, out double res);
return suc ? res.ToString() : "0";
}
default:
return $"{JsonSerializer.Serialize(_value)}";
}
}
}
[JsonIgnore]
public dynamic Value {
get {
switch (DataType) {
case WebConfigUserSettingDataType.Boolean: {
var suc = bool.TryParse(_value, out bool res);
return suc ? res : false;
}
case WebConfigUserSettingDataType.Number: {
var suc = double.TryParse(_value, out double res);
return suc ? res : 0;
}
case WebConfigUserSettingDataType.Color: {
try {
return (System.Windows.Media.Color) System.Windows.Media.ColorConverter.ConvertFromString(_value);
}
catch { return System.Windows.Media.Color.FromArgb(255, 0, 0, 0); }
}
default:
return _value;
}
}
set {
switch (DataType) {
case WebConfigUserSettingDataType.Boolean: {
_value = value ? "true" : "false";
break;
}
case WebConfigUserSettingDataType.Number: {
_value = (value as object).ToString();
break;
}
case WebConfigUserSettingDataType.Color: {
_value = ColorTranslator.ToHtml(((System.Windows.Media.Color) value).ToDrawingColor());
break;
}
default:
_value = (value as object).ToString();
break;
}
}
}
public WebConfigUserSettingDataType DataType { get; set; } = WebConfigUserSettingDataType.String;
}
[Serializable]
public class WebConfigData : ConfigData {
public string WebContent { get; set; }
public BindingList UserSettings { get; set; } = new() { new() { } };
}
[Serializable]
public class WebConfig : Config {
[JsonIgnore]
public WebConfigData Data { get => ConfigData as WebConfigData; set
{
ConfigData = value;
}
}
public WebConfig() {
ConfigData = new WebConfigData() { WebContent = """
""" };
}
private void _Start(WebView2 webView, Mutex webViewReady, Taskbar t) {
if(!webViewReady.WaitOne(1500)) return;
webViewReady.ReleaseMutex();
App.Current.Dispatcher.Invoke(() => {
webView?.CoreWebView2.Resume();
webView.CoreWebView2.MemoryUsageTargetLevel = Microsoft.Web.WebView2.Core.CoreWebView2MemoryUsageTargetLevel.Low;
File.WriteAllText(Path.Join(App.rainbowTaskbarDir, "current.html"), Data.WebContent);
var code = $$"""
// requestAnimationFrame code adapted from https://github.com/PixelsCommander/fps-control-chrome-extension/blob/master/src/js/content.js
window.rtMaxFPS = {{App.Settings.MaxWebFPS}};
window.rtUserConfig = {};
let __rafs = 0;
let __raf = window.requestAnimationFrame;
let __nextRAFTime = Date.now();
let __mockedRaf = (callback) => {
let skip = (window.rtMaxFPS !== 0 && Date.now() < __nextRAFTime);
if (skip) {
__skippingRaf(callback);
} else {
__nextRAFTime = Date.now() + 1000/window.rtMaxFPS;
__raf(callback);
}
return __rafs++;
}
function __skippingRaf(func) {
__raf(() => {
window.requestAnimationFrame(func);
})
}
window.rainbowTaskbar = {
setTaskbarOpacity: (v) => {window.chrome.webview.postMessage({m:"transparency",v,which:0}); return window.rainbowTaskbar},
setUnderlayOpacity: (v) => {window.chrome.webview.postMessage({m:"transparency",v,which:1}); return window.rainbowTaskbar},
setTaskbarElementsOpacity: (v) => {window.chrome.webview.postMessage({m:"transparency",v,which:5}); return window.rainbowTaskbar},
setStyleDefault: () => {window.chrome.webview.postMessage({m:"style",style:0}); return window.rainbowTaskbar},
setStyleBlur: () => {window.chrome.webview.postMessage({m:"style",style:1}); return window.rainbowTaskbar},
setStyleTransparent: () => {window.chrome.webview.postMessage({m:"style",style:2}); return window.rainbowTaskbar},
setTaskbarOffset: (offset) => {window.chrome.webview.postMessage({m:"offset",v:offset}); return window.rainbowTaskbar},
uiInfo: {},
graphicsRepeat: {{(App.Settings.GraphicsRepeat ? "true" : "false")}},
maxFps: window.rtMaxFPS,
rtUserConfig: window.rtUserConfig,
taskbarIndex: {{(t is not null ? App.taskbars.IndexOf(t) : -1)}},
helpers: {
normalizeTaskbarCoords: (_ui, copy = true) => {
let ui = copy ? JSON.parse(JSON.stringify(_ui)) : _ui;
let minX = _ui.sort((a,b)=>a.taskbar.X - b.taskbar.X)[0].taskbar.X;
for(let e of ui) {
e.taskbar.X -= minX;
}
return ui;
},
normalizeAndScaleUICoords: (_ui, copy = true) => {
let ui = rainbowTaskbar.helpers.normalizeTaskbarCoords(_ui, copy);
for(let e of ui) {
e.taskbar.X /= window.devicePixelRatio;
e.taskbar.Y /= window.devicePixelRatio;
e.taskbar.Width /= window.devicePixelRatio;
e.taskbar.Height /= window.devicePixelRatio;
e.taskbarFrameRepeater.X /= window.devicePixelRatio;
e.taskbarFrameRepeater.Y /= window.devicePixelRatio;
e.taskbarFrameRepeater.Width /= window.devicePixelRatio;
e.taskbarFrameRepeater.Height /= window.devicePixelRatio;
e.systemTrayFrame.X /= window.devicePixelRatio;
e.systemTrayFrame.Y /= window.devicePixelRatio;
e.systemTrayFrame.Width /= window.devicePixelRatio;
e.systemTrayFrame.Height /= window.devicePixelRatio;
}
return ui;
},
generateCSSMaskForUI: (_ui, fadeTop = true) => {
let ui = rainbowTaskbar.helpers.normalizeAndScaleUICoords(_ui);
ui.sort((a,b) => a.taskbar.X - b.taskbar.X);
let genVis = ``;
if(rainbowTaskbar.graphicsRepeat) {
let x = ui.find(x=>x.taskbarIndex == rainbowTaskbar.taskbarIndex);
genVis = `rgba(255, 255, 255, 0) ${x.taskbarFrameRepeater.X - 24}px, rgba(255, 255, 255, 1) ${x.taskbarFrameRepeater.X + 64}px, rgba(255, 255, 255, 1) ${x.taskbarFrameRepeater.X + x.taskbarFrameRepeater.Width - 64}px, rgba(255, 255, 255, 0) ${x.taskbarFrameRepeater.X + x.taskbarFrameRepeater.Width + 24}px, rgba(255, 255, 255, 0) ${x.systemTrayFrame.X - 24}px, rgba(255, 255, 255, 1) ${x.systemTrayFrame.X + 64}px, rgba(255, 255, 255, 1) ${x.taskbar.Width - 8}px, rgba(255, 255, 255, 0) ${x.taskbar.Width}px,`
} else {
genVis = ui.map((x,i)=>
`rgba(255, 255, 255, ${+(x.taskbarFrameRepeater.X == 0)}) ${x.taskbar.X + x.taskbarFrameRepeater.X - 24}px, rgba(255, 255, 255, 1) ${x.taskbar.X + x.taskbarFrameRepeater.X + 64}px, rgba(255, 255, 255, 1) ${x.taskbar.X + x.taskbarFrameRepeater.X + x.taskbarFrameRepeater.Width - 64}px, rgba(255, 255, 255, 0) ${x.taskbar.X + x.taskbarFrameRepeater.X + x.taskbarFrameRepeater.Width + 24}px, rgba(255, 255, 255, 0) ${x.taskbar.X + x.systemTrayFrame.X - 24}px, rgba(255, 255, 255, 1) ${x.taskbar.X + x.systemTrayFrame.X + 64}px, rgba(255, 255, 255, 1) ${x.taskbar.X + x.taskbar.Width - 8}px, rgba(255, 255, 255, ${+(x.taskbarFrameRepeater.X == 0)}) ${x.taskbar.X + x.taskbar.Width}px,`
).join("")
}
let mask = `linear-gradient(90deg,rgba(255, 255, 255, 0) 0%, ${genVis} rgba(255, 255, 255, 1) 100%) 0px 0px / 100% 100% no-repeat${fadeTop ? ", linear-gradient(180deg,rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0) 1px, rgba(255, 255, 255, 1) 40%, rgba(255, 255, 255, 1) 100%) 0px 0px / 100% 100% no-repeat" : ""}`;
let maskComposite = 'intersect';
return {
mask, maskComposite,
apply: () => {
document.documentElement.style.mask = mask;
document.documentElement.style.maskComposite = maskComposite;
}
}
}
},
onUIChanged: (uiInfo) => {},
__internal: {
__onUIChanged: (data) => {window.rainbowTaskbar.uiInfo=data;window.rainbowTaskbar.onUIChanged(window.rainbowTaskbar.uiInfo);},
}
}
window.chrome.webview.addEventListener("message", (m) => {
let message = JSON.parse(m.data);
if(message.message == "ui") {
window.rainbowTaskbar.__internal.__onUIChanged(message.data);
}
});
window.chrome.webview.postMessage({m:"ui"})
for(let i = 1; i <= 5; i++) setTimeout(() => window.chrome.webview.postMessage({m:"ui"}), i*500);
window.requestAnimationFrame = __mockedRaf;
{{string.Join('\n', Data.UserSettings.Select((x) => {
return "window.rtUserConfig[" + JsonSerializer.Serialize(new Regex("[^\\w$]").Replace(x.Key, " ")) + "]=" + x.ValueJS + ";";
})) ?? ""}}
""";
webView?.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(
code).ContinueWith((s) => {
App.Current.Dispatcher.Invoke(() => {
webView?.CoreWebView2.Navigate(Path.Join(App.rainbowTaskbarDir, "current.html"));
EventHandler handler = null;
handler = (sender, args) => {
webView.CoreWebView2.RemoveScriptToExecuteOnDocumentCreated(s.Result);
webView.NavigationCompleted -= handler;
};
webView.NavigationCompleted += handler;
});
});
});
}
public override async Task Start() {
if (!(await base.Start())) return false;
App.taskbars.ForEach(x => {
x.ClassicGrid.Visibility = System.Windows.Visibility.Collapsed;
x.WebGrid.Visibility = System.Windows.Visibility.Visible;
});
if(App.Settings.GraphicsRepeat) {
App.taskbars.ForEach(x => {
Task.Run(() => {
_Start(x.webView, x.webViewReady_, x);
});
});
} else {
Task.Run(() => {
_Start(App.webView, App.webViewReady, null);
});
}
return true;
}
public override Task Stop() {
var wv = App.webView;
return Task.Run(() => {
App.Current.Dispatcher.Invoke(() => {
try {
wv?.NavigateToString("");
wv?.CoreWebView2.TrySuspendAsync();
}
catch { }
});
});
}
}
}
================================================
FILE: RainbowTaskbar/Drawing/CanvasManager.cs
================================================
using System.Drawing;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Shapes;
using System.Linq;
using System.Collections.Generic;
using System.Windows.Media;
using System.Globalization;
using System.Windows.Media.Imaging;
namespace RainbowTaskbar.Drawing;
public class CanvasManager {
public List canvases;
private LayerManager _layers = null;
public LayerManager layers {
get {
if (_layers == null) {
return App.layers;
}
else return _layers;
}
set => _layers = value;
}
public Window window;
public CanvasManager(Taskbar window, Canvas[] canvases) {
this.window = window;
this.canvases = canvases.ToList();
this.canvases.ForEach((c) => {
c.Width = window.Width;
c.Height = window.Height;
});
if (App.Settings.GraphicsRepeat) _layers = new LayerManager(window);
}
public void SetImage(int index, RenderTargetBitmap target) {
var c = canvases[index];
var img = new System.Windows.Controls.Image();
img.Name = $"{c.Name}Image";
img.Width = layers.width;
img.Height = c.Height;
img.SnapsToDevicePixels = true;
img.Source = target;
img.Stretch = Stretch.None;
c.Children.Add(img);
Canvas.SetTop(img, 0);
if(!App.Settings.GraphicsRepeat) {
Canvas.SetLeft(img, -window.Left);
}
}
}
================================================
FILE: RainbowTaskbar/Drawing/LayerManager.cs
================================================
using RainbowTaskbar.Helpers;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace RainbowTaskbar.Drawing
{
public class LayerManager
{
public int width = 0;
public int height = 0;
public Taskbar window = null;
public List renderTargets = new List();
public List brushes = new List();
public LayerManager() {
for (int i = 0; i < 16; i++) brushes.Add(new SolidColorBrush(System.Windows.Media.Color.FromRgb(255, 255, 255)));
}
public LayerManager(Taskbar window) {
this.window = window;
width = (int) (window.Width);
height = (int) (window.Height);
for (int i = 0; i < 16; i++) brushes.Add(new SolidColorBrush(System.Windows.Media.Color.FromRgb(255, 255, 255)));
}
public void MakeIfNeeded(int layer) {
if (renderTargets.Count - 1 < layer && layer < 16) {
for (int i = renderTargets.Count; i <= layer; i++) {
var target = new RenderTargetBitmap((int) width, (int) height, 96, 96, PixelFormats.Pbgra32);
renderTargets.Add(target);
if(window is not null) window.canvasManager.SetImage(i, target);
else {
App.taskbars.ForEach(b => {
b.canvasManager.SetImage(i, target);
});
}
}
}
}
public void DrawRect(int layer, System.Windows.Media.Brush fill, Rect? rect = null) {
MakeIfNeeded(layer);
var visual = new DrawingVisual();
var ctx = visual.RenderOpen();
ctx.DrawRectangle(fill, null, rect ?? new Rect(0, 0, width, height));
brushes[layer] = fill;
ctx.Close();
renderTargets[layer].Render(visual);
}
public void DrawImage(int layer, Rect rect, ImageSource imageSource) {
MakeIfNeeded(layer);
var visual = new DrawingVisual();
var ctx = visual.RenderOpen();
ctx.DrawImage(imageSource, rect);
ctx.Close();
renderTargets[layer].Render(visual);
}
public void DrawShape(int layer, Geometry shape, System.Windows.Media.Brush brush = null, System.Windows.Media.Pen pen = null) {
MakeIfNeeded(layer);
var visual = new DrawingVisual();
var ctx = visual.RenderOpen();
ctx.DrawGeometry(brush, pen, shape);
ctx.Close();
renderTargets[layer].Render(visual);
}
public void DrawText(int layer, string content, int x = 0, int y = 0, int size = 32, string font = "Arial", System.Windows.Media.Brush fill = null, bool Center = false) {
MakeIfNeeded(layer);
var visual = new DrawingVisual();
var ctx = visual.RenderOpen();
var ftext = new FormattedText(
content ?? "",
CultureInfo.GetCultureInfo("en-us"),
FlowDirection.LeftToRight,
new Typeface(font),
size,
fill,
TaskbarHelper.GetSystemDpi() / 96.0
);
ctx.DrawText(ftext, new System.Windows.Point(Center ? width/2 - ftext.Width/2 : x, y));
ctx.Close();
renderTargets[layer].Render(visual);
}
}
}
================================================
FILE: RainbowTaskbar/Editor/DebugWindow.xaml
================================================
================================================
FILE: RainbowTaskbar/Editor/DebugWindow.xaml.cs
================================================
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Dynamic;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Wpf.Ui.Appearance;
using Wpf.Ui.Controls;
namespace RainbowTaskbar.Editor
{
///
/// Interaction logic for DebugWindow.xaml
///
public partial class DebugWindow : FluentWindow, INotifyPropertyChanged
{
public string DebugText { get; set; }
private bool active = true;
public DebugWindow()
{
DataContext = this;
InitializeComponent();
ApplicationThemeManager.ApplySystemTheme(true);
Task.Run(() => {
while (active) {
List missingKeys = new List();
foreach (DictionaryEntry key in App.localization.dictionary_en_US) {
if(!App.localization.dictionary.Contains(key.Key)) missingKeys.Add((string)key.Key);
}
DebugText = $"Missing translation keys: {string.Join(", ", missingKeys)}\n\n";
if (ExplorerTAP.ExplorerTAP.IsInjected) {
DebugText += $"UI Data: {ExplorerTAP.ExplorerTAP.GetUIDataStr(App.taskbars[0])}\n";
}
Thread.Sleep(100);
}
});
}
public event PropertyChangedEventHandler PropertyChanged;
private void FluentWindow_Closing(object sender, CancelEventArgs e) {
active = false;
}
}
}
================================================
FILE: RainbowTaskbar/Editor/EditorViewModel.cs
================================================
using RainbowTaskbar.Editor.Pages.Edit;
using RainbowTaskbar.Helpers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
namespace RainbowTaskbar.Editor {
public class EditorViewModel {
public EditPage EditPage { get; set; }
public string? LatestUpdateInfo { get; set; } = null;
public bool IsAppMicrosoftStore { get => App.IsAppMicrosoftStore; }
}
}
================================================
FILE: RainbowTaskbar/Editor/EditorWindow.xaml
================================================
================================================
FILE: RainbowTaskbar/Editor/EditorWindow.xaml.cs
================================================
using RainbowTaskbar.Configuration;
using RainbowTaskbar.Editor.Pages;
using RainbowTaskbar.Editor.Pages.Controls;
using RainbowTaskbar.Editor.Pages.Edit;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Reflection.Metadata;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Wpf.Ui;
using Wpf.Ui.Appearance;
using Wpf.Ui.Controls;
using Wpf.Ui.Extensions;
using Xceed.Wpf.AvalonDock.Controls;
namespace RainbowTaskbar.Editor {
///
/// Interaction logic for EditorWindow.xaml
///
public partial class EditorWindow : FluentWindow {
public IContentDialogService contentDialogService;
public EditorWindow() {
SystemThemeWatcher.Watch(this);
InitializeComponent();
nav.Loaded += (_, _) => {
nav.Navigate(typeof(Home));
ApplicationThemeManager.ApplySystemTheme(true);
};
this.DataContext = App.editorViewModel;
this.contentDialogService = new ContentDialogService();
contentDialogService.SetDialogHost(RootContentDialogPresenter);
App.localization.Enable(Resources.MergedDictionaries);
if (!App.monacoExtracted) {
Stream stream = new MemoryStream(Properties.Resources.monaco);
if (Directory.Exists(App.monacoDir))
Directory.Delete(App.monacoDir, true);
ZipFile.ExtractToDirectory(stream, App.monacoDir);
}
}
public void OpenConfig(Config config) {
App.editor.nav.Navigate(typeof(EmptyPageBadFix));
var page = new ViewInfo(config);
Task.Run(() => {
Thread.Sleep(50);
Dispatcher.Invoke(() => App.editor.nav.Navigate(typeof(EmptyPageBadFix2)));
Thread.Sleep(50);
Dispatcher.Invoke(() => App.editor.nav.ReplaceContent(page));
});
}
private void nav_Navigating(NavigationView sender, NavigatingCancelEventArgs args) {
// this is totally disgusting but wpf ui is cooked so whatever
if(args.Page is Browse b) {
b.OnSortChanged();
}
var navigationViewContentPresenter = (NavigationViewContentPresenter) sender.GetType()
.GetProperty("NavigationViewContentPresenter", BindingFlags.NonPublic | BindingFlags.Instance)
.GetValue(sender);
var current = (Page)navigationViewContentPresenter.Content;
current.FindVisualChildren().ToList().ForEach(x => {
x.Dispose();
});
if (current is not null && current.GetType() != args.Page.GetType() && (current is Browse || App.editorViewModel.EditPage is InstructionEditPage) && args.Page is not EmptyPageBadFix) {
args.Cancel = true;
nav.Navigate(typeof(EmptyPageBadFix));
Type t = args.Page.GetType();
Task.Run(() => {
Thread.Sleep(50);
Dispatcher.Invoke(() => nav.Navigate(t));
});
}
if(current is EditInfo editInfo) {
editInfo.Save(null, null);
return;
}
if (App.editorViewModel.EditPage is not null && App.editorViewModel.EditPage is InstructionEditPage) {
var page = App.editorViewModel.EditPage as InstructionEditPage;
page.Current.Stop();
if (App.Settings.SelectedConfig is not null) App.Settings.SelectedConfig.Start();
}
if (App.editorViewModel.EditPage is not null && App.editorViewModel.EditPage is WebEditPage) {
if (App.Settings.SelectedConfig is not null) App.Settings.SelectedConfig.Start();
}
if (App.editorViewModel.EditPage is not null && App.editorViewModel.EditPage.Modified) {
args.Cancel = true;
if(App.editorViewModel.EditPage is WebEditPage) {
var page = App.editorViewModel.EditPage as WebEditPage;
page.webView.Visibility = Visibility.Hidden;
}
var task = contentDialogService.ShowSimpleDialogAsync(
new SimpleContentDialogCreateOptions() {
Title = App.localization.Get("msgbox_save_title"),
Content = App.localization.Get("msgbox_save"),
PrimaryButtonText = App.localization.Get("msgbox_save_b1"),
SecondaryButtonText = App.localization.Get("msgbox_save_b2"),
CloseButtonText = App.localization.Get("msgbox_button_cancel"),
});
Task.Run(() => {
var res = task.Result;
var saving = false;
switch (res) {
case ContentDialogResult.Primary:
if (App.editorViewModel.EditPage is WebEditPage) {
var page = App.editorViewModel.EditPage as WebEditPage;
// INSANE!
Dispatcher.Invoke(() => {
saving = true;
page.Save();
Task.Run(() => {
Thread.Sleep(1500);
saving = false;
Dispatcher.Invoke(() => {
try {
page.webView.Dispose();
}
catch { }
});
});
});
}
goto case ContentDialogResult.Secondary;
case ContentDialogResult.Secondary:
Dispatcher.Invoke(() => {
// weird COM error sometimes?
try {
if(!saving) (App.editorViewModel.EditPage as WebEditPage).webView.Dispose();
}
catch { }
});
App.editorViewModel.EditPage = null;
Dispatcher.Invoke(() => sender.Navigate(args.Page.GetType()));
Dispatcher.Invoke(() => { if (App.Settings.SelectedConfig is not null) App.Settings.SelectedConfig.Start(); });
break;
case ContentDialogResult.None:
if (App.editorViewModel.EditPage is WebEditPage) {
var page = App.editorViewModel.EditPage as WebEditPage;
Dispatcher.Invoke(() => page.webView.Visibility = Visibility.Visible);
}
break;
}
});
return;
}
if (App.editorViewModel.EditPage is not null && App.editorViewModel.EditPage is WebEditPage) {
(App.editorViewModel.EditPage as WebEditPage).webView.Dispose();
}
if(App.editorViewModel.EditPage is not null) {
App.editorViewModel.EditPage = null;
}
ApplicationThemeManager.ApplySystemTheme(true);
}
private void FluentWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e) {
App.editor = null;
nav.FindVisualChildren().ToList().ForEach(x => {
x.Dispose();
});
//e.Cancel = true;
//Hide();
}
DebugWindow curDeb = null;
private void FluentWindow_KeyDown(object sender, KeyEventArgs e) {
if(e.Key == Key.F12) {
if(curDeb is not null) {
curDeb.Close();
}
curDeb = new DebugWindow();
curDeb.Show();
}
}
}
}
================================================
FILE: RainbowTaskbar/Editor/Pages/About.xaml
================================================
GitHub
================================================
FILE: RainbowTaskbar/Editor/Pages/About.xaml.cs
================================================
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Wpf.Ui.Appearance;
namespace RainbowTaskbar.Editor.Pages {
///
/// Interaction logic for About.xaml
///
public partial class About : Page {
public About() {
InitializeComponent();
ApplicationThemeManager.ApplySystemTheme(true);
App.localization.Enable(Resources.MergedDictionaries);
}
private void Image_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) {
Process.Start(new ProcessStartInfo("https://paypal.me/ad2k17") { UseShellExecute = true });
}
private void Hyperlink_Click(object sender, RoutedEventArgs e) {
Process.Start(new ProcessStartInfo("https://github.com/ad2017gd") { UseShellExecute = true });
}
private void Hyperlink_Click_1(object sender, RoutedEventArgs e) {
Process.Start(new ProcessStartInfo("https://github.com/ad2017gd/RainbowTaskbar/issues/new/choose") { UseShellExecute = true });
}
private void Hyperlink_Click_2(object sender, RoutedEventArgs e) {
Process.Start(new ProcessStartInfo("https://ad2017.dev/rnb") { UseShellExecute = true });
}
}
}
================================================
FILE: RainbowTaskbar/Editor/Pages/Browse.xaml
================================================
================================================
FILE: RainbowTaskbar/Editor/Pages/Browse.xaml.cs
================================================
using RainbowTaskbar.Configuration;
using RainbowTaskbar.Editor.Pages.Controls;
using RainbowTaskbar.HTTPAPI;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Wpf.Ui.Appearance;
using Xceed.Wpf.AvalonDock.Controls;
namespace RainbowTaskbar.Editor.Pages
{
public enum SortBy {
Likes,
Match
}
///
/// Interaction logic for Browse.xaml
///
public partial class Browse : Page, INotifyPropertyChanged
{
public ObservableCollection ResultList { get; set; } = new();
public SortBy Sort { get; set; } = SortBy.Likes;
public int Page { get; set; } = -1;
private bool end = false;
public bool SearchLoaded { get; set; } = true;
public Browse()
{
DataContext = this;
InitializeComponent();
ApplicationThemeManager.ApplySystemTheme(true);
App.localization.Enable(Resources.MergedDictionaries);
}
public void Clear() {
itemscontrol.FindVisualChildren().ToList().ForEach(x => {
x.Dispose();
});
ResultList.Clear();
}
public void OnSortChanged() {
if (!SearchLoaded) return;
SearchLoaded = false;
scrollViewer.ScrollToHome();
Clear();
Page = -1;
end = false;
Task.Run(() => {
Thread.Sleep(300);
while (scrollViewer.VerticalOffset == scrollViewer.ScrollableHeight && !end) {
Page++;
Task t = null;
Dispatcher.Invoke(() => t = Search());
t.Wait();
Thread.Sleep(300);
}
});
}
public Task Search() {
SearchLoaded = false;
var configsreq = App.Settings.workshopAPI.SearchConfigsAsync(search.Text.Trim(), Sort, Page);
return Task.Run(() => {
var cfgs = configsreq.Result;
if (cfgs is null) {
end = true;
SearchLoaded = true;
return;
}
var parsed = cfgs.Parse();
if(parsed.Count() == 0) {
end = true;
SearchLoaded = true;
return;
}
Dispatcher.Invoke(() => parsed.ToList().ForEach(x=>ResultList.Add(x)));
SearchLoaded = true;
});
}
Timer searchTimer;
private void TextBox_TextChanged(object sender, TextChangedEventArgs e) {
if (!SearchLoaded) return;
if (searchTimer != null) searchTimer.Dispose();
searchTimer = new Timer((_) => {
Dispatcher.Invoke(() => {
Clear();
Page = 0;
end = false;
Search();
});
});
searchTimer.Change(250, Timeout.Infinite);
}
private void ScrollViewer_ScrollChanged(object sender, ScrollChangedEventArgs e) {
if (!SearchLoaded) return;
var scroll = (ScrollViewer)sender;
if (scroll.VerticalOffset == scroll.ScrollableHeight && e.ExtentHeightChange == 0 && !end) {
Page++;
Search();
}
}
}
}
================================================
FILE: RainbowTaskbar/Editor/Pages/Configs.xaml
================================================
================================================
FILE: RainbowTaskbar/Editor/Pages/Configs.xaml.cs
================================================
using PropertyChanged;
using RainbowTaskbar.Configuration;
using RainbowTaskbar.Configuration.Instruction;
using RainbowTaskbar.Configuration.Web;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Wpf.Ui.Appearance;
namespace RainbowTaskbar.Editor.Pages
{
///
/// Interaction logic for Configs.xaml
///
public partial class Configs : Page
{
public ObservableCollection ConfigList { get => App.Configs; }
public Configs()
{
DataContext = this;
InitializeComponent();
ApplicationThemeManager.ApplySystemTheme(true);
App.localization.Enable(Resources.MergedDictionaries);
}
private void AddNewConfig(object sender, RoutedEventArgs e) {
var menu = (MenuItem)sender;
Config cfg = null;
if(menu.Tag.ToString() == "classic") {
cfg = new InstructionConfig();
} else {
cfg = new WebConfig();
}
cfg.InitNew();
cfg.ToFile();
App.Configs.Insert(0, cfg);
}
}
}
================================================
FILE: RainbowTaskbar/Editor/Pages/Controls/ConfigListItemControl.xaml
================================================
================================================
FILE: RainbowTaskbar/Editor/Pages/Controls/ConfigListItemControl.xaml.cs
================================================
using Kasay;
using PropertyChanged;
using RainbowTaskbar.Configuration;
using RainbowTaskbar.Configuration.Web;
using RainbowTaskbar.Editor.Pages.Edit;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Xceed.Wpf.AvalonDock.Controls;
namespace RainbowTaskbar.Editor.Pages.Controls
{
///
/// Interaction logic for ConfigListItemControl.xaml
///
public partial class ConfigListItemControl : UserControl, INotifyPropertyChanged
{
public static readonly DependencyProperty ConfigProperty =
DependencyProperty.Register(
"Config",
typeof(Config),
typeof(ConfigListItemControl));
public Config Config {
get {
return (Config) GetValue(ConfigProperty);
}
set {
SetValue(ConfigProperty, value);
}
}
public string ConfigType { get => (Config is WebConfig) ? App.localization["enum_web"] : App.localization["enum_classic"]; }
public void OnConfigChanged() {
image.Source = Config.LoadImage();
}
public ConfigListItemControl()
{
InitializeComponent();
DependencyPropertyDescriptor
.FromProperty(ConfigProperty, typeof(ConfigListItemControl))
.AddValueChanged(this, (s, e) => OnConfigChanged());
}
private void Delete(object sender, RoutedEventArgs e) {
e.Handled = true;
var button = (UIElement) sender;
var control = button.FindVisualAncestor();
App.Configs.Remove(control.Config);
control.Config.DeleteFile();
}
private void Edit(object sender, RoutedEventArgs e) {
e.Handled = true;
var page = new EditInfo(Config);
App.editor.nav.Navigate(typeof(EmptyPageBadFix));
Task.Run(() => {
Thread.Sleep(50);
Dispatcher.Invoke(() => App.editor.nav.ReplaceContent(page));
});
}
private void Select(object sender, RoutedEventArgs e) {
if (App.Settings.SelectedConfig != Config) {
App.Settings.SelectedConfig = Config;
} else {
App.ReloadTaskbars();
}
App.Settings.ToFile();
}
}
}
================================================
FILE: RainbowTaskbar/Editor/Pages/Controls/InstructionContextMenu.xaml
================================================
================================================
FILE: RainbowTaskbar/Editor/Pages/Controls/InstructionContextMenu.xaml.cs
================================================
using RainbowTaskbar.Configuration.Instruction;
using RainbowTaskbar.Editor.Pages.Controls;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace RainbowTaskbar.Editor.Pages.Controls
{
///
/// Interaction logic for InstructionContextMenu.xaml
///
public partial class InstructionContextMenu : ContextMenu
{
public static readonly DependencyProperty ListBoxProperty =
DependencyProperty.Register(
"ParentListBox",
typeof(ListBox),
typeof(InstructionContextMenu));
public ListBox ParentListBox {
get {
return (ListBox) GetValue(ListBoxProperty);
}
set {
SetValue(ListBoxProperty, value);
}
}
public InstructionContextMenu()
{
InitializeComponent();
App.localization.Enable(Resources.MergedDictionaries);
}
private void Duplicate_Click(object sender, RoutedEventArgs e) {
var list = (ParentListBox.ItemsSource as BindingList);
list.Insert(ParentListBox.SelectedIndex+1, JsonSerializer.Deserialize(JsonSerializer.Serialize(ParentListBox.SelectedItem as Instruction)));
}
private void Delete_Click(object sender, RoutedEventArgs e) {
(ParentListBox.ItemsSource as BindingList).Remove(ParentListBox.SelectedItem as Instruction);
}
}
}
================================================
FILE: RainbowTaskbar/Editor/Pages/Controls/InstructionControls/BorderRadiusInstructionControl.xaml
================================================
================================================
FILE: RainbowTaskbar/Editor/Pages/Controls/InstructionControls/BorderRadiusInstructionControl.xaml.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Wpf.Ui.Appearance;
namespace RainbowTaskbar.Editor.Pages.Controls.InstructionControls {
///
/// Interaction logic for BorderRadiusControl.xaml
///
public partial class BorderRadiusInstructionControl : UserControl {
public BorderRadiusInstructionControl() {
InitializeComponent();
App.localization.Enable(Resources.MergedDictionaries);
ApplicationThemeManager.ApplySystemTheme(true);
}
}
}
================================================
FILE: RainbowTaskbar/Editor/Pages/Controls/InstructionControls/ClearLayerInstructionControl.xaml
================================================
================================================
FILE: RainbowTaskbar/Editor/Pages/Controls/InstructionControls/ClearLayerInstructionControl.xaml.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Wpf.Ui.Appearance;
namespace RainbowTaskbar.Editor.Pages.Controls.InstructionControls {
///
/// Interaction logic for ClearLayerInstructionControl.xaml
///
public partial class ClearLayerInstructionControl : UserControl {
public ClearLayerInstructionControl() {
InitializeComponent();
App.localization.Enable(Resources.MergedDictionaries);
ApplicationThemeManager.ApplySystemTheme(true);
}
}
}
================================================
FILE: RainbowTaskbar/Editor/Pages/Controls/InstructionControls/ColorInstructionControl.xaml
================================================
================================================
FILE: RainbowTaskbar/Editor/Pages/Controls/InstructionControls/ColorInstructionControl.xaml.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Wpf.Ui.Appearance;
using static RainbowTaskbar.Configuration.Instruction.Instructions.ColorInstruction;
namespace RainbowTaskbar.Editor.Pages.Controls.InstructionControls {
///
/// Interaction logic for ColorInstructionControl.xaml
///
public partial class ColorInstructionControl : UserControl {
public ColorInstructionControl() {
InitializeComponent();
App.localization.Enable(Resources.MergedDictionaries);
ApplicationThemeManager.ApplySystemTheme(true);
Task.Run(() => {
Thread.Sleep(100);
Dispatcher.Invoke(() => {
ColorPicker1_SelectedColorChanged(null, null);
});
});
}
private void ColorPicker1_SelectedColorChanged(object sender, RoutedPropertyChangedEventArgs e) {
if (SelectedEffect.SelectedItem is ColorInstructionEffect instructionEffect) {
if (instructionEffect == ColorInstructionEffect.Gradient ||
instructionEffect == ColorInstructionEffect.FadeGradient)
if (ColorPicker1.SelectedColor.HasValue && ColorPicker2.SelectedColor.HasValue)
PreviewRectangle.Fill = new LinearGradientBrush(ColorPicker1.SelectedColor.Value,
ColorPicker2.SelectedColor.Value, AnglePicker.Value ?? 0);
if (instructionEffect == ColorInstructionEffect.Fade || instructionEffect == ColorInstructionEffect.Solid)
if (ColorPicker1.SelectedColor.HasValue)
PreviewRectangle.Fill = new SolidColorBrush(ColorPicker1.SelectedColor.Value);
}
}
private void Randomize_Checked(object sender, RoutedEventArgs e) {
if ((bool) Randomize.IsChecked) {
var rnd = new Random();
var Color1 = Color.FromRgb((byte) rnd.Next(0, 255), (byte) rnd.Next(0, 255), (byte) rnd.Next(0, 255));
var Color2 = Color.FromRgb((byte) rnd.Next(0, 255), (byte) rnd.Next(0, 255), (byte) rnd.Next(0, 255));
if (SelectedEffect.SelectedItem is ColorInstructionEffect instructionEffect) {
if (instructionEffect == ColorInstructionEffect.Gradient ||
instructionEffect == ColorInstructionEffect.FadeGradient)
PreviewRectangle.Fill = new LinearGradientBrush(Color1, Color2, AnglePicker.Value ?? 0);
if (instructionEffect == ColorInstructionEffect.Fade ||
instructionEffect == ColorInstructionEffect.Solid)
PreviewRectangle.Fill = new SolidColorBrush(Color1);
}
}
else {
ColorPicker1_SelectedColorChanged(null, null);
}
}
public void UpdateColors() {
ColorPicker1_SelectedColorChanged(null, null);
}
}
}
================================================
FILE: RainbowTaskbar/Editor/Pages/Controls/InstructionControls/Converters/ColorConverter.cs
================================================
using RainbowTaskbar.Interpolation;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
namespace RainbowTaskbar.Editor.Pages.Controls.InstructionControls.Converters {
public class ColorConverter : IValueConverter {
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) =>
value is not null ? ((Color) value).ToMediaColor() : null;
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) =>
value is not null ? ((System.Windows.Media.Color) value).ToDrawingColor() : null;
}
}
================================================
FILE: RainbowTaskbar/Editor/Pages/Controls/InstructionControls/Converters/DivideHalf.cs
================================================
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
namespace RainbowTaskbar.Editor.Pages.Controls.InstructionControls.Converters {
public class DivideHalf : IValueConverter {
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
double p;
if (double.TryParse(value.ToString(), out p)) return p / 2.0;
else return 0;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
double p;
if (double.TryParse(value.ToString(), out p)) return p * 2.0;
else return 0;
}
}
}
================================================
FILE: RainbowTaskbar/Editor/Pages/Controls/InstructionControls/Converters/FileExists.cs
================================================
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
namespace RainbowTaskbar.Editor.Pages.Controls.InstructionControls.Converters {
public class FileExists : ValidationRule {
public override ValidationResult Validate(object value, CultureInfo cultureInfo) => File.Exists(value?.ToString())
? ValidationResult.ValidResult
: new ValidationResult(false, "File must exist");
}
}
================================================
FILE: RainbowTaskbar/Editor/Pages/Controls/InstructionControls/Converters/FloatToPercentage.cs
================================================
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
namespace RainbowTaskbar.Editor.Pages.Controls.InstructionControls.Converters {
public class FloatToPercentage : IValueConverter {
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
double p;
if (double.TryParse(value.ToString(), out p)) return (int)(p * 100);
else return 0;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
double p;
if (double.TryParse(value.ToString(), out p)) return p / 100.0;
else return 0;
}
}
}
================================================
FILE: RainbowTaskbar/Editor/Pages/Controls/InstructionControls/DelayInstructionControl.xaml
================================================
================================================
FILE: RainbowTaskbar/Editor/Pages/Controls/InstructionControls/DelayInstructionControl.xaml.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Wpf.Ui.Appearance;
namespace RainbowTaskbar.Editor.Pages.Controls.InstructionControls {
///
/// Interaction logic for DelayInstructionControl.xaml
///
public partial class DelayInstructionControl : UserControl {
public DelayInstructionControl() {
InitializeComponent();
App.localization.Enable(Resources.MergedDictionaries);
ApplicationThemeManager.ApplySystemTheme(true);
}
}
}
================================================
FILE: RainbowTaskbar/Editor/Pages/Controls/InstructionControls/ImageInstructionControl.xaml
================================================
================================================
FILE: RainbowTaskbar/Editor/Pages/Controls/InstructionControls/ImageInstructionControl.xaml.cs
================================================
using Microsoft.Win32;
using RainbowTaskbar.Configuration.Instruction.Instructions;
using RainbowTaskbar.Editor.Pages.Edit;
using System;
using System.Collections.Generic;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Wpf.Ui.Appearance;
namespace RainbowTaskbar.Editor.Pages.Controls.InstructionControls {
///
/// Interaction logic for ImageInstructionControl.xaml
///
public partial class ImageInstructionControl : UserControl {
public ImageInstructionControl() {
InitializeComponent();
App.localization.Enable(Resources.MergedDictionaries);
ApplicationThemeManager.ApplySystemTheme(true);
}
private void Button_Click(object sender, RoutedEventArgs e) {
var openFileDialog = new OpenFileDialog {
Filter = GetImageFilter(),
CheckFileExists = true
};
if (openFileDialog.ShowDialog() == true) {
ImagePathTextBox.Text = openFileDialog.FileName;
((DataContext as InstructionEditPage).SelectedInstruction as ImageInstruction).Path = openFileDialog.FileName;
}
}
public string GetImageFilter() {
var allImageExtensions = new StringBuilder();
var separator = "";
var codecs = ImageCodecInfo.GetImageEncoders();
var images = new Dictionary();
foreach (var codec in codecs) {
allImageExtensions.Append(separator);
allImageExtensions.Append(codec.FilenameExtension);
separator = ";";
images.Add($"{codec.FormatDescription} Files: ({codec.FilenameExtension})",
codec.FilenameExtension);
}
var sb = new StringBuilder();
if (allImageExtensions.Length > 0) sb.Append($"All Images|{allImageExtensions.ToString()}");
images.Add("All Files", "*.*");
foreach (var image in images) sb.Append($"|{image.Key}|{image.Value}");
return sb.ToString();
}
}
}
================================================
FILE: RainbowTaskbar/Editor/Pages/Controls/InstructionControls/ShapeInstructionControl.xaml
================================================
================================================
FILE: RainbowTaskbar/Editor/Pages/Controls/InstructionControls/ShapeInstructionControl.xaml.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Wpf.Ui.Appearance;
namespace RainbowTaskbar.Editor.Pages.Controls.InstructionControls {
///
/// Interaction logic for ShapeInstructionControl.xaml
///
public partial class ShapeInstructionControl : UserControl {
public ShapeInstructionControl() {
InitializeComponent();
App.localization.Enable(Resources.MergedDictionaries);
ApplicationThemeManager.ApplySystemTheme(true);
}
}
}
================================================
FILE: RainbowTaskbar/Editor/Pages/Controls/InstructionControls/TextInstructionControl.xaml
================================================
================================================
FILE: RainbowTaskbar/Editor/Pages/Controls/InstructionControls/TextInstructionControl.xaml.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Wpf.Ui.Appearance;
namespace RainbowTaskbar.Editor.Pages.Controls.InstructionControls {
///
/// Interaction logic for TextInstructionControl.xaml
///
public partial class TextInstructionControl : UserControl {
public TextInstructionControl() {
InitializeComponent();
App.localization.Enable(Resources.MergedDictionaries);
ApplicationThemeManager.ApplySystemTheme(true);
}
}
}
================================================
FILE: RainbowTaskbar/Editor/Pages/Controls/InstructionControls/TransparencyInstructionControl.xaml
================================================
================================================
FILE: RainbowTaskbar/Editor/Pages/Controls/InstructionControls/TransparencyInstructionControl.xaml.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Wpf.Ui.Appearance;
namespace RainbowTaskbar.Editor.Pages.Controls.InstructionControls
{
///
/// Interaction logic for TransparencyInstructionControl.xaml
///
public partial class TransparencyInstructionControl : UserControl
{
public TransparencyInstructionControl()
{
InitializeComponent();
App.localization.Enable(Resources.MergedDictionaries);
ApplicationThemeManager.ApplySystemTheme(true);
}
}
}
================================================
FILE: RainbowTaskbar/Editor/Pages/Controls/IssueControl.xaml
================================================
================================================
FILE: RainbowTaskbar/Editor/Pages/Controls/IssueControl.xaml.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace RainbowTaskbar.Editor.Pages.Controls
{
///
/// Interaction logic for IssueControl.xaml
///
public partial class IssueControl : UserControl
{
public string Title { get; set; } = "";
public string Description { get; set; } = "";
public string Contact { get; set; } = "";
public IssueControl()
{
DataContext = this;
InitializeComponent();
}
}
}
================================================
FILE: RainbowTaskbar/Editor/Pages/Controls/LoginControl.xaml
================================================
================================================
FILE: RainbowTaskbar/Editor/Pages/Controls/LoginControl.xaml.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace RainbowTaskbar.Editor.Pages.Controls {
///
/// Interaction logic for LoginControl.xaml
///
public partial class LoginControl : UserControl {
public LoginControl() {
InitializeComponent();
}
}
}
================================================
FILE: RainbowTaskbar/Editor/Pages/Controls/ResultListItemControl.xaml
================================================
================================================
FILE: RainbowTaskbar/Editor/Pages/Controls/ResultListItemControl.xaml.cs
================================================
using Kasay;
using PropertyChanged;
using RainbowTaskbar.Configuration;
using RainbowTaskbar.Configuration.Web;
using RainbowTaskbar.Editor.Pages.Edit;
using RainbowTaskbar.HTTPAPI;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Xceed.Wpf.AvalonDock.Controls;
namespace RainbowTaskbar.Editor.Pages.Controls
{
///
/// Interaction logic for ResultListItemControl.xaml
///
public partial class ResultListItemControl : UserControl, INotifyPropertyChanged
{
public static readonly DependencyProperty ConfigProperty =
DependencyProperty.Register(
"Config",
typeof(Config),
typeof(ResultListItemControl));
public Config Config {
get {
return (Config) GetValue(ConfigProperty);
}
set {
SetValue(ConfigProperty, value);
}
}
public static readonly DependencyProperty PageParentProperty =
DependencyProperty.Register(
"PageParent",
typeof(Browse),
typeof(ResultListItemControl));
public Browse PageParent {
get {
return (Browse) GetValue(PageParentProperty);
}
set {
SetValue(PageParentProperty, value);
}
}
public string ConfigType { get => (Config is WebConfig) ? App.localization["enum_web"] : App.localization["enum_classic"]; }
public bool Downloaded { get => App.Configs.Any(x=>x.PublishedID == Config.PublishedID || (x.PublishedID is null && x.PreviousPublishedID == Config.PublishedID)); }
public bool CanDelete { get => Config.CachedPublisherUsername == App.Settings.AccountUsername || App.Settings.AccountUsername == "ad2017gd"; }
public bool Unverified { get; set; } = false;
public async void OnConfigChanged() {
Config.CachedBase64Thumbnail = await App.Settings.workshopAPI.DownloadThumbnailBase64(Config);
if(Config.CachedBase64Thumbnail is null && App.Settings.AccountUsername == "ad2017gd") {
Config.CachedBase64Thumbnail = await App.Settings.workshopAPI.DownloadThumbnailBase64(Config, true);
if (Config.CachedBase64Thumbnail is not null) Unverified = true;
}
image.Source = Config.LoadImage();
}
public ResultListItemControl()
{
InitializeComponent();
DependencyPropertyDescriptor
.FromProperty(ConfigProperty, typeof(ConfigListItemControl))
.AddValueChanged(this, (s, e) => OnConfigChanged());
}
private void Select(object sender, RoutedEventArgs e) {
e.Handled = true;
App.editor.OpenConfig(Config);
}
private void Download(object sender, RoutedEventArgs e) {
e.Handled = true;
var copy = Config.Copy();
if(copy.CachedPublisherUsername != App.Settings.AccountUsername) {
copy.PreviousPublishedID = copy.PublishedID;
copy.PublishedID = null;
}
copy.ToFile();
App.Configs.Insert(0, copy);
OnPropertyChanged("Downloaded");
}
private void Delete(object sender, RoutedEventArgs e) {
e.Handled = true;
var res = App.Settings.workshopAPI.DeleteConfigAsync(Config);
Task.Run(() => {
var result = res.Result;
Dispatcher.InvokeAsync(() => {
if (result.Result) {
var existing = App.Configs.FirstOrDefault(x => x.PublishedID == Config.PublishedID, null);
if(existing is not null) {
existing.PublishedID = null;
existing.Published = DateTime.MinValue;
PageParent.ResultList.Remove(Config);
}
}
});
});
}
private void Verify(object sender, RoutedEventArgs e) {
e.Handled = true;
var res = App.Settings.workshopAPI.VerifyThumbnail(Config);
Task.Run(() => {
var result = res.Result;
Dispatcher.InvokeAsync(() => {
if (result.Result) {
Unverified = false;
}
});
});
}
}
}
================================================
FILE: RainbowTaskbar/Editor/Pages/Controls/UnsafeImage.cs
================================================
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RainbowTaskbar.Editor.Pages.Controls {
public class UnsafeImage : System.Windows.Controls.Image, IDisposable {
public void Dispose() {
Source = null;
UpdateLayout();
}
}
}
================================================
FILE: RainbowTaskbar/Editor/Pages/Controls/WebControls/AddPropertyDialogControl.xaml
================================================
================================================
FILE: RainbowTaskbar/Editor/Pages/Controls/WebControls/AddPropertyDialogControl.xaml.cs
================================================
using RainbowTaskbar.Configuration.Web;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace RainbowTaskbar.Editor.Pages.Controls.WebControls {
///
/// Interaction logic for AddPropertyDialogControl.xaml
///
public partial class AddPropertyDialogControl : UserControl {
public WebConfigUserSetting Setting { get; set; } = new();
public AddPropertyDialogControl() {
InitializeComponent();
DataContext = this;
}
}
}
================================================
FILE: RainbowTaskbar/Editor/Pages/Edit/EditInfo.xaml
================================================
================================================
FILE: RainbowTaskbar/Editor/Pages/Edit/EditInfo.xaml.cs
================================================
using Microsoft.Win32;
using PropertyChanged;
using RainbowTaskbar.Configuration;
using RainbowTaskbar.Configuration.Instruction;
using RainbowTaskbar.Configuration.Web;
using RainbowTaskbar.Editor.Pages.Controls.WebControls;
using RainbowTaskbar.Helpers;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection.Metadata;
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Xml.Linq;
using Wpf.Ui.Appearance;
using Wpf.Ui.Controls;
using Wpf.Ui.Extensions;
using static System.Runtime.InteropServices.JavaScript.JSType;
using Button = Wpf.Ui.Controls.Button;
namespace RainbowTaskbar.Editor.Pages.Edit {
///
/// Interaction logic for EditInfo.xaml
///
public partial class EditInfo : Page {
public Config Config { get; set; }
public Config New { get; set; }
public bool IsClassic { get => Config is InstructionConfig; }
public EditInfo(Config config) {
InitializeComponent();
this.DataContext = this;
ApplicationThemeManager.ApplySystemTheme(true);
App.localization.Enable(Resources.MergedDictionaries);
Config = config;
New = Config.Copy();
var content = new TextRange(richDescription.Document.ContentStart, richDescription.Document.ContentEnd);
if (content.CanLoad(DataFormats.Rtf)) {
try {
using (var stream = new MemoryStream(Encoding.Default.GetBytes(Config.Description)))
content.Load(stream, DataFormats.Rtf);
}
catch { }
}
thumbPreview.Source = Config.LoadImage();
}
public void Save(object sender, RoutedEventArgs e) {
string newDesc = "";
var textRange = new TextRange(richDescription.Document.ContentStart, richDescription.Document.ContentEnd);
using (var stream = new MemoryStream()) {
textRange.Save(stream, DataFormats.Rtf);
stream.Position = 0;
newDesc = Encoding.Default.GetString(stream.ToArray());
}
Config.Description = newDesc;
Config.Name = New.Name;
Config.Updated = DateTime.Now;
if(Config is WebConfig) {
(Config.ConfigData as WebConfigData).UserSettings = (New.ConfigData as WebConfigData).UserSettings;
}
Config.ToFile();
if (this.Config == Config.currentlyRunning) {
Config.Start();
}
}
private void Edit(object sender, RoutedEventArgs e) {
if(Config is WebConfig) {
App.editorViewModel.EditPage = new WebEditPage();
App.editorViewModel.EditPage.Config = Config;
} else if (Config is InstructionConfig) {
App.editorViewModel.EditPage = new InstructionEditPage(Config as InstructionConfig);
}
App.editor.nav.ReplaceContent(App.editorViewModel.EditPage);
}
private void Preset(object sender, RoutedEventArgs e) {
var b = (Wpf.Ui.Controls.Button) sender;
b.ContextMenu = new();
DefaultPresets.Presets.ForEach(x => {
var v = new Wpf.Ui.Controls.MenuItem() { Header = x.Name };
v.Click += (_,_) => {
var cfg = Config as InstructionConfig;
cfg.Data.RunOnceGroup = x.RunOnceGroup;
cfg.Data.LoopGroups.Clear();
foreach(var group in x.LoopGroups) {
cfg.Data.LoopGroups.Add(group);
}
cfg.ToFile();
};
b.ContextMenu.Items.Add(v);
});
b.ContextMenu.IsOpen = true;
}
private void Publish(object sender, RoutedEventArgs e) {
Save(null, null);
if(!App.Settings.LoggedIn) {
App.editor.contentDialogService.ShowSimpleDialogAsync(new() {
Content = App.localization.Get("msgbox_notloggedin"),
Title = App.localization.Get("msgbox_notloggedin_title"),
CloseButtonText = "OK"
});
return;
}
Task.Run(() => {
var res = App.Settings.workshopAPI.PublishConfigAsync(Config).Result;
if (res is null || !res.Result) {
Dispatcher.Invoke(() => App.editor.contentDialogService.ShowSimpleDialogAsync(new() {
Content = App.localization.Get("msgbox_fail"),
Title = App.localization.Get("msgbox_fail_title"),
CloseButtonText = "OK"
}));
return;
}
Dispatcher.Invoke(() => {
if (thumbPreview.Source is not null)
Task.Run(() => {
var res2 = App.Settings.workshopAPI.SetConfigThumbnail(Config, thumbPreview).Result;
if (res2 is null || !res2.Result) {
Dispatcher.Invoke(() => App.editor.contentDialogService.ShowSimpleDialogAsync(new() {
Content = App.localization.Get("msgbox_thumbnail"),
Title = App.localization.Get("msgbox_fail_title"),
CloseButtonText = "OK"
}));
}
});
Config.PublishedID = res.Data.PublishedID;
Config.CachedPublisherUsername = App.Settings.AccountUsername;
Config.Published = DateTime.Now;
Config.ToFile();
});
});
}
private void richDescription_MouseWheel(object sender, MouseWheelEventArgs e) {
var fontSizes = new List() { 8, 9, 10, 11, 12, 13, 14, 16, 18, 20, 24, 30, 36, 42, 48, 60, 72 };
if (Keyboard.Modifiers == ModifierKeys.Control) {
var current = ((double) (richDescription.Selection.GetPropertyValue(FontSizeProperty) == DependencyProperty.UnsetValue ? 12.0 : richDescription.Selection.GetPropertyValue(FontSizeProperty)));
var nearest = fontSizes.MinBy(x => Math.Abs(x - current));
var nextIdx = Math.Min(Math.Max(0,fontSizes.IndexOf(nearest) + Math.Sign(e.Delta)), fontSizes.Count-1);
richDescription.Selection.ApplyPropertyValue(FontSizeProperty, fontSizes[nextIdx]);
}
}
private void picture_Click(object sender, RoutedEventArgs e) {
OpenFileDialog openFileDialog =
new() {
InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures),
Filter = "Image files (*.bmp;*.jpg;*.jpeg;*.png;*.webp)|*.bmp;*.jpg;*.jpeg;*.png;*.webp|All files (*.*)|*.*"
};
if (openFileDialog.ShowDialog() ?? false) {
if(openFileDialog.CheckFileExists) {
Config.CachedBase64Thumbnail = Convert.ToBase64String(File.ReadAllBytes(openFileDialog.FileName));
Config.Updated = DateTime.Now;
}
}
thumbPreview.Source = Config.LoadImage();
}
private void Delete(object sender, RoutedEventArgs e) {
var btn = sender as Button;
(New.ConfigData as WebConfigData).UserSettings.Remove(btn.Tag as WebConfigUserSetting);
}
private void AddProperty(object sender, RoutedEventArgs e) {
var ctrl = new AddPropertyDialogControl();
Task.Run(() => {
Task result = null;
Dispatcher.Invoke(() => result = App.editor.contentDialogService.ShowSimpleDialogAsync(new() {
Content = ctrl,
Title = App.localization.Get("msgbox_property_title"),
CloseButtonText = "OK"
}));
result.Wait();
Dispatcher.Invoke(() => {
(New.ConfigData as WebConfigData).UserSettings.Add(ctrl.Setting);
;
});
});
}
private void richDescription_Pasting(object sender, DataObjectPastingEventArgs e) {
// also checked server side dont worry!
if (e.FormatToApply == "Bitmap" || e.FormatToApply == DataFormats.FileDrop) {
e.CancelCommand();
}
}
}
}
================================================
FILE: RainbowTaskbar/Editor/Pages/Edit/EditPage.cs
================================================
using RainbowTaskbar.Configuration;
using RainbowTaskbar.Editor.Pages.Controls;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
namespace RainbowTaskbar.Editor.Pages.Edit {
public class EditPage : Page {
public Config Config { get; set; }
public bool Modified { get; set; } = false;
}
}
================================================
FILE: RainbowTaskbar/Editor/Pages/Edit/InstructionEditPage.xaml
================================================
================================================
FILE: RainbowTaskbar/Editor/Pages/Edit/InstructionEditPage.xaml.cs
================================================
using PropertyChanged;
using RainbowTaskbar.Configuration;
using RainbowTaskbar.Configuration.Instruction;
using RainbowTaskbar.Editor.Pages.Controls.InstructionControls;
using RainbowTaskbar.Languages;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing.Text;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Wpf.Ui.Appearance;
using Xceed.Wpf.AvalonDock.Controls;
namespace RainbowTaskbar.Editor.Pages.Edit {
///
/// Interaction logic for InstructionEditPage.xaml
///
public partial class InstructionEditPage : EditPage, INotifyPropertyChanged {
public InstructionConfig IConfig { get => Config as InstructionConfig; set => Config = value; }
public InstructionConfig Current { get; set; }
public Instruction SelectedInstruction { get; set; }
public string[] InstalledFonts { get; set; } =
new InstalledFontCollection().Families.Select(font => font.Name).ToArray();
[DependsOn("SelectedInstruction")]
public UserControl SelectedInstructionControl {
get {
if (SelectedInstruction is null) return null;
switch (SelectedInstruction.GetType().Name) {
case "DelayInstruction": return new DelayInstructionControl();
case "TransparencyInstruction": return new TransparencyInstructionControl();
case "ColorInstruction": return new ColorInstructionControl();
case "BorderRadiusInstruction": return new BorderRadiusInstructionControl();
case "ClearLayerInstruction": return new ClearLayerInstructionControl();
case "ImageInstruction": return new ImageInstructionControl();
case "TextInstruction": return new TextInstructionControl();
case "ShapeInstruction": return new ShapeInstructionControl();
}
return null;
}
}
public void OnSelectedInstructionChanged() {
;
}
public InstructionEditPage(InstructionConfig config) {
InitializeComponent();
DataContext = this;
ApplicationThemeManager.ApplySystemTheme(true);
App.localization.Enable(Resources.MergedDictionaries);
Config = config;
Current = config.Copy() as InstructionConfig;
}
private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) {
if (e.AddedItems.Count == 0) return;
var others = this.FindVisualChildren().Where(x => x != (sender as ListBox)).ToList() ;
others.ForEach(x=>x.SelectedItem = null);
SelectedInstruction = (sender as ListBox).SelectedItem as Instruction;
}
private void AddGroup(object sender, RoutedEventArgs e) {
Current.Data.LoopGroups.Add(new());
}
private void AddInstruction(object sender, RoutedEventArgs e) {
var btn = sender as Wpf.Ui.Controls.Button;
btn.ContextMenu = new();
Instruction.DisplayableInstructionTypes.ToList().ForEach(x => {
var v = new Wpf.Ui.Controls.MenuItem() { Header = App.localization.Get(x.Name.ToLower()) };
v.Click += (_, _) => {
(btn.DataContext as InstructionGroup).Instructions.Add(x.GetConstructor(Array.Empty()).Invoke(null) as Instruction);
};
btn.ContextMenu.Items.Add(v);
});
btn.ContextMenu.IsOpen = true;
;
}
private void DeleteGroup(object sender, RoutedEventArgs e) {
var btn = sender as Wpf.Ui.Controls.Button;
Current.Data.LoopGroups.Remove(btn.DataContext as InstructionGroup);
}
private void RunConfig(object sender, RoutedEventArgs e) {
if(App.Settings.SelectedConfig is not null) App.Settings.SelectedConfig.Stop();
App.ReloadTaskbars(false);
Taskbar.SoftReset(true, Current);
}
private void SaveConfig(object sender, RoutedEventArgs e) {
Current.Updated = DateTime.Now;
Current.ToFile();
var idx = App.Configs.IndexOf(Config);
App.Configs.RemoveAt(idx);
App.Configs.Insert(idx, Current);
Config = Current;
Current = Current.Copy() as InstructionConfig;
}
}
}
================================================
FILE: RainbowTaskbar/Editor/Pages/Edit/ViewComments.xaml
================================================
================================================
FILE: RainbowTaskbar/Editor/Pages/Edit/ViewComments.xaml.cs
================================================
using PropertyChanged;
using RainbowTaskbar.Configuration;
using RainbowTaskbar.Configuration.Instruction;
using RainbowTaskbar.Configuration.Web;
using RainbowTaskbar.Helpers;
using RainbowTaskbar.HTTPAPI;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Wpf.Ui.Appearance;
using Wpf.Ui.Controls;
using Wpf.Ui.Extensions;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using Page = System.Windows.Controls.Page;
namespace RainbowTaskbar.Editor.Pages.Edit {
///
/// Interaction logic for ViewComments.xaml
///
public partial class ViewComments : Page, INotifyPropertyChanged {
public Config Config { get; set; }
public Page OldPage { get; set; }
public bool SignedIn { get => App.Settings.LoggedIn; }
public BindingList Comments { get; set; }
public ViewComments(Config config) {
InitializeComponent();
this.DataContext = this;
ApplicationThemeManager.ApplySystemTheme(true);
App.localization.Enable(Resources.MergedDictionaries);
Config = config;
App.Settings.workshopAPI.GetConfigComments(Config).ContinueWith(c => {
var res = c?.Result;
if (res.Result)
Comments = new BindingList(c.Result.Comments);
});
}
public event PropertyChangedEventHandler PropertyChanged;
private void Button_Click(object sender, RoutedEventArgs e) {
App.editor.nav.Navigate(typeof(EmptyPageBadFix));
Task.Run(() => {
Thread.Sleep(50);
Dispatcher.Invoke(() => App.editor.nav.Navigate(typeof(EmptyPageBadFix2)));
Thread.Sleep(50);
Dispatcher.Invoke(() => App.editor.nav.ReplaceContent(OldPage));
});
}
private void Button_Click_1(object sender, RoutedEventArgs e) {
App.Settings.workshopAPI.AddConfigComment(Config, textb.Text).ContinueWith(c=> {
var res = c.Result;
if(res.Result) {
Dispatcher.Invoke(() => {
Comments.Insert(0, new() { AuthorUsername = App.Settings.AccountUsername, Content = textb.Text, ID = res.ID });
Config.CachedCommentCount++;
textb.Text = "";
});
}
});
}
private void Button_Click_2(object sender, RoutedEventArgs e) {
var btn = (sender as Wpf.Ui.Controls.Button);
var cfg = btn.Tag as CommentData;
App.Settings.workshopAPI.DeleteConfigComment(Config, cfg.ID);
Comments.Remove(Comments.First(x => x.ID == cfg.ID));
Config.CachedCommentCount--;
}
}
}
================================================
FILE: RainbowTaskbar/Editor/Pages/Edit/ViewInfo.xaml
================================================
================================================
FILE: RainbowTaskbar/Editor/Pages/Edit/ViewInfo.xaml.cs
================================================
using PropertyChanged;
using RainbowTaskbar.Configuration;
using RainbowTaskbar.Configuration.Instruction;
using RainbowTaskbar.Configuration.Web;
using RainbowTaskbar.Helpers;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Wpf.Ui.Appearance;
using Wpf.Ui.Controls;
using Wpf.Ui.Extensions;
namespace RainbowTaskbar.Editor.Pages.Edit {
///
/// Interaction logic for EditInfo.xaml
///
public partial class ViewInfo : Page, INotifyPropertyChanged {
public Config Config { get; set; }
public bool IsClassic { get => Config is InstructionConfig; }
public bool Downloaded { get => App.Configs.Any(x => x.PublishedID == Config.PublishedID); }
public string FileSize { get => (Encoding.UTF8.GetBytes(JsonSerializer.Serialize(Config)).Length / 1024.0).ToString("N1"); }
public bool Liked { get; set; }
public string CommentButtonText { get => App.localization.Get("comments") + $" ({Config.CachedCommentCount})"; }
public ViewInfo(Config config) {
InitializeComponent();
this.DataContext = this;
ApplicationThemeManager.ApplySystemTheme(true);
App.localization.Enable(Resources.MergedDictionaries);
Config = config;
var content = new TextRange(description.Document.ContentStart, description.Document.ContentEnd);
if (content.CanLoad(DataFormats.Rtf)) {
using (var stream = new MemoryStream(Encoding.Default.GetBytes(Config.Description)))
content.Load(stream, DataFormats.Rtf);
}
thumbPreview.Source = config.LoadImage();
if (App.Settings.LoggedIn) App.Settings.workshopAPI.GetLikedConfigs().ContinueWith(x => Liked = x?.Result.Search.Contains(Config.PublishedID) ?? false);
}
private void Download(object sender, RoutedEventArgs e) {
var copy = Config.Copy();
if (copy.CachedPublisherUsername != App.Settings.AccountUsername || Downloaded) {
copy.PreviousPublishedID = copy.PublishedID;
copy.PublishedID = null;
}
copy.ToFile();
App.Configs.Insert(0, copy);
}
private void Like(object sender, RoutedEventArgs e) {
if(!App.Settings.LoggedIn) {
App.editor.contentDialogService.ShowSimpleDialogAsync(new() {
Content = App.localization.Get("msgbox_notloggedin2"),
Title = App.localization.Get("msgbox_notloggedin_title"),
CloseButtonText = "OK"
});
return;
}
Liked = !Liked;
Config.CachedLikeCount += Liked ? 1 : -1;
App.Settings.workshopAPI.LikeConfig(Config, Liked);
}
private void Comment(object sender, RoutedEventArgs e) {
var page = new ViewComments(Config);
page.OldPage = this;
App.editor.nav.Navigate(typeof(EmptyPageBadFix));
Task.Run(() => {
Thread.Sleep(50);
Dispatcher.Invoke(() => App.editor.nav.Navigate(typeof(EmptyPageBadFix2)));
Thread.Sleep(50);
Dispatcher.Invoke(() => App.editor.nav.ReplaceContent(page));
});
}
private void OpenWeb(object sender, RoutedEventArgs e) {
Process.Start(new ProcessStartInfo("https://ad2017.dev/rnb/web/config/"+Config.PublishedID) { UseShellExecute = true });
}
}
}
================================================
FILE: RainbowTaskbar/Editor/Pages/Edit/WebEditPage.xaml
================================================
================================================
FILE: RainbowTaskbar/Editor/Pages/Edit/WebEditPage.xaml.cs
================================================
using Microsoft.Web.WebView2.Core;
using Microsoft.Web.WebView2.Wpf;
using RainbowTaskbar.Configuration;
using RainbowTaskbar.Configuration.Web;
using RainbowTaskbar.Editor.Pages.Controls;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Dynamic;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Wpf.Ui.Appearance;
namespace RainbowTaskbar.Editor.Pages.Edit {
///
/// Interaction logic for WebEdit.xaml
///
public partial class WebEditPage : EditPage {
public bool OpenDevTools { get; set; } = false;
public void OnOpenDevToolsChanged() {
if(OpenDevTools) {
if(!App.Settings.GraphicsRepeat) {
App.hiddenWebViewHost.webView_.CoreWebView2?.OpenDevToolsWindow();
} else {
App.taskbars.ForEach(x=>x.webView.CoreWebView2?.OpenDevToolsWindow());
}
}
}
public WebEditPage() {
InitializeComponent();
this.DataContext = this;
ApplicationThemeManager.ApplySystemTheme(true);
App.localization.Enable(Resources.MergedDictionaries);
var envasync = CoreWebView2Environment.CreateAsync(null, System.IO.Path.GetTempPath(), new CoreWebView2EnvironmentOptions());
Task.Run(() => {
var env = envasync.Result;
Dispatcher.Invoke(() =>
webView.EnsureCoreWebView2Async(env).ContinueWith((t) => {
Dispatcher.Invoke(() => {
webView.Source = new Uri(System.IO.Path.Join(App.monacoDir, "index.html"));
webView.SetCurrentValue(WebView2.DefaultBackgroundColorProperty, System.Drawing.Color.Transparent);
});
})
);
});
var theme = Wpf.Ui.Appearance.ApplicationThemeManager.GetAppTheme() == Wpf.Ui.Appearance.ApplicationTheme.Light ? "vs" : "vs-dark";
webView.NavigationCompleted += (_, _) => {
webView.ExecuteScriptAsync(
$$$"""
monaco.editor.defineTheme('editortheme', {
base: '{{{theme}}}',
inherit: true,
rules: [{ background: 'FFFFFF00' }],
colors: {'editor.background': '#FFFFFF00','minimap.background': '#FFFFFF00',}});
monaco.editor.setTheme('editortheme');
window.addEventListener('resize', () => {
editor.layout({ width: 0, height: 0 })
window.requestAnimationFrame(() => {
editor.layout({ width: document.documentElement.clientWidth - 2, height: document.documentElement.clientHeight - 2})
})
})
editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS, () => window.chrome.webview.postMessage({m:"save"}));
"""
);
webView.ExecuteScriptAsync($"editor.getModel().setValue(atob('{Convert.ToBase64String(Encoding.UTF8.GetBytes((Config as WebConfig).Data.WebContent))}'));")
.ContinueWith((_) => {
Dispatcher.Invoke(() => webView.ExecuteScriptAsync("""
editor.getModel().onDidChangeContent((event) => {
window.chrome.webview.postMessage({m:"changed"});
});
"""));
});
};
webView.WebMessageReceived += (_, args) => {
var message = JsonSerializer.Deserialize(args.WebMessageAsJson);
switch(message["m"].GetValue()) {
case "changed":
Modified = true;
break;
case "save":
Save();
Modified = false;
break;
}
};
}
public async Task GetContent() {
var res = await webView.ExecuteScriptAsync("editor.getModel().getValue()");
return Regex.Unescape(res).TrimStart('"').TrimEnd('"');
}
public void Save() {
GetContent().ContinueWith((t) => {
var res = t.Result;
Dispatcher.Invoke(() => { (Config as WebConfig).Data.WebContent = res; Config.Updated = DateTime.Now; Config.ToFile(); });
});
}
public WebConfig Current { get; set; } = new WebConfig();
private void RunConfig(object sender, RoutedEventArgs e) {
if (App.Settings.SelectedConfig is not null) {
App.Settings.SelectedConfig.Stop();
App.ReloadTaskbars(false);
}
GetContent().ContinueWith((t) => {
Current.Data.UserSettings = (Config as WebConfig).Data.UserSettings;
Current.Data.WebContent = t.Result;
Thread.Sleep(500);
Dispatcher.Invoke(() => {
Current.Start();
});
Thread.Sleep(1000);
Dispatcher.Invoke(() => {
OnOpenDevToolsChanged();
});
});
}
}
}
================================================
FILE: RainbowTaskbar/Editor/Pages/Edit/WebView2Fixed.cs
================================================
using Microsoft.Web.WebView2.Wpf;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
namespace RainbowTaskbar.Editor.Pages.Edit {
public class WebView2Fixed : WebView2 {
protected override void OnPreviewKeyDown(KeyEventArgs e) {
return;
}
}
}
================================================
FILE: RainbowTaskbar/Editor/Pages/EmptyPageBadFix.xaml
================================================
================================================
FILE: RainbowTaskbar/Editor/Pages/EmptyPageBadFix.xaml.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Wpf.Ui.Appearance;
namespace RainbowTaskbar.Editor.Pages {
///
/// Interaction logic for EmptyPageBadFix.xaml
///
public partial class EmptyPageBadFix : Page {
public EmptyPageBadFix() {
InitializeComponent();
ApplicationThemeManager.ApplySystemTheme(true);
}
}
}
================================================
FILE: RainbowTaskbar/Editor/Pages/EmptyPageBadFix2.xaml
================================================
================================================
FILE: RainbowTaskbar/Editor/Pages/EmptyPageBadFix2.xaml.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Wpf.Ui.Appearance;
namespace RainbowTaskbar.Editor.Pages {
///
/// Interaction logic for EmptyPageBadFix2.xaml
///
public partial class EmptyPageBadFix2 : Page {
public EmptyPageBadFix2() {
InitializeComponent();
ApplicationThemeManager.ApplySystemTheme(true);
}
}
}
================================================
FILE: RainbowTaskbar/Editor/Pages/Home.xaml
================================================
================================================
FILE: RainbowTaskbar/Editor/Pages/Home.xaml.cs
================================================
using RainbowTaskbar.Configuration.Web;
using RainbowTaskbar.Editor.Pages.Controls;
using RainbowTaskbar.Editor.Pages.Controls.WebControls;
using RainbowTaskbar.Editor.Pages.Edit;
using RainbowTaskbar.Helpers;
using RainbowTaskbar.Interpolation;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Wpf.Ui.Appearance;
using Wpf.Ui.Controls;
using Wpf.Ui.Extensions;
namespace RainbowTaskbar.Editor.Pages {
///
/// Interaction logic for Home.xaml
///
public partial class Home : Page {
public Home() {
InitializeComponent();
ApplicationThemeManager.ApplySystemTheme(true);
App.localization.Enable(Resources.MergedDictionaries);
DataContext = App.editorViewModel;
Task.Run( () => {
if(App.editorViewModel.LatestUpdateInfo is null) {
string str;
try {
str = AutoUpdate.GetLatestBody().Result;
}
catch (Exception ex) {
str = "Failed to get latest update info.";
}
App.editorViewModel.LatestUpdateInfo = Markdig.Markdown.ToHtml(str);
}
Task t = null;
Dispatcher.Invoke(() => {
t = wv.EnsureCoreWebView2Async();
wv.DefaultBackgroundColor = System.Drawing.Color.Transparent;
});
t.Wait();
Dispatcher.Invoke(() => {
wv.CoreWebView2.Settings.AreBrowserAcceleratorKeysEnabled = false;
wv.CoreWebView2.Settings.AreDefaultContextMenusEnabled = false;
wv.CoreWebView2.Settings.IsSwipeNavigationEnabled = false;
wv.CoreWebView2.Settings.IsStatusBarEnabled = false;
wv.CoreWebView2.Settings.IsPinchZoomEnabled = false;
wv.CoreWebView2.Settings.AreDevToolsEnabled = false;
wv.CoreWebView2.Settings.UserAgent = "RainbowTaskbar Web Display https://ad2017.dev/rnb";
wv.CoreWebView2.IsMuted = true;
wv.NavigateToString(
$$"""
""" + App.editorViewModel.LatestUpdateInfo);
lastupdate.Visibility = Visibility.Visible;
ApplicationThemeManager.ApplySystemTheme(true);
});
});
}
private void Button_Click(object sender, RoutedEventArgs e) {
Process.Start(new ProcessStartInfo("ms-windows-store:Review?PFN=48822ad2017.30397FC5B3C66_32727fk258az6") { UseShellExecute = true });
}
private void Button_Click_1(object sender, RoutedEventArgs e) {
var ctrl = new IssueControl();
lastupdate.Visibility = Visibility.Hidden;
Task.Run(() => {
Task result = null;
Dispatcher.Invoke(() => result = App.editor.contentDialogService.ShowSimpleDialogAsync(new() {
Content = ctrl,
Title = App.localization.Get("issueorreq"),
PrimaryButtonText = "OK",
SecondaryButtonText = App.localization.Get("msgbox_issuegithub"),
CloseButtonText = App.localization.Get("msgbox_button_cancel")
}));
result.Wait();
if (result.Result == ContentDialogResult.Primary) {
Task res = null;
Dispatcher.Invoke(() => {
res = App.Settings.workshopAPI.SubmitIssue(ctrl.Title, ctrl.Description, ctrl.Contact);
});
res.Wait();
if (!res.Result.Result) {
Dispatcher.Invoke(() => App.editor.contentDialogService.ShowSimpleDialogAsync(new() {
Content = App.localization.Get("msgbox_fail_title"),
Title = App.localization.Get("msgbox_fail_title"),
CloseButtonText = "OK"
}).ContinueWith((t) => Dispatcher.Invoke(() => lastupdate.Visibility = Visibility.Visible)));
} else {
Dispatcher.Invoke(() => lastupdate.Visibility = Visibility.Visible);
}
}
else if(result.Result == ContentDialogResult.Secondary) {
Process.Start(new ProcessStartInfo("https://github.com/ad2017gd/RainbowTaskbar/issues/new/choose") { UseShellExecute = true });
Dispatcher.Invoke(() => lastupdate.Visibility = Visibility.Visible);
} else {
Dispatcher.Invoke(() => lastupdate.Visibility = Visibility.Visible);
}
});
}
private void Button_Click_2(object sender, RoutedEventArgs e) {
Process.Start(new ProcessStartInfo("https://ad2017.dev/rnb") { UseShellExecute = true });
}
}
}
================================================
FILE: RainbowTaskbar/Editor/Pages/Settings.xaml
================================================
)
API
================================================
FILE: RainbowTaskbar/Editor/Pages/Settings.xaml.cs
================================================
using RainbowTaskbar.Editor.Pages.Controls;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.Http;
using System.Net;
using System.Security.Policy;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Net.Http.Json;
using System.Text.Json;
using System.Dynamic;
using Wpf.Ui.Extensions;
namespace RainbowTaskbar.Editor.Pages {
///
/// Interaction logic for Settings.xaml
///
public partial class Settings : Page {
public Preferences.Settings SettingsCfg { get => App.Settings; }
public List Languages {
get => RainbowTaskbar.Languages.Localization.languages;
}
public Settings() {
DataContext = this;
InitializeComponent();
App.localization.Enable(Resources.MergedDictionaries);
}
private void genericLogin(string oauthUrl) {
Process.Start(new ProcessStartInfo($"{oauthUrl}{(SettingsCfg.LoginKey is not null && SettingsCfg.LoginKey != string.Empty ? $"&state={SettingsCfg.LoginKey}" : "")}") { UseShellExecute = true });
var loginControl = new LoginControl();
var task = App.editor.contentDialogService.ShowSimpleDialogAsync(new() {
Content = loginControl,
Title = App.localization.Get("msgbox_login_title"),
PrimaryButtonText = App.localization.Get("msgbox_login_button"),
CloseButtonText = "Cancel"
});
Task.Run(() => {
var res = task.Result;
if (res == Wpf.Ui.Controls.ContentDialogResult.Primary) {
string code = "";
Dispatcher.Invoke(() => {
code = loginControl.code.Text;
});
using var http = new HttpClient();
using var web = new WebClient();
try {
var content = http.PostAsJsonAsync("https://rnbsrv.ad2017.dev/user/code", new { code }).Result;
dynamic json = content.Content.ReadFromJsonAsync().Result;
SettingsCfg.LoginKey = json.key.ToString();
SettingsCfg.ToFile();
}
catch { }
}
});
}
private void github_Click(object sender, RoutedEventArgs e) {
genericLogin("https://github.com/login/oauth/authorize?client_id=Ov23li82ypW7MrlXLsQx");
}
private void google_Click(object sender, RoutedEventArgs e) {
genericLogin("https://accounts.google.com/o/oauth2/auth?client_id=1034862162125-eo3oug90ecm84gpt2tuodfmmtfuuovle.apps.googleusercontent.com&redirect_uri=https://rnbsrv.ad2017.dev/google/auth&scope=email&response_type=code");
}
private void login_Click(object sender, RoutedEventArgs e) {
}
private void login2_Click(object sender, RoutedEventArgs e) {
SettingsCfg.LoginKey = null;
SettingsCfg.ToFile();
SettingsCfg.OnLanguageChanged();
}
}
}
================================================
FILE: RainbowTaskbar/ExplorerTAP/ExplorerTAP.cs
================================================
using H.Pipes;
using RainbowTaskbar.Configuration.Instruction;
using RainbowTaskbar.Configuration.Instruction.Instructions;
using RainbowTaskbar.Helpers;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Metadata;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Shapes;
using WebSocketSharp;
namespace RainbowTaskbar.ExplorerTAP {
[StructLayout(LayoutKind.Sequential)]
struct GUID {
public uint a;
public short b;
public short c;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] d;
}
class ExplorerTAP
{
[DllImport("kernel32.dll")]
public static extern IntPtr LoadLibrary(string lib);
[DllImport("kernel32.dll")]
public static extern void FreeLibrary(IntPtr module);
[DllImport("kernel32.dll")]
public static extern IntPtr GetProcAddress(IntPtr module, string proc);
[DllImport("user32.dll", SetLastError = true)]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
[DllImport("Windows.UI.Xaml.dll", CharSet = CharSet.Unicode)]
public static extern int InitializeXamlDiagnosticsEx(string endPointName, uint pid, string xamlDiagDll, string TAPDllName, GUID clsID, string numiPASA);
[DllImport("user32.dll", SetLastError = true)]
static extern bool PostMessage(IntPtr hWnd, [MarshalAs(UnmanagedType.U4)] uint Msg, IntPtr wParam, IntPtr lParam);
public delegate int SetAppearanceTypeDelegate(uint type);
public delegate int CloseDelegate();
public delegate int VersionDelegate();
public delegate int GetDataPtrDelegate();
public delegate int DebugGetUITreeDelegate(ref IntPtr tree);
public delegate int GetYPositionDelegate(IntPtr hwnd);
public delegate int SetTaskbarElementsOpacityDelegate(uint alpha);
public static SetAppearanceTypeDelegate SetAppearanceTypeDLL;
public static CloseDelegate CloseDLL;
public static VersionDelegate VersionDLL;
public static GetDataPtrDelegate GetDataPtrDLL;
public static DebugGetUITreeDelegate DebugGetUITreeDLL;
public static GetYPositionDelegate GetYPositionDLL;
public static SetTaskbarElementsOpacityDelegate SetTaskbarElementsOpacityDLL;
public static IntPtr library;
public static int tries = 0;
public static bool IsInjected { get; set; } = false;
public static bool IsInjecting { get; set; } = false;
public static bool NeedsTAPCache { get; set; } = false;
public static bool NeedsTAP() {
var taskbarHWND = TaskbarHelper.FindWindow("Shell_TrayWnd", null);
return
(NeedsTAPCache = taskbarHWND != IntPtr.Zero &&
TaskbarHelper.FindWindowEx(taskbarHWND, IntPtr.Zero, "Windows.UI.Composition.DesktopWindowContentBridge", null) != IntPtr.Zero &&
TaskbarHelper.FindWindowEx(taskbarHWND, IntPtr.Zero, "WorkerW", null) == IntPtr.Zero);
}
public const int TAPVERSION = 4;
private static void StartExplorer() {
string explorer = string.Format("{0}\\{1}", Environment.GetEnvironmentVariable("WINDIR"), "explorer.exe");
Process process = new Process();
process.StartInfo.FileName = explorer;
process.StartInfo.UseShellExecute = true;
process.Start();
do {
Thread.Sleep(100);
} while (!NeedsTAP());
}
public static IntPtr dataPtr = IntPtr.Zero;
static IntPtr proc = IntPtr.Zero;
static IntPtr rtdStruct = IntPtr.Zero;
static int version = 0;
public static bool TryInject() {
var taskbarHWND = TaskbarHelper.FindWindow("Shell_TrayWnd", null);
if (NeedsTAP() && !IsInjecting) {
if (library != IntPtr.Zero) FreeLibrary(library);
IsInjecting = true;
var inject = true;
// We re on win11 with new taskbar
string dllPath = Environment.GetEnvironmentVariable("temp") + "\\RainbowTaskbarDLL.dll";
dataPtr = IntPtr.Zero;
if (File.Exists(dllPath)) {
bool deleted = false;
try {
File.Delete(dllPath);
deleted = true;
}
catch { }
if (!deleted) {
library = LoadLibrary(dllPath);
IntPtr VersionDLLPtr = GetProcAddress(library, "VersionDLL");
if (VersionDLLPtr != IntPtr.Zero) {
VersionDLL = Marshal.GetDelegateForFunctionPointer(VersionDLLPtr);
version = VersionDLL();
}
FreeLibrary(library);
if (VersionDLLPtr == IntPtr.Zero || version < TAPVERSION) {
var result = MessageBox.Show(
App.localization["msgbox_olddll"], "RainbowTaskbar", MessageBoxButton.YesNoCancel, MessageBoxImage.Information
);
if (result == MessageBoxResult.Yes) {
Process.Start("cmd", $"/c taskkill /f /im explorer.exe").WaitForExit();
Thread.Sleep(100);
Process.Start("cmd", $"/c del /q \"{dllPath}\"").WaitForExit();
do {
Thread.Sleep(500);
} while (TaskbarHelper.FindWindow("Shell_TrayWnd", null) != IntPtr.Zero);
StartExplorer();
Thread.Sleep(4000);
taskbarHWND = TaskbarHelper.FindWindow("Shell_TrayWnd", null);
} else {
IsInjecting = true;
return true;
}
} else {
inject = false;
}
}
}
try {
var assembly = Assembly.GetExecutingAssembly();
var arch = System.Runtime.InteropServices.RuntimeInformation.OSArchitecture.ToString();
if (arch == "X64") arch = "x64";
var resourceName = $"RainbowTaskbar.RainbowTaskbarDLL_{arch}.dll";
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
using (BinaryReader reader = new BinaryReader(stream)) {
var fstr = File.OpenWrite(dllPath);
reader.BaseStream.CopyTo(fstr);
fstr.Close();
}
}
catch { }
library = LoadLibrary(dllPath);
if(GetProcAddress(library, "SetAppearanceTypeDLL") != IntPtr.Zero)
SetAppearanceTypeDLL = Marshal.GetDelegateForFunctionPointer(GetProcAddress(library, "SetAppearanceTypeDLL"));
if(GetProcAddress(library, "CloseDLL") != IntPtr.Zero)
CloseDLL = Marshal.GetDelegateForFunctionPointer(GetProcAddress(library, "CloseDLL"));
if (GetProcAddress(library, "GetDataPtrDLL") != IntPtr.Zero)
GetDataPtrDLL = Marshal.GetDelegateForFunctionPointer(GetProcAddress(library, "GetDataPtrDLL"));
if (GetProcAddress(library, "DebugGetUITreeDLL") != IntPtr.Zero)
DebugGetUITreeDLL = Marshal.GetDelegateForFunctionPointer(GetProcAddress(library, "DebugGetUITreeDLL"));
if (GetProcAddress(library, "GetYPositionDLL") != IntPtr.Zero)
GetYPositionDLL = Marshal.GetDelegateForFunctionPointer(GetProcAddress(library, "GetYPositionDLL"));
if (GetProcAddress(library, "SetTaskbarElementsOpacityDLL") != IntPtr.Zero)
SetTaskbarElementsOpacityDLL = Marshal.GetDelegateForFunctionPointer(GetProcAddress(library, "SetTaskbarElementsOpacityDLL"));
if (inject) {
var guid = new GUID() {
a = 0xc9d60190,
b = 0x2c89,
c = 0x11ee,
d = new byte[] { 0xbe, 0x56, 0x02, 0x42, 0xac, 0x12, 0x00, 0x02 }
};
uint pid = 0;
GetWindowThreadProcessId(TaskbarHelper.FindWindow("Shell_TrayWnd", null), out pid);
int hr = -1;
int tries = 1;
do {
var xamlthread = new Thread(() => {
hr = InitializeXamlDiagnosticsEx($"VisualDiagConnection{tries}", pid, null, dllPath, guid, null);
});
xamlthread.Start();
xamlthread.Join();
Thread.Sleep(50);
} while (hr != 0 && tries++ < 50);
// too lazy to make an event, this shall work
Task.Delay(1250).Wait();
}
if (proc != IntPtr.Zero) CloseHandle(proc);
if (rtdStruct != IntPtr.Zero) Marshal.FreeHGlobal(rtdStruct);
GetWindowThreadProcessId(taskbarHWND, out var pidd);
proc = OpenProcess(ProcessAccessFlags.VirtualMemoryRead, false, pidd);
rtdStruct = Marshal.AllocHGlobal(Marshal.SizeOf());
IsInjecting = false;
IsInjected = true;
} else {
return false;
}
return true;
}
public static void Reset() {
if (!IsInjected) return;
if (CloseDLL is not null || !IsInjected)
CloseDLL();
if (library != IntPtr.Zero) FreeLibrary(library);
SetAppearanceTypeDLL = null;
CloseDLL = null;
IsInjected = false;
}
public static void SetAppearanceType(TransparencyInstruction.TransparencyInstructionStyle type) {
if (!NeedsTAP() || IsInjecting) return;
if (SetAppearanceTypeDLL is null || !IsInjected) return;
uint hres = unchecked((uint) SetAppearanceTypeDLL((uint) type));
if (hres == 0) tries = 0;
if (hres != 0 && tries < 10) { // MK_E_UNAVAILABLE or other errors?
while(hres != 0 && tries < 10) {
if(TryInject())
tries++;
hres = unchecked((uint) SetAppearanceTypeDLL((uint) type));
}
if (hres != 0 && tries >= 10) {
MessageBox.Show(
$"0x{hres.ToString("X8")} : {Marshal.GetExceptionForHR(unchecked((int) hres))?.Message}\n\n{App.localization["msgbox_baddll"]}", "RainbowTaskbar Error", MessageBoxButton.OK, MessageBoxImage.Warning
);
}
}
}
public static void SetTaskbarElementsOpacity(double opacity) {
if (!NeedsTAP() || IsInjecting) return;
if (SetTaskbarElementsOpacityDLL is null || !IsInjected) return;
SetTaskbarElementsOpacityDLL((uint)(opacity * 255));
}
public static int GetDataPtr() {
if (!NeedsTAP() || IsInjecting) return -1;
if (GetDataPtrDLL is null || !IsInjected) return -1;
return GetDataPtrDLL();
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
public struct TaskbarInfo {
public IntPtr taskbar;
public int YPosition;
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U1, SizeConst = 16)]
public byte[,] _reserved;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
public struct TaskbarInfo2 {
public IntPtr taskbar;
public IntPtr UIDataPtr;
public int UIDataSize;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
public struct RainbowTaskbarData {
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public TaskbarInfo[] lTaskbarInfo;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public TaskbarInfo2[] lTaskbarInfo2;
}
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool ReadProcessMemory(
IntPtr hProcess,
IntPtr lpBaseAddress,
IntPtr lpBuffer,
int dwSize,
out IntPtr lpNumberOfBytesRead);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr OpenProcess(
ProcessAccessFlags processAccess,
bool bInheritHandle,
uint processId
);
[Flags]
public enum ProcessAccessFlags : uint {
All = 0x001F0FFF,
Terminate = 0x00000001,
CreateThread = 0x00000002,
VirtualMemoryOperation = 0x00000008,
VirtualMemoryRead = 0x00000010,
VirtualMemoryWrite = 0x00000020,
DuplicateHandle = 0x00000040,
CreateProcess = 0x000000080,
SetQuota = 0x00000100,
SetInformation = 0x00000200,
QueryInformation = 0x00000400,
QueryLimitedInformation = 0x00001000,
Synchronize = 0x00100000
}
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool CloseHandle(IntPtr hObject);
public static int GetYPosition(Taskbar t) {
if (!NeedsTAP() || IsInjecting) return 0;
if (version > 0 && version < TAPVERSION) return 0;
if (dataPtr == IntPtr.Zero) dataPtr = GetDataPtr();
ReadProcessMemory(proc, dataPtr, rtdStruct, Marshal.SizeOf(), out _);
var data = Marshal.PtrToStructure(rtdStruct);
var x = data.lTaskbarInfo.FirstOrDefault(x => x.taskbar == t.taskbarHelper.HWND, new()).YPosition;
return x;
}
public static string GetUIDataStr(Taskbar t) {
if (!NeedsTAP() || IsInjecting) return string.Empty;
if (version > 0 && version < TAPVERSION) return string.Empty;
if (dataPtr == IntPtr.Zero) dataPtr = GetDataPtr();
ReadProcessMemory(proc, dataPtr, rtdStruct, Marshal.SizeOf(), out _);
var data = Marshal.PtrToStructure(rtdStruct);
var x = data.lTaskbarInfo2.FirstOrDefault(x => x.taskbar == t.taskbarHelper.HWND, new());
var alloc = Marshal.AllocHGlobal(x.UIDataSize);
ReadProcessMemory(proc, x.UIDataPtr, alloc, x.UIDataSize, out _);
string st = Marshal.PtrToStringUni(alloc);
Marshal.FreeHGlobal(alloc);
return st;
}
[Serializable]
public class UIData {
[JsonPropertyName("stfPt")]
public List SystemTrayFramePoint { get; set; }
[JsonPropertyName("stfSize")]
public List SystemTrayFrameSize { get; set; }
[JsonPropertyName("tfrPt")]
public List TaskbarFrameRepeaterPoint { get; set; }
[JsonPropertyName("tfrSize")]
public List TaskbarFrameRepeaterSize { get; set; }
public RectangleF SystemTrayFrame { get => new(SystemTrayFramePoint[0], SystemTrayFramePoint[1], SystemTrayFrameSize[0], SystemTrayFrameSize[1]); }
public RectangleF TaskbarFrameRepeater { get => new(TaskbarFrameRepeaterPoint[0], TaskbarFrameRepeaterPoint[1], TaskbarFrameRepeaterSize[0], TaskbarFrameRepeaterSize[1]); }
}
public static UIData GetUIData(Taskbar t) {
string str = GetUIDataStr(t);
if(!str.IsNullOrEmpty()) {
return JsonSerializer.Deserialize(str);
}
return null;
}
}
}
================================================
FILE: RainbowTaskbar/FodyWeavers.xml
================================================
================================================
FILE: RainbowTaskbar/HTTPAPI/WorkshopAPI.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net;
using System.Text;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using RainbowTaskbar.Configuration;
using System.Net.Http.Json;
using RainbowTaskbar.Configuration.Web;
using System.IO;
using System.Text.Json;
using System.Dynamic;
using RainbowTaskbar.Configuration.Instruction;
using RainbowTaskbar.Editor.Pages;
using System.Drawing.Imaging;
using System.Windows.Media.Imaging;
using System.Windows.Media;
using System.Windows.Controls;
using System.Windows.Threading;
namespace RainbowTaskbar.HTTPAPI {
public class AuthenticatedRequest {
[JsonPropertyName("key")]
public string LoginKey { get; set; }
}
public class ResultResponse {
[JsonPropertyName("result")]
public bool Result { get; set; }
}
public class PublishConfigRequest : AuthenticatedRequest {
[JsonPropertyName("title")]
public string Title { get; set; }
[JsonPropertyName("configData")]
public string Data { get; set; }
[JsonPropertyName("id")]
public string? PublishedID { get; set; }
[JsonPropertyName("prevId")]
public string? PreviousPublishedId { get; set; }
[JsonPropertyName("description")]
public string Description { get; set; }
[JsonPropertyName("type")]
public string Type { get; set; }
}
public class ConfigData {
[JsonPropertyName("title")]
public string Title { get; set; }
[JsonPropertyName("data")]
public string Data { get; set; }
[JsonPropertyName("description")]
public string Description { get; set; }
[JsonPropertyName("type")]
public string Type { get; set; }
[JsonPropertyName("id")]
public string PublishedID { get; set; }
[JsonPropertyName("previousId")]
public string PreviousPublishedID { get; set; }
[JsonPropertyName("datePublished")]
public long Published { get; set; }
[JsonPropertyName("dateUpdated")]
public long Updated { get; set; }
[JsonPropertyName("author")]
public string AuthorUsername { get; set; }
[JsonPropertyName("likes")]
public int LikeCount { get; set; }
[JsonPropertyName("comments")]
public int CommentCount { get; set; }
}
public class PublishConfigResponse : ResultResponse {
[JsonPropertyName("config")]
public ConfigData Data { get; set; }
}
public class CommentData {
[JsonPropertyName("author")]
public string AuthorUsername { get; set; }
[JsonPropertyName("content")]
public string Content { get; set; }
[JsonPropertyName("datePublished")]
public long Published { get; set; }
[JsonPropertyName("id")]
public string ID { get; set; }
[JsonIgnore]
public bool OwnComment { get => AuthorUsername == App.Settings.AccountUsername || App.Settings.AccountUsername == "ad2017gd"; }
}
public class ConfigCommentsResponse : ResultResponse {
[JsonPropertyName("comments")]
public List Comments { get; set; }
}
public class ConfigCommentRequest : AuthenticatedRequest {
[JsonPropertyName("content")]
public string Content { get; set; }
}
public class ConfigCommentResponse : ResultResponse {
[JsonPropertyName("id")]
public string ID { get; set; }
}
public class SearchConfigRequest {
[JsonPropertyName("search")]
public string Search { get; set; }
[JsonPropertyName("page")]
public int Page { get; set; }
[JsonPropertyName("sort")]
public int Sort { get; set; }
}
public class LikedConfigsResponse {
[JsonPropertyName("search")]
public List Search { get; set; }
}
public class SearchConfigResponse : ResultResponse {
[JsonPropertyName("search")]
public List Results { get; set; }
public IEnumerable Parse() {
return Results.Select(x => {
try {
Config cfg = x.Type == "web" ? new WebConfig() : new InstructionConfig();
cfg.InitNew();
cfg.Name = x.Title;
cfg.Description = x.Description;
cfg.Updated = new DateTime(1970, 1, 1).AddMilliseconds(x.Updated);
cfg.PublishedID = x.PublishedID;
cfg.PreviousPublishedID = x.PreviousPublishedID;
cfg.CachedPublisherUsername = x.AuthorUsername;
cfg.ConfigData = JsonSerializer.Deserialize(x.Data, Config.SerializerOptions);
cfg.CachedLikeCount = x.LikeCount;
cfg.CachedCommentCount = x.CommentCount;
return cfg;
} catch {
return null;
}
}).Where(x=>x is not null);
}
}
public class ThumbnailConfigRequest : AuthenticatedRequest {
[JsonPropertyName("thumbnail")]
public string Image { get; set; }
}
public class IssueRequest {
[JsonPropertyName("title")]
public string Title { get; set; }
[JsonPropertyName("content")]
public string Content { get; set; }
[JsonPropertyName("contact")]
public string Contact { get; set; }
}
public class ExceptionRequest {
[JsonPropertyName("message")]
public string Message { get; set; }
}
public class WorkshopAPI {
public string LoginKey { get; set; }
public async Task PublishConfigAsync(Config cfg) {
try {
using var http = new HttpClient();
var content = await http.PostAsJsonAsync("https://rnbsrv.ad2017.dev/user/me/publish", new PublishConfigRequest {
LoginKey = LoginKey,
Title = cfg.Name,
Data = JsonSerializer.Serialize(cfg.ConfigData, Config.SerializerOptions),
PublishedID = cfg.PublishedID,
PreviousPublishedId = cfg.PreviousPublishedID,
Description = cfg.Description,
Type = cfg is WebConfig ? "web" : "instruction"
});
var result = await content.Content.ReadFromJsonAsync();
return result;
} catch (Exception e) {
return null;
}
}
public async Task SearchConfigsAsync(string search, SortBy sort, int page = 0) {
try {
using var http = new HttpClient();
var content = await http.PostAsJsonAsync("https://rnbsrv.ad2017.dev/config", new SearchConfigRequest {
Sort = (int)sort,
Search = search,
Page = page
});
var result = await content.Content.ReadFromJsonAsync();
return result;
}
catch (Exception e) {
return null;
}
}
public async Task DeleteConfigAsync(Config config) {
try {
using var http = new HttpClient();
var content = await http.PostAsJsonAsync($"https://rnbsrv.ad2017.dev/user/me/config/{config.PublishedID}/delete", new AuthenticatedRequest {
LoginKey = LoginKey
});
var result = await content.Content.ReadFromJsonAsync();
return result;
}
catch (Exception e) {
return null;
}
}
public async Task DownloadThumbnailBase64(Config config, bool unverified = false) {
try {
using var http = new HttpClient();
var res = await http.PostAsJsonAsync($"https://rnbsrv.ad2017.dev/{(unverified ? "u/" : "")}img/{config.PublishedID}.jpg", new AuthenticatedRequest {
LoginKey = LoginKey
});
if (res.StatusCode != HttpStatusCode.OK) return null;
var bytes = await res.Content.ReadAsByteArrayAsync();
return Convert.ToBase64String(bytes);
} catch {
return null;
}
}
public async Task VerifyThumbnail(Config config) {
try {
using var http = new HttpClient();
var content = await http.PostAsJsonAsync($"https://rnbsrv.ad2017.dev/thumb/{config.PublishedID}/verify", new AuthenticatedRequest {
LoginKey = LoginKey
});
var result = await content.Content.ReadFromJsonAsync();
return result;
}
catch {
return null;
}
}
public async Task GetLikedConfigs() {
try {
using var http = new HttpClient();
var content = await http.PostAsJsonAsync($"https://rnbsrv.ad2017.dev/user/me/liked", new AuthenticatedRequest {
LoginKey = LoginKey
});
var result = await content.Content.ReadFromJsonAsync();
return result;
}
catch {
return null;
}
}
public async Task GetConfigComments(Config config) {
try {
using var http = new HttpClient();
var content = await http.PostAsJsonAsync($"https://rnbsrv.ad2017.dev/config/{config.PublishedID}/comments", new AuthenticatedRequest {
LoginKey = LoginKey
});
var result = await content.Content.ReadFromJsonAsync();
return result;
}
catch {
return null;
}
}
public async Task AddConfigComment(Config config, string comment) {
try {
using var http = new HttpClient();
var content = await http.PostAsJsonAsync($"https://rnbsrv.ad2017.dev/config/{config.PublishedID}/comment", new ConfigCommentRequest {
Content = comment,
LoginKey = LoginKey
});
var result = await content.Content.ReadFromJsonAsync();
return result;
}
catch {
return null;
}
}
public async Task DeleteConfigComment(Config config, string ID) {
try {
using var http = new HttpClient();
var content = await http.PostAsJsonAsync($"https://rnbsrv.ad2017.dev/config/{config.PublishedID}/comment/{ID}/delete", new AuthenticatedRequest {
LoginKey = LoginKey
});
var result = await content.Content.ReadFromJsonAsync();
return result;
}
catch {
return null;
}
}
public async Task LikeConfig(Config cfg, bool like = true) {
try {
using var http = new HttpClient();
var content = await http.PostAsJsonAsync($"https://rnbsrv.ad2017.dev/config/{cfg.PublishedID}/{(like ? "" : "un")}like", new AuthenticatedRequest {
LoginKey = LoginKey
});
var result = await content.Content.ReadFromJsonAsync();
return result;
}
catch {
return null;
}
}
public async Task SubmitIssue(string title, string desc, string contact) {
try {
using var http = new HttpClient();
var content = await http.PostAsJsonAsync($"https://rnbsrv.ad2017.dev/issue", new IssueRequest {
Title = title,
Contact = contact == "" || contact == string.Empty ? "Not provided" : contact,
Content = desc
});
var result = await content.Content.ReadFromJsonAsync();
return result;
}
catch {
return null;
}
}
public async Task ReportException(Exception e) {
try {
using var http = new HttpClient();
var content = await http.PostAsJsonAsync($"https://rnbsrv.ad2017.dev/exception", new ExceptionRequest {
Message = e.Message + "\n" + e.StackTrace,
});
var result = await content.Content.ReadFromJsonAsync();
return result;
}
catch {
return null;
}
}
public async Task SetConfigThumbnail(Config config, Image img) {
try {
using var http = new HttpClient();
string base64img = "";
img.Dispatcher.Invoke(() => {
using (MemoryStream m = new MemoryStream()) {
var bitmap = new TransformedBitmap((BitmapSource) img.Source,
new ScaleTransform(
720.0 / img.Source.Height,
720.0 / img.Source.Height));
var bmpEncoder = new JpegBitmapEncoder();
bmpEncoder.Frames.Add(BitmapFrame.Create(bitmap));
bmpEncoder.Save(m);
byte[] imageBytes = m.ToArray();
base64img = Convert.ToBase64String(imageBytes);
}
});
var content = await http.PostAsJsonAsync($"https://rnbsrv.ad2017.dev/user/me/config/{config.PublishedID}/thumbnail", new ThumbnailConfigRequest {
LoginKey = LoginKey,
Image = base64img
});
var result = await content.Content.ReadFromJsonAsync();
return result;
}
catch (Exception e) {
return null;
}
}
}
}
================================================
FILE: RainbowTaskbar/Helpers/AutoUpdate.cs
================================================
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Reflection;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Security.AccessControl;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
using RainbowTaskbar.Configuration;
namespace RainbowTaskbar.Helpers;
internal static class AutoUpdate {
public static void CheckForUpdate() =>
Task.Run(async () => {
using var http = new HttpClient();
using var web = new WebClient();
http.DefaultRequestHeaders.Add("User-Agent", "RainbowTaskbar");
var content =
await http.GetStreamAsync("https://api.github.com/repos/ad2017gd/RainbowTaskbar/releases/latest");
var ser = new DataContractJsonSerializer(typeof(GitHubAPIResponse));
var response = ser.ReadObject(content) as GitHubAPIResponse;
if (Assembly.GetExecutingAssembly().GetName().Version.CompareTo(Version.Parse(response.TagName)) < 0) {
// Outdated version
var res = MessageBox.Show(App.localization.Get("msgbox_update"),
"RainbowTaskbar", MessageBoxButton.YesNo, MessageBoxImage.Information);
if (res == MessageBoxResult.Yes) {
var asset = response.Assets.First(asset => asset.Name.StartsWith($"rnbtsk-{System.Runtime.InteropServices.RuntimeInformation.OSArchitecture.ToString().ToLower()}"));
var uri = new Uri(asset.BrowserDownloadUrl);
var oldfile = Environment.ProcessPath;
var newfile = $"{Environment.ProcessPath}_new.exe";
var programfilesX86 = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86);
var verb = "";
var programfiles = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);
if (Environment.ProcessPath.StartsWith(programfilesX86, StringComparison.OrdinalIgnoreCase) || Environment.ProcessPath.StartsWith(programfiles, StringComparison.OrdinalIgnoreCase)) {
verb = "runas";
newfile = Environment.ExpandEnvironmentVariables("%temp%\\rnbtsk_newver_.exe");
}
await web.DownloadFileTaskAsync(uri, newfile);
var data = false;
var proc = Process.Start(
new ProcessStartInfo {
UseShellExecute = verb == "runas",
Verb = verb,
Arguments =
$"/C echo p && timeout /t 1 /nobreak > nul && taskkill /f /im \"{Process.GetCurrentProcess().MainModule.ModuleName}\" > nul && timeout /t 1 /nobreak > nul && move /y \"{newfile}\" \"{oldfile}\" > nul",
FileName = "cmd",
WindowStyle = ProcessWindowStyle.Hidden
}
);
var procStart = Process.Start(
new ProcessStartInfo {
Arguments =
$"/C timeout /t 10 /nobreak > nul && start \"\" \"{oldfile}\"",
FileName = "cmd",
WindowStyle = ProcessWindowStyle.Hidden
}
);
}
}
});
public static async Task GetLatestBody() {
using var http = new HttpClient();
using var web = new WebClient();
http.DefaultRequestHeaders.Add("User-Agent", "RainbowTaskbar");
var content =
await http.GetStreamAsync("https://api.github.com/repos/ad2017gd/RainbowTaskbar/releases/latest");
var ser = new DataContractJsonSerializer(typeof(GitHubAPIResponse));
var response = ser.ReadObject(content) as GitHubAPIResponse;
return response.Body;
}
[DataContract]
public class Asset {
[DataMember(Name = "name")] public string Name { get; set; }
[DataMember(Name = "label")] public string Label { get; set; }
[DataMember(Name = "browser_download_url")]
public string BrowserDownloadUrl { get; set; }
}
[DataContract]
public class GitHubAPIResponse {
[DataMember(Name = "tag_name")] public string TagName { get; set; }
[DataMember(Name = "name")] public string Name { get; set; }
[DataMember(Name = "body")] public string Body { get; set; }
[DataMember(Name = "assets")] public List Assets { get; set; }
}
}
================================================
FILE: RainbowTaskbar/Helpers/Cache.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RainbowTaskbar.Helpers {
public class Cache {
public T Value { get; set; }
public DateTime LastUpdated { get; set; } = DateTime.Now;
public TimeSpan UpdateInterval { get; set; } = TimeSpan.FromDays(1);
public bool NeedsUpdate { get => DateTime.Now >= LastUpdated + UpdateInterval; }
public Cache(T value, TimeSpan interval) { Value = value; UpdateInterval = interval; }
}
}
================================================
FILE: RainbowTaskbar/Helpers/DPIUtil.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Interop;
namespace RainbowTaskbar.Helpers {
// https://stackoverflow.com/a/76402250
public static class DPIUtil {
///
/// Min OS version build that supports DPI per monitor
///
private const int MinOSVersionBuild = 14393;
///
/// Min OS version major build that support DPI per monitor
///
private const int MinOSVersionMajor = 10;
///
/// Flag, if OS supports DPI per monitor
///
private static bool _isSupportingDpiPerMonitor;
///
/// Flag, if OS version checked
///
private static bool _isOSVersionChecked;
///
/// Flag, if OS supports DPI per monitor
///
internal static bool IsSupportingDpiPerMonitor {
get {
if (_isOSVersionChecked) {
return _isSupportingDpiPerMonitor;
}
_isOSVersionChecked = true;
var osVersionInfo = new OSVERSIONINFOEXW {
dwOSVersionInfoSize = Marshal.SizeOf(typeof(OSVERSIONINFOEXW))
};
if (RtlGetVersion(ref osVersionInfo) != 0) {
_isSupportingDpiPerMonitor = Environment.OSVersion.Version.Major >= MinOSVersionMajor && Environment.OSVersion.Version.Build >= MinOSVersionBuild;
return _isSupportingDpiPerMonitor;
}
_isSupportingDpiPerMonitor = osVersionInfo.dwMajorVersion >= MinOSVersionMajor && osVersionInfo.dwBuildNumber >= MinOSVersionBuild;
return _isSupportingDpiPerMonitor;
}
}
public static double ScaleFactor(Taskbar window) {
var dpi = GetDpi(window);
return dpi / 96.0;
}
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[StructLayout(LayoutKind.Sequential)]
public struct POINT {
public int X;
public int Y;
public POINT(int x, int y) {
this.X = x;
this.Y = y;
}
public static implicit operator System.Drawing.Point(POINT p) {
return new System.Drawing.Point(p.X, p.Y);
}
public static implicit operator POINT(System.Drawing.Point p) {
return new POINT(p.X, p.Y);
}
public static implicit operator POINT(System.Windows.Point p) {
return new POINT((int)p.X, (int)p.Y);
}
public override string ToString() {
return $"X: {X}, Y: {Y}";
}
}
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr MonitorFromPoint(POINT pt, MonitorOptions dwFlags);
enum MonitorOptions : uint {
MONITOR_DEFAULTTONULL = 0x00000000,
MONITOR_DEFAULTTOPRIMARY = 0x00000001,
MONITOR_DEFAULTTONEAREST = 0x00000002
}
public static uint GetDpi(Taskbar window) {
uint dpiX, dpiY;
if (IsSupportingDpiPerMonitor) {
POINT pt = new POINT(0, 0);
if(window is not null && window.IsVisible) {
return GetDpiForWindow(window.taskbarHelper.HWND);
}
var monitorFromPoint = MonitorFromPoint(pt, MonitorOptions.MONITOR_DEFAULTTONEAREST);
GetDpiForMonitor(monitorFromPoint, DpiType.Effective, out dpiX, out dpiY);
}
else {
return 96;
}
return dpiX;
}
[DllImport("user32.dll")]
static extern IntPtr MonitorFromWindow(IntPtr hwnd, uint dwFlags);
///
/// Queries the dots per inch (dpi) of a display.
///
/// Handle of the monitor being queried.
/// The type of DPI being queried.
/// The value of the DPI along the X axis.
/// The value of the DPI along the Y axis.
/// Status success
///
///
///
[DllImport("Shcore.dll")]
private static extern IntPtr GetDpiForMonitor([In] IntPtr hmonitor, [In] DpiType dpiType, [Out] out uint dpiX, [Out] out uint dpiY);
[DllImport("User32.dll")]
private static extern uint GetDpiForWindow([In] IntPtr window);
///
/// The RtlGetVersion routine returns version information about the currently running operating system.
///
/// Operating system version information
/// Status success
///
///
///
[SecurityCritical]
[DllImport("ntdll.dll", SetLastError = true)]
private static extern int RtlGetVersion(ref OSVERSIONINFOEXW versionInfo);
///
/// Contains operating system version information.
///
///
///
///
[StructLayout(LayoutKind.Sequential)]
private struct OSVERSIONINFOEXW {
///
/// The size of this data structure, in bytes
///
internal int dwOSVersionInfoSize;
///
/// The major version number of the operating system.
///
internal int dwMajorVersion;
///
/// The minor version number of the operating system.
///
internal int dwMinorVersion;
///
/// The build number of the operating system.
///
internal int dwBuildNumber;
///
/// The operating system platform.
///
internal int dwPlatformId;
///
/// A null-terminated string, such as "Service Pack 3", that indicates the latest Service Pack installed on the system.
///
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
internal string szCSDVersion;
///
/// The major version number of the latest Service Pack installed on the system.
///
internal ushort wServicePackMajor;
///
/// The minor version number of the latest Service Pack installed on the system.
///
internal ushort wServicePackMinor;
///
/// A bit mask that identifies the product suites available on the system.
///
internal short wSuiteMask;
///
/// Any additional information about the system.
///
internal byte wProductType;
///
/// Reserved for future use.
///
internal byte wReserved;
}
///
/// DPI type
///
///
///
///
private enum DpiType {
///
/// The effective DPI. This value should be used when determining the correct scale factor for scaling UI elements.
///
Effective = 0,
///
/// The angular DPI. This DPI ensures rendering at a compliant angular resolution on the screen.
///
Angular = 1,
///
/// The raw DPI. This value is the linear DPI of the screen as measured on the screen itself. Use this value when you want to read the pixel density and not the recommended scaling setting.
///
Raw = 2,
}
}
}
================================================
FILE: RainbowTaskbar/Helpers/HiddenWebViewHost.xaml
================================================
================================================
FILE: RainbowTaskbar/Helpers/HiddenWebViewHost.xaml.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace RainbowTaskbar.Helpers {
///
/// Interaction logic for HiddenWebViewHost.xaml
///
public partial class HiddenWebViewHost : Window {
public HiddenWebViewHost() {
InitializeComponent();
WindowHelper.InitOther(this);
Width = 2000;
Height = 100;
Background = new SolidColorBrush(Color.FromArgb(0, 0, 0, 0));
}
}
}
================================================
FILE: RainbowTaskbar/Helpers/JsonColorConverter.cs
================================================
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
namespace RainbowTaskbar.Helpers {
public class JsonColorConverter : JsonConverter {
public override Color Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => Color.FromArgb(reader.GetInt32());
public override void Write(Utf8JsonWriter writer, Color value, JsonSerializerOptions options) => writer.WriteNumberValue(value.ToArgb());
}
}
================================================
FILE: RainbowTaskbar/Helpers/Taskbar.cs
================================================
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
namespace RainbowTaskbar.Helpers;
public class TaskbarHelper {
public enum DWMWINDOWATTRIBUTE : uint {
NCRenderingEnabled = 1,
NCRenderingPolicy,
TransitionsForceDisabled,
AllowNCPaint,
CaptionButtonBounds,
NonClientRtlLayout,
ForceIconicRepresentation,
Flip3DPolicy,
ExtendedFrameBounds,
HasIconicBitmap,
DisallowPeek,
ExcludedFromPeek,
Cloak,
Cloaked,
FreezeRepresentation,
DWMWA_PASSIVE_UPDATE_MODE,
DWMWA_USE_HOSTBACKDROPBRUSH,
DWMWA_USE_IMMERSIVE_DARK_MODE = 20,
DWMWA_WINDOW_CORNER_PREFERENCE = 33,
DWMWA_BORDER_COLOR,
DWMWA_CAPTION_COLOR,
DWMWA_TEXT_COLOR,
DWMWA_VISIBLE_FRAME_BORDER_THICKNESS,
DWMWA_LAST
}
[DllImport("dwmapi.dll", PreserveSig = true)]
public static extern int DwmSetWindowAttribute(IntPtr hwnd, DWMWINDOWATTRIBUTE attr, ref int attrValue, int attrSize);
public delegate bool EnumThreadDelegate(IntPtr hWnd, IntPtr lParam);
public enum CombineRgnStyles {
RGN_AND = 1,
RGN_OR = 2,
RGN_XOR = 3,
RGN_DIFF = 4,
RGN_COPY = 5,
RGN_MIN = RGN_AND,
RGN_MAX = RGN_COPY
}
public enum TaskbarStyle {
Default,
Blur,
Transparent,
ForceDefault // temporary value
}
public const int GWL_EXSTYLE = -20;
public const int WS_EX_LAYERED = 0x80000;
public const int LWA_ALPHA = 0x2;
public const int LWA_COLORKEY = 0x1;
private const uint EVENT_OBJECT_LOCATIONCHANGE = 0x800B;
private const uint WINEVENT_OUTOFCONTEXT = 0;
public const int WM_DWMCOMPOSITIONCHANGED = 0x031E;
private float scale;
private byte _alpha = 255;
public bool autoHide = IsAutoHide();
public bool first = false;
public bool last = false;
private IntPtr hhook;
public IntPtr HWND = (IntPtr) 0;
private bool layered;
private int old_radius = 0;
private WinEventDelegate procDelegate;
private WinEventDelegate proc2Delegate;
public int Radius = 0;
public int YOffset = 0;
private IntPtr rgn = IntPtr.Zero;
public bool Secondary;
public TaskbarStyle Style = TaskbarStyle.Default;
public Taskbar window = null;
public TaskbarHelper(IntPtr hWnd, bool secondary = false) {
HWND = hWnd;
Secondary = secondary;
scale = GetScalingFactor();
SendMessage(HWND, WM_DWMCOMPOSITIONCHANGED, 1, null);
}
public event EventHandler TaskbarPositionChanged;
[DllImport("user32.dll")]
private static extern bool SetLayeredWindowAttributes(IntPtr hwnd, uint crKey, byte bAlpha, uint dwFlags);
[DllImport("user32.dll")]
public static extern int SetWindowLong(IntPtr hWnd, int nIndex, uint dwNewLong);
[DllImport("user32.dll", EntryPoint = "GetWindowLong")]
public static extern IntPtr GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr hWndChildAfter, string className, string windowTitle);
[DllImport("user32.dll")]
private static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
[DllImport("user32.dll", SetLastError = true)]
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy,
int uFlags);
[DllImport("user32.dll")]
private static extern bool EnumThreadWindows(int dwThreadId, EnumThreadDelegate lpfn,
IntPtr lParam);
[DllImport("user32.dll")]
private static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax, IntPtr
hmodWinEventProc, WinEventDelegate lpfnWinEventProc, uint idProcess,
uint idThread, uint dwFlags);
[DllImport("user32.dll")]
private static extern bool UnhookWinEvent(IntPtr hWinEventHook);
[DllImport("user32.dll")]
internal static extern int SetWindowCompositionAttribute(IntPtr hwnd, ref WindowCompositionAttributeData data);
[DllImport("user32.dll")]
internal static extern bool GetWindowCompositionAttribute(IntPtr point, ref WindowCompositionAttributeData data);
private void WinEventProc(IntPtr hWinEventHook, uint eventType,
IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime) {
if (hwnd != HWND) return;
if (idObject != 0 || idChild != 0) return;
if (window is not null && window.TaskbarClip is not null)
window.TaskbarClip.Rect = new(0, 0, window.Width, window.Height);
var raise = TaskbarPositionChanged;
if (raise != null) raise(null, null);
}
public void PositionChangedHook() {
procDelegate = WinEventProc;
hhook = SetWinEventHook(EVENT_OBJECT_LOCATIONCHANGE, EVENT_OBJECT_LOCATIONCHANGE, IntPtr.Zero,
procDelegate, 0, 0, WINEVENT_OUTOFCONTEXT);
}
public void PositionChangedUnhook() => UnhookWinEvent(hhook);
public void SetAlpha(double alpha) {
if (!IsWindow(HWND)) return;
if (!layered) {
SetWindowLong(HWND, GWL_EXSTYLE, (uint) GetWindowLong(HWND, GWL_EXSTYLE).ToInt32() | WS_EX_LAYERED);
layered = true;
}
// I have no idea what the reasoning behind this is, but it probably meant something when i first did it so we're keeping it!
if (_alpha != (byte) (alpha * 255)) {
SetLayeredWindowAttributes(HWND, 0, (byte) (alpha * 255), LWA_ALPHA);
_alpha = (byte) (alpha * 255);
} else {
SetLayeredWindowAttributes(HWND, 0, 254, LWA_ALPHA);
_alpha = 254;
}
}
[DllImport("user32")]
public static extern bool PostMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, uint wParam,
[MarshalAs(UnmanagedType.LPWStr)] string lParam);
[DllImport("user32.dll")]
public static extern bool IsWindow(IntPtr hWnd);
public void SetBlur() {
if (!IsWindow(HWND)) return;
if (ExplorerTAP.ExplorerTAP.NeedsTAPCache) return;
var accent = new AccentPolicy();
switch (Style) {
case TaskbarStyle.Default:
return;
case TaskbarStyle.ForceDefault:
Style = TaskbarStyle.Default;
SendMessage(HWND, WM_DWMCOMPOSITIONCHANGED, 1, null);
return;
case TaskbarStyle.Blur:
accent.AccentState = AccentState.ACCENT_ENABLE_BLURBEHIND;
break;
case TaskbarStyle.Transparent:
accent.AccentState = AccentState.ACCENT_ENABLE_TRANSPARENTGRADIENT;
break;
default: return;
}
unchecked {
accent.GradientColor = 0x01000000;
}
;
accent.AccentFlags = 0;
accent.AnimationId = 2;
var accentStructSize = Marshal.SizeOf(accent);
var accentPtr = Marshal.AllocHGlobal(accentStructSize);
Marshal.StructureToPtr(accent, accentPtr, false);
var data = new WindowCompositionAttributeData();
data.Attribute = WindowCompositionAttribute.WCA_ACCENT_POLICY;
data.SizeOfData = accentStructSize;
data.Data = accentPtr;
GetWindowCompositionAttribute(HWND, ref data);
SetWindowCompositionAttribute(HWND, ref data);
Marshal.FreeHGlobal(accentPtr);
}
public System.Drawing.Point GetPoint() {
if (!IsWindow(HWND)) return new System.Drawing.Point(0,0);
RECT rc;
GetWindowRect(HWND, out rc);
return new System.Drawing.Point(rc.Left, rc.Top);
}
private int oldActualHeight = 0;
public Rectangle GetRealRectangle() {
if (!IsWindow(HWND)) return new Rectangle(0, 0, 0, 0);
RECT rc;
GetWindowRect(HWND, out rc);
return new Rectangle(rc.Left, rc.Top, rc.Right - rc.Left, rc.Bottom - rc.Top);
}
public Rectangle GetRectangle(bool scaling = true) {
if (!IsWindow(HWND)) return new Rectangle(0, 0, 0, 0);
RECT rc;
GetWindowRect(HWND, out rc);
if(ExplorerTAP.ExplorerTAP.NeedsTAPCache) {
var actualPos = ExplorerTAP.ExplorerTAP.GetYPosition(window);
;
rc.Top += (int)(actualPos * (scaling ? GetScalingFactor() : 1));
//rc.Bottom += actualPos;
}
return new Rectangle(rc.Left, rc.Top + YOffset, rc.Right - rc.Left, rc.Bottom - rc.Top - YOffset);
}
enum QUERY_USER_NOTIFICATION_STATE {
QUNS_NOT_PRESENT = 1,
QUNS_BUSY = 2,
QUNS_RUNNING_D3D_FULL_SCREEN = 3,
QUNS_PRESENTATION_MODE = 4,
QUNS_ACCEPTS_NOTIFICATIONS = 5,
QUNS_QUIET_TIME = 6,
QUNS_APP = 7
};
[DllImport("shell32.dll")]
static extern int SHQueryUserNotificationState(
out QUERY_USER_NOTIFICATION_STATE pquns);
public void PlaceWindowUnder(Taskbar window) {
if (!IsWindow(HWND)) return;
UpdateRadius();
var rect = GetRectangle();
SetWindowPos(window.windowHelper.HWND, HWND, rect.X, rect.Y, 0, 0,
SWP.NOACTIVATE | SWP.SHOWWINDOW | SWP.NOSIZE);
if (window.Width != rect.Width * (1 / scale)) window.Width = rect.Width * (1/scale);
var off = App.Settings.GraphicsRepeat ? 0 : window.UnderlayOffset;
if (window.Height - off != rect.Height * (1 / scale)) window.Height = rect.Height * (1 / scale) - off;
}
//SetWindowLong(HWND, GWL_EXSTYLE, (uint)((int)GetWindowLong(HWND, GWL_EXSTYLE) | WS_EX_LAYERED));
[DllImport("shell32.dll")]
private static extern IntPtr SHAppBarMessage(uint dwMessage,
ref APPBARDATA pData);
private static bool IsAutoHide() {
var appbar = new APPBARDATA {cbSize = Marshal.SizeOf(typeof(APPBARDATA))};
var state = (uint) SHAppBarMessage(4, ref appbar);
return (state & 1) == 1;
}
[DllImport("user32.dll")]
private static extern int SetWindowRgn(IntPtr hWnd, IntPtr hRgn, bool bRedraw);
[DllImport("gdi32.dll")]
private static extern IntPtr CreateRoundRectRgn(int x1, int y1, int x2, int y2, int cx, int cy);
[DllImport("gdi32.dll")]
private static extern IntPtr CreateRectRgn(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);
[DllImport("gdi32.dll")]
private static extern int CombineRgn(IntPtr hrgnDest, IntPtr hrgnSrc1, IntPtr hrgnSrc2,
CombineRgnStyles fnCombineMode);
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr GetDC(IntPtr hWnd);
[DllImport("user32.dll", SetLastError = true)]
private static extern int ReleaseDC(IntPtr hWnd, IntPtr hdc);
[DllImport("gdi32.dll")]
private static extern int GetDeviceCaps(IntPtr hdc, int nIndex);
[DllImport("gdi32.dll", EntryPoint = "DeleteObject")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DeleteObject([In] IntPtr hObject);
[DllImport("user32.dll")]
private static extern int GetWindowRgn(IntPtr hWnd, IntPtr hRgn);
public static int GetSystemDpi() {
using (Graphics screen = Graphics.FromHwnd(IntPtr.Zero)) {
IntPtr hdc = screen.GetHdc();
int virtualWidth = GetDeviceCaps(hdc, 8);
int physicalWidth = GetDeviceCaps(hdc,118);
screen.ReleaseHdc(hdc);
return (int) (96f * physicalWidth / virtualWidth);
}
}
public float GetScalingFactor() {
if (DPIUtil.IsSupportingDpiPerMonitor) return (float)DPIUtil.ScaleFactor(window);
var desktop = GetDC(IntPtr.Zero);
var real = GetDeviceCaps(desktop, 10);
var fals = GetDeviceCaps(desktop, 117);
var scale = fals / (float) real;
ReleaseDC(IntPtr.Zero, desktop);
return scale;
}
[DllImport("gdi32.dll")]
public static extern int OffsetRgn(IntPtr hrgn, int nXOffset, int nYOffset);
private TaskbarStyle old_style = TaskbarStyle.ForceDefault;
public bool UpdateRadius() {
if (!IsWindow(HWND)) return false;
if (old_radius != Radius && old_style != Style) {
old_radius = Radius;
old_style = Style;
var scale = GetScalingFactor();
var r = GetRealRectangle();
var w = (int) ((r.Width) * scale);
var h = (int) ((r.Height) * scale);
if (!autoHide && App.taskbars.Count > 1 && !App.Settings.SameRadiusOnEach) {
rgn = CreateRectRgn(0, 0, 0, 0);
if (last) {
var rgn2 = CreateRectRgn(0, 0, w / 2, h + 1);
var rgn1 = CreateRoundRectRgn(w / 3, 0, w + 1, h + 1, Radius, Radius);
CombineRgn(rgn, rgn1, rgn2, CombineRgnStyles.RGN_OR);
if(SetWindowRgn(HWND, rgn, true) != 0) DeleteObject(rgn);
DeleteObject(rgn1);
DeleteObject(rgn2);
window.Dispatcher.Invoke(() => {
window.TaskbarClip.RadiusX = window.TaskbarClip.RadiusY = Radius / 2;
window.TaskbarClip.Rect = new(0, 0, window.Width, window.Height);
window.TaskbarClipHide.RadiusX = window.TaskbarClipHide.RadiusY = 0;
window.TaskbarClipHide.Rect = new(0, 0, Radius / 2, window.Height);
});
}
else if (first){
var rgn1 = CreateRoundRectRgn(0, 0, w + 1, h + 1, Radius, Radius);
var rgn2 = CreateRectRgn(w / 2, 0, w + 1, h + 1);
CombineRgn(rgn, rgn1, rgn2, CombineRgnStyles.RGN_OR);
if(SetWindowRgn(HWND, rgn, true) != 0) DeleteObject(rgn);
DeleteObject(rgn1);
DeleteObject(rgn2);
window.Dispatcher.Invoke(() => {
window.TaskbarClip.RadiusX = window.TaskbarClip.RadiusY = Radius / 2;
window.TaskbarClip.Rect = new(0, 0, window.Width, window.Height);
window.TaskbarClipHide.RadiusX = window.TaskbarClipHide.RadiusY = 0;
window.TaskbarClipHide.Rect = new(window.Width - Radius / 2, 0, Radius / 2, window.Height);
});
}
}
else {
rgn = CreateRoundRectRgn(0, 0, w + 1, h + 1, Radius, Radius);
if(SetWindowRgn(HWND, rgn, true)!=0) DeleteObject(rgn);
window.Dispatcher.Invoke(() => {
window.TaskbarClip.RadiusX = window.TaskbarClip.RadiusY = Radius / 2;
window.TaskbarClip.Rect = new(0, 0, window.Width, window.Height);
window.TaskbarClipHide.RadiusX = window.TaskbarClipHide.RadiusY = 0;
window.TaskbarClipHide.Rect = new(0, 0, 0, 0);
});
}
rgn = CreateRectRgn(0, 0, 0, 0);
GetWindowRgn(HWND, rgn);
if(Style == TaskbarStyle.Default || Style == TaskbarStyle.Blur) {
if(SetWindowRgn(window.windowHelper.HWND, rgn, true) != 0) DeleteObject(rgn);
} else {
var rgn2 = CreateRectRgn(0, 0, w, h);
if(SetWindowRgn(window.windowHelper.HWND, rgn2, true) != 0) DeleteObject(rgn2);
DeleteObject(rgn);
}
return true;
}
return false;
}
[StructLayout(LayoutKind.Sequential)]
public struct RECT {
public int Left; // x position of upper-left corner
public int Top; // y position of upper-left corner
public int Right; // x position of lower-right corner
public int Bottom; // y position of lower-right corner
}
public static class SWP {
public static readonly int
NOSIZE = 0x0001,
NOMOVE = 0x0002,
NOZORDER = 0x0004,
NOREDRAW = 0x0008,
NOACTIVATE = 0x0010,
DRAWFRAME = 0x0020,
FRAMECHANGED = 0x0020,
SHOWWINDOW = 0x0040,
HIDEWINDOW = 0x0080,
NOCOPYBITS = 0x0100,
NOOWNERZORDER = 0x0200,
NOREPOSITION = 0x0200,
NOSENDCHANGING = 0x0400,
DEFERERASE = 0x2000,
ASYNCWINDOWPOS = 0x4000;
}
private delegate void WinEventDelegate(IntPtr hWinEventHook, uint eventType,
IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime);
[StructLayout(LayoutKind.Sequential)]
internal struct WindowCompositionAttributeData {
public WindowCompositionAttribute Attribute;
public IntPtr Data;
public int SizeOfData;
}
internal enum WindowCompositionAttribute {
// ...
WCA_ACCENT_POLICY = 19
// ...
}
internal enum AccentState {
ACCENT_DISABLED = 0,
ACCENT_ENABLE_GRADIENT = 1,
ACCENT_ENABLE_TRANSPARENTGRADIENT = 2,
ACCENT_ENABLE_BLURBEHIND = 3,
ACCENT_INVALID_STATE = 4
}
[StructLayout(LayoutKind.Sequential)]
internal struct AccentPolicy {
public AccentState AccentState;
public int AccentFlags;
public int GradientColor;
public int AnimationId;
}
[StructLayout(LayoutKind.Sequential)]
public struct APPBARDATA {
public int cbSize; // initialize this field using: Marshal.SizeOf(typeof(APPBARDATA));
public IntPtr hWnd;
public uint uCallbackMessage;
public uint uEdge;
public RECT rc;
public int lParam;
}
}
================================================
FILE: RainbowTaskbar/Helpers/Window.cs
================================================
using System;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Interop;
namespace RainbowTaskbar.Helpers;
public class WindowHelper {
public enum CombineRgnStyles {
RGN_AND = 1,
RGN_OR = 2,
RGN_XOR = 3,
RGN_DIFF = 4,
RGN_COPY = 5,
RGN_MIN = RGN_AND,
RGN_MAX = RGN_COPY
}
public static int Count;
public float scale;
public bool autoHide = IsAutoHide();
public IntPtr HWND = (IntPtr) 0;
public int Radius = 0;
public TaskbarHelper taskbar;
public Taskbar window;
public WindowHelper(Taskbar window, TaskbarHelper taskbarHelper) {
Count++;
this.window = window;
Init(taskbarHelper);
scale = taskbar.GetScalingFactor();
}
[DllImport("user32.dll")]
public static extern int SetWindowLong(IntPtr hWnd, int nIndex, uint dwNewLong);
[DllImport("user32.dll", EntryPoint = "GetWindowLong")]
public static extern IntPtr GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")]
static extern IntPtr MonitorFromWindow(IntPtr hwnd, uint dwFlags);
// size of a device name string
private const int CCHDEVICENAME = 32;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
internal struct MonitorInfoEx {
public int Size;
public RECT Monitor;
public RECT WorkArea;
public uint Flags;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCHDEVICENAME)]
public string DeviceName;
public void Init() {
this.Size = 40 + 2 * CCHDEVICENAME;
this.DeviceName = string.Empty;
}
}
[DllImport("user32.dll")]
static extern bool GetMonitorInfo(IntPtr hMonitor, out MonitorInfoEx lpmi);
[DllImport("gdi32.dll", EntryPoint = "DeleteObject")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DeleteObject([In] IntPtr hObject);
[DllImport("user32.dll")]
static extern IntPtr WindowFromPoint(System.Drawing.Point p);
public event EventHandler? TaskbarUIChanged;
public string LastUIData = "";
DateTime lastZIndex = DateTime.MinValue;
private void TaskbarPosChanged(object sender, EventArgs args) {
var rect = taskbar.GetRectangle();
var changed = Math.Abs(window.Left - rect.Left * (1 / scale)) > 0.001 || Math.Abs(window.Top - rect.Top * (1 / scale)) > 0.001 || Math.Abs(window.Width - rect.Width * (1 / scale)) > 0.001 || Math.Abs(window.Height - rect.Height * (1 / scale)) > 0.001;
if (changed) {
taskbar.PlaceWindowUnder(window);
taskbar.SetBlur();
}
if (DateTime.Now - lastZIndex > TimeSpan.FromSeconds(0.05) && !changed) {
lastZIndex = DateTime.Now;
taskbar.PlaceWindowUnder(window);
taskbar.SetBlur();
}
if(ExplorerTAP.ExplorerTAP.IsInjected) {
string UIData = ExplorerTAP.ExplorerTAP.GetUIDataStr(window);
if(UIData != LastUIData) {
LastUIData = UIData;
TaskbarUIChanged?.Invoke(this, null);
}
}
if (!App.Settings.GraphicsRepeat && App.hiddenWebViewHost is not null && window.Height != rect.Height * (1 / scale)) {
App.hiddenWebViewHost.Height = App.taskbars.Max(x=>x.Height);
}
if(autoHide && changed) {
var Taskbar = rect;
var finalW = Taskbar.Width * (1 / scale);
var finalH = Taskbar.Width * (1 / scale);
if(finalW > window.MinWidth) {
window.MinWidth = Taskbar.Width * (1 / scale);
window.Width = Taskbar.Width * (1 / scale);
}
if (finalH > window.MinHeight) {
window.MinHeight = Taskbar.Height * (1 / scale);
window.Height = Taskbar.Height * (1 / scale);
}
var scr = Screen.FromPoint(new((int)(rect.X*scale), (int)(rect.Y * scale)));
int max = (int) Math.Max(0,Math.Min(rect.Height, scr.Bounds.Bottom - rect.Y));
var rgn1 = CreateRectRgn(0, 0, (int)(rect.Width * scale), (int) (rect.Height * scale));
var rgn2 = CreateRectRgn(0, (int) (max* scale), (int) (rect.Width * scale), (int) (rect.Height * scale));
var rgn = CreateRectRgn(0, 0, 0, 0);
CombineRgn(rgn, rgn1, rgn2, CombineRgnStyles.RGN_XOR);
if(SetWindowRgn(HWND, rgn, false) != 0) DeleteObject(rgn);
DeleteObject(rgn1);
DeleteObject(rgn2);
window.AutoHideClip.RadiusX = window.AutoHideClip.RadiusY = 0;
window.AutoHideClip.Rect = new(0, max, 1920, rect.Height);
}
if (ddHandle != IntPtr.Zero) UpdateDuplicate();
}
public static IntPtr GetHWND(Window window) => new WindowInteropHelper(Window.GetWindow(window)).EnsureHandle();
public bool alive = true;
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
public void Init(TaskbarHelper taskbarHelper) {
HWND = GetHWND(window);
SetWindowLong(HWND, (int) GWL.EXSTYLE,
(uint) GetWindowLong(HWND, (int) GWL.EXSTYLE).ToInt32() | (uint) WS_EX.TRANSPARENT);
SetWindowLong(HWND, (int) GWL.STYLE,
(uint) GetWindowLong(HWND, (int) GWL.STYLE).ToInt32() | (uint) WS.POPUP | (uint) WS.VISIBLE);
taskbar = taskbarHelper;
taskbarHelper.TaskbarPositionChanged += TaskbarPosChanged;
Task.Run(() => {
while (alive) {
window.Dispatcher.Invoke(() => TaskbarPosChanged(null, null));
Thread.Sleep(20);
}
});
}
public static void InitOther(Window wnd) {
var _HWND = GetHWND(wnd);
SetWindowLong(_HWND, (int) GWL.EXSTYLE,
(uint) GetWindowLong(_HWND, (int) GWL.EXSTYLE).ToInt32() | (uint) WS_EX.TRANSPARENT);
SetWindowLong(_HWND, (int) GWL.STYLE,
(uint) GetWindowLong(_HWND, (int) GWL.STYLE).ToInt32() | (uint) WS.POPUP | (uint) WS.VISIBLE);
}
[DllImport("shell32.dll")]
private static extern IntPtr SHAppBarMessage(uint dwMessage,
ref APPBARDATA pData);
private static bool IsAutoHide() {
var appbar = new APPBARDATA {cbSize = Marshal.SizeOf(typeof(APPBARDATA))};
var state = (uint) SHAppBarMessage(4, ref appbar);
return (state & 1) == 1;
}
[DllImport("user32.dll")]
private static extern int SetWindowRgn(IntPtr hWnd, IntPtr hRgn, bool bRedraw);
[DllImport("gdi32.dll")]
private static extern IntPtr CreateRoundRectRgn(int x1, int y1, int x2, int y2, int cx, int cy);
[DllImport("gdi32.dll")]
private static extern IntPtr CreateRectRgn(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);
[DllImport("gdi32.dll")]
private static extern int CombineRgn(IntPtr hrgnDest, IntPtr hrgnSrc1, IntPtr hrgnSrc2,
CombineRgnStyles fnCombineMode);
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr GetDC(IntPtr hWnd);
[DllImport("user32.dll", SetLastError = true)]
private static extern int ReleaseDC(IntPtr hWnd, IntPtr hdc);
[DllImport("dwmapi.dll", SetLastError = true)]
static extern int DwmRegisterThumbnail(IntPtr dest, IntPtr src, out IntPtr thumb);
[StructLayout(LayoutKind.Sequential)]
public struct RECT {
public int Left, Top, Right, Bottom;
}
[StructLayout(LayoutKind.Sequential)]
public struct DWM_THUMBNAIL_PROPERTIES {
public DWM_TNP dwFlags;
public RECT rcDestination;
public RECT rcSource;
public byte opacity;
public int fVisible;
public int fSourceClientAreaOnly;
}
public enum DWM_TNP : uint {
DWM_TNP_RECTDESTINATION = 0x00000001,
DWM_TNP_RECTSOURCE = 0x00000002,
DWM_TNP_OPACITY = 0x00000004,
DWM_TNP_VISIBLE = 0x00000008,
DWM_TNP_SOURCECLIENTAREAONLY = 0x00000010,
}
[DllImport("dwmapi.dll", PreserveSig = true)]
public static extern int DwmUpdateThumbnailProperties(IntPtr hThumbnail, ref DWM_THUMBNAIL_PROPERTIES props);
[DllImport("dwmapi.dll")]
static extern int DwmUnregisterThumbnail(IntPtr thumb);
IntPtr ddHandle = IntPtr.Zero;
public void Duplicate(nint handle) {
if (ddHandle != IntPtr.Zero) DwmUnregisterThumbnail(ddHandle);
var r = DwmRegisterThumbnail(this.HWND, handle, out ddHandle);
;
}
public void UpdateDuplicate() {
if (ddHandle == IntPtr.Zero) return;
DWM_THUMBNAIL_PROPERTIES dskThumbProps = new();
dskThumbProps.dwFlags = DWM_TNP.DWM_TNP_SOURCECLIENTAREAONLY | DWM_TNP.DWM_TNP_VISIBLE | DWM_TNP.DWM_TNP_RECTSOURCE | DWM_TNP.DWM_TNP_OPACITY | DWM_TNP.DWM_TNP_RECTDESTINATION;
dskThumbProps.fSourceClientAreaOnly = 1;
dskThumbProps.fVisible = 1;
dskThumbProps.opacity = 255;
var rect = taskbar.GetRectangle(true);
rect.X -= (int) App.taskbars.Min(x => x.Left); ;
dskThumbProps.rcSource = new RECT() { Top = 0, Left = rect.X, Right = (int) rect.Width + rect.X, Bottom = (int) rect.Height };
dskThumbProps.rcDestination = new RECT() { Top = (int) (rect.Top - window.Top * scale), Left = 0, Right = (int) rect.Width, Bottom = (int) rect.Height };
DwmUpdateThumbnailProperties(ddHandle, ref dskThumbProps);
;
}
public void RemoveDuplicate() {
DwmUnregisterThumbnail(ddHandle);
ddHandle = IntPtr.Zero;
}
public enum GWL {
EXSTYLE = -20,
HINSTANCE = -6,
HWNDPARENT = -8,
ID = -12,
STYLE = -16,
USERDATA = -21,
WNDPROC = -4,
DWLP_USER = 0x8,
DWLP_MSGRESULT = 0x0,
DWLP_DLGPROC = 0x4
}
[Flags]
public enum WS : uint {
OVERLAPPED = 0x00000000,
POPUP = 0x80000000,
CHILD = 0x40000000,
MINIMIZE = 0x20000000,
VISIBLE = 0x10000000,
DISABLED = 0x08000000,
CLIPSIBLINGS = 0x04000000,
CLIPCHILDREN = 0x02000000,
MAXIMIZE = 0x01000000,
BORDER = 0x00800000,
DLGFRAME = 0x00400000,
VSCROLL = 0x00200000,
HSCROLL = 0x00100000,
SYSMENU = 0x00080000,
THICKFRAME = 0x00040000,
GROUP = 0x00020000,
TABSTOP = 0x00010000,
MINIMIZEBOX = 0x00020000,
MAXIMIZEBOX = 0x00010000,
CAPTION = BORDER | DLGFRAME,
TILED = OVERLAPPED,
ICONIC = MINIMIZE,
SIZEBOX = THICKFRAME,
TILEDWINDOW = OVERLAPPEDWINDOW,
OVERLAPPEDWINDOW = OVERLAPPED | CAPTION | SYSMENU | THICKFRAME | MINIMIZEBOX | MAXIMIZEBOX,
POPUPWINDOW = POPUP | BORDER | SYSMENU,
CHILDWINDOW = CHILD
}
public enum WS_EX : uint {
DLGMODALFRAME = 0x00000001,
NOPARENTNOTIFY = 0x00000004,
TOPMOST = 0x00000008,
ACCEPTFILES = 0x00000010,
TRANSPARENT = 0x00000020,
//#if(WINVER >= 0x0400)
MDICHILD = 0x00000040,
TOOLWINDOW = 0x00000080,
WINDOWEDGE = 0x00000100,
CLIENTEDGE = 0x00000200,
CONTEXTHELP = 0x00000400,
RIGHT = 0x00001000,
LEFT = 0x00000000,
RTLREADING = 0x00002000,
LTRREADING = 0x00000000,
LEFTSCROLLBAR = 0x00004000,
RIGHTSCROLLBAR = 0x00000000,
CONTROLPARENT = 0x00010000,
STATICEDGE = 0x00020000,
APPWINDOW = 0x00040000,
OVERLAPPEDWINDOW = WINDOWEDGE | CLIENTEDGE,
PALETTEWINDOW = WINDOWEDGE | TOOLWINDOW | TOPMOST,
//#endif /* WINVER >= 0x0400 */
//#if(WIN32WINNT >= 0x0500)
LAYERED = 0x00080000,
//#endif /* WIN32WINNT >= 0x0500 */
//#if(WINVER >= 0x0500)
NOINHERITLAYOUT = 0x00100000, // Disable inheritence of mirroring by children
LAYOUTRTL = 0x00400000, // Right to left mirroring
//#endif /* WINVER >= 0x0500 */
//#if(WIN32WINNT >= 0x0500)
COMPOSITED = 0x02000000,
NOACTIVATE = 0x08000000
//#endif /* WIN32WINNT >= 0x0500 */
}
public static class SWP {
public static readonly int
NOSIZE = 0x0001,
NOMOVE = 0x0002,
NOZORDER = 0x0004,
NOREDRAW = 0x0008,
NOACTIVATE = 0x0010,
DRAWFRAME = 0x0020,
FRAMECHANGED = 0x0020,
SHOWWINDOW = 0x0040,
HIDEWINDOW = 0x0080,
NOCOPYBITS = 0x0100,
NOOWNERZORDER = 0x0200,
NOREPOSITION = 0x0200,
NOSENDCHANGING = 0x0400,
DEFERERASE = 0x2000,
ASYNCWINDOWPOS = 0x4000;
}
[StructLayout(LayoutKind.Sequential)]
public struct APPBARDATA {
public int cbSize; // initialize this field using: Marshal.SizeOf(typeof(APPBARDATA));
public IntPtr hWnd;
public uint uCallbackMessage;
public uint uEdge;
public TaskbarHelper.RECT rc;
public int lParam;
}
}
================================================
FILE: RainbowTaskbar/Interpolation/ColorInterpolation.cs
================================================
using System;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Windows.Data;
namespace RainbowTaskbar.Interpolation;
internal class ColorInterpolation {
public enum INTERPOLATE_FUNCTION {
Linear,
Sine,
Cubic,
Exponential,
Back
}
private static double Cubic(double x) => x < 0.5 ? 4 * x * x * x : 1 - Math.Pow(-2 * x + 2, 3) / 2;
private static double Back(double x) {
const double c1 = 1.70158;
const double c2 = c1 * 1.525;
return x < 0.5
? Math.Pow(2 * x, 2) * ((c2 + 1) * 2 * x - c2) / 2
: (Math.Pow(2 * x - 2, 2) * ((c2 + 1) * (x * 2 - 2) + c2) + 2) / 2;
}
private static double Sine(double x) => -(Math.Cos(3.14159 /*PI*/ * x) - 1) / 2;
private static double Exponential(double x) =>
x == 0
? 0
: x == 1
? 1
: x < 0.5
? Math.Pow(2, 20 * x - 10) / 2
: (2 - Math.Pow(2, -20 * x + 10)) / 2;
private static double clamp(double d, double min, double max) {
var t = d < min ? min : d;
return t > max ? max : t;
}
private static Color interp(Color color1, Color color2, double fraction) {
var r = (byte) clamp((color2.R - color1.R) * fraction + color1.R, 0, 255);
var g = (byte) clamp((color2.G - color1.G) * fraction + color1.G, 0, 255);
var b = (byte) clamp((color2.B - color1.B) * fraction + color1.B, 0, 255);
return Color.FromArgb(255, r, g, b);
}
public static Color Interpolate(Color color1, Color color2, INTERPOLATE_FUNCTION which, double fraction) {
switch (which) {
case INTERPOLATE_FUNCTION.Linear: {
return interp(color1, color2, fraction);
}
case INTERPOLATE_FUNCTION.Sine: {
return interp(color1, color2, Sine(fraction));
}
case INTERPOLATE_FUNCTION.Cubic: {
return interp(color1, color2, Cubic(fraction));
}
case INTERPOLATE_FUNCTION.Exponential: {
return interp(color1, color2, Exponential(fraction));
}
case INTERPOLATE_FUNCTION.Back: {
return interp(color1, color2, Back(fraction));
}
default: {
return interp(color1, color2, fraction);
}
}
}
}
internal static class ColorExtension {
public static Color ToDrawingColor(this System.Windows.Media.Color color) =>
Color.FromArgb(color.A, color.R, color.G, color.B);
public static System.Windows.Media.Color ToMediaColor(this Color color) =>
System.Windows.Media.Color.FromArgb(color.A, color.R, color.G, color.B);
public static string HexConverter(Color c) => "#" + c.R.ToString("X2") + c.G.ToString("X2") + c.B.ToString("X2");
}
public class ColorConverter : IValueConverter {
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) =>
value is not null ? ((Color) value).ToMediaColor() : null;
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) =>
value is not null ? ((System.Windows.Media.Color) value).ToDrawingColor() : null;
}
================================================
FILE: RainbowTaskbar/Languages/Localization.cs
================================================
using RainbowTaskbar.Configuration.Instruction.Instructions;
using RainbowTaskbar.Configuration.Instruction;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Data;
namespace RainbowTaskbar.Languages {
public class Localization
{
public static List languages = new List() { "SystemDefault", "en_US", "zh_CN", "fr_FR", "ro_RO" };
public ResourceDictionary dictionary;
public en_US dictionary_en_US;
public Localization() {
dictionary_en_US = new en_US();
dictionary_en_US.InitializeComponent();
Switch(CultureInfo.InstalledUICulture.Name);
}
public void Switch(string lang) {
var language = lang is not null ? lang.Replace("-", "_") : null;
switch (language) {
case "zh":
case "zh_CN":
case "zh_SG":
dictionary = new zh_CN();
(dictionary as zh_CN).InitializeComponent();
break;
case "fr":
case "fr_FR":
dictionary = new fr_FR();
(dictionary as fr_FR).InitializeComponent();
break;
case "ro":
case "ro_RO":
case "ro_MD":
dictionary = new ro_RO();
(dictionary as ro_RO).InitializeComponent();
break;
default:
dictionary = dictionary_en_US;
break;
}
}
public string Get(string key) {
return dictionary[key] as string;
}
public string this[string key] {
get {
return dictionary[key] as string;
}
}
public string UseSystemDefaultString { get {
return this["systemdefault"];
} }
public string InstructionFormat(Instruction instruction, params object[] args) {
return string.Format(Get($"{instruction.GetType().Name.ToLower()}format"), args);
}
public string Name(string str) {
return str is not null ? Get(str.ToLower()) : null;
}
public string InstructionFormatSuffix(Instruction instruction, string suffix, params object[] args) {
return string.Format(Get($"{instruction.GetType().Name.ToLower()}{suffix}format"), args);
}
public string Enum(Enum en) {
return en is not null ? Get($"enum_{en.ToString().ToLower()}") : null;
}
public void Enable(Collection mergedDicts) {
mergedDicts.ToList().Where(x=>x.Contains("systemdefault")).ToList().ForEach(x => mergedDicts.Remove(x));
mergedDicts.Add(dictionary_en_US);
mergedDicts.Add(dictionary);
}
}
public static class EnumLocalization {
public static string ToStringLocalized(this Enum shape) {
return App.localization.Enum(shape);
}
}
}
================================================
FILE: RainbowTaskbar/Languages/Translators.cs
================================================
using RainbowTaskbar.Configuration;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
namespace RainbowTaskbar.Languages
{
public class EnumTranslator : IValueConverter {
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) =>
value is not null ? App.localization.Enum(value as Enum) : null;
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) =>
throw new NotImplementedException();
}
public class InstructionTranslator : IValueConverter {
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) =>
value is not null ? App.localization.Name((value as string).ToLower()) : null;
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) =>
throw new NotImplementedException();
}
public class LanguageConverter : IValueConverter {
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) =>
value is not null ? (
value as string == "SystemDefault" ? App.localization.UseSystemDefaultString : new CultureInfo(value as string).Parent.NativeName
) : null;
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) =>
throw new NotImplementedException();
}
}
================================================
FILE: RainbowTaskbar/Languages/en_US.xaml
================================================
Home
Settings
About
Browse
Configs
About RainbowTaskbar
Open RainbowTaskbar website
RainbowTaskbar is a tool that allows you to greatly customize the appearance of your taskbar.
It is completely free to use, but donations are well appreciated!
Untitled
New
Classic
Web
Run once group
Looping groups
Group
Run
Save
Add
Title
Thumbnail
Edit config
Save and publish
Publish status:
Latest published
Previously published, not latest
Not published
Pick image
Copy instructions from preset
Description
Add property
Property name
Property key
Property type
property_1
New property
Open Developer Tools
String
Number
Color
Boolean
File size:
KB (incl. thumbnail)
Author:
Likes:
Download
Download new copy
Like
Unlike
Comments
Go back
Open in web
Welcome to the RainbowTaskbar editor!
What's new in the latest update
Review on Store
*using GitHub to submit an issue or request is preferred.
Issue title
Description
Contact info (optional)
General
Run at startup
Check for updates
Show tray icon
Language
Workshop
Signed in as
Log in (GitHub)
Log in (Google)
Log out
Pass mouse input to underlay (may use CPU)
Allow JavaScript
Graphics
Interpolation quality (smaller = better)
Multiple taskbars
(current value may impact performance)
Same radius
Repeat graphics
Coming soon...
Maximum web FPS
(Use system language)
Global properties
*to keep config setting, use value '-1'
Taskbar transparency (0-1)
Send info on unhandled exceptions
Search something...
Likes
Match
Border radius
Clear layer
Color
Delay
Image
Shape
Text
Transparency/Style
Border Radius - {0}px
Clear layer - {0}
{0} - Randomized
{0} - {1} -> {2}
{0} - {1}
Delay - {0}ms
Image - {0}
Shape - {0}
Text - {0}
Style - {0}
Layer {0} - {1}%
{0} - {1}%
Line
Rectangle
Rounded rectangle
Ellipse
Solid
Fading solid
Gradient
Fading gradient
Linear
Cubic
Sine
Exponential
Back
Taskbar opacity
Underlay opacity
Taskbar and underlay opacities
Layer opacity
Taskbar style
Taskbar elements
Default
Blurred
Transparent
Draw only once
Stroke color
Fill color
Thickness
Border radius
Fit to taskbar
Randomize colors
Hold time
Fade time
Gradient angle °
Layer
ms
Choose image
Width
Height
Font size
Font color
Center on X-axis
Change
to
Duplicate
Delete
Duplicate - Swap colors
Open editor
Donate
Open project page
Submit an issue or request
Exit
There seems to be an issue with the RainbowTaskbar DLL injected into explorer.exe.
This process is very experimental, so please open up an issue on GitHub (Right-click RainbowTaskbar on system tray -> Submit an issue or request)
to try and debug the problem. Make sure to also include any other errors you might have encountered.
To enable transparency effects, RainbowTaskbar must restart the explorer.exe process.
Do you wish to proceed?
Your processor architecture (x64) is incompatible with this executable (x86).
Please download the correct executable (rnbtsk-x64.exe / setup-x64.exe) from GitHub releases.
RainbowTaskbar has found a legacy config version.
Do you wish to migrate it to the new config format?
Input the code displayed on the login success page below
You must be logged in to publish your config! Check the settings page to sign in.
Not logged in
You must be logged in to like a config!
Failed to publish config.
Fail
Config info/data updated. Failed to upload thumbnail.
Create new property
Log in with code
Log in
Save your work?
Do you wish to save your current config?
Save
Don't save
Cancel
A new RainbowTaskbar update has released. Would you like to update?
Do you wish to migrate the legacy (v2) config and presets to the current version?
Use GitHub
================================================
FILE: RainbowTaskbar/Languages/en_US.xaml.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace RainbowTaskbar.Languages
{
///
/// Interaction logic for en_US.xaml
///
public partial class en_US : ResourceDictionary
{
public en_US()
{
}
}
}
================================================
FILE: RainbowTaskbar/Languages/fr_FR.xaml
================================================
Accueil
Paramètres
À propos
Galerie
Configurations
À propos de RainbowTaskbar
Accéder au site de RainbowTaskbar
RainbowTaskbar est un outil gratuit et open source qui permet de personnaliser l'apparence de la barre des tâches.
Les dons sont les bienvenus !
Sans titre
Nouveau
Classique
Web
Lancer un seul groupe une seule fois
Lancer plusieurs groupes en boucle
Groupe
Lancer
Enregistrer
Ajouter
Titre
Image
Modifier la configuration
Enregistrer et publier
Statut de publication:
Dernière publication
Publié précédemment, pas le plus récent
Non publié
Choisir une image
Copier les instructions du préréglage
Description
Ajouter une propriété
Nom de la propriété
Clé de la propriété
Type de la propriété
Ouvrir les outils développeur
propriété_1
Nouvelle propriété
Chaîne
Nombre
Couleur
Booléen
Taille du fichier:
Ko (image inclue)
Auteur:
Favoris:
Télécharger
Télécharger une copie
Ajouter aux favoris
Supprimer des favoris
Commentaires
Retour
Ouvrir dans le navigateur
Bienvenue dans l'éditeur de RainbowTaskbar !
Nouveautés de la dernière mise à jour
Déposer un avis (Microsoft Store)
*utiliser GitHub pour ouvrir un ticket ou soumettre une demande est le moyen recommandé.
Sujet
Description
Information de contact (facultatif)
Général
Lancer au démarrage
Rechercher des mises à jour
Afficher l’icône dans la barre d’état système
Langue
Galerie
Connecté en tant que
Se connecter (GitHub)
Se connecter (Google)
Se déconnecter
Transmettre la souris à la sous-couche (peut utiliser le CPU)
Autoriser JavaScript
Graphismes
Qualité d'interpolation (plus petit = meilleur)
Plusieurs barre des tâches
(la valeur actuelle peut impacter les performances)
Même rayon
Répéter
Arrive bientôt
IPS Web maximum
(Utiliser la langue du système)
Propriétés globales
*pour garder le paramètre de la configuration, utiliser '-1'
Opacité de la barre (0-1)
Envoyer les informations sur les exceptions non gérées
Rechercher...
Favoris
Correspondance
Rayon de Bordure
Calque vide
Couleur
Délai
Image
Forme
Texte
Transparence/Style
Rayon de Bordure - {0}px
Calque vide - {0}
{0} - Aléatoire
{0} - {1} -> {2}
{0} - {1}
Délai - {0}ms
Image - {0}
Forme - {0}
Texte - {0}
Style - {0}
Calque {0} - {1}%
{0} - {1}%
Ligne
Rectangle
Rectangle arrondi
Ellipse
Opaque
Fondu opaque
Dégradé
Fondu en dégradé
Linéaire
Cubique
Ondulation
Exponentiel
Retour
Opacité de la barre des tâches
Opacité de la sous-couche
Opacité de la barre des tâches et de la sous-couche
Opacité du calque
Style de la barre des tâches
Taskbar elements
Par défaut
Flou
Transparent
Dessiner une seule fois
Couleur du contour
Couleur de remplissage
Épaisseur
Rayon de bordure
Adapter à la barre des tâches
Couleurs aléatoires
Durée de maintien
Durée de fondu
Angle du dégradé °
Calque
ms
Choisir une image
Largeur
Hauteur
Taille de la police
Couleur de la police
Centrer sur l'axe X (horizontal)
Changer
en
Dupliquer
Supprimer
Dupliquer - Échanger les couleurs
Ouvrir l'éditeur
Faire un don
Ouvrir la page du projet
Ouvrir un ticket ou soumettre une demande
Quitter
Il semble y avoir un problème avec la DLL de RainbowTaskbar injectée dans explorer.exe.
Ce processus étant encore expérimental, veuillez ouvrir un ticket sur GitHub (clic droit sur RainbowTaskbar dans la barre d’état système -> Ouvrir un ticket ou soumettre une demande)
afin d’aider à diagnostiquer le problème. Veillez également à joindre tout autre message d’erreur que vous auriez rencontré.
Pour activer les effets de transparence, RainbowTaskbar doit redémarrer le processus explorer.exe.
Souhaitez-vous continuer ?
Votre architecture de processeur (x64) est incompatible avec cet exécutable (x86).
Veuillez télécharger l’exécutable correspondant (rnbtsk-x64.exe / setup-x64.exe) depuis les publications GitHub.
RainbowTaskbar a détecté une version de configuration héritée.
Souhaitez-vous la migrer vers le nouveau format de configuration ?
Veuillez saisir le code affiché sur la page de connexion réussie ci-dessous.
Vous devez être connecté pour pouvoir publier votre configuration ! Rendez vous dans les paramètres pour vous connecter.
Non connecté
Vous devez être connecté pour ajouter cette configuration à vos favoris !
Erreur lors de la publication de la configuration.
Erreur
Configuration mise à jour. Erreur lors de la publication de l'image.
Ajouter une propriété
Se connecter avec un code
Se connecter
Souhaitez-vous enregistrer votre progression ?
Souhaitez-vous enregistrer votre configuration actuelle ?
Enregistrer
Ne pas enregistrer
Annuler
Une nouvelle version de RainbowTaskbar est disponible. Souhaitez-vous mettre à jour ?
Souhaitez-vous migrer la configuration et les préréglages de la version héritée (v2) vers la version actuelle ?
Utiliser GitHub
Traduit par Jean-Baptiste A.
================================================
FILE: RainbowTaskbar/Languages/fr_FR.xaml.cs
================================================
using System.Windows;
namespace RainbowTaskbar.Languages
{
///
/// Interaction logic for fr_FR.xaml
///
public partial class fr_FR : ResourceDictionary
{
public fr_FR() {
}
}
}
================================================
FILE: RainbowTaskbar/Languages/ro_RO.xaml
================================================
Acasă
Setări
Despre
Caută
Configurații
Despre RainbowTaskbar
Deschide site-ul RainbowTaskbar
RainbowTaskbar este un instrument care vă permite să personalizați taskbar-ul.
Este complet gratuit, dar donațiile sunt apreciate!
Fără titlu
Nou
Clasic
Web
Grup care execută o data
Grup care execută continuu
Grup
Execută
Salvează
Adaugă
Titlu
Imagine
Modifică configurația
Salvează și publică
Status:
Cel mai nou publicat
Publicat precedent, dar nu cel mai nou
Nu a fost publicat
Alege o imagine
Copiază instrucțiuni din prestabilite
Descriere
Adaugă proprietate
Nume proprietate
Cheie proprietate
Tip proprietate
proprietate_1
Proprietate nouă
Deschide instrumentele de dezvoltator
Text
Număr
Culoare
Boolean
Mărime fișier:
KO (cu imagine)
Autor:
Aprecieri:
Descarcă
Descarcă o copie nouă
Apreciază
Nu mai aprecia
Comentarii
Înapoi
Deschide în web
Bun venit la editor-ul RainbowTaskbar!
Ce e nou în ultimul update
Adaugă un review
*este preferată utilizarea platformei GitHub pentru a publica o problemă sau o cerere.
Titlu cerere
Descriere
Date de contact (optional)
General
Execută la pornirea sistemului
Verifică actualizari
Afișează iconița de notificari
Limbă
Workshop
Autentificat ca
Autentificare (GitHub)
Autentificare (Google)
Deconectare
Trimite mouse input la substrat (poate utiliza CPU)
Permite JavaScript
Grafici
Calitate interpolare (mai mic = mai bun)
Mai multe taskbar-uri
(valoarea selectată poate afecta performanța)
Aceeași rază
Repetă graficile
În curând...
FPS (cadre pe secundă) maxim web
(Utilizează limba sistemului)
Proprietăți globale
*pentru a păstra setările configurației selectate, utilizați valoarea '-1'
Transparență taskbar (0-1)
Trimite informații despre erori
Caută...
După aprecieri
După potrivire
Raza colțurilor
Golește strat
Culoare
Întârziere
Imagine
Formă
Text
Transparență/Stil
Raza colțurilor - {0}px
Golește strat - {0}
{0} - Aleatoriu
{0} - {1} -> {2}
{0} - {1}
Intârziere - {0}ms
Imagine - {0}
Formă- {0}
Text - {0}
Stil - {0}
Strat {0} - {1}%
{0} - {1}%
Linie
Dreptunghi
Dreptunghi rotunjit
Elipsă
Solid
Solid cu estompare
Gradient
Gradient cu estompare
Linear
Cubic
Sinus
Exponențial
Înapoi
Opacitate taskbar
Opacitate substrat
Opacitate taskbar și substrat
Opacitate strat
Stilul taskbar-ului
Elementele taskbar-ului
Prestabilit
Blurat
Transparent
Desenează o singură dată
Culoare linie
Culoare umplutură
Grosime
Raza colțurilor
Potrivește la dimensiunea taskbar-ului
Culori aleatorii
Timp de susținere
Timp de estompare
Unghiul gradientului °
Strat
ms
Alege imagine
Lățime
Înălțime
Marime font
Culoare font
Centrează pe axa Ox
Schimbă
la
Duplică
Șterge
Duplică - Inversează culorile
Deschide editor-ul
Donează
Deschide pagina proiectului
Publică o cerere sau problema
Închide
Se pare că există o problema cu DLL-ul injectat in procesul explorer.exe.
Acest proces este experimental, va rugăm să publicați o problema pe GitHub (Click-dreapta pe iconița de notificari -> Publică o cerere sau problema)
pentru a permite depanarea problemei. Vă rugam să menționați și orice altă eroare ați mai întâmpinat.
Pentru a permite efectele de transparență, RainbowTaskbar trebuie să reporneasca procesul explorer.exe.
Doriți să continuați?
Tipul procesorului dvs. (x64) este incompatibil cu acest executabil (x86).
Vă rugăm să descărcați varianta corectă a programului (rnbtsk-x64.exe / setup-x64.exe) de pe GitHub.
RainbowTaskbar a găsit o configurație veche.
Doriți să o actualizați la noul format?
Introduceți codul afișat pe pagina de autentificare cu succes
Trebuie să fiți autentificat pentru a publica o configurație! Verificați pagina Setări pentru a vă autentifica.
Neautentificat
Trebuie sa fiți autentificat pentru a aprecia o configurație!
Nu s-a putut publica configurația.
Eșec
Datele/informațiile configurației au fost actualizate. Nu s-a putut actualiza poza.
Creează proprietate nouă
Autentificare cu cod
Autentificare
Salvați?
Doriți să salvați configurația actuală?
Salvează
Nu salva
Anulează
Un nou update RainbowTaskbar a fost găsit. Doriți să actualizați?
Vrei să migrezi configurațiile v2 la v3 (actual)?
Folosește GitHub
================================================
FILE: RainbowTaskbar/Languages/ro_RO.xaml.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace RainbowTaskbar.Languages
{
///
/// Interaction logic for ro_RO.xaml
///
public partial class ro_RO : ResourceDictionary
{
public ro_RO()
{
}
}
}
================================================
FILE: RainbowTaskbar/Languages/zh_CN.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace RainbowTaskbar.Languages {
///
/// Interaction logic for zh_CN.xaml
///
public partial class zh_CN : ResourceDictionary {
public zh_CN() {
}
}
}
================================================
FILE: RainbowTaskbar/Languages/zh_CN.xaml
================================================
主页
设置
关于
浏览
配置
关于 RainbowTaskbar
打开 RainbowTaskbar 网站
RainbowTaskbar 是一款系统增强工具,允许您极大地自定义任务栏的外观。
它完全免费使用,但非常欢迎捐赠支持!
未命名
新建
经典
网络
运行一次组
循环组
组
运行
保存
添加
标题
缩略图
编辑配置
保存并发布
发布状态:
最新发布
先前已发布,但不是最新的
未发布
选择图片
从预设复制指令
描述
添加属性
属性名称
属性键
属性类型
property_1
新建属性
打开开发者工具
字符串
数字
颜色
布尔值
文件大小:
KB (包含缩略图)
作者:
点赞数:
下载
下载新版本
点赞
取消点赞
评论
返回
在网页中打开
欢迎使用 RainbowTaskbar 编辑器!
最新更新中的新功能
商店评论
*最好使用 GitHub 提交问题或请求。
问题标题
描述
联系信息(可选)
常规
启动时运行
检查更新
显示托盘图标
语言
工作区
已登录为
登录(GitHub)
登录(Google)
注销
传递鼠标输入到底层(可能会使用 CPU)
允许 JavaScript
图形
插值质量(数值越小越好)
多个任务栏
(当前设置可能会影响性能)
相同的圆角半径
重复图形
即将推出...
最大网页帧率
(使用系统语言)
全局属性
*为了保持配置的设置,使用值 '-1'
任务栏透明度 (0-1)
发送未处理异常的信息
搜索内容...
喜欢
匹配
圆角半径
清除图层
颜色
延迟
图像
形状
文本
透明度/样式
圆角半径 - {0}px
清除层 - {0}
{0} - 随机
{0} - {1} -> {2}
{0} - {1}
延迟 - {0}ms
图像 - {0}
形状 - {0}
文本 - {0}
样式 - {0}
图层 {0} - {1}%
{0} - {1}%
直线
矩形
圆角矩形
椭圆
纯色
渐隐纯色
渐变
渐隐渐变
线性
三次方
正弦
指数
回弹
任务栏透明度
底层透明度
任务栏和底层透明度
图层透明度
任务栏样式
Taskbar elements
默认
模糊
透明
仅绘制一次
描边颜色
填充颜色
厚度
圆角半径
适应任务栏
随机颜色
保持时间
褪色时间
渐变角度 °
图层
毫秒
选择图像
宽度
高度
字体大小
字体颜色
沿 X 轴居中
更改
到
重复
删除
复制 - 交换颜色
打开编辑器
捐赠
打开项目页面
提交问题或请求
退出
注入 explorer.exe 的 RainbowTaskbar DLL 似乎存在问题。
此过程非常具有实验性,因此请在 GitHub 上打开一个问题(右键单击系统托盘上的 RainbowTaskbar -> 提交问题或请求)
尝试调试问题。请确保还包括您可能遇到的任何其他错误。
要启用透明效果,RainbowTaskbar 必须重新启动 explorer.exe 进程。
您想要继续吗?
您的处理器架构 (x64) 与此可执行文件 (x86) 不兼容。
请从 GitHub 版本下载正确的可执行文件(rnbtsk-x64.exe / setup-x64.exe)。
RainbowTaskbar 发现了旧版配置版本。
您希望将其迁移到新的配置格式吗?
输入下面登录成功页面显示的代码
您必须登录才能发布您的配置!请前往设置页面进行登录。
未登录
您必须登录才能点赞配置!
发布配置失败。
失败
配置信息/数据已更新。缩略图上传失败。
创建新属性
使用验证码登录
登录
保存您的工作吗?
您是否希望保存当前的配置?
保存
不保存
取消
RainbowTaskbar 有新版本发布了。您想要更新吗?
您是否希望将旧版(v2)配置和预设迁移到当前版本?
使用 GitHub
大眼仔~旭
================================================
FILE: RainbowTaskbar/Preferences/Settings.cs
================================================
using Microsoft.Win32;
using PropertyChanged;
using RainbowTaskbar.Configuration;
using RainbowTaskbar.Editor;
using RainbowTaskbar.HTTPAPI;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
using System.Net.Http.Json;
using System.Dynamic;
using RainbowTaskbar.Configuration.Web;
using RainbowTaskbar.Configuration.Instruction.Instructions;
using System.Windows;
#if MSIX_BUILD
using Windows.ApplicationModel;
#endif
namespace RainbowTaskbar.Preferences {
public class Settings : INotifyPropertyChanged {
[OnChangedMethod(nameof(SaveChanged))]
public bool CheckUpdate { get; set; } = true;
public int InterpolationQuality { get; set; } = 25;
[OnChangedMethod(nameof(SaveChanged))]
[OnChangedMethod(nameof(OnTaskbarBehaviourChanged))]
public bool GraphicsRepeat { get; set; } = false;
[OnChangedMethod(nameof(SaveChanged))]
[OnChangedMethod(nameof(OnTaskbarBehaviourChanged))]
public bool SameRadiusOnEach { get; set; } = false;
[OnChangedMethod(nameof(SaveChanged))]
[OnChangedMethod(nameof(OnLanguageChanged))]
public string Language { get; set; } = "SystemDefault";
[OnChangedMethod(nameof(SaveChanged))]
[OnChangedMethod(nameof(OnTrayIconVisibilityChanged))]
public bool ShowTrayIcon { get; set; } = true;
[OnChangedMethod(nameof(OnConfigChanged))]
public string SelectedConfigID { get; set; }
[OnChangedMethod(nameof(SaveChanged))]
[OnChangedMethod(nameof(OnTaskbarBehaviourChanged))]
public int MaxWebFPS { get; set; } = 40;
[JsonIgnore]
public string AccountUsername { get; set; } = "";
[JsonIgnore]
public bool LoggedIn { get; set; } = false;
public string LoginKey { get; set; }
public WorkshopAPI workshopAPI = null;
[OnChangedMethod(nameof(SaveChanged))]
[OnChangedMethod(nameof(OnWebTouchThroughChanged))]
public bool WebTouchThrough { get; set; } = true;
[OnChangedMethod(nameof(SaveChanged))]
[OnChangedMethod(nameof(OnWebScriptEnabledChanged))]
public bool WebScriptEnabled { get; set; } = true;
public void OnWebTouchThroughChanged() {
if (WebTouchThrough) App.StartHook();
else App.StopHook();
}
[OnChangedMethod(nameof(SaveChanged))]
[OnChangedMethod(nameof(OnTaskbarBehaviourChanged))]
[OnChangedMethod(nameof(OnGlobalOpacityChanged))]
public double GlobalOpacity { get; set; } = -1;
public Version Version { get; set; } = new Version("1.0");
[OnChangedMethod(nameof(SaveChanged))]
public bool ReportExceptions { get; set; } = true;
public void OnGlobalOpacityChanged() {
if(GlobalOpacity != -1) App.taskbars.ForEach(x => {
new TransparencyInstruction() {
Type = TransparencyInstruction.TransparencyInstructionType.Taskbar,
Opacity = GlobalOpacity
}.Execute(x);
});
}
public void OnWebScriptEnabledChanged() {
App.taskbars.ForEach(x => {
try {
x.webView.CoreWebView2.Settings.IsScriptEnabled = WebScriptEnabled;
}
catch {
}
});
if (App.Settings.SelectedConfig is WebConfig) Taskbar.SoftReset(true);
}
private Timer TryLoginTimer = null;
public async void OnLoginKeyChanged() {
if (App.Settings is null) return;
if (LoginKey is null) return;
try {
using var http = new HttpClient();
using var web = new WebClient();
var content = await http.PostAsJsonAsync("https://rnbsrv.ad2017.dev/user/me/info", new { key = LoginKey });
dynamic json = JsonSerializer.Deserialize(content.Content.ReadAsStringAsync().Result);
if (json.result.GetBoolean()) {
dynamic user = JsonSerializer.Deserialize(json.user);
LoggedIn = true;
if (TryLoginTimer is not null) {
TryLoginTimer.Dispose();
TryLoginTimer = null;
}
AccountUsername = user.username.ToString();
workshopAPI = new WorkshopAPI() { LoginKey = LoginKey };
ToFile();
}
} catch {
LoggedIn = false;
AccountUsername = "";
if(TryLoginTimer is null) {
TryLoginTimer = new Timer((_) => {
OnLoginKeyChanged();
}, null, 30000, 30000);
}
}
}
[JsonIgnore]
public Config SelectedConfig { get => App.Configs.FirstOrDefault(x=>x.LocalID == SelectedConfigID, null); set => SelectedConfigID = value.LocalID; }
public bool FirstStart { get; set; } = true;
[JsonIgnore]
public bool RunAtStartup {
get {
if (App.IsMicrosoftStore()) {
#if MSIX_BUILD
StartupTask t = StartupTask.GetAsync("RnbTsk_Startup").AsTask().Result;
if (t is null) return false;
return t.State == StartupTaskState.Enabled || t.State == StartupTaskState.EnabledByPolicy;
#else
return false;
#endif
} else {
return (string?) Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Run")
.GetValue("RainbowTaskbar") == Environment.ProcessPath;
}
}
set {
if(App.IsMicrosoftStore()) {
#if MSIX_BUILD
StartupTask t = StartupTask.GetAsync("RnbTsk_Startup").AsTask().Result;
if (t is null) return;
if (value)
t.RequestEnableAsync();
else
t.Disable();
#endif
} else {
var key = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Run", true);
if (value)
key.SetValue("RainbowTaskbar", Environment.ProcessPath);
else
key.DeleteValue("RainbowTaskbar");
key.Close();
}
string prot = "rnbtsk";
RegistryKey reg = Registry.CurrentUser.OpenSubKey($"Software\\Classes\\{prot}", true);
if (reg != null) {
reg = reg.OpenSubKey(@"shell\open\command", true);
reg.SetValue(string.Empty, Environment.ProcessPath + " " + "shell \"%1\"");
reg.Close();
} else {
reg = Registry.CurrentUser.CreateSubKey($"Software\\Classes\\{prot}", true);
reg.SetValue(string.Empty, "URL: " + prot);
reg.SetValue("URL Protocol", string.Empty);
reg = reg.CreateSubKey(@"shell\open\command");
reg.SetValue(string.Empty, Environment.ProcessPath + " " + "shell \"%1\"");
reg.Close();
}
}
}
public string language {
get {
return Language == "SystemDefault" ? CultureInfo.CurrentUICulture.Name : Language;
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnTaskbarBehaviourChanged() {
if (App.Settings is null) return;
App.ReloadTaskbars();
}
public void OnLanguageChanged() {
if (App.Settings is null) return;
App.localization.Switch(language);
if (App.editor is not null) {
App.editor.Close();
App.editor = new EditorWindow();
App.trayWindow.TrayIcon.Dispose();
App.trayWindow.Close();
App.trayWindow = new();
App.LaunchEditor();
}
}
public void OnTrayIconVisibilityChanged() {
if (App.Settings is null) return;
if (App.trayWindow is not null) {
App.trayWindow.TrayIcon.Dispose();
App.trayWindow.Close();
App.trayWindow = null;
} else {
App.trayWindow = new();
}
}
public void OnConfigChanged() {
if (App.Settings is null) return;
App.ReloadTaskbars();
}
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
public static Settings FromFile(string file = null) {
if (file is null) file = Path.Join(App.rainbowTaskbarDir, "settings.json");
if (!File.Exists(file)) return new();
var settings = JsonSerializer.Deserialize(File.ReadAllText(file));
settings.loaded = true;
return settings;
}
public void ToFile(string file = null) {
if (file is null) file = Path.Join(App.rainbowTaskbarDir, "settings.json");
File.WriteAllText(file, JsonSerializer.Serialize(this));
}
public bool loaded = false;
public void SaveChanged() {
if (!loaded) return;
ToFile();
}
}
}
================================================
FILE: RainbowTaskbar/Properties/Resources.Designer.cs
================================================
//------------------------------------------------------------------------------
//
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
//------------------------------------------------------------------------------
namespace RainbowTaskbar.Properties {
using System;
///
/// A strongly-typed resource class, for looking up localized strings, etc.
///
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
public class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
///
/// Returns the cached ResourceManager instance used by this class.
///
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
public static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("RainbowTaskbar.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
///
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
///
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
public static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
///
/// Looks up a localized string similar to .
///
public static string g {
get {
return ResourceManager.GetString("g", resourceCulture);
}
}
///
/// Looks up a localized resource of type System.Byte[].
///
public static byte[] monaco {
get {
object obj = ResourceManager.GetObject("monaco", resourceCulture);
return ((byte[])(obj));
}
}
///
/// Looks up a localized resource of type System.Drawing.Bitmap.
///
public static System.Drawing.Bitmap Paypal {
get {
object obj = ResourceManager.GetObject("Paypal", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
}
}
================================================
FILE: RainbowTaskbar/Properties/Resources.resx
================================================
text/microsoft-resx
2.0
System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
..\Resources\Paypal.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a
..\Resources\monaco.zip;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
================================================
FILE: RainbowTaskbar/Properties/Settings.Designer.cs
================================================
//------------------------------------------------------------------------------
//
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
//------------------------------------------------------------------------------
namespace RainbowTaskbar.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.14.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
}
}
================================================
FILE: RainbowTaskbar/Properties/Settings.settings
================================================
================================================
FILE: RainbowTaskbar/Properties/launchSettings.json
================================================
{
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"RainbowTaskbar": {
"commandName": "Project",
"hotReloadEnabled": false
}
}
}
================================================
FILE: RainbowTaskbar/RainbowTaskbar.csproj
================================================
WinExe
net8.0-windows10.0.19041.0
net8.0-windows7.0
true
3.2.2
https://ad2017.dev/rnb
RainbowTaskbar is a Windows utility to customize the shell taskbar.
ad2017gd, zCri
icon.ico
https://github.com/ad2017gd/RainbowTaskbar
GitHub
en
true
latest
disable
prompt
3.2.2
3.2.2
False
None
AnyCPU;x64;x86;ARM64
true
RainbowTaskbar
RainbowTaskbar.App
Debug;Release;Release (MSIX)
$(DefineConstants);MSIX_BUILD
False
False
False
False
Never
True
Never
Never
Never
Never
all
runtime
compile; build; native; contentfiles; analyzers; buildtransitive
Never
Never
Never
Code
Code
Code
Code
Code
Code
True
True
Resources.resx
True
True
Settings.settings
PublicResXFileCodeGenerator
Resources.Designer.cs
SettingsSingleFileGenerator
Settings.Designer.cs
Designer
================================================
FILE: RainbowTaskbar/Taskbar.xaml
================================================
================================================
FILE: RainbowTaskbar/Taskbar.xaml.cs
================================================
using Microsoft.Web.WebView2.Core;
using Microsoft.Web.WebView2.WinForms;
using Microsoft.Web.WebView2.Wpf;
using RainbowTaskbar.Configuration;
using RainbowTaskbar.Configuration.Instruction;
using RainbowTaskbar.Configuration.Instruction.Instructions;
using RainbowTaskbar.Drawing;
using RainbowTaskbar.Helpers;
using RainbowTaskbar.HTTPAPI;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Media3D;
using Wpf.Ui.Controls;
using static RainbowTaskbar.Taskbar;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using WebView2 = Microsoft.Web.WebView2.Wpf.WebView2;
namespace RainbowTaskbar;
///
/// Interaction logic for Taskbar.xaml
///
public partial class Taskbar : System.Windows.Window {
public CanvasManager canvasManager;
public bool secondary;
public TaskbarHelper taskbarHelper;
public TaskbarViewModel viewModel;
public WindowHelper windowHelper;
public Mutex webViewReady_ = new Mutex();
public Mutex webViewReady { get => App.Settings.GraphicsRepeat ? webViewReady_ : App.webViewReady; }
public WebView2 webView { get => App.Settings.GraphicsRepeat ? webView_ : App.webView; }
public int UnderlayOffset { get => taskbarHelper.YOffset; set => taskbarHelper.YOffset = value; }
public Taskbar(IntPtr HWND, bool secondary) {
webViewReady_.WaitOne();
InitializeComponent();
this.secondary = secondary;
viewModel = new TaskbarViewModel(this, HWND);
Closing += viewModel.OnWindowClosing;
DataContext = viewModel;
if(HWND != IntPtr.Zero && !App.Settings.GraphicsRepeat) {
//webView_.Dispose();
webView_ = null;
}
}
public Taskbar(IntPtr HWND) : this(HWND, false) { }
#region Ugly win32 message handler
public IntPtr hwndInsertAfter = IntPtr.Zero;
public struct WINDOWPOS {
public IntPtr hwnd;
public IntPtr hwndInsertAfter;
public int x;
public int y;
public int cx;
public int cy;
public uint flags;
}
public const int WM_WINDOWPOSCHANGING = 0x46;
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) {
if (msg == WM_WINDOWPOSCHANGING) {
WINDOWPOS wp = (WINDOWPOS) System.Runtime.InteropServices.Marshal.PtrToStructure(lParam, typeof(WINDOWPOS));
if (GetWindow(wp.hwndInsertAfter, 3) != hwndInsertAfter) {
//taskbarHelper.PlaceWindowUnder(this);
taskbarHelper.SetBlur();
hwndInsertAfter = taskbarHelper.HWND;
}
}
if (msg == WM_Shell) {
var wnd = lParam;
var clname = new StringBuilder(256);
GetClassName(wnd, clname, clname.Capacity);
// fix: used to hide underlay when peeking window on taskbar
var dontcare = clname.ToString() == "XamlExplorerHostIslandWindow" || clname.ToString() == "Shell_InputSwitchTopLevelWindow";
if ((uint) wParam == 53 && !dontcare)
App.IsAppFullscreen = true;
if ((uint) wParam == 54 && !dontcare)
App.IsAppFullscreen = false;
}
return IntPtr.Zero;
}
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern uint RegisterWindowMessage(string lpString);
[DllImport("user32.dll", SetLastError = true)]
static extern bool RegisterShellHookWindow(IntPtr window);
private uint WM_Shell = 0;
protected override void OnSourceInitialized(EventArgs e) {
base.OnSourceInitialized(e);
var hWnd = new WindowInteropHelper(this).EnsureHandle();
HwndSource source = (HwndSource) HwndSource.FromHwnd(hWnd);
if (!secondary) {
RegisterShellHookWindow(new WindowInteropHelper(this).EnsureHandle());
WM_Shell = RegisterWindowMessage("SHELLHOOK");
}
source.AddHook(WndProc);
}
#endregion
private void RainbowTaskbar_Closed(object sender, EventArgs e) {
taskbarHelper.Style = TaskbarHelper.TaskbarStyle.ForceDefault;
taskbarHelper.SetBlur();
}
public static void SetupLayers() {
App.Current.Dispatcher.Invoke(() => {
if (App.Settings.GraphicsRepeat) {
App.taskbars.ForEach(t => {
t.canvasManager.layers = new LayerManager(t);
});
}
else {
App.layers = new LayerManager();
App.layers.width = (int) App.taskbars.Sum(t => t.Width);
App.layers.height = (int) App.taskbars[0].Height;
}
});
}
private static void SetupWebView(WebView2 webView, Mutex mutex = null) {
var envasync = CoreWebView2Environment.CreateAsync(null, Path.GetTempPath(), new CoreWebView2EnvironmentOptions());
Task.Run(() => {
var env = envasync.Result;
App.Current.Dispatcher.Invoke(() => {
Task t = null;
// THIS IS MAD
try {
t = webView.EnsureCoreWebView2Async(env);
}
catch {
try {
t = webView.EnsureCoreWebView2Async();
} catch {
return;
}
}
Task.Run(() => {
try { t.Wait(); } catch { return; }
webView.Dispatcher.Invoke(() => {
if(mutex is not null) mutex.ReleaseMutex();
webView.CoreWebView2.Settings.AreBrowserAcceleratorKeysEnabled = false;
webView.CoreWebView2.Settings.AreDefaultContextMenusEnabled = false;
webView.CoreWebView2.Settings.IsSwipeNavigationEnabled = false;
webView.CoreWebView2.Settings.IsStatusBarEnabled = false;
webView.CoreWebView2.Settings.IsPinchZoomEnabled = false;
webView.CoreWebView2.Settings.AreDevToolsEnabled = false;
webView.CoreWebView2.Settings.UserAgent = "RainbowTaskbar Web Display https://ad2017.dev/rnb";
webView.CoreWebView2.IsMuted = true;
webView.CoreWebView2.MemoryUsageTargetLevel = Microsoft.Web.WebView2.Core.CoreWebView2MemoryUsageTargetLevel.Low;
webView.CoreWebView2.ProcessFailed += (_, _) => {
App.ReloadTaskbars();
};
});
});
});
});
}
[Serializable]
public class RectangleF {
public float X { get; set; }
public float Y { get; set; }
public float Width { get; set; }
public float Height { get; set; }
public RectangleF(System.Drawing.Rectangle rectangle) {
X = rectangle.X;
Y = rectangle.Y;
Width = rectangle.Width;
Height = rectangle.Height;
}
public RectangleF(System.Drawing.RectangleF rectangle) {
X = rectangle.X;
Y = rectangle.Y;
Width = rectangle.Width;
Height = rectangle.Height;
}
public RectangleF(RectangleF rectangle) {
X = rectangle.X;
Y = rectangle.Y;
Width = rectangle.Width;
Height = rectangle.Height;
}
public static RectangleF operator*(RectangleF left, float right) {
var nw = new RectangleF(left);
nw.X *= right;
nw.Y *= right;
nw.Width *= right;
nw.Height *= right;
return nw;
}
}
[Serializable]
public class UIData {
[JsonPropertyName("systemTrayFrame")]
public RectangleF SystemTrayFrame { get; set; }
[JsonPropertyName("taskbarFrameRepeater")]
public RectangleF TaskbarFrameRepeater { get; set; }
[JsonPropertyName("taskbar")]
public RectangleF Taskbar { get; set; }
[JsonPropertyName("taskbarIndex")]
public int Index { get; set; }
public UIData(string rawUIData, Taskbar t) {
var form = JsonSerializer.Deserialize(rawUIData);
SystemTrayFrame = new(form.SystemTrayFrame);
var off = ExplorerTAP.ExplorerTAP.GetYPosition(t);
SystemTrayFrame.Y -= off;
TaskbarFrameRepeater = new(form.TaskbarFrameRepeater);
TaskbarFrameRepeater.Y -= off;
SystemTrayFrame *= (t.windowHelper.scale);
TaskbarFrameRepeater *= (t.windowHelper.scale);
Taskbar = new(t.taskbarHelper.GetRectangle());
SystemTrayFrame.Height = Taskbar.Height;
Index = App.taskbars.IndexOf(t);
}
}
public class CS2WVMessage {
[JsonPropertyName("message")]
public string Message { get; set; } = "";
[JsonPropertyName("data")]
public T Data { get; set; }
public CS2WVMessage(string message, T data) {
Message = message;
Data = data;
}
}
public List UIDataForAllTaskbars() {
try {
return App.taskbars.Select(x => new UIData(x.windowHelper.LastUIData, x)).ToList();
} catch { return new List(); }
}
EventHandler uiChangedHandler = null;
public void SetupWebViewMessageReceiver() {
uiChangedHandler = (_, args) => {
if (webView.CoreWebView2 is null) return;
webView.CoreWebView2.PostWebMessageAsString(JsonSerializer.Serialize(new CS2WVMessage>("ui",UIDataForAllTaskbars())));
};
windowHelper.TaskbarUIChanged += uiChangedHandler;
webView.WebMessageReceived += (_, args) => {
var message = JsonSerializer.Deserialize(args.WebMessageAsJson);
switch (message["m"]?.GetValue()) {
case "style": {
var taskbars = new List(App.Settings.GraphicsRepeat ? new List() { this } : App.taskbars);
taskbars.ForEach(x => {
new TransparencyInstruction() {
Type = TransparencyInstruction.TransparencyInstructionType.Style,
Style = (TransparencyInstruction.TransparencyInstructionStyle) (message["style"]?.GetValue() ?? (int) TransparencyInstruction.TransparencyInstructionStyle.Default)
}.Execute(x);
});
break;
}
case "transparency": {
var taskbars = new List(App.Settings.GraphicsRepeat ? new List() { this } : App.taskbars);
taskbars.ForEach(x => {
new TransparencyInstruction() {
Type = (TransparencyInstruction.TransparencyInstructionType) (message["which"]?.GetValue() ?? (int) TransparencyInstruction.TransparencyInstructionType.RainbowTaskbar),
Layer = message["layer"]?.GetValue() ?? 0,
Opacity = message["v"]?.GetValue() ?? 1
}.Execute(x);
});
break;
}
case "offset": {
var taskbars = new List(App.Settings.GraphicsRepeat ? new List() { this } : App.taskbars);
taskbars.ForEach(x => {
var old = UnderlayOffset;
UnderlayOffset = Math.Max(Math.Min(message["v"]?.GetValue() ?? 0, 96), -96);
int nwh = App.layers is not null ? (App.layers.height - UnderlayOffset) : ((canvasManager.layers?.height ?? 48) - UnderlayOffset);
x.Height = nwh;
});
break;
}
case "ui": {
webView.CoreWebView2.PostWebMessageAsString(JsonSerializer.Serialize(new CS2WVMessage>("ui", UIDataForAllTaskbars())));
break;
}
case "audio":
// request audio stream
// todo
break;
}
};
}
public static void SetupWebViews() {
App.Current.Dispatcher.Invoke(() => {
if (App.Settings.GraphicsRepeat) {
App.taskbars.ForEach((t) => {
SetupWebView(t.webView, t.webViewReady_);
t.SetupWebViewMessageReceiver();
});
}
else {
if (App.hiddenWebViewHost is null) App.hiddenWebViewHost = new();
App.hiddenWebViewHost.Show();
SetupWebView(App.hiddenWebViewHost.webView_, App.webViewReady);
App.taskbars.ForEach((t) => {
t.SetupWebViewMessageReceiver();
Task.Run(() => {
App.webViewReady.WaitOne();
App.webViewReady.ReleaseMutex();
App.Current.Dispatcher.Invoke(() => {
App.hiddenWebViewHost.Background = Brushes.Transparent;
var taskbars = App.taskbars;
App.hiddenWebViewHost.MinWidth = App.taskbars.Sum(t2 => t2.Width);
App.hiddenWebViewHost.MinHeight = App.taskbars.Max(t2 => t2.Height);
App.hiddenWebViewHost.Top = 19999;
App.hiddenWebViewHost.Left = 19999;
t.windowHelper.Duplicate(new WindowInteropHelper(App.hiddenWebViewHost).EnsureHandle());
});
});
});
}
});
}
public static void SoftReset(bool startConfig = true, Config cfg = null) {
if (cfg is null) cfg = App.Settings.SelectedConfig;
if (cfg is InstructionConfig) {
var config = cfg as InstructionConfig;
// insane coding
;
(new List(config.Data.RunOnceGroup.Instructions)).Concat(config.Data.LoopGroups.Select(x => x.Instructions).SelectMany(x => x)).ToList().ForEach((i) => {
if (i is ImageInstruction) {
((ImageInstruction) i).drawn = false;
}
if (i is ShapeInstruction) {
((ShapeInstruction) i).drawn = false;
}
if (i is TextInstruction) {
((TextInstruction) i).drawn = false;
}
});
}
if(cfg is not null && startConfig) cfg.Start();
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) {
windowHelper.TaskbarUIChanged -= uiChangedHandler;
}
}
================================================
FILE: RainbowTaskbar/TaskbarViewModel.cs
================================================
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interop;
using System.Windows.Media;
using RainbowTaskbar.Drawing;
using RainbowTaskbar.Helpers;
using RainbowTaskbar.HTTPAPI;
namespace RainbowTaskbar;
public class TaskbarViewModel {
//public readonly CancellationTokenSource cts;
private readonly Taskbar Window;
//public Thread drawThread;
//public Thread zThread;
public TaskbarViewModel(Taskbar window, IntPtr HWND) {
Window = window;
window.Background = new SolidColorBrush(Color.FromArgb(0, 0, 0, 0));
window.taskbarHelper =
new TaskbarHelper(
HWND,
window.secondary);
window.windowHelper = new WindowHelper(window, window.taskbarHelper);
window.taskbarHelper.window = window;
window.taskbarHelper.PositionChangedHook();
window.taskbarHelper.UpdateRadius();
IntPtr thisHwnd = new WindowInteropHelper(window).Handle;
TaskbarHelper.SetWindowLong(thisHwnd, TaskbarHelper.GWL_EXSTYLE, (uint) (TaskbarHelper.GetWindowLong(thisHwnd, TaskbarHelper.GWL_EXSTYLE).ToInt32() | 0x00000080L) /*WS_EX_TOOLWINDOW*/);
var Taskbar = window.taskbarHelper.GetRectangle(true);
//window.Left = 0;
//window.Top = 0;
double scale = window.taskbarHelper.GetScalingFactor();
window.MinWidth = Taskbar.Width * (1/ scale);
window.Width = Taskbar.Width * (1 / scale);
window.MinHeight = Taskbar.Height * (1 / scale);
window.Height = Taskbar.Height * (1 / scale);
window.TaskbarClip.RadiusX = window.TaskbarClip.RadiusY = 0;
window.TaskbarClip.Rect = new(0, 0, window.Width, window.Height);
window.TaskbarClipHide.RadiusX = window.TaskbarClipHide.RadiusY = 0;
window.TaskbarClipHide.Rect = new(0, 0, 0, 0);
if (HWND == IntPtr.Zero) return;
window.canvasManager = new CanvasManager(window, new Canvas[] {
window.Layer0, window.Layer1, window.Layer2, window.Layer3, window.Layer4, window.Layer5,
window.Layer6, window.Layer7, window.Layer8, window.Layer9, window.Layer10, window.Layer11,
window.Layer12, window.Layer13, window.Layer14, window.Layer15
});
foreach (var cvs in window.canvasManager.canvases) {
cvs.Background = new SolidColorBrush(Color.FromArgb(0, 0, 0, 0));
}
//cts = new CancellationTokenSource();
//StartZThread(window);
}
/*
public void StartZThread(Taskbar window) {
var token = cts.Token;
zThread = new Thread(() => {
while (!token.IsCancellationRequested) {
TaskbarHelper taskbar = null;
window.Dispatcher.Invoke(() => { taskbar = window.taskbarHelper; });
taskbar.SetWindowZUnder(window);
taskbar.SetBlur();
token.WaitHandle.WaitOne(100);
}
})
{IsBackground = true};
zThread.Start();
}
*/
public void OnWindowClosing(object sender, CancelEventArgs e) {
Window.taskbarHelper.PositionChangedUnhook();
Window.windowHelper.alive = false;
//cts.Cancel();
//cts.Dispose();
}
}
================================================
FILE: RainbowTaskbar/TrayWindow.xaml
================================================
================================================
FILE: RainbowTaskbar/TrayWindow.xaml.cs
================================================
using RainbowTaskbar.Configuration;
using RainbowTaskbar.Helpers;
//using RainbowTaskbar.UserControls;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using static RainbowTaskbar.Taskbar;
namespace RainbowTaskbar {
///
/// Interaction logic for TrayWindow.xaml
///
public partial class TrayWindow : Window {
public TrayWindow() {
InitializeComponent();
TrayIcon.TrayMouseDoubleClick += TrayIcon_TrayMouseDoubleClick;
TrayIcon.ToolTipText = $"RainbowTaskbar {Assembly.GetExecutingAssembly().GetName().Version?.ToString()}";
TrayIcon.ContextMenu = this.ContextMenu;
App.localization.Enable(TrayIcon.ContextMenu.Resources.MergedDictionaries);
App.trayWindow = this;
}
private void TrayIcon_TrayMouseDoubleClick(object sender, RoutedEventArgs e) {
App.LaunchEditor();
}
private void Open_Click(object sender, RoutedEventArgs e) {
e.Handled = true;
App.LaunchEditor();
}
private void Exit_Click(object sender, RoutedEventArgs e) {
e.Handled = true;
App.Exit();
}
private void Issue_Click(object sender, RoutedEventArgs e) {
e.Handled = true;
Process.Start(new ProcessStartInfo("https://github.com/ad2017gd/RainbowTaskbar/issues/new/choose") { UseShellExecute = true });
}
private void ProjectPage_Click(object sender, RoutedEventArgs e) {
e.Handled = true;
Process.Start(new ProcessStartInfo("https://ad2017.dev/rnb") { UseShellExecute = true });
}
}
}
================================================
FILE: RainbowTaskbar/V2Legacy/Configuration/Config.cs
================================================
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Dynamic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Text.RegularExpressions;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media.Animation;
using System.Xml;
using PropertyChanged;
using RainbowTaskbar.HTTPAPI;
using System.Diagnostics;
using RainbowTaskbar.V2Legacy.Configuration.Instructions;
namespace RainbowTaskbar.V2Legacy.Configuration;
[DataContract]
public class Config : INotifyPropertyChanged {
public Config() {
}
[field: DataMember] public int ConfigFileVersion { get; set; } = 0;
[field: DataMember] public bool CheckUpdate { get; set; } = true;
[field: DataMember] public long MagicCookie { get; set; } = 0;
[field: DataMember]
public BindingList Instructions { get; set; } = new BindingList();
[field: DataMember]
public BindingList Presets { get; set; } = new BindingList();
[field: DataMember]
public bool IsAPIEnabled { get; set; } = false;
[field: DataMember]
public int APIPort { get; set; } = 9093;
[field: DataMember]
public int InterpolationQuality { get; set; } = 25;
[field: DataMember]
public bool GraphicsRepeat { get; set; } = true;
[field: DataMember]
public bool SameRadiusOnEach { get; set; } = false;
[field: DataMember]
public string Language { get; set; } = "SystemDefault";
[field: DataMember]
public bool FirstStart { get; set; } = true;
public event PropertyChangedEventHandler PropertyChanged;
}
================================================
FILE: RainbowTaskbar/V2Legacy/Configuration/Instruction.cs
================================================
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.Text.RegularExpressions;
using System.Threading;
using FastMember;
namespace RainbowTaskbar.V2Legacy.Configuration;
[DataContract]
[KnownType("GetKnownInstructionTypes")]
public abstract class Instruction : INotifyPropertyChanged {
public static IEnumerable InstructionTypes { get; set; } = GetKnownInstructionTypes();
public abstract string Description { get; }
public event PropertyChangedEventHandler PropertyChanged;
public static IEnumerable GetKnownInstructionTypes() {
if (InstructionTypes == null)
InstructionTypes = Assembly.GetExecutingAssembly().GetTypes()
.Where(type => typeof(Instruction).IsAssignableFrom(type)).ToList();
return InstructionTypes;
}
public bool Execute(Taskbar window) => Execute(window, CancellationToken.None);
public abstract bool Execute(Taskbar window, CancellationToken token);
}
================================================
FILE: RainbowTaskbar/V2Legacy/Configuration/InstructionPreset.cs
================================================
using System.ComponentModel;
using System.Runtime.Serialization;
namespace RainbowTaskbar.V2Legacy.Configuration;
[DataContract]
public class InstructionPreset {
[field: DataMember] public string Name { get; set; }
[field: DataMember] public BindingList Instructions { get; set; }
}
================================================
FILE: RainbowTaskbar/V2Legacy/Configuration/Instructions/BorderRadiusInstruction.cs
================================================
using System.Dynamic;
using System.Runtime.Serialization;
using System.Threading;
namespace RainbowTaskbar.V2Legacy.Configuration.Instructions;
[DataContract]
internal class BorderRadiusInstruction : Instruction {
[field: DataMember] public int Radius { get; set; } = 0;
public override string Description {
get {
return null;
}
}
public override bool Execute(Taskbar window, CancellationToken _) {
return false;
}
}
================================================
FILE: RainbowTaskbar/V2Legacy/Configuration/Instructions/ClearLayerInstruction.cs
================================================
using System.Dynamic;
using System.Linq;
using System.Runtime.Serialization;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
namespace RainbowTaskbar.V2Legacy.Configuration.Instructions;
[DataContract]
internal class ClearLayerInstruction : Instruction {
[field: DataMember] public int Layer { get; set; } = 0;
public override string Description {
get {
return null;
}
}
public override bool Execute(Taskbar window, CancellationToken token) {
return false;
}
}
================================================
FILE: RainbowTaskbar/V2Legacy/Configuration/Instructions/ColorInstruction.cs
================================================
using System.Drawing;
using System.Dynamic;
using System.Runtime.Serialization;
using System.Threading;
using System.Windows.Media;
using RainbowTaskbar.Interpolation;
using Color = System.Drawing.Color;
using Brush = System.Windows.Media.Brush;
using RainbowTaskbar.Languages;
using RainbowTaskbar.V2Legacy.Configuration;
namespace RainbowTaskbar.V2Legacy.Configuration.Instructions;
[DataContract]
internal class ColorInstruction : Instruction {
public override string Description {
get {
return "";
}
}
public enum ColorInstructionEffect {
Solid,
Fade,
Gradient,
FadeGradient
}
public enum ColorInstructionTransition {
Linear,
Sine,
Cubic,
Exponential,
Back
}
[field: DataMember] public int Time { get; set; } = 1;
[field: DataMember] public Color Color1 { get; set; } = Color.FromArgb(0, 0, 0);
[field: DataMember] public ColorInstructionEffect Effect { get; set; }
[field: DataMember] public Color Color2 { get; set; } = Color.FromArgb(0, 0, 0);
[field: DataMember] public int Time2 { get; set; } = 1;
[field: DataMember] public ColorInstructionTransition Transition { get; set; }
[field: DataMember] public double Angle { get; set; } = 0;
[field: DataMember] public int Layer { get; set; } = 0;
[field: DataMember] public bool Randomize { get; set; } = false;
public bool Has2Colors { get => Effect == ColorInstructionEffect.FadeGradient || Effect == ColorInstructionEffect.Gradient; }
public override bool Execute(Taskbar window, CancellationToken token) {
return true;
}
}
================================================
FILE: RainbowTaskbar/V2Legacy/Configuration/Instructions/DelayInstruction.cs
================================================
using System.Dynamic;
using System.Runtime.Serialization;
using System.Threading;
namespace RainbowTaskbar.V2Legacy.Configuration.Instructions;
[DataContract]
internal class DelayInstruction : Instruction {
[field: DataMember] public int Time { get; set; } = 1;
public override string Description {
get {
return "";
}
}
public override bool Execute(Taskbar window, CancellationToken token) {
return true;
}
}
================================================
FILE: RainbowTaskbar/V2Legacy/Configuration/Instructions/ImageInstruction.cs
================================================
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Dynamic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace RainbowTaskbar.V2Legacy.Configuration.Instructions;
[DataContract]
internal class ImageInstruction : Instruction {
[field: DataMember] public int Layer { get; set; } = 0;
[field: DataMember] public string Path { get; set; } = "";
[field: DataMember] public int X { get; set; } = 0;
[field: DataMember] public int Y { get; set; } = 0;
[field: DataMember] public int Width { get; set; } = 0;
[field: DataMember] public int Height { get; set; } = 0;
[field: DataMember] public double Opacity { get; set; } = 1;
[field: DataMember] public bool DrawOnce { get; set; } = false;
public override string Description {
get {
return "";
}
}
public override bool Execute(Taskbar window, CancellationToken token) {
return false;
}
}
================================================
FILE: RainbowTaskbar/V2Legacy/Configuration/Instructions/ShapeInstruction.cs
================================================
using System;
using System.Dynamic;
using System.Globalization;
using System.Linq;
using System.Runtime.Serialization;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows.Shapes;
using RainbowTaskbar.Interpolation;
using RainbowTaskbar.Languages;
namespace RainbowTaskbar.V2Legacy.Configuration.Instructions;
[DataContract]
public class ShapeInstruction : Instruction {
[field: DataMember]
public int Layer { get; set; } = 0;
[field: DataMember]
public ShapeInstructionShapes Shape { get; set; } = ShapeInstructionShapes.Line;
[field: DataMember] public int X { get; set; } = 0;
[field: DataMember] public int Y { get; set; } = 0;
[field: DataMember] public int X2 { get; set; } = 0;
[field: DataMember] public int Y2 { get; set; } = 0;
[field: DataMember] public bool DrawOnce { get; set; } = false;
[field: DataMember]
public System.Drawing.Color Fill { get; set; } = System.Drawing.Color.FromArgb(255, 0, 0, 0);
[field: DataMember]
public System.Drawing.Color Line { get; set; } = System.Drawing.Color.FromArgb(255, 0, 0, 0);
[field: DataMember]
public int LineSize { get; set; } = 1;
[field: DataMember]
public int Radius { get; set; } = 0;
[field: DataMember]
public bool FitTaskbars { get; set; } = false;
public override string Description {
get {
return "";
}
}
public override bool Execute(Taskbar window, CancellationToken token) {
return false;
}
public enum ShapeInstructionShapes {
Line,
Rectangle,
Ellipse
}
}
================================================
FILE: RainbowTaskbar/V2Legacy/Configuration/Instructions/TextInstruction.cs
================================================
using System.Dynamic;
using System.Runtime.Serialization;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using RainbowTaskbar.Interpolation;
using Color = System.Drawing.Color;
namespace RainbowTaskbar.V2Legacy.Configuration.Instructions;
[DataContract]
internal class TextInstruction : Instruction {
[field: DataMember] public int Layer { get; set; } = 1;
[field: DataMember] public string Text { get; set; } = "";
[field: DataMember] public int X { get; set; } = 0;
[field: DataMember] public int Y { get; set; } = 0;
[field: DataMember] public string Font { get; set; } = "Arial";
[field: DataMember] public int Size { get; set; } = 32;
[field: DataMember] public bool DrawOnce { get; set; } = false;
[field: DataMember] public Color Color { get; set; } = Color.Black;
[field: DataMember] public bool Center { get; set; } = false;
public override string Description {
get {
return "";
}
}
public override bool Execute(Taskbar window, CancellationToken token) {
return false;
}
}
================================================
FILE: RainbowTaskbar/V2Legacy/Configuration/Instructions/TransparencyInstruction.cs
================================================
using System;
using System.Dynamic;
using System.Runtime.Serialization;
using System.Threading;
using System.Windows.Controls;
using RainbowTaskbar.Helpers;
using RainbowTaskbar.Languages;
namespace RainbowTaskbar.V2Legacy.Configuration.Instructions;
[DataContract]
public class TransparencyInstruction : Instruction {
public enum TransparencyInstructionStyle {
Default,
Blur,
Transparent
}
public enum TransparencyInstructionType {
Taskbar,
RainbowTaskbar,
All,
Style,
Layer
}
[field: DataMember] public TransparencyInstructionType Type { get; set; }
[field: DataMember] public double Opacity { get; set; } = 1;
[field: DataMember] public TransparencyInstructionStyle Style { get; set; }
[field: DataMember] public int Layer { get; set; }
public override string Description {
get {
return "";
}
}
public override bool Execute(Taskbar window, CancellationToken token) {
return false;
}
}
================================================
FILE: RainbowTaskbar/msix.build.props
================================================
true
$(DefineConstants);MSIX_BUILD
================================================
FILE: RainbowTaskbar.sln
================================================
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.1.32407.343
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RainbowTaskbar", "RainbowTaskbar\RainbowTaskbar.csproj", "{03366AEB-0D3C-453B-BB5F-50DFB417D325}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RainbowTaskbarDLL", "RainbowTaskbarDLL\RainbowTaskbarDLL.vcxproj", "{3FF5D07D-44D1-4B85-9465-4793B3A9EE8A}"
EndProject
Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "MSIXPkg2", "MSIXPkg2\MSIXPkg2.wapproj", "{EEAF81A9-BB63-40D9-A733-7F25D2313DF5}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM64 = Debug|ARM64
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release (MSIX)|ARM64 = Release (MSIX)|ARM64
Release (MSIX)|x64 = Release (MSIX)|x64
Release (MSIX)|x86 = Release (MSIX)|x86
Release|ARM64 = Release|ARM64
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{03366AEB-0D3C-453B-BB5F-50DFB417D325}.Debug|ARM64.ActiveCfg = Debug|ARM64
{03366AEB-0D3C-453B-BB5F-50DFB417D325}.Debug|ARM64.Build.0 = Debug|ARM64
{03366AEB-0D3C-453B-BB5F-50DFB417D325}.Debug|x64.ActiveCfg = Debug|x64
{03366AEB-0D3C-453B-BB5F-50DFB417D325}.Debug|x64.Build.0 = Debug|x64
{03366AEB-0D3C-453B-BB5F-50DFB417D325}.Debug|x86.ActiveCfg = Debug|x86
{03366AEB-0D3C-453B-BB5F-50DFB417D325}.Debug|x86.Build.0 = Debug|x86
{03366AEB-0D3C-453B-BB5F-50DFB417D325}.Release (MSIX)|ARM64.ActiveCfg = Release (MSIX)|ARM64
{03366AEB-0D3C-453B-BB5F-50DFB417D325}.Release (MSIX)|ARM64.Build.0 = Release (MSIX)|ARM64
{03366AEB-0D3C-453B-BB5F-50DFB417D325}.Release (MSIX)|x64.ActiveCfg = Release (MSIX)|x64
{03366AEB-0D3C-453B-BB5F-50DFB417D325}.Release (MSIX)|x64.Build.0 = Release (MSIX)|x64
{03366AEB-0D3C-453B-BB5F-50DFB417D325}.Release (MSIX)|x86.ActiveCfg = Release (MSIX)|x86
{03366AEB-0D3C-453B-BB5F-50DFB417D325}.Release (MSIX)|x86.Build.0 = Release (MSIX)|x86
{03366AEB-0D3C-453B-BB5F-50DFB417D325}.Release|ARM64.ActiveCfg = Release|ARM64
{03366AEB-0D3C-453B-BB5F-50DFB417D325}.Release|ARM64.Build.0 = Release|ARM64
{03366AEB-0D3C-453B-BB5F-50DFB417D325}.Release|x64.ActiveCfg = Release|x64
{03366AEB-0D3C-453B-BB5F-50DFB417D325}.Release|x64.Build.0 = Release|x64
{03366AEB-0D3C-453B-BB5F-50DFB417D325}.Release|x86.ActiveCfg = Release|x86
{03366AEB-0D3C-453B-BB5F-50DFB417D325}.Release|x86.Build.0 = Release|x86
{3FF5D07D-44D1-4B85-9465-4793B3A9EE8A}.Debug|ARM64.ActiveCfg = Debug|ARM64
{3FF5D07D-44D1-4B85-9465-4793B3A9EE8A}.Debug|ARM64.Build.0 = Debug|ARM64
{3FF5D07D-44D1-4B85-9465-4793B3A9EE8A}.Debug|x64.ActiveCfg = Debug|x64
{3FF5D07D-44D1-4B85-9465-4793B3A9EE8A}.Debug|x64.Build.0 = Debug|x64
{3FF5D07D-44D1-4B85-9465-4793B3A9EE8A}.Debug|x86.ActiveCfg = Debug|Win32
{3FF5D07D-44D1-4B85-9465-4793B3A9EE8A}.Debug|x86.Build.0 = Debug|Win32
{3FF5D07D-44D1-4B85-9465-4793B3A9EE8A}.Release (MSIX)|ARM64.ActiveCfg = Release|ARM64
{3FF5D07D-44D1-4B85-9465-4793B3A9EE8A}.Release (MSIX)|ARM64.Build.0 = Release|ARM64
{3FF5D07D-44D1-4B85-9465-4793B3A9EE8A}.Release (MSIX)|x64.ActiveCfg = Release|x64
{3FF5D07D-44D1-4B85-9465-4793B3A9EE8A}.Release (MSIX)|x64.Build.0 = Release|x64
{3FF5D07D-44D1-4B85-9465-4793B3A9EE8A}.Release (MSIX)|x86.ActiveCfg = Release (MSIX)|Win32
{3FF5D07D-44D1-4B85-9465-4793B3A9EE8A}.Release (MSIX)|x86.Build.0 = Release (MSIX)|Win32
{3FF5D07D-44D1-4B85-9465-4793B3A9EE8A}.Release|ARM64.ActiveCfg = Release|ARM64
{3FF5D07D-44D1-4B85-9465-4793B3A9EE8A}.Release|ARM64.Build.0 = Release|ARM64
{3FF5D07D-44D1-4B85-9465-4793B3A9EE8A}.Release|x64.ActiveCfg = Release|x64
{3FF5D07D-44D1-4B85-9465-4793B3A9EE8A}.Release|x64.Build.0 = Release|x64
{3FF5D07D-44D1-4B85-9465-4793B3A9EE8A}.Release|x86.ActiveCfg = Release|Win32
{3FF5D07D-44D1-4B85-9465-4793B3A9EE8A}.Release|x86.Build.0 = Release|Win32
{EEAF81A9-BB63-40D9-A733-7F25D2313DF5}.Debug|ARM64.ActiveCfg = Debug|ARM64
{EEAF81A9-BB63-40D9-A733-7F25D2313DF5}.Debug|ARM64.Build.0 = Debug|ARM64
{EEAF81A9-BB63-40D9-A733-7F25D2313DF5}.Debug|ARM64.Deploy.0 = Debug|ARM64
{EEAF81A9-BB63-40D9-A733-7F25D2313DF5}.Debug|x64.ActiveCfg = Debug|x64
{EEAF81A9-BB63-40D9-A733-7F25D2313DF5}.Debug|x64.Build.0 = Debug|x64
{EEAF81A9-BB63-40D9-A733-7F25D2313DF5}.Debug|x64.Deploy.0 = Debug|x64
{EEAF81A9-BB63-40D9-A733-7F25D2313DF5}.Debug|x86.ActiveCfg = Debug|x86
{EEAF81A9-BB63-40D9-A733-7F25D2313DF5}.Debug|x86.Build.0 = Debug|x86
{EEAF81A9-BB63-40D9-A733-7F25D2313DF5}.Debug|x86.Deploy.0 = Debug|x86
{EEAF81A9-BB63-40D9-A733-7F25D2313DF5}.Release (MSIX)|ARM64.ActiveCfg = Release (MSIX)|ARM64
{EEAF81A9-BB63-40D9-A733-7F25D2313DF5}.Release (MSIX)|ARM64.Build.0 = Release (MSIX)|ARM64
{EEAF81A9-BB63-40D9-A733-7F25D2313DF5}.Release (MSIX)|ARM64.Deploy.0 = Release (MSIX)|ARM64
{EEAF81A9-BB63-40D9-A733-7F25D2313DF5}.Release (MSIX)|x64.ActiveCfg = Release (MSIX)|x64
{EEAF81A9-BB63-40D9-A733-7F25D2313DF5}.Release (MSIX)|x64.Build.0 = Release (MSIX)|x64
{EEAF81A9-BB63-40D9-A733-7F25D2313DF5}.Release (MSIX)|x64.Deploy.0 = Release (MSIX)|x64
{EEAF81A9-BB63-40D9-A733-7F25D2313DF5}.Release (MSIX)|x86.ActiveCfg = Release (MSIX)|x86
{EEAF81A9-BB63-40D9-A733-7F25D2313DF5}.Release (MSIX)|x86.Build.0 = Release (MSIX)|x86
{EEAF81A9-BB63-40D9-A733-7F25D2313DF5}.Release (MSIX)|x86.Deploy.0 = Release (MSIX)|x86
{EEAF81A9-BB63-40D9-A733-7F25D2313DF5}.Release|ARM64.ActiveCfg = Release|ARM64
{EEAF81A9-BB63-40D9-A733-7F25D2313DF5}.Release|ARM64.Build.0 = Release|ARM64
{EEAF81A9-BB63-40D9-A733-7F25D2313DF5}.Release|ARM64.Deploy.0 = Release|ARM64
{EEAF81A9-BB63-40D9-A733-7F25D2313DF5}.Release|x64.ActiveCfg = Release (MSIX)|x64
{EEAF81A9-BB63-40D9-A733-7F25D2313DF5}.Release|x64.Build.0 = Release (MSIX)|x64
{EEAF81A9-BB63-40D9-A733-7F25D2313DF5}.Release|x64.Deploy.0 = Release (MSIX)|x64
{EEAF81A9-BB63-40D9-A733-7F25D2313DF5}.Release|x86.ActiveCfg = Release|x86
{EEAF81A9-BB63-40D9-A733-7F25D2313DF5}.Release|x86.Build.0 = Release|x86
{EEAF81A9-BB63-40D9-A733-7F25D2313DF5}.Release|x86.Deploy.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C4E67E8A-1256-45FB-8FC7-156FD12B1E62}
EndGlobalSection
EndGlobal
================================================
FILE: RainbowTaskbarDLL/AppearanceServiceAPI.cpp
================================================
#include "AppearanceServiceAPI.h"
#include "Taskbar.h"
#include "winrt.h"
#include
#include
#include
HRESULT STDMETHODCALLTYPE AppearanceServiceAPI::SetAppearanceType(UINT type) {_F
if (!active) return S_FALSE;
try {
_E auto watch = treeWatch.get();
_E for (auto& [handle, taskbar] : watch->taskbarMap) {
_E Taskbar& t = taskbar;//?
_E switch (type) {
_E case 0: // default
_E taskbar.dispatcher.RunAsync(winrt::Windows::UI::Core::CoreDispatcherPriority::High, [&]() {
_E t.rectangleBackground.Fill(t.originalBrush);
_E t.border.Opacity(1);
_E });
_E
_E break;
_E case 2: // transparent
_E taskbar.dispatcher.RunAsync(winrt::Windows::UI::Core::CoreDispatcherPriority::High, [&]() {
_E t.rectangleBackground.Fill(winrt::Windows::UI::Xaml::Media::SolidColorBrush(winrt::Windows::UI::Colors::Transparent()));
_E t.border.Opacity(0);
_E });
_E
_E break;
_E
_E case 1: // blurred (?)
_E taskbar.dispatcher.RunAsync(winrt::Windows::UI::Core::CoreDispatcherPriority::High, [&]() {
_E auto brush = winrt::Windows::UI::Xaml::Media::AcrylicBrush();
_E brush.TintColor(winrt::Windows::UI::Colors::Transparent());
_E brush.TintOpacity(0);
_E brush.TintLuminosityOpacity(0.0);
_E brush.BackgroundSource(winrt::Windows::UI::Xaml::Media::AcrylicBackgroundSource::Backdrop);
_E t.rectangleBackground.Fill(brush);
_E t.border.Opacity(1);
_E });
_E break;
_E }
_E }
}
catch (...) {
HRESULT res = winrt::to_hresult();
_com_error err(res);
WCHAR data[1024];
__EFMT(data, err.ErrorMessage());
return res;
}
return S_OK;
}
HRESULT STDMETHODCALLTYPE AppearanceServiceAPI::ChangeTaskbarElementsOpacity(UINT alpha) {_F
if (!active) return S_FALSE;
try {
_E auto watch = treeWatch.get();
_E for (auto& [handle, taskbar] : watch->taskbarMap) {
_E Taskbar& t = taskbar;//?
_E if (t.SystemTrayFrame && t.TaskbarFrameRepeater) {
_E t.SystemTrayFrame.Opacity(alpha / 255.0);
_E t.TaskbarFrameRepeater.Opacity(alpha / 255.0);
_E }
_E }
}
catch (...) {
HRESULT res = winrt::to_hresult();
_com_error err(res);
WCHAR data[1024];
__EFMT(data, err.ErrorMessage());
return res;
}
return S_OK;
}
HRESULT STDMETHODCALLTYPE AppearanceServiceAPI::Close() try { _F
_E SetAppearanceType(0);
_E ChangeTaskbarElementsOpacity(255);
_E return 0;
}
catch (...)
{
HRESULT res = winrt::to_hresult();
_com_error err(res);
WCHAR data[1024];
__EFMT(data, err.ErrorMessage());
return res;
}
HRESULT STDMETHODCALLTYPE AppearanceServiceAPI::Version() {
return 5;
}
//#include
//HRESULT STDMETHODCALLTYPE AppearanceServiceAPI::DebugGetUITree(BSTR* tree) try { _F
//_E auto watch = treeWatch.get();
//
//_E if (!watch->taskbarMap.begin()->first) return S_FALSE;
//_E std::wstring str = std::wstring();
// for (auto& taskbar : watch->taskbarMap) {
//_E auto frame = watch->ConvertFromH(taskbar.first);
//_E auto root = frame.Parent().as();
//_E auto children = watch->FindChildrenRecursive(std::nullopt, root, 0);
////_E std::sort(children.begin(), children.end(), [&](std::pair& a, std::pair& b) { return a.first < b.first; });
//_E for (auto& child : children) {
//_E auto iinsp = watch->ConvertFromH(watch->ConvertToH(child.second));
//_E winrt::hstring str3 = winrt::get_class_name(iinsp);
//_E auto add = std::wstring(child.first*2, ' ');
//_E auto pt = child.second.TransformToVisual(watch->root).TransformPoint(winrt::Windows::Foundation::Point(0, 0));
//_E auto felem = child.second.try_as< winrt::Windows::UI::Xaml::FrameworkElement>();
//_E str = str + add + std::wstring{ str3 } + L" " + (felem ? std::wstring{ felem.Name() } : L"NULL") + L" " + L" " + std::to_wstring(pt.X) + L" " + std::to_wstring(pt.Y) + L"\n";
//
//_E
// }
// str = str + L"\n\n\n";
// }
//_E BSTR bstr = SysAllocStringLen(str.data(), str.size());
//_E if (tree)
// *tree = bstr;
//
//} catch (...) {
// HRESULT res = winrt::to_hresult();
//
// _com_error err(res);
// WCHAR data[1024];
// __EFMT(data, err.ErrorMessage());
// return res;
//}
\
HRESULT STDMETHODCALLTYPE AppearanceServiceAPI::GetDataPtr(){
auto watch = treeWatch.get();
return (HRESULT)watch->data;
}
HRESULT AppearanceServiceAPI::Invoke(DISPID dispIdMember, // 0 or 1
REFIID riid, // null
LCID lcid, // null
WORD wFlags, // DISPATCH_METHOD
DISPPARAMS* pDispParams,
VARIANT* pVarResult,
EXCEPINFO* pExcepInfo,
unsigned int* puArgErr
) {
// this is such a shitty implementation but I DONT CARE!
switch (dispIdMember)
{
case 0:
if (pDispParams->cArgs == 1 && pDispParams->rgvarg[0].vt == VT_UI4)
{
UINT appearanceType = pDispParams->rgvarg[0].ulVal;
HRESULT hr = SetAppearanceType(appearanceType);
if (FAILED(hr))
return hr;
}
return S_OK;
case 1:
{
HRESULT hr = Close();
if (FAILED(hr))
return hr;
return S_OK;
}
case 2:
return Version();
case 3: {
return GetDataPtr();
case 4:
if (pDispParams->cArgs == 1 && pDispParams->rgvarg[0].vt == VT_UI4)
{
UINT opac = pDispParams->rgvarg[0].ulVal;
HRESULT hr = ChangeTaskbarElementsOpacity(opac);
if (FAILED(hr))
return hr;
}
return S_OK;
}
}
return DISP_E_MEMBERNOTFOUND;
}
HRESULT STDMETHODCALLTYPE AppearanceServiceAPI::GetTypeInfoCount(UINT* pctinfo)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE AppearanceServiceAPI::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE AppearanceServiceAPI::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId)
{
return E_NOTIMPL;
}
void AppearanceServiceAPI::Unload() {
CoRevokeClassObject(s_proxyCookie);
}
DWORD s_proxyCookie = 0;
DWORD s_activeObjectCookie = 0;
AppearanceServiceAPI::AppearanceServiceAPI(winrt::com_ptr watch) try {_F
treeWatch = watch;
watch->data = (struct RainbowTaskbarData*)malloc(sizeof(struct RainbowTaskbarData));
memset(watch->data, 0, sizeof(struct RainbowTaskbarData));
winrt::com_ptr stub;
const CLSID CLSID_PROXY = PROXY_CLSID_IS;
_E winrt::check_hresult(DllGetClassObject(CLSID_PROXY, winrt::guid_of(), (void**)stub.put()));
_E winrt::check_hresult(CoRegisterClassObject(CLSID_PROXY, stub.get(), CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &s_proxyCookie));
_E
_E winrt::check_hresult(RegisterActiveObject(static_cast(this), CLSID_AppearanceServiceAPI, ACTIVEOBJECT_STRONG, &s_activeObjectCookie));
}
catch (...)
{
HRESULT res = winrt::to_hresult();
_com_error err(res);
WCHAR data[1024];
__EFMT(data, err.ErrorMessage());
}
================================================
FILE: RainbowTaskbarDLL/AppearanceServiceAPI.h
================================================
#pragma once
#include "winrt.h"
#include "VisualTreeWatch.h"
#include
#include "RainbowTaskbarDLL_h.h"
#include "ErrorDebug.h"
extern DWORD s_proxyCookie;
extern DWORD s_activeObjectCookie;
class AppearanceServiceAPI : public winrt::implements
{
private:
size_t line = 0;
char* file = 0;
public:
winrt::com_ptr treeWatch;
bool active = true;
HRESULT STDMETHODCALLTYPE SetAppearanceType(UINT type);
HRESULT STDMETHODCALLTYPE ChangeTaskbarElementsOpacity(UINT alpha);
HRESULT STDMETHODCALLTYPE Close();
HRESULT STDMETHODCALLTYPE Version();
HRESULT STDMETHODCALLTYPE GetDataPtr();
HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS* pDispParams,
VARIANT* pVarResult,
EXCEPINFO* pExcepInfo,
unsigned int* puArgErr
) override;
// BORING!
HRESULT STDMETHODCALLTYPE GetTypeInfoCount(
UINT* pctinfo) override;
HRESULT STDMETHODCALLTYPE GetTypeInfo(
UINT iTInfo,
LCID lcid,
ITypeInfo** ppTInfo) override;
HRESULT STDMETHODCALLTYPE GetIDsOfNames(
REFIID riid,
LPOLESTR* rgszNames,
UINT cNames,
LCID lcid,
DISPID* rgDispId) override;
AppearanceServiceAPI(winrt::com_ptr watch);
static void Unload();
};
================================================
FILE: RainbowTaskbarDLL/ArmFix/RpcProxy.h
================================================
/*++
Copyright (c) Microsoft Corporation. All rights reserved.
Module Name:
rpcproxy.h
Abstract:
Definitions for rpc proxy stubs.
Compiler switches:
-DREGISTER_PROXY_DLL
Generates DllMain, DllRegisterServer, and DllUnregisterServer functions
for automatically registering a proxy DLL.
-DPROXY_CLSID=clsid
Specifies a class ID to be used by the proxy DLL.
-DPROXY_CLSID_IS={0x6f11fe5c,0x2fc5,0x101b,{0x9e,0x45,0x00,0x00,0x0b,0x65,0xc7,0xef}}
Specifies the value of the class ID to be used by the proxy DLL.
-DENTRY_PREFIX=
String to be prepended on all the DllGetClassObject etc routines
in dlldata.c. This includes: DllGetClassObject, DllCanUnloadNow
and DllMain, DllRegisterServer, and DllUnregisterServer.
-DNT35_STRICT
Specifies that the target platform is Windows NT 3.5. This switch disables
the new functions added after the Windows NT 3.5 release.
--*/
// This version of the rpcndr.h file corresponds to MIDL version 5.0.+
// used with NT5 beta1+ env from build #1700 on.
#ifndef __RPCPROXY_H_VERSION__
#define __RPCPROXY_H_VERSION__ ( 477 )
#endif // __RPCPROXY_H_VERSION__
#include
#if !defined(_KRPCENV_)
#ifndef __RPCPROXY_H__
#define __RPCPROXY_H__
#if _MSC_VER > 1000
#pragma once
#endif
#define __midl_proxy
#ifdef __REQUIRED_RPCPROXY_H_VERSION__
#if ( __RPCPROXY_H_VERSION__ < __REQUIRED_RPCPROXY_H_VERSION__ )
#error incorrect version. Use the header that matches with the MIDL compiler.
#endif
#endif
// If this is the first file included __RPC_WIN64__ is not defined yet.
#if defined(_M_IA64) || defined(_WIN64)
#include
#endif
#include
#ifndef INC_OLE2
#define INC_OLE2
#endif
#ifndef DECLSPEC_SELECTANY
#if (_MSC_VER >= 1200)
#define DECLSPEC_SELECTANY __declspec(selectany)
#else
#define DECLSPEC_SELECTANY
#endif
#endif
#ifndef DECLSPEC_NOINLINE
#if (_MSC_VER >= 1200)
#define DECLSPEC_NOINLINE __declspec(noinline)
#else
#define DECLSPEC_NOINLINE
#endif
#endif
#ifndef RPCPROXY_IID_DECLSPEC_SECTION
#if (_MSC_VER >= 1100)
#pragma section("rpcproxy$_iid", read)
#define RPCPROXY_IID_DECLSPEC_SECTION __declspec(allocate("rpcproxy$_iid"))
#else
#define RPCPROXY_IID_DECLSPEC_SECTION
#endif
#endif
#if defined(WIN32) || defined(_WIN64)
//We need to define REFIID, REFCLSID, REFGUID, & REFFMTID here so that the
//proxy code won't get the const GUID *const definition.
#ifndef GUID_DEFINED
#include
#endif /* GUID_DEFINED */
#if defined(__cplusplus)
extern "C"
{
#endif
#pragma region Application or OneCore or Games Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM | WINAPI_PARTITION_GAMES)
// forward declarations
// By default, this header cannot be compiled as C++ without defining CINTERFACE (which uses a
// C-style view of COM interfaces for C++ in MIDL-generated headers), because type definitions here
// depend on *Vtbl types not present in this configuration. Define RPCPROXY_ENABLE_CPP_NO_CINTERFACE
// to enable this when needed.
#if defined(RPCPROXY_ENABLE_CPP_NO_CINTERFACE) && defined(__cplusplus) && !defined(CINTERFACE)
typedef struct IRpcStubBufferVtbl IRpcStubBufferVtbl;
typedef struct ICallFactoryVtbl ICallFactoryVtbl;
typedef struct IReleaseMarshalBuffersVtbl IReleaseMarshalBuffersVtbl;
typedef struct IPSFactoryBufferVtbl IPSFactoryBufferVtbl;
#endif
typedef struct tagCInterfaceStubVtbl CInterfaceStubVtbl;
typedef struct tagCInterfaceProxyVtbl CInterfaceProxyVtbl;
typedef struct tagCInterfaceStubVtbl * PCInterfaceStubVtblList;
typedef struct tagCInterfaceProxyVtbl * PCInterfaceProxyVtblList;
typedef const char * PCInterfaceName;
typedef int __stdcall IIDLookupRtn( const IID * pIID, int * pIndex );
typedef IIDLookupRtn * PIIDLookup;
// Uses a default lookup mechanism
#define NdrDefaultIIDLookup ((PIIDLookup)-1)
#if _MSC_VER >= 1200
#pragma warning(push)
#pragma warning(disable:4610) // struct can never be instantiated - user defined constructor required
#pragma warning(disable:4510) // default constructor could not be generated
#pragma warning(disable:4512) // assignment operator could not be generated
#endif
// pointers to arrays of CInterfaceProxyVtbl's and CInterfaceStubVtbls
typedef struct tagProxyFileInfo
{
const PCInterfaceProxyVtblList *pProxyVtblList;
const PCInterfaceStubVtblList *pStubVtblList;
const PCInterfaceName * pNamesArray;
const IID ** pDelegatedIIDs;
const PIIDLookup pIIDLookupRtn;
unsigned short TableSize;
unsigned short TableVersion;
const IID ** pAsyncIIDLookup;
LONG_PTR Filler2;
LONG_PTR Filler3;
LONG_PTR Filler4;
}ProxyFileInfo;
#if _MSC_VER >= 1200
#pragma warning(pop)
#endif
// extended info with list of interface names
typedef ProxyFileInfo ExtendedProxyFileInfo;
#include
#include
#include
#include
typedef struct tagCInterfaceProxyHeader
{
//
// New fields should be added here, at the beginning of the structure.
//
#ifdef USE_STUBLESS_PROXY
const void * pStublessProxyInfo;
#endif
const IID * piid;
} CInterfaceProxyHeader;
// Macro used for ANSI compatible stubs.
#define CINTERFACE_PROXY_VTABLE( n ) \
struct \
{ \
CInterfaceProxyHeader header; \
void *Vtbl[ n ]; \
}
#define IInspectableInterfaceProxyTag ((void *)-1)
#define IUnknownInterfaceProxyTag ((void *)-2)
#if _MSC_VER >= 1200
#pragma warning(push)
#endif
#pragma warning( disable:4200 )
typedef struct tagCInterfaceProxyVtbl
{
CInterfaceProxyHeader header;
#if defined( _MSC_VER )
void *Vtbl[];
#else
void *Vtbl[1];
#endif
} CInterfaceProxyVtbl;
#if _MSC_VER >= 1200
#pragma warning(pop)
#else
#pragma warning( default:4200 )
#endif
typedef
void
(__RPC_STUB * PRPC_STUB_FUNCTION) (
IRpcStubBuffer * This,
IRpcChannelBuffer * _pRpcChannelBuffer,
PRPC_MESSAGE _pRpcMessage,
DWORD *pdwStubPhase);
typedef struct tagCInterfaceStubHeader
{
//New fields should be added here, at the beginning of the structure.
const IID * piid;
const MIDL_SERVER_INFO * pServerInfo;
ULONG DispatchTableCount;
const PRPC_STUB_FUNCTION * pDispatchTable;
} CInterfaceStubHeader;
#define IInspectableNdrStubCall2CommonStubListTag ((const PRPC_STUB_FUNCTION*)-1)
#define IInspectableNdrStubCall3CommonStubListTag ((const PRPC_STUB_FUNCTION*)-2)
#if !defined(RPCPROXY_ENABLE_CPP_NO_CINTERFACE) || !defined(__cplusplus) || defined(CINTERFACE)
typedef struct tagCInterfaceStubVtbl
{
CInterfaceStubHeader header;
IRpcStubBufferVtbl Vtbl;
} CInterfaceStubVtbl;
#define RPCPROXY_GET_STUB_HEADER(StubVtblListEntry) (&(StubVtblListEntry)->header)
#else
// No definition of CInterfaceStubVtbl is provided in this configuration, but
// RPCPROXY_GET_STUB_HEADER can be used to get the stub header from an entry in
// a stub vtable list.
#define RPCPROXY_GET_STUB_HEADER(StubVtblListEntry) (reinterpret_cast(StubVtblListEntry))
#endif
typedef struct tagCInterfaceStubVtblTag
{
CInterfaceStubHeader header;
void * tag;
} CInterfaceStubVtblTag;
typedef struct tagCStdStubBuffer
{
const struct IRpcStubBufferVtbl * lpVtbl; //Points to Vtbl field in CInterfaceStubVtbl.
LONG RefCount;
struct IUnknown * pvServerObject;
const struct ICallFactoryVtbl * pCallFactoryVtbl;
const IID * pAsyncIID;
struct IPSFactoryBuffer * pPSFactory;
const struct IReleaseMarshalBuffersVtbl * pRMBVtbl;
} CStdStubBuffer;
typedef struct tagCStdPSFactoryBuffer
{
const IPSFactoryBufferVtbl * lpVtbl;
LONG RefCount;
const ProxyFileInfo ** pProxyFileList;
LONG Filler1; //Reserved for future use.
} CStdPSFactoryBuffer;
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM | WINAPI_PARTITION_GAMES) */
#pragma endregion
#pragma region Desktop or OneCore Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM | WINAPI_PARTITION_GAMES)
RPCRTAPI
void
RPC_ENTRY
NdrProxyInitialize(
void * This,
PRPC_MESSAGE pRpcMsg,
PMIDL_STUB_MESSAGE pStubMsg,
PMIDL_STUB_DESC pStubDescriptor,
unsigned int ProcNum );
RPCRTAPI
void
RPC_ENTRY
NdrProxyGetBuffer(
void * This,
PMIDL_STUB_MESSAGE pStubMsg);
RPCRTAPI
void
RPC_ENTRY
NdrProxySendReceive(
void *This,
MIDL_STUB_MESSAGE *pStubMsg);
RPCRTAPI
void
RPC_ENTRY
NdrProxyFreeBuffer(
void *This,
MIDL_STUB_MESSAGE *pStubMsg);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM | WINAPI_PARTITION_GAMES) */
#pragma endregion
#pragma region Application or OneCore or Games Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM | WINAPI_PARTITION_GAMES)
RPCRTAPI
HRESULT
RPC_ENTRY
NdrProxyErrorHandler(
DWORD dwExceptionCode);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM | WINAPI_PARTITION_GAMES) */
#pragma endregion
#pragma region Desktop or OneCore Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM | WINAPI_PARTITION_GAMES)
RPCRTAPI
void
RPC_ENTRY
NdrStubInitialize(
PRPC_MESSAGE pRpcMsg,
PMIDL_STUB_MESSAGE pStubMsg,
PMIDL_STUB_DESC pStubDescriptor,
IRpcChannelBuffer * pRpcChannelBuffer);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM | WINAPI_PARTITION_GAMES) */
#pragma endregion
#pragma region Application or OneCore or Games Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM | WINAPI_PARTITION_GAMES)
RPCRTAPI
void
RPC_ENTRY
NdrStubInitializePartial(
PRPC_MESSAGE pRpcMsg,
PMIDL_STUB_MESSAGE pStubMsg,
PMIDL_STUB_DESC pStubDescriptor,
IRpcChannelBuffer * pRpcChannelBuffer,
ULONG RequestedBufferSize);
void __RPC_STUB NdrStubForwardingFunction(
IN IRpcStubBuffer * This,
IN IRpcChannelBuffer * pChannel,
IN PRPC_MESSAGE pmsg,
OUT DWORD * pdwStubPhase);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM | WINAPI_PARTITION_GAMES) */
#pragma endregion
#pragma region Desktop or OneCore Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM | WINAPI_PARTITION_GAMES)
RPCRTAPI
void
RPC_ENTRY
NdrStubGetBuffer(
IRpcStubBuffer * This,
IRpcChannelBuffer * pRpcChannelBuffer,
PMIDL_STUB_MESSAGE pStubMsg);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM | WINAPI_PARTITION_GAMES) */
#pragma endregion
#pragma region Application or OneCore or Games Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM | WINAPI_PARTITION_GAMES)
RPCRTAPI
HRESULT
RPC_ENTRY
NdrStubErrorHandler(
DWORD dwExceptionCode);
HRESULT STDMETHODCALLTYPE
CStdStubBuffer_QueryInterface(
IRpcStubBuffer * This,
REFIID riid,
void ** ppvObject);
ULONG STDMETHODCALLTYPE
CStdStubBuffer_AddRef(
IRpcStubBuffer * This);
ULONG STDMETHODCALLTYPE
CStdStubBuffer_Release(
IRpcStubBuffer * This);
ULONG STDMETHODCALLTYPE
NdrCStdStubBuffer_Release(
IRpcStubBuffer * This,
IPSFactoryBuffer * pPSF);
HRESULT STDMETHODCALLTYPE
CStdStubBuffer_Connect(
IRpcStubBuffer * This,
IUnknown * pUnkServer);
void STDMETHODCALLTYPE
CStdStubBuffer_Disconnect(
IRpcStubBuffer * This);
HRESULT STDMETHODCALLTYPE
CStdStubBuffer_Invoke(
IRpcStubBuffer * This,
RPCOLEMESSAGE * pRpcMsg,
IRpcChannelBuffer * pRpcChannelBuffer);
IRpcStubBuffer * STDMETHODCALLTYPE
CStdStubBuffer_IsIIDSupported(
IRpcStubBuffer * This,
REFIID riid);
ULONG STDMETHODCALLTYPE
CStdStubBuffer_CountRefs(
IRpcStubBuffer * This);
HRESULT STDMETHODCALLTYPE
CStdStubBuffer_DebugServerQueryInterface(
IRpcStubBuffer * This,
void **ppv);
void STDMETHODCALLTYPE
CStdStubBuffer_DebugServerRelease(
IRpcStubBuffer * This,
void *pv);
HRESULT STDMETHODCALLTYPE
CStdStubBuffer2_QueryInterface(
IRpcStubBuffer * This,
REFIID riid,
void ** ppvObject);
ULONG STDMETHODCALLTYPE
CStdStubBuffer2_Release(
IRpcStubBuffer *This);
HRESULT STDMETHODCALLTYPE
CStdStubBuffer2_Connect(
IRpcStubBuffer *pthis,
IUnknown *pUnkServer);
void STDMETHODCALLTYPE
CStdStubBuffer2_Disconnect(
IRpcStubBuffer *pthis);
ULONG STDMETHODCALLTYPE
CStdStubBuffer2_CountRefs(
IRpcStubBuffer *pthis);
ULONG STDMETHODCALLTYPE
NdrCStdStubBuffer2_Release(
IRpcStubBuffer *This,
IPSFactoryBuffer * pPSF);
HRESULT STDMETHODCALLTYPE
CStdAsyncStubBuffer_QueryInterface(
IRpcStubBuffer *pthis,
REFIID riid,
void **ppvObject);
ULONG STDMETHODCALLTYPE
CStdAsyncStubBuffer_AddRef(
IRpcStubBuffer *pthis);
ULONG STDMETHODCALLTYPE
CStdAsyncStubBuffer_Release(
IRpcStubBuffer *pthis);
HRESULT STDMETHODCALLTYPE
CStdAsyncStubBuffer_Connect(
IRpcStubBuffer *pthis,
IUnknown *pUnkServer);
void STDMETHODCALLTYPE
CStdAsyncStubBuffer_Disconnect(
IRpcStubBuffer *pthis);
HRESULT STDMETHODCALLTYPE
CStdAsyncStubBuffer_Invoke(
IRpcStubBuffer *pthis,
RPCOLEMESSAGE *_prpcmsg,
IRpcChannelBuffer *_pRpcChannelBuffer);
ULONG STDMETHODCALLTYPE
CStdAsyncStubBuffer2_Release(
IRpcStubBuffer *pthis);
HRESULT STDMETHODCALLTYPE
CStdAsyncStubBuffer2_Connect(
IRpcStubBuffer *pthis,
IUnknown *pUnkServer);
void STDMETHODCALLTYPE
CStdAsyncStubBuffer2_Disconnect(
IRpcStubBuffer *pthis);
DECLSPEC_CHPE_GUEST void STDMETHODCALLTYPE ObjectStublessClient3(void);
DECLSPEC_CHPE_GUEST void STDMETHODCALLTYPE ObjectStublessClient4(void);
DECLSPEC_CHPE_GUEST void STDMETHODCALLTYPE ObjectStublessClient5(void);
DECLSPEC_CHPE_GUEST void STDMETHODCALLTYPE ObjectStublessClient6(void);
DECLSPEC_CHPE_GUEST void STDMETHODCALLTYPE ObjectStublessClient7(void);
DECLSPEC_CHPE_GUEST void STDMETHODCALLTYPE ObjectStublessClient8(void);
DECLSPEC_CHPE_GUEST void STDMETHODCALLTYPE ObjectStublessClient9(void);
DECLSPEC_CHPE_GUEST void STDMETHODCALLTYPE ObjectStublessClient10(void);
DECLSPEC_CHPE_GUEST void STDMETHODCALLTYPE ObjectStublessClient11(void);
DECLSPEC_CHPE_GUEST void STDMETHODCALLTYPE ObjectStublessClient12(void);
DECLSPEC_CHPE_GUEST void STDMETHODCALLTYPE ObjectStublessClient13(void);
DECLSPEC_CHPE_GUEST void STDMETHODCALLTYPE ObjectStublessClient14(void);
DECLSPEC_CHPE_GUEST void STDMETHODCALLTYPE ObjectStublessClient15(void);
DECLSPEC_CHPE_GUEST void STDMETHODCALLTYPE ObjectStublessClient16(void);
DECLSPEC_CHPE_GUEST void STDMETHODCALLTYPE ObjectStublessClient17(void);
DECLSPEC_CHPE_GUEST void STDMETHODCALLTYPE ObjectStublessClient18(void);
DECLSPEC_CHPE_GUEST void STDMETHODCALLTYPE ObjectStublessClient19(void);
DECLSPEC_CHPE_GUEST void STDMETHODCALLTYPE ObjectStublessClient20(void);
DECLSPEC_CHPE_GUEST void STDMETHODCALLTYPE ObjectStublessClient21(void);
DECLSPEC_CHPE_GUEST void STDMETHODCALLTYPE ObjectStublessClient22(void);
DECLSPEC_CHPE_GUEST void STDMETHODCALLTYPE ObjectStublessClient23(void);
DECLSPEC_CHPE_GUEST void STDMETHODCALLTYPE ObjectStublessClient24(void);
DECLSPEC_CHPE_GUEST void STDMETHODCALLTYPE ObjectStublessClient25(void);
DECLSPEC_CHPE_GUEST void STDMETHODCALLTYPE ObjectStublessClient26(void);
DECLSPEC_CHPE_GUEST void STDMETHODCALLTYPE ObjectStublessClient27(void);
DECLSPEC_CHPE_GUEST void STDMETHODCALLTYPE ObjectStublessClient28(void);
DECLSPEC_CHPE_GUEST void STDMETHODCALLTYPE ObjectStublessClient29(void);
DECLSPEC_CHPE_GUEST void STDMETHODCALLTYPE ObjectStublessClient30(void);
DECLSPEC_CHPE_GUEST void STDMETHODCALLTYPE ObjectStublessClient31(void);
DECLSPEC_CHPE_GUEST void STDMETHODCALLTYPE ObjectStublessClient32(void);
DECLSPEC_CHPE_GUEST
void STDMETHODCALLTYPE
NdrProxyForwardingFunction3(void);
DECLSPEC_CHPE_GUEST
void STDMETHODCALLTYPE
NdrProxyForwardingFunction4(void);
DECLSPEC_CHPE_GUEST
void STDMETHODCALLTYPE
NdrProxyForwardingFunction5(void);
DECLSPEC_CHPE_GUEST
void STDMETHODCALLTYPE
NdrProxyForwardingFunction6(void);
DECLSPEC_CHPE_GUEST
void STDMETHODCALLTYPE
NdrProxyForwardingFunction7(void);
DECLSPEC_CHPE_GUEST
void STDMETHODCALLTYPE
NdrProxyForwardingFunction8(void);
DECLSPEC_CHPE_GUEST
void STDMETHODCALLTYPE
NdrProxyForwardingFunction9(void);
DECLSPEC_CHPE_GUEST
void STDMETHODCALLTYPE
NdrProxyForwardingFunction10(void);
DECLSPEC_CHPE_GUEST
void STDMETHODCALLTYPE
NdrProxyForwardingFunction11(void);
DECLSPEC_CHPE_GUEST
void STDMETHODCALLTYPE
NdrProxyForwardingFunction12(void);
DECLSPEC_CHPE_GUEST
void STDMETHODCALLTYPE
NdrProxyForwardingFunction13(void);
DECLSPEC_CHPE_GUEST
void STDMETHODCALLTYPE
NdrProxyForwardingFunction14(void);
DECLSPEC_CHPE_GUEST
void STDMETHODCALLTYPE
NdrProxyForwardingFunction15(void);
DECLSPEC_CHPE_GUEST
void STDMETHODCALLTYPE
NdrProxyForwardingFunction16(void);
DECLSPEC_CHPE_GUEST
void STDMETHODCALLTYPE
NdrProxyForwardingFunction17(void);
DECLSPEC_CHPE_GUEST
void STDMETHODCALLTYPE
NdrProxyForwardingFunction18(void);
DECLSPEC_CHPE_GUEST
void STDMETHODCALLTYPE
NdrProxyForwardingFunction19(void);
DECLSPEC_CHPE_GUEST
void STDMETHODCALLTYPE
NdrProxyForwardingFunction20(void);
DECLSPEC_CHPE_GUEST
void STDMETHODCALLTYPE
NdrProxyForwardingFunction21(void);
DECLSPEC_CHPE_GUEST
void STDMETHODCALLTYPE
NdrProxyForwardingFunction22(void);
DECLSPEC_CHPE_GUEST
void STDMETHODCALLTYPE
NdrProxyForwardingFunction23(void);
DECLSPEC_CHPE_GUEST
void STDMETHODCALLTYPE
NdrProxyForwardingFunction24(void);
DECLSPEC_CHPE_GUEST
void STDMETHODCALLTYPE
NdrProxyForwardingFunction25(void);
DECLSPEC_CHPE_GUEST
void STDMETHODCALLTYPE
NdrProxyForwardingFunction26(void);
DECLSPEC_CHPE_GUEST
void STDMETHODCALLTYPE
NdrProxyForwardingFunction27(void);
DECLSPEC_CHPE_GUEST
void STDMETHODCALLTYPE
NdrProxyForwardingFunction28(void);
DECLSPEC_CHPE_GUEST
void STDMETHODCALLTYPE
NdrProxyForwardingFunction29(void);
DECLSPEC_CHPE_GUEST
void STDMETHODCALLTYPE
NdrProxyForwardingFunction30(void);
DECLSPEC_CHPE_GUEST
void STDMETHODCALLTYPE
NdrProxyForwardingFunction31(void);
DECLSPEC_CHPE_GUEST
void STDMETHODCALLTYPE
NdrProxyForwardingFunction32(void);
#define CStdStubBuffer_METHODS \
CStdStubBuffer_QueryInterface, \
CStdStubBuffer_AddRef, \
CStdStubBuffer_Release, \
CStdStubBuffer_Connect, \
CStdStubBuffer_Disconnect, \
CStdStubBuffer_Invoke, \
CStdStubBuffer_IsIIDSupported, \
CStdStubBuffer_CountRefs, \
CStdStubBuffer_DebugServerQueryInterface, \
CStdStubBuffer_DebugServerRelease
#define CStdStubBuffer_DELEGATING_METHODS 0,0,CStdStubBuffer2_Release,0,0,0,0,0,0,0
#define CStdAsyncStubBuffer_METHODS 0,0,0,0,0,0,0,0,0,0
#define CStdAsyncStubBuffer_DELEGATING_METHODS 0,0,0,0,0,0,0,0,0,0
#define CStdStubBuffer_METHODS_OPT \
CStdStubBuffer_QueryInterface, \
CStdStubBuffer_AddRef, \
CStdStubBuffer_Release, \
CStdStubBuffer_Connect, \
CStdStubBuffer_Disconnect, \
CStdStubBuffer_Invoke, \
CStdStubBuffer_IsIIDSupported, \
CStdStubBuffer_CountRefs, \
CStdStubBuffer_DebugServerQueryInterface, \
CStdStubBuffer_DebugServerRelease
#define CStdStubBuffer_DELEGATING_METHODS_OPT \
CStdStubBuffer2_QueryInterface, \
CStdStubBuffer_AddRef, \
CStdStubBuffer2_Release, \
CStdStubBuffer2_Connect, \
CStdStubBuffer2_Disconnect, \
CStdStubBuffer_Invoke, \
CStdStubBuffer_IsIIDSupported, \
CStdStubBuffer2_CountRefs, \
CStdStubBuffer_DebugServerQueryInterface, \
CStdStubBuffer_DebugServerRelease
#define CStdAsyncStubBuffer_METHODS_OPT \
CStdAsyncStubBuffer_QueryInterface, \
CStdAsyncStubBuffer_AddRef, \
CStdAsyncStubBuffer_Release, \
CStdAsyncStubBuffer_Connect, \
CStdAsyncStubBuffer_Disconnect, \
CStdAsyncStubBuffer_Invoke, \
CStdStubBuffer_IsIIDSupported, \
CStdStubBuffer_CountRefs, \
CStdStubBuffer_DebugServerQueryInterface, \
CStdStubBuffer_DebugServerRelease
#define CStdAsyncStubBuffer_DELEGATING_METHODS_OPT \
CStdAsyncStubBuffer_QueryInterface, \
CStdAsyncStubBuffer_AddRef, \
CStdAsyncStubBuffer2_Release, \
CStdAsyncStubBuffer2_Connect, \
CStdAsyncStubBuffer2_Disconnect, \
CStdAsyncStubBuffer_Invoke, \
CStdStubBuffer_IsIIDSupported, \
CStdStubBuffer2_CountRefs, \
CStdStubBuffer_DebugServerQueryInterface, \
CStdStubBuffer_DebugServerRelease
#define CStdStubBuffer_METHODS_TAG ((void *)-1)
#define CStdStubBuffer_DELEGATING_METHODS_TAG ((void *)-2)
#define CStdAsyncStubBuffer_METHODS_TAG ((void *)-3)
#define CStdAsyncStubBuffer_DELEGATING_METHODS_TAG ((void *)-4)
//+-------------------------------------------------------------------------
//
// Macro definitions for the proxy file
//
//--------------------------------------------------------------------------
#define IID_GENERIC_CHECK_IID(name,pIID,index) memcmp( pIID, name##_ProxyVtblList[ index ]->header.piid, 16 )
#define IID_BS_LOOKUP_SETUP int result, low=-1;
#define IID_BS_LOOKUP_INITIAL_TEST(name, sz, split) \
result = name##_CHECK_IID( split ); \
if ( result > 0 ) \
{ low = sz - split; } \
else if ( !result ) \
{ low = split; goto found_label; }
#define IID_BS_LOOKUP_NEXT_TEST(name, split ) \
result = name##_CHECK_IID( low + split ); \
if ( result >= 0 ) \
{ low = low + split; if ( !result ) goto found_label; }
#define IID_BS_LOOKUP_RETURN_RESULT(name, sz, index ) \
low = low + 1; \
if (low >= sz) \
goto not_found_label; \
result = name##_CHECK_IID( low ); \
if (result) \
goto not_found_label; \
found_label: (index) = low; return 1; \
not_found_label: return 0;
//+-------------------------------------------------------------------------
//
// Macro and routine definitions for the dlldata file
//
//--------------------------------------------------------------------------
/****************************************************************************
* Proxy Dll APIs
****************************************************************************/
RPCRTAPI
HRESULT
RPC_ENTRY
NdrDllGetClassObject (
IN REFCLSID rclsid,
IN REFIID riid,
OUT void ** ppv,
IN const ProxyFileInfo ** pProxyFileList,
IN const CLSID * pclsid,
IN CStdPSFactoryBuffer * pPSFactoryBuffer);
RPCRTAPI
HRESULT
RPC_ENTRY
NdrDllCanUnloadNow(
IN CStdPSFactoryBuffer * pPSFactoryBuffer);
// if the user specified a routine prefix, pick it up...
// if not, add nothing
#ifndef ENTRY_PREFIX
#ifndef DllMain
#define DISABLE_THREAD_LIBRARY_CALLS(x) DisableThreadLibraryCalls(x)
#endif
#define ENTRY_PREFIX
#define DLLREGISTERSERVER_ENTRY DllRegisterServer
#define DLLUNREGISTERSERVER_ENTRY DllUnregisterServer
#define DLLMAIN_ENTRY DllMain
#define DLLGETCLASSOBJECT_ENTRY DllGetClassObject
#define DLLCANUNLOADNOW_ENTRY DllCanUnloadNow
#define DLLRPCDUMMYCALL_ENTRY DllRpcDummyCall
#else // ENTRY_PREFIX
#define __rpc_macro_expand2(a, b) a##b
#define __rpc_macro_expand(a, b) __rpc_macro_expand2(a,b)
#define DLLREGISTERSERVER_ENTRY __rpc_macro_expand(ENTRY_PREFIX, DllRegisterServer)
#define DLLUNREGISTERSERVER_ENTRY __rpc_macro_expand(ENTRY_PREFIX, DllUnregisterServer)
#define DLLMAIN_ENTRY __rpc_macro_expand(ENTRY_PREFIX, DllMain)
#define DLLGETCLASSOBJECT_ENTRY __rpc_macro_expand(ENTRY_PREFIX, DllGetClassObject)
#define DLLCANUNLOADNOW_ENTRY __rpc_macro_expand(ENTRY_PREFIX, DllCanUnloadNow)
#define DLLRPCDUMMYCALL_ENTRY __rpc_macro_expand(ENTRY_PREFIX, DllRpcDummyCall)
#endif // ENTRY_PREFIX
#ifndef DISABLE_THREAD_LIBRARY_CALLS
#define DISABLE_THREAD_LIBRARY_CALLS(x)
#endif
/*************************************************************************
The following new functions were added after the Windows NT 3.5 release.
*************************************************************************/
RPCRTAPI
HRESULT
RPC_ENTRY
NdrDllRegisterProxy(
IN HMODULE hDll,
IN const ProxyFileInfo ** pProxyFileList,
IN const CLSID * pclsid);
RPCRTAPI
HRESULT
RPC_ENTRY
NdrDllUnregisterProxy(
IN HMODULE hDll,
IN const ProxyFileInfo ** pProxyFileList,
IN const CLSID * pclsid);
#define REGISTER_PROXY_DLL_ROUTINES(pProxyFileList, pClsID) \
\
HINSTANCE hProxyDll = 0; \
\
/*DllMain saves the DLL module handle for later use by DllRegisterServer */ \
BOOL WINAPI DLLMAIN_ENTRY( \
HINSTANCE hinstDLL, \
DWORD fdwReason, \
LPVOID lpvReserved) \
{ \
UNREFERENCED_PARAMETER(lpvReserved); \
if(fdwReason == DLL_PROCESS_ATTACH) \
{ \
hProxyDll = hinstDLL; \
DISABLE_THREAD_LIBRARY_CALLS(hinstDLL); \
} \
return TRUE; \
} \
\
/* DllRegisterServer registers the interfaces contained in the proxy DLL. */ \
HRESULT STDAPICALLTYPE DLLREGISTERSERVER_ENTRY() \
{ \
return NdrDllRegisterProxy(hProxyDll, (const ProxyFileInfo **)pProxyFileList, pClsID); \
} \
\
/* DllUnregisterServer unregisters the interfaces contained in the proxy DLL. */ \
HRESULT STDAPICALLTYPE DLLUNREGISTERSERVER_ENTRY() \
{ \
return NdrDllUnregisterProxy(hProxyDll, (const ProxyFileInfo **)pProxyFileList, pClsID); \
}
//Delegation support.
#define STUB_FORWARDING_FUNCTION NdrStubForwardingFunction
/*************************************************************************
End of new functions.
*************************************************************************/
// PROXY_CLSID has precedence over PROXY_CLSID_IS
#ifdef PROXY_CLSID
#define CLSID_PSFACTORYBUFFER extern CLSID PROXY_CLSID;
#else // PROXY_CLSID
#ifdef PROXY_CLSID_IS
#define CLSID_PSFACTORYBUFFER const CLSID CLSID_PSFactoryBuffer = PROXY_CLSID_IS;
#define PROXY_CLSID CLSID_PSFactoryBuffer
#else // PROXY_CLSID_IS
#define CLSID_PSFACTORYBUFFER
#endif //PROXY_CLSID_IS
#endif //PROXY_CLSID
// if the user specified an override for the class id, it is
// PROXY_CLSID at this point
#ifndef PROXY_CLSID
#define GET_DLL_CLSID \
( aProxyFileList[0]->pStubVtblList[0] != 0 ? \
aProxyFileList[0]->pStubVtblList[0]->header.piid : 0)
#else //PROXY_CLSID
#define GET_DLL_CLSID &PROXY_CLSID
#endif //PROXY_CLSID
#define EXTERN_PROXY_FILE(name) \
EXTERN_C const ProxyFileInfo name##_ProxyFileInfo;
#define PROXYFILE_LIST_START \
extern const ProxyFileInfo* const aProxyFileList[] = {
#define REFERENCE_PROXY_FILE(name) \
& name##_ProxyFileInfo
#define PROXYFILE_LIST_END \
0 };
// return pointers to the class information
#define DLLDATA_GETPROXYDLLINFO(pPFList,pClsid) \
void RPC_ENTRY GetProxyDllInfo( const ProxyFileInfo*** pInfo, const CLSID ** pId ) \
{ \
*pInfo = (const ProxyFileInfo**)pPFList; \
*pId = pClsid; \
};
// ole entry points:
#define DLLGETCLASSOBJECTROUTINE(pPFlist, pClsid,pFactory) \
_Check_return_ HRESULT STDAPICALLTYPE DLLGETCLASSOBJECT_ENTRY ( \
_In_ REFCLSID rclsid, \
_In_ REFIID riid, \
_Outptr_ void ** ppv ) \
{ \
return \
NdrDllGetClassObject(rclsid,riid,ppv,(const ProxyFileInfo**)pPFlist,pClsid,pFactory ); \
}
#define DLLCANUNLOADNOW(pFactory) \
HRESULT STDAPICALLTYPE DLLCANUNLOADNOW_ENTRY() \
{ \
return NdrDllCanUnloadNow( pFactory ); \
}
#define DLLRPCDUMMYCALL \
void __cdecl DLLRPCDUMMYCALL_ENTRY(void) \
{ \
/* Don't define __purecall method anymore */ \
}
#define CSTDSTUBBUFFERRELEASE(pFactory) \
DECLSPEC_XFGVIRT(IUnknown, Release) \
ULONG STDMETHODCALLTYPE CStdStubBuffer_Release(IRpcStubBuffer *This) \
{ \
return NdrCStdStubBuffer_Release(This,(IPSFactoryBuffer *)pFactory); \
} \
#ifdef PROXY_DELEGATION
#define CSTDSTUBBUFFER2RELEASE(pFactory) \
DECLSPEC_XFGVIRT(IUnknown, Release) \
ULONG STDMETHODCALLTYPE CStdStubBuffer2_Release(IRpcStubBuffer *This) \
{ \
return NdrCStdStubBuffer2_Release(This,(IPSFactoryBuffer *)pFactory); \
}
#else
#define CSTDSTUBBUFFER2RELEASE(pFactory)
#endif //PROXY_DELEGATION
#ifdef REGISTER_PROXY_DLL
#define DLLREGISTRY_ROUTINES(pProxyFileList,pClsID ) REGISTER_PROXY_DLL_ROUTINES(pProxyFileList,pClsID )
#else
#define DLLREGISTRY_ROUTINES(pProxyFileList,pClsID )
#endif //REGISTER_PROXY_DLL
// the dll entry points that must be defined
#define DLLDATA_ROUTINES(pProxyFileList,pClsID ) \
\
CLSID_PSFACTORYBUFFER \
\
CStdPSFactoryBuffer gPFactory = {0,0,0,0}; \
\
DLLDATA_GETPROXYDLLINFO(pProxyFileList,pClsID) \
\
DLLGETCLASSOBJECTROUTINE(pProxyFileList,pClsID,&gPFactory) \
\
DLLCANUNLOADNOW(&gPFactory) \
\
CSTDSTUBBUFFERRELEASE(&gPFactory) \
\
CSTDSTUBBUFFER2RELEASE(&gPFactory) \
\
DLLRPCDUMMYCALL \
\
DLLREGISTRY_ROUTINES(pProxyFileList, pClsID) \
\
// more code goes here...
#define DLLDATA_STANDARD_ROUTINES \
DLLDATA_ROUTINES( (const ProxyFileInfo**) pProxyFileList, &CLSID_PSFactoryBuffer ) \
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM | WINAPI_PARTITION_GAMES) */
#pragma endregion
#if defined(__cplusplus)
} // extern "C"
#endif
#endif // WIN32 or _WIN64_
#if defined(_M_IA64) || defined(_M_AMD64)
#include
#endif
#endif // __RPCPROXY_H__
#endif // _KRPCENV_
================================================
FILE: RainbowTaskbarDLL/ErrorDebug.h
================================================
#pragma once
struct TaskbarInfo {
HWND taskbar;
int YPosition;
char _reserved[16];
};
struct TaskbarInfo2 {
HWND taskbar;
void* UIData;
int UIDataSize;
};
struct RainbowTaskbarData {
struct TaskbarInfo lTaskbarInfo[8];
struct TaskbarInfo2 lTaskbarInfo2[8];
};
struct IErrorDebug
{
private:
size_t line;
char* file;
};
#define _E this->line = __LINE__;
#define _F this->file = (char*)__FILE__;
#define __EFMT(buf,X) swprintf_s(buf, L"Exception on line %zd, in file %hs: %ls", this->line, this->file, X); MessageBoxW(0, buf, L"RainbowTaskbarDLL Error", 0);
#define _EFMT(buf,x) __EFMT(buf,x)
================================================
FILE: RainbowTaskbarDLL/Factory.h
================================================
#pragma once
#include
#include "winrt.h"
template
struct Factory : winrt::implements, IClassFactory>
{
HRESULT STDMETHODCALLTYPE CreateInstance(IUnknown* pUnkOuter, REFIID riid, void** ppvObject) override try
{
*ppvObject = nullptr;
return winrt::make().as(riid, ppvObject);
}
catch (...)
{
return winrt::to_hresult();
}
HRESULT STDMETHODCALLTYPE LockServer(BOOL fLock) noexcept override
{
if (fLock)
{
++winrt::get_module_lock();
}
else
{
--winrt::get_module_lock();
}
return S_OK;
}
};
================================================
FILE: RainbowTaskbarDLL/IUnused.h
================================================
#pragma once
================================================
FILE: RainbowTaskbarDLL/IUnused.idl
================================================
import "oaidl.idl";
import "ocidl.idl";
[
object,
uuid(3e987340-78d8-48ce-aa6b-46ec8ba343c7)
]
interface IUnused : IUnknown {
}
================================================
FILE: RainbowTaskbarDLL/RainbowTaskbarDLL.def
================================================
EXPORTS
DllGetClassObject PRIVATE
DllCanUnloadNow PRIVATE
SetAppearanceTypeDLL
CloseDLL
VersionDLL
GetDataPtrDLL
DebugGetUITreeDLL
SetTaskbarElementsOpacityDLL
================================================
FILE: RainbowTaskbarDLL/RainbowTaskbarDLL.idl
================================================
import "unknwn.idl";
import "ocidl.idl";
[uuid(b9684566-2c89-11ee-be56-0242ac120002)]
library RainbowTaskbarDLL {
[uuid(c9d60190-2c89-11ee-be56-0242ac120002)]
coclass TAPSite
{
interface IObjectWithSite;
}
[uuid(5a71c99f-5386-48a9-9165-de45a6a305ff)]
coclass AppearanceServiceAPI
{
interface IDispatch;
}
}
================================================
FILE: RainbowTaskbarDLL/RainbowTaskbarDLL.vcxproj
================================================
Debug
ARM64
Debug
Win32
Release (MSIX)
ARM64
Release (MSIX)
Win32
Release (MSIX)
x64
Release
ARM64
Release
Win32
Debug
x64
Release
x64
16.0
Win32Proj
{3ff5d07d-44d1-4b85-9465-4793b3a9ee8a}
RainbowTaskbarDLL
10.0
DynamicLibrary
true
v143
Unicode
false
false
false
DynamicLibrary
false
v143
true
Unicode
false
false
false
DynamicLibrary
false
v143
true
Unicode
false
false
false
DynamicLibrary
true
v143
Unicode
false
false
false
DynamicLibrary
true
v143
Unicode
false
false
false
DynamicLibrary
false
v143
true
Unicode
false
false
false
DynamicLibrary
false
v143
true
Unicode
false
false
false
DynamicLibrary
false
v143
true
Unicode
false
false
false
DynamicLibrary
false
v143
true
Unicode
false
false
false
$(ProjectName)_$(PlatformName)
Build
Build
$(ProjectName)_$(PlatformName)
Build
Build
$(ProjectName)_$(PlatformName)
Build
Build
$(ProjectName)_$(PlatformName)
Build
Build
$(ProjectName)_$(PlatformName)
Build
Build
ArmFix;$(VC_IncludePath);$(WindowsSDK_IncludePath);
$(ProjectName)_$(PlatformName)
Build
Build
$(ProjectName)_$(PlatformName)
Build
Build
ArmFix;$(VC_IncludePath);$(WindowsSDK_IncludePath);
$(ProjectName)_$(PlatformName)
Build
Build
$(ProjectName)_$(PlatformName)
Build
Build
ArmFix;$(VC_IncludePath);$(WindowsSDK_IncludePath);
Level3
true
WIN32;_DEBUG;RAINBOWTASKBARDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions);_CRT_NO_SECURE_WARNINGS;_CRT_SECURE_NO_WARNINGS
true
NotUsing
pch.h
stdcpp17
stdc17
/DENTRY_PREFIX=Old /DPROXY_CLSID_IS="{ 0x5a71c99f, 0x5386, 0x48a9, 0x9165, 0xde, 0x45, 0xa6, 0xa3, 0x05, 0xff }" %(AdditionalOptions)
MultiThreadedDebug
Windows
true
false
$(CoreLibraryDependencies);%(AdditionalDependencies);Ole32.lib;OleAut32.lib;rpcrt4.lib;user32.lib;WindowsApp.lib;
RainbowTaskbarDLL.def
cd "%(ProjectDir)" && del /q *_p.c
Cleaning proxy files
cd "%(ProjectDir)" && del /q *_p.c
Level3
true
true
true
WIN32;NDEBUG;RAINBOWTASKBARDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions);_CRT_NO_SECURE_WARNINGS;_CRT_SECURE_NO_WARNINGS
true
NotUsing
pch.h
stdcpp17
stdc17
/DENTRY_PREFIX=Old /DPROXY_CLSID_IS="{ 0x5a71c99f, 0x5386, 0x48a9, 0x9165, 0xde, 0x45, 0xa6, 0xa3, 0x05, 0xff }" %(AdditionalOptions)
MultiThreaded
Windows
true
true
true
false
$(CoreLibraryDependencies);%(AdditionalDependencies);Ole32.lib;OleAut32.lib;rpcrt4.lib;user32.lib;WindowsApp.lib;
RainbowTaskbarDLL.def
cd "%(ProjectDir)" && del /q *_p.c
Cleaning proxy files
cd "%(ProjectDir)" && del /q *_p.c
Level3
true
true
true
WIN32;NDEBUG;RAINBOWTASKBARDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions);_CRT_NO_SECURE_WARNINGS;_CRT_SECURE_NO_WARNINGS
true
NotUsing
pch.h
stdcpp17
stdc17
/DENTRY_PREFIX=Old /DPROXY_CLSID_IS="{ 0x5a71c99f, 0x5386, 0x48a9, 0x9165, 0xde, 0x45, 0xa6, 0xa3, 0x05, 0xff }" %(AdditionalOptions)
MultiThreaded
Windows
true
true
true
false
$(CoreLibraryDependencies);%(AdditionalDependencies);Ole32.lib;OleAut32.lib;rpcrt4.lib;user32.lib;WindowsApp.lib;
RainbowTaskbarDLL.def
cd "%(ProjectDir)" && del /q *_p.c
Cleaning proxy files
cd "%(ProjectDir)" && del /q *_p.c
Level3
true
_DEBUG;RAINBOWTASKBARDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions);_CRT_NO_SECURE_WARNINGS;_CRT_SECURE_NO_WARNINGS
true
NotUsing
pch.h
stdcpp17
stdc17
/DENTRY_PREFIX=Old /DPROXY_CLSID_IS="{ 0x5a71c99f, 0x5386, 0x48a9, 0x9165, 0xde, 0x45, 0xa6, 0xa3, 0x05, 0xff }" %(AdditionalOptions)
MultiThreadedDebug
Windows
true
false
$(CoreLibraryDependencies);%(AdditionalDependencies);Ole32.lib;OleAut32.lib;rpcrt4.lib;user32.lib;WindowsApp.lib;
RainbowTaskbarDLL.def
cd "%(ProjectDir)" && del /q *_p.c
Cleaning proxy files
cd "%(ProjectDir)" && del /q *_p.c
Level3
true
_DEBUG;RAINBOWTASKBARDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions);_CRT_NO_SECURE_WARNINGS;_CRT_SECURE_NO_WARNINGS
true
NotUsing
pch.h
stdcpp17
stdc17
/DENTRY_PREFIX=Old /DPROXY_CLSID_IS="{ 0x5a71c99f, 0x5386, 0x48a9, 0x9165, 0xde, 0x45, 0xa6, 0xa3, 0x05, 0xff }" %(AdditionalOptions)
MultiThreadedDebug
Windows
true
false
$(CoreLibraryDependencies);%(AdditionalDependencies);Ole32.lib;OleAut32.lib;rpcrt4.lib;user32.lib;WindowsApp.lib;
RainbowTaskbarDLL.def
cd "%(ProjectDir)" && del /q *_p.c
Cleaning proxy files
cd "%(ProjectDir)" && del /q *_p.c
Level3
true
true
true
NDEBUG;RAINBOWTASKBARDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions);_CRT_NO_SECURE_WARNINGS;_CRT_SECURE_NO_WARNINGS
true
NotUsing
pch.h
stdcpp17
stdc17
/DENTRY_PREFIX=Old /DPROXY_CLSID_IS="{ 0x5a71c99f, 0x5386, 0x48a9, 0x9165, 0xde, 0x45, 0xa6, 0xa3, 0x05, 0xff }" %(AdditionalOptions)
MultiThreaded
Windows
true
true
true
false
$(CoreLibraryDependencies);%(AdditionalDependencies);Ole32.lib;OleAut32.lib;rpcrt4.lib;user32.lib;WindowsApp.lib;
RainbowTaskbarDLL.def
cd "%(ProjectDir)" && del /q *_p.c
Cleaning proxy files
cd "%(ProjectDir)" && del /q *_p.c
Level3
true
true
true
NDEBUG;RAINBOWTASKBARDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions);_CRT_NO_SECURE_WARNINGS;_CRT_SECURE_NO_WARNINGS
true
NotUsing
pch.h
stdcpp17
stdc17
/DENTRY_PREFIX=Old /DPROXY_CLSID_IS="{ 0x5a71c99f, 0x5386, 0x48a9, 0x9165, 0xde, 0x45, 0xa6, 0xa3, 0x05, 0xff }" %(AdditionalOptions)
MultiThreaded
Windows
true
true
true
false
$(CoreLibraryDependencies);%(AdditionalDependencies);Ole32.lib;OleAut32.lib;rpcrt4.lib;user32.lib;WindowsApp.lib;
RainbowTaskbarDLL.def
cd "%(ProjectDir)" && del /q *_p.c
Cleaning proxy files
cd "%(ProjectDir)" && del /q *_p.c
Level3
true
true
true
NDEBUG;RAINBOWTASKBARDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions);_CRT_NO_SECURE_WARNINGS;_CRT_SECURE_NO_WARNINGS
true
NotUsing
pch.h
stdcpp17
stdc17
/DENTRY_PREFIX=Old /DPROXY_CLSID_IS="{ 0x5a71c99f, 0x5386, 0x48a9, 0x9165, 0xde, 0x45, 0xa6, 0xa3, 0x05, 0xff }" %(AdditionalOptions)
MultiThreaded
Windows
true
true
true
false
$(CoreLibraryDependencies);%(AdditionalDependencies);Ole32.lib;OleAut32.lib;rpcrt4.lib;user32.lib;WindowsApp.lib;
RainbowTaskbarDLL.def
cd "%(ProjectDir)" && del /q *_p.c
Cleaning proxy files
cd "%(ProjectDir)" && del /q *_p.c
Level3
true
true
true
NDEBUG;RAINBOWTASKBARDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions);_CRT_NO_SECURE_WARNINGS;_CRT_SECURE_NO_WARNINGS
true
NotUsing
pch.h
stdcpp17
stdc17
/DENTRY_PREFIX=Old /DPROXY_CLSID_IS="{ 0x5a71c99f, 0x5386, 0x48a9, 0x9165, 0xde, 0x45, 0xa6, 0xa3, 0x05, 0xff }" %(AdditionalOptions)
MultiThreaded
Windows
true
true
true
false
$(CoreLibraryDependencies);%(AdditionalDependencies);Ole32.lib;OleAut32.lib;rpcrt4.lib;user32.lib;WindowsApp.lib;
RainbowTaskbarDLL.def
cd "%(ProjectDir)" && del /q *_p.c
Cleaning proxy files
cd "%(ProjectDir)" && del /q *_p.c
false
This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
================================================
FILE: RainbowTaskbarDLL/RainbowTaskbarDLL.vcxproj.filters
================================================
{4FC737F1-C7A5-4376-A066-2A32D752A2FF}
cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
{93995380-89BD-4b04-88EB-625FBE52EBFB}
h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
Header Files
Header Files
Header Files
Header Files
Header Files
Header Files
Header Files
Header Files
Header Files
Header Files
Source Files
Source Files
Source Files
Source Files
Source Files
Source Files
Source Files
Source Files
Source Files
Source Files
Source Files
Source Files
================================================
FILE: RainbowTaskbarDLL/TAP.cpp
================================================
#include "TAP.h"
#include "AppearanceServiceAPI.h"
#include "RainbowTaskbarDLL_h.h"
#include
#include
#include
HRESULT TAP::SetSite(IUnknown* pUnk) try
{_F
_E winrt::com_ptr cast;
_E cast.copy_from(pUnk);
_E
_E visualTreeService = cast.as();
_E visualTreeWatch = winrt::make_self();
_E visualTreeWatch->xamlDiagnostics = cast.as();
_E
_E visualTreeService->AdviseVisualTreeChange(visualTreeWatch.get());
_E winrt::com_ptr<::IInspectable> _disp;
_E visualTreeWatch->xamlDiagnostics->GetDispatcher(_disp.put());
_E visualTreeWatch->dispatcher = _disp.as();
_E return S_OK;
}
catch (...)
{
HRESULT res = winrt::to_hresult();
_com_error err(res);
WCHAR data[1024];
__EFMT(data, err.ErrorMessage());
return res;
}
HRESULT TAP::GetSite(REFIID riid, void** ppvSite) noexcept
{
return visualTreeService.as(riid, ppvSite);
}
================================================
FILE: RainbowTaskbarDLL/TAP.h
================================================
#pragma once
#include "winrt.h"
#include "VisualTreeWatch.h"
#include
#include
#include
#include "AppearanceServiceAPI.h"
#include "ErrorDebug.h"
class TAP : public winrt::implements
{
private:
size_t line = 0;
char* file = 0;
public:
HRESULT STDMETHODCALLTYPE SetSite(IUnknown* pUnkSite) override;
HRESULT STDMETHODCALLTYPE GetSite(REFIID riid, void** ppvSite) noexcept override;
winrt::com_ptr visualTreeService;
winrt::com_ptr visualTreeWatch;
};
================================================
FILE: RainbowTaskbarDLL/Taskbar.h
================================================
#pragma once
#include "winrt.h"
struct UITree {
winrt::Windows::UI::Xaml::UIElement element{ nullptr };
std::vector children;
};
struct Taskbar {
public:
winrt::Windows::UI::Xaml::Shapes::Rectangle rectangleBackground = nullptr;
winrt::Windows::UI::Xaml::Shapes::Rectangle border = nullptr;
winrt::Windows::UI::Xaml::Media::Brush originalBrush = nullptr;
winrt::Windows::UI::Core::CoreDispatcher dispatcher = nullptr;
winrt::Windows::UI::Xaml::FrameworkElement gripper = nullptr;
winrt::Windows::UI::Xaml::FrameworkElement frame = nullptr;
winrt::Windows::UI::Xaml::FrameworkElement SystemTrayFrame = nullptr;
winrt::Windows::UI::Xaml::FrameworkElement TaskbarFrameRepeater = nullptr;
HWND handle = NULL;
int tInfoIndex = 0;
Taskbar() {
}
};
================================================
FILE: RainbowTaskbarDLL/VisualTreeWatch.cpp
================================================
#include "VisualTreeWatch.h"
#include "winrt.h"
#include "Taskbar.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
winrt::Windows::UI::Xaml::FrameworkElement FindRootElement(winrt::Windows::UI::Xaml::FrameworkElement child)
{
const auto parent = winrt::Windows::UI::Xaml::Media::VisualTreeHelper::GetParent(child).try_as();
if (parent)
{
return FindRootElement(parent);
}
else
{
return child;
}
}
std::vector> VisualTreeWatch::FindChildrenRecursive(std::optional name, winrt::Windows::UI::Xaml::UIElement root, int deep = 0)
try {
auto children = std::vector>();
auto childrenc = winrt::Windows::UI::Xaml::Media::VisualTreeHelper::GetChildrenCount(root);
for (int i = 0; i < childrenc; i++) {
auto child_ = winrt::Windows::UI::Xaml::Media::VisualTreeHelper::GetChild(root, i);
auto child = child_.try_as< winrt::Windows::UI::Xaml::FrameworkElement>();
if (!name.has_value() || (child && child.Name() == name.value())) {
children.push_back(std::pair(deep, child));
}
auto recurse = FindChildrenRecursive(name, child, deep+1);
children.insert(children.end(), recurse.begin(), recurse.end());
}
return children;
}
catch (...) {
return std::vector>();
}
winrt::Windows::UI::Xaml::FrameworkElement VisualTreeWatch::FindChildRecursive(std::wstring name, winrt::Windows::UI::Xaml::UIElement root)
try {
auto childrenc = winrt::Windows::UI::Xaml::Media::VisualTreeHelper::GetChildrenCount(root);
for (int i = 0; i < childrenc; i++) {
auto child_ = winrt::Windows::UI::Xaml::Media::VisualTreeHelper::GetChild(root, i);
auto child = child_.try_as< winrt::Windows::UI::Xaml::FrameworkElement>();
if (child && child.Name() == name) {
return child;
}
auto recurse = FindChildRecursive(name, child);
if (recurse) return recurse;
}
return nullptr;
}
catch (...) {
return nullptr;
}
winrt::Windows::Foundation::IAsyncAction VisualTreeWatch::StartYPosTask(Taskbar* taskbar) try { _F
_E data->lTaskbarInfo[taskbar->tInfoIndex]._reserved[0] = 1;
_E co_await winrt::resume_background();
_E co_await winrt::resume_after(std::chrono::seconds(1));
while (true) {
_E co_await winrt::resume_foreground(dispatcher);
_E auto v = taskbar->gripper.TransformToVisual(root).TransformPoint(winrt::Windows::Foundation::Point(0, 0)).Y;
_E co_await winrt::resume_background();
_E data->lTaskbarInfo[taskbar->tInfoIndex].YPosition = v;
_E co_await winrt::resume_after(std::chrono::milliseconds(16));
}
}
catch (...) {
HRESULT res = winrt::to_hresult();
_com_error err(res);
WCHAR data[1024];
__EFMT(data, err.ErrorMessage());
}
#include
winrt::Windows::Foundation::IAsyncAction VisualTreeWatch::StartUITask(Taskbar* taskbar) try { _F
_E data->lTaskbarInfo2[taskbar->tInfoIndex].UIData = malloc(1024 * sizeof(wchar_t));
_E memset(data->lTaskbarInfo2[taskbar->tInfoIndex].UIData, 0, 1024 * sizeof(wchar_t));
_E
_E data->lTaskbarInfo2[taskbar->tInfoIndex].UIDataSize = 1024 * sizeof(wchar_t);
_E
_E co_await winrt::resume_background();
_E co_await winrt::resume_after(std::chrono::seconds(1));
_E co_await winrt::resume_foreground(dispatcher);
_E
_E auto start = taskbar->frame.Parent().try_as< winrt::Windows::UI::Xaml::FrameworkElement>();
_E
_E auto SystemTrayFrame = FindChildRecursive(L"SystemTrayFrameGrid", start);
_E auto TaskbarFrameRepeater = FindChildRecursive(L"TaskbarFrameRepeater", start);
_E taskbar->SystemTrayFrame = SystemTrayFrame;
_E taskbar->TaskbarFrameRepeater = TaskbarFrameRepeater;
_E auto StartButton = FindChildRecursive(L"LaunchListButton", TaskbarFrameRepeater);
_E
_E auto stfPt = winrt::Windows::Foundation::Point(0, 0);
_E auto stfSize = winrt::Windows::Foundation::Size(0, 0);
_E auto tfrPt = winrt::Windows::Foundation::Point(0, 0);
_E auto tfrSize = winrt::Windows::Foundation::Size(0, 0);
_E
_E co_await winrt::resume_background();
_E
while (true) {
_E co_await winrt::resume_foreground(dispatcher);
_E auto n_stfPt = SystemTrayFrame.TransformToVisual(root).TransformPoint(winrt::Windows::Foundation::Point(0, 0));
_E auto n_stfSize = SystemTrayFrame.DesiredSize();
_E auto n_tfrPt = StartButton.TransformToVisual(root).TransformPoint(winrt::Windows::Foundation::Point(0, 0));
_E auto n_tfrSize = TaskbarFrameRepeater.DesiredSize();
_E
_E co_await winrt::resume_background();
_E
_E if (n_stfPt != stfPt || n_stfSize != stfSize || n_tfrPt != tfrPt || n_tfrSize != tfrSize) {
_E std::swprintf((wchar_t*)data->lTaskbarInfo2[taskbar->tInfoIndex].UIData, data->lTaskbarInfo2[taskbar->tInfoIndex].UIDataSize - 1,
L"{\"stfPt\":[%f,%f],\"stfSize\":[%f,%f],\"tfrPt\":[%f,%f],\"tfrSize\":[%f,%f]}", n_stfPt.X, n_stfPt.Y, n_stfSize.Width, n_stfSize.Height, n_tfrPt.X, n_tfrPt.Y, n_tfrSize.Width, n_tfrSize.Height);
_E stfPt = n_stfPt;
_E stfSize = n_stfSize;
_E tfrPt = n_tfrPt;
_E tfrSize = n_tfrSize;
_E }
_E
_E co_await winrt::resume_after(std::chrono::milliseconds(16));
}
}
catch (...) {
HRESULT res = winrt::to_hresult();
_com_error err(res);
WCHAR data[1024];
__EFMT(data, err.ErrorMessage());
}
HRESULT VisualTreeWatch::OnVisualTreeChange(ParentChildRelation rel, VisualElement element, VisualMutationType mutationType)
{_F
try {
// Navigate down the visual tree and find the taskbarframes
// * this is required because we cannot get the DesktopWindowXamlSource by navigating up the tree
// we also cannot get its children so we wait for an element that has it as its parent,
// its weird idk
_E auto changed = ConvertFromH< winrt::Windows::UI::Xaml::Hosting::IDesktopWindowXamlSource>(rel.Parent);
_E if (changed && mutationType == Add) {
_E root = ConvertFromH(element.Handle);
_E if (root) {
_E
_E auto frame = FindChildRecursive(L"TaskbarFrame", root);
_E if(frame){
[&]() -> winrt::Windows::Foundation::IAsyncAction {
if (dispatcher) {
co_await winrt::resume_background();
co_await winrt::resume_after(std::chrono::milliseconds(1000));
co_await winrt::resume_foreground(dispatcher);
}
_E InstanceHandle handle = ConvertToH(frame);
_E
_E auto rect_ = FindChildRecursive(L"BackgroundFill", frame);
_E if(rect_){
_E auto rect = rect_.try_as();
_E if (rect) {
_E
_E if (taskbarMap.find(handle) == taskbarMap.end()) {
_E Taskbar t = Taskbar();
_E t.originalBrush = rect.Fill();
_E t.rectangleBackground = rect;
_E t.dispatcher = rect.Dispatcher();
_E t.frame = frame;
_E HWND hwnd;
_E changed.try_as()->get_WindowHandle(&hwnd);
_E t.handle = GetParent(hwnd);
_E for (int i = 0; i < 8; i++) {
_E if (!data->lTaskbarInfo[i].taskbar) {
_E data->lTaskbarInfo[i].taskbar = t.handle;
_E data->lTaskbarInfo2[i].taskbar = t.handle;
_E t.tInfoIndex = i;
_E break;
_E }
_E }
_E
_E
_E
_E taskbarMap.emplace(handle, t);
_E }
_E }
_E }
_E
_E auto border_ = FindChildRecursive(L"BackgroundStroke", frame);
_E if(border_){
_E auto border = border_.try_as();
_E if (border) {
_E if(taskbarMap.find(handle) != taskbarMap.end())
taskbarMap.find(handle)->second.border = border;
_E }
_E }
_E
_E auto gripper = FindChildRecursive(L"GripperControl", frame);
_E if (gripper) {
_E if(taskbarMap.find(handle) != taskbarMap.end()) {
_E auto& tb = taskbarMap.find(handle)->second;
_E tb.gripper = gripper.try_as< winrt::Windows::UI::Xaml::FrameworkElement>();
_E StartYPosTask(&taskbarMap.find(handle)->second);
_E
_E
_E }
_E }
StartUITask(&taskbarMap.find(handle)->second);
}();
_E
_E }
_E }
_E }
}
catch (...) {
HRESULT res = winrt::to_hresult();
_com_error err(res);
WCHAR data[1024];
__EFMT(data, err.ErrorMessage());
return res;
}
return S_OK;
}
void VisualTreeWatch::Stop() {
xamlDiagnostics.as()->UnadviseVisualTreeChange(this);
}
HRESULT VisualTreeWatch::OnElementStateChanged(InstanceHandle, VisualElementState, LPCWSTR) noexcept
{
return S_OK;
}
VisualTreeWatch::VisualTreeWatch() {
appService = winrt::make_self(get_strong());
}
================================================
FILE: RainbowTaskbarDLL/VisualTreeWatch.h
================================================
#pragma once
#include "winrt.h"
#include
#include "Taskbar.h"
class AppearanceServiceAPI;
class VisualTreeWatch;
#include "AppearanceServiceAPI.h"
#include "ErrorDebug.h"
class VisualTreeWatch : public winrt::implements
{
HRESULT STDMETHODCALLTYPE OnVisualTreeChange(ParentChildRelation relation, VisualElement element, VisualMutationType mutationType) override;
HRESULT STDMETHODCALLTYPE OnElementStateChanged(InstanceHandle element, VisualElementState elementState, LPCWSTR context) noexcept override;
private:
size_t line = 0;
char* file = 0;
public:
winrt::com_ptr xamlDiagnostics;
winrt::com_ptr appService;
winrt::Windows::UI::Xaml::FrameworkElement root = nullptr;
winrt::Windows::UI::Core::CoreDispatcher dispatcher = nullptr;
winrt::Windows::UI::Xaml::Hosting::IDesktopWindowXamlSource dwxsource = nullptr;
struct RainbowTaskbarData* data;
HANDLE hPipe = 0;
int taskbarFrames = 0;
std::map taskbarMap = std::map();
std::map dwxsourceMap = std::map();
VisualTreeWatch();
void Stop();
template
T ConvertFromH(InstanceHandle handle)
{
winrt::Windows::Foundation::IInspectable obj;
xamlDiagnostics->GetIInspectableFromHandle(handle, reinterpret_cast<::IInspectable**>(winrt::put_abi(obj)));
return obj.try_as();
}
template
InstanceHandle ConvertToH(T obj)
{
InstanceHandle handle = 0;
xamlDiagnostics->GetHandleFromIInspectable(reinterpret_cast<::IInspectable*>(winrt::get_abi(obj)), &handle);
return handle;
}
std::vector> FindChildrenRecursive(std::optional name, winrt::Windows::UI::Xaml::UIElement root, int deep);
winrt::Windows::UI::Xaml::FrameworkElement FindChildRecursive(std::wstring name, winrt::Windows::UI::Xaml::UIElement root);
winrt::Windows::Foundation::IAsyncAction StartYPosTask(Taskbar* taskbar);
winrt::Windows::Foundation::IAsyncAction StartUITask(Taskbar* taskbar);
};
================================================
FILE: RainbowTaskbarDLL/csharpinterop.cpp
================================================
#include "winrt.h"
#include "RainbowTaskbarDLL_h.h"
#include
#include
#include