mirror of
https://github.com/zs-yg/kortapp-z.git
synced 2025-12-07 00:20:43 +08:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ac93c8418f | ||
|
|
5a49714ed7 | ||
|
|
19056a1a8c | ||
|
|
7c4250f912 | ||
|
|
d056c24a1b | ||
|
|
5651e944f9 | ||
|
|
1dbd9968c9 | ||
|
|
e387d22fee | ||
|
|
68bd471bd2 | ||
|
|
53392a2ce8 |
@@ -17,12 +17,13 @@ namespace AppStore
|
|||||||
private void InitializeComponent()
|
private void InitializeComponent()
|
||||||
{
|
{
|
||||||
this.Dock = DockStyle.Fill;
|
this.Dock = DockStyle.Fill;
|
||||||
this.BackColor = Color.White;
|
this.BackColor = ThemeManager.BackgroundColor;
|
||||||
this.Padding = new Padding(20);
|
this.Padding = new Padding(20);
|
||||||
|
|
||||||
// 创建主布局面板
|
// 创建主布局面板
|
||||||
TableLayoutPanel mainLayout = new TableLayoutPanel();
|
TableLayoutPanel mainLayout = new TableLayoutPanel();
|
||||||
mainLayout.Dock = DockStyle.Fill;
|
mainLayout.Dock = DockStyle.Fill;
|
||||||
|
mainLayout.BackColor = ThemeManager.BackgroundColor;
|
||||||
mainLayout.ColumnCount = 1;
|
mainLayout.ColumnCount = 1;
|
||||||
mainLayout.RowCount = 2;
|
mainLayout.RowCount = 2;
|
||||||
mainLayout.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
|
mainLayout.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
|
||||||
@@ -50,7 +51,7 @@ namespace AppStore
|
|||||||
|
|
||||||
// 初始化并添加应用信息
|
// 初始化并添加应用信息
|
||||||
infoLabel = new Label();
|
infoLabel = new Label();
|
||||||
infoLabel.Text = "kortapp-z\n版本: 1.0.9\n作者: zs-yg\n一个简单、开源的应用商店\nkortapp-z是完全免费\n基于.NET8和C/C++的软件";
|
infoLabel.Text = "kortapp-z\n版本: 1.1.1\n作者: zs-yg\n一个简单、开源的应用商店\nkortapp-z是完全免费\n基于.NET8和C/C++的软件";
|
||||||
infoLabel.Font = new Font("Microsoft YaHei", 12);
|
infoLabel.Font = new Font("Microsoft YaHei", 12);
|
||||||
infoLabel.AutoSize = false;
|
infoLabel.AutoSize = false;
|
||||||
infoLabel.Width = 300;
|
infoLabel.Width = 300;
|
||||||
@@ -68,6 +69,7 @@ namespace AppStore
|
|||||||
// 在底部添加GitHub链接区域
|
// 在底部添加GitHub链接区域
|
||||||
TableLayoutPanel githubPanel = new TableLayoutPanel();
|
TableLayoutPanel githubPanel = new TableLayoutPanel();
|
||||||
githubPanel.Dock = DockStyle.Bottom;
|
githubPanel.Dock = DockStyle.Bottom;
|
||||||
|
githubPanel.BackColor = ThemeManager.BackgroundColor;
|
||||||
githubPanel.Height = 60;
|
githubPanel.Height = 60;
|
||||||
githubPanel.ColumnCount = 3;
|
githubPanel.ColumnCount = 3;
|
||||||
githubPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
|
githubPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
|
||||||
@@ -109,6 +111,7 @@ namespace AppStore
|
|||||||
// 创建包含图标和文字的面板
|
// 创建包含图标和文字的面板
|
||||||
Panel linkPanel = new Panel();
|
Panel linkPanel = new Panel();
|
||||||
linkPanel.AutoSize = true;
|
linkPanel.AutoSize = true;
|
||||||
|
linkPanel.BackColor = ThemeManager.BackgroundColor;
|
||||||
linkPanel.Controls.Add(githubIcon);
|
linkPanel.Controls.Add(githubIcon);
|
||||||
linkPanel.Controls.Add(githubLabel);
|
linkPanel.Controls.Add(githubLabel);
|
||||||
githubIcon.Location = new Point(0, 0);
|
githubIcon.Location = new Point(0, 0);
|
||||||
|
|||||||
@@ -23,13 +23,40 @@ namespace AppStore
|
|||||||
cancelBtn = new Button();
|
cancelBtn = new Button();
|
||||||
|
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
|
// 监听主题变化
|
||||||
|
ThemeManager.ThemeChanged += (theme) => {
|
||||||
|
this.Invoke((MethodInvoker)delegate {
|
||||||
|
ApplyTheme();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyTheme()
|
||||||
|
{
|
||||||
|
this.BackColor = ThemeManager.CurrentTheme == ThemeManager.ThemeMode.Light
|
||||||
|
? Color.White
|
||||||
|
: Color.Black;
|
||||||
|
this.ForeColor = ThemeManager.CurrentTheme == ThemeManager.ThemeMode.Light
|
||||||
|
? Color.Black
|
||||||
|
: Color.White;
|
||||||
|
|
||||||
|
cancelBtn.BackColor = ThemeManager.CurrentTheme == ThemeManager.ThemeMode.Light
|
||||||
|
? SystemColors.Control
|
||||||
|
: Color.FromArgb(70, 70, 70);
|
||||||
|
cancelBtn.ForeColor = ThemeManager.TextColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitializeComponent()
|
private void InitializeComponent()
|
||||||
{
|
{
|
||||||
this.Size = new Size(400, 60);
|
this.Size = new Size(400, 60);
|
||||||
this.BackColor = Color.White;
|
this.BackColor = ThemeManager.CurrentTheme == ThemeManager.ThemeMode.Light
|
||||||
|
? Color.White
|
||||||
|
: Color.Black;
|
||||||
this.BorderStyle = BorderStyle.FixedSingle;
|
this.BorderStyle = BorderStyle.FixedSingle;
|
||||||
|
this.ForeColor = ThemeManager.CurrentTheme == ThemeManager.ThemeMode.Light
|
||||||
|
? Color.Black
|
||||||
|
: Color.White;
|
||||||
|
|
||||||
// 文件名标签
|
// 文件名标签
|
||||||
nameLabel = new Label();
|
nameLabel = new Label();
|
||||||
@@ -56,6 +83,12 @@ namespace AppStore
|
|||||||
cancelBtn.Text = "取消";
|
cancelBtn.Text = "取消";
|
||||||
cancelBtn.Size = new Size(60, 25);
|
cancelBtn.Size = new Size(60, 25);
|
||||||
cancelBtn.Location = new Point(320, 30);
|
cancelBtn.Location = new Point(320, 30);
|
||||||
|
cancelBtn.BackColor = ThemeManager.CurrentTheme == ThemeManager.ThemeMode.Light
|
||||||
|
? SystemColors.Control
|
||||||
|
: Color.FromArgb(70, 70, 70);
|
||||||
|
cancelBtn.ForeColor = ThemeManager.TextColor;
|
||||||
|
cancelBtn.FlatStyle = FlatStyle.Flat;
|
||||||
|
cancelBtn.FlatAppearance.BorderSize = 0;
|
||||||
cancelBtn.Click += CancelBtn_Click;
|
cancelBtn.Click += CancelBtn_Click;
|
||||||
this.Controls.Add(cancelBtn);
|
this.Controls.Add(cancelBtn);
|
||||||
}
|
}
|
||||||
|
|||||||
129
MainForm.cs
129
MainForm.cs
@@ -140,11 +140,19 @@ namespace AppStore
|
|||||||
this.StartPosition = FormStartPosition.CenterScreen;
|
this.StartPosition = FormStartPosition.CenterScreen;
|
||||||
this.Icon = new Icon("img/ico/icon.ico"); // 设置窗体图标
|
this.Icon = new Icon("img/ico/icon.ico"); // 设置窗体图标
|
||||||
|
|
||||||
|
// 注册主题变更事件
|
||||||
|
ThemeManager.ThemeChanged += (theme) =>
|
||||||
|
{
|
||||||
|
this.Invoke((MethodInvoker)delegate {
|
||||||
|
AnimateThemeChange();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// 现代化顶部导航栏
|
// 现代化顶部导航栏
|
||||||
Panel buttonPanel = new Panel();
|
Panel buttonPanel = new Panel();
|
||||||
buttonPanel.Dock = DockStyle.Top;
|
buttonPanel.Dock = DockStyle.Top;
|
||||||
buttonPanel.Height = 70;
|
buttonPanel.Height = 70;
|
||||||
buttonPanel.BackColor = Color.FromArgb(240, 240, 240);
|
buttonPanel.BackColor = ThemeManager.ControlBackgroundColor;
|
||||||
buttonPanel.Padding = new Padding(10, 15, 10, 0);
|
buttonPanel.Padding = new Padding(10, 15, 10, 0);
|
||||||
buttonPanel.AutoScroll = true;
|
buttonPanel.AutoScroll = true;
|
||||||
buttonPanel.AutoSize = true;
|
buttonPanel.AutoSize = true;
|
||||||
@@ -154,11 +162,13 @@ namespace AppStore
|
|||||||
Action<Button> styleButton = (Button btn) => {
|
Action<Button> styleButton = (Button btn) => {
|
||||||
btn.FlatStyle = FlatStyle.Flat;
|
btn.FlatStyle = FlatStyle.Flat;
|
||||||
btn.FlatAppearance.BorderSize = 0;
|
btn.FlatAppearance.BorderSize = 0;
|
||||||
btn.BackColor = Color.Transparent;
|
btn.BackColor = ThemeManager.ControlBackgroundColor;
|
||||||
btn.ForeColor = Color.FromArgb(64, 64, 64);
|
btn.ForeColor = ThemeManager.TextColor;
|
||||||
btn.Font = new Font("Microsoft YaHei", 10, FontStyle.Regular);
|
btn.Font = new Font("Microsoft YaHei", 10, FontStyle.Regular);
|
||||||
btn.Size = new Size(120, 40);
|
btn.Size = new Size(120, 40);
|
||||||
btn.Cursor = Cursors.Hand;
|
btn.Cursor = Cursors.Hand;
|
||||||
|
btn.FlatAppearance.MouseOverBackColor = ThemeManager.ButtonHoverColor;
|
||||||
|
btn.FlatAppearance.MouseDownBackColor = ThemeManager.ButtonActiveColor;
|
||||||
|
|
||||||
// 悬停效果
|
// 悬停效果
|
||||||
btn.MouseEnter += (s, e) => {
|
btn.MouseEnter += (s, e) => {
|
||||||
@@ -167,7 +177,7 @@ namespace AppStore
|
|||||||
};
|
};
|
||||||
|
|
||||||
btn.MouseLeave += (s, e) => {
|
btn.MouseLeave += (s, e) => {
|
||||||
btn.ForeColor = Color.FromArgb(64, 64, 64);
|
btn.ForeColor = ThemeManager.TextColor;
|
||||||
btn.Font = new Font(btn.Font, FontStyle.Regular);
|
btn.Font = new Font(btn.Font, FontStyle.Regular);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -230,7 +240,7 @@ namespace AppStore
|
|||||||
// 现代化内容区域
|
// 现代化内容区域
|
||||||
contentPanel = new Panel();
|
contentPanel = new Panel();
|
||||||
contentPanel.Dock = DockStyle.Fill;
|
contentPanel.Dock = DockStyle.Fill;
|
||||||
contentPanel.BackColor = Color.White;
|
contentPanel.BackColor = ThemeManager.BackgroundColor;
|
||||||
contentPanel.Padding = new Padding(20);
|
contentPanel.Padding = new Padding(20);
|
||||||
this.Controls.Add(contentPanel);
|
this.Controls.Add(contentPanel);
|
||||||
|
|
||||||
@@ -238,11 +248,13 @@ namespace AppStore
|
|||||||
Panel separator = new Panel();
|
Panel separator = new Panel();
|
||||||
separator.Dock = DockStyle.Top;
|
separator.Dock = DockStyle.Top;
|
||||||
separator.Height = 1;
|
separator.Height = 1;
|
||||||
separator.BackColor = Color.FromArgb(230, 230, 230);
|
separator.BackColor = ThemeManager.CurrentTheme == ThemeManager.ThemeMode.Light
|
||||||
|
? Color.FromArgb(230, 230, 230)
|
||||||
|
: Color.FromArgb(60, 60, 60);
|
||||||
contentPanel.Controls.Add(separator);
|
contentPanel.Controls.Add(separator);
|
||||||
|
|
||||||
this.Controls.Add(buttonPanel);
|
this.Controls.Add(buttonPanel);
|
||||||
this.BackColor = Color.White;
|
this.BackColor = ThemeManager.BackgroundColor;
|
||||||
|
|
||||||
// 默认显示软件下载视图
|
// 默认显示软件下载视图
|
||||||
ShowAppsView();
|
ShowAppsView();
|
||||||
@@ -518,6 +530,42 @@ namespace AppStore
|
|||||||
}
|
}
|
||||||
flowPanel.Controls.Add(imageViewerCard);
|
flowPanel.Controls.Add(imageViewerCard);
|
||||||
|
|
||||||
|
// 密码生成器工具卡片
|
||||||
|
var passwordGeneratorCard = new ToolCard();
|
||||||
|
passwordGeneratorCard.ToolName = "密码生成器";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string iconPath = Path.Combine(Application.StartupPath, "img", "resource", "png", "password_generator.png");
|
||||||
|
if (File.Exists(iconPath))
|
||||||
|
{
|
||||||
|
passwordGeneratorCard.ToolIcon = Image.FromFile(iconPath);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
passwordGeneratorCard.ToolIcon = SystemIcons.Shield.ToBitmap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
passwordGeneratorCard.ToolIcon = SystemIcons.Shield.ToBitmap();
|
||||||
|
}
|
||||||
|
passwordGeneratorCard.ToolCardClicked += (s, e) => {
|
||||||
|
try {
|
||||||
|
string toolPath = Path.Combine(Application.StartupPath, "resource", "password_generator.exe");
|
||||||
|
if (File.Exists(toolPath)) {
|
||||||
|
Process.Start(toolPath);
|
||||||
|
} else {
|
||||||
|
MessageBox.Show("密码生成器工具未找到,请确保已正确安装", "错误",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
MessageBox.Show($"启动密码生成器失败: {ex.Message}", "错误",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
passwordGeneratorCard.UpdateDisplay();
|
||||||
|
flowPanel.Controls.Add(passwordGeneratorCard);
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -1235,6 +1283,9 @@ namespace AppStore
|
|||||||
// 初始化窗体组件
|
// 初始化窗体组件
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
|
// 应用主题
|
||||||
|
ThemeManager.ApplyTheme(this);
|
||||||
|
|
||||||
// 订阅下载管理器事件
|
// 订阅下载管理器事件
|
||||||
DownloadManager.Instance.DownloadAdded += OnDownloadAdded; // 下载添加事件
|
DownloadManager.Instance.DownloadAdded += OnDownloadAdded; // 下载添加事件
|
||||||
DownloadManager.Instance.DownloadProgressChanged += OnDownloadProgressChanged; // 下载进度变化事件
|
DownloadManager.Instance.DownloadProgressChanged += OnDownloadProgressChanged; // 下载进度变化事件
|
||||||
@@ -1316,5 +1367,69 @@ namespace AppStore
|
|||||||
Logger.Log($"下载完成: {item.FileName}, 状态: {item.Status}"); // 记录日志
|
Logger.Log($"下载完成: {item.FileName}, 状态: {item.Status}"); // 记录日志
|
||||||
item.UpdateDisplay(); // 更新UI显示
|
item.UpdateDisplay(); // 更新UI显示
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 主题切换动画效果
|
||||||
|
/// </summary>
|
||||||
|
private void AnimateThemeChange()
|
||||||
|
{
|
||||||
|
const int animationSteps = 10;
|
||||||
|
const int animationInterval = 30;
|
||||||
|
|
||||||
|
var timer = new System.Windows.Forms.Timer { Interval = animationInterval };
|
||||||
|
int step = 0;
|
||||||
|
|
||||||
|
// 保存当前和目标颜色
|
||||||
|
var originalBackColor = this.BackColor;
|
||||||
|
var targetBackColor = ThemeManager.BackgroundColor;
|
||||||
|
var originalForeColor = this.ForeColor;
|
||||||
|
var targetForeColor = ThemeManager.TextColor;
|
||||||
|
|
||||||
|
timer.Tick += (s, e) => {
|
||||||
|
if (step >= animationSteps)
|
||||||
|
{
|
||||||
|
timer.Stop();
|
||||||
|
timer.Dispose();
|
||||||
|
// 确保最终颜色准确
|
||||||
|
ThemeManager.ApplyTheme(this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算插值比例
|
||||||
|
float ratio = (float)step / animationSteps;
|
||||||
|
step++;
|
||||||
|
|
||||||
|
// 插值计算新颜色
|
||||||
|
var newBackColor = Color.FromArgb(
|
||||||
|
(int)(originalBackColor.R + (targetBackColor.R - originalBackColor.R) * ratio),
|
||||||
|
(int)(originalBackColor.G + (targetBackColor.G - originalBackColor.G) * ratio),
|
||||||
|
(int)(originalBackColor.B + (targetBackColor.B - originalBackColor.B) * ratio));
|
||||||
|
|
||||||
|
var newForeColor = Color.FromArgb(
|
||||||
|
(int)(originalForeColor.R + (targetForeColor.R - originalForeColor.R) * ratio),
|
||||||
|
(int)(originalForeColor.G + (targetForeColor.G - originalForeColor.G) * ratio),
|
||||||
|
(int)(originalForeColor.B + (targetForeColor.B - originalForeColor.B) * ratio));
|
||||||
|
|
||||||
|
// 应用新颜色
|
||||||
|
this.Invoke((MethodInvoker)delegate {
|
||||||
|
this.BackColor = newBackColor;
|
||||||
|
this.ForeColor = newForeColor;
|
||||||
|
foreach (Control control in this.Controls)
|
||||||
|
{
|
||||||
|
control.BackColor = newBackColor;
|
||||||
|
control.ForeColor = newForeColor;
|
||||||
|
|
||||||
|
// 特殊处理按钮的悬停状态
|
||||||
|
if (control is Button button)
|
||||||
|
{
|
||||||
|
button.FlatAppearance.MouseOverBackColor = ThemeManager.ButtonHoverColor;
|
||||||
|
button.FlatAppearance.MouseDownBackColor = ThemeManager.ButtonActiveColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
timer.Start();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,29 +2,64 @@ using System;
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
namespace AppStore
|
namespace AppStore
|
||||||
{
|
{
|
||||||
public class SettingsUserControl : UserControl
|
public class SettingsUserControl : UserControl
|
||||||
{
|
{
|
||||||
private Button btnCleanLogs;
|
private Button btnCleanLogs;
|
||||||
|
private Button btnLightTheme;
|
||||||
|
private Button btnDarkTheme;
|
||||||
|
|
||||||
public SettingsUserControl()
|
public SettingsUserControl()
|
||||||
{
|
{
|
||||||
this.Dock = DockStyle.Fill;
|
this.Dock = DockStyle.Fill;
|
||||||
this.BackColor = Color.White;
|
ThemeManager.ApplyTheme(this);
|
||||||
|
|
||||||
// 设置顶部内边距
|
// 设置顶部内边距
|
||||||
this.Padding = new Padding(0, 30, 0, 0);
|
this.Padding = new Padding(0, 30, 0, 0);
|
||||||
|
|
||||||
|
// 主题切换按钮
|
||||||
|
btnLightTheme = new Button();
|
||||||
|
btnLightTheme.Text = "浅色模式";
|
||||||
|
btnLightTheme.Size = new Size(150, 40);
|
||||||
|
btnLightTheme.Location = new Point((this.Width - 320) / 2, 50);
|
||||||
|
btnLightTheme.Font = new Font("Microsoft YaHei", 10);
|
||||||
|
btnLightTheme.Anchor = AnchorStyles.Top;
|
||||||
|
btnLightTheme.Click += (s, e) => SwitchTheme(ThemeManager.ThemeMode.Light);
|
||||||
|
this.Controls.Add(btnLightTheme);
|
||||||
|
|
||||||
|
btnDarkTheme = new Button();
|
||||||
|
btnDarkTheme.Text = "深色模式";
|
||||||
|
btnDarkTheme.Size = new Size(150, 40);
|
||||||
|
btnDarkTheme.Location = new Point(btnLightTheme.Right + 20, 50);
|
||||||
|
btnDarkTheme.Font = new Font("Microsoft YaHei", 10);
|
||||||
|
btnDarkTheme.Anchor = AnchorStyles.Top;
|
||||||
|
btnDarkTheme.Click += (s, e) => SwitchTheme(ThemeManager.ThemeMode.Dark);
|
||||||
|
this.Controls.Add(btnDarkTheme);
|
||||||
|
|
||||||
|
// 清理日志按钮
|
||||||
btnCleanLogs = new Button();
|
btnCleanLogs = new Button();
|
||||||
btnCleanLogs.Text = "清理日志";
|
btnCleanLogs.Text = "清理日志";
|
||||||
btnCleanLogs.Size = new Size(150, 40);
|
btnCleanLogs.Size = new Size(150, 40);
|
||||||
btnCleanLogs.Location = new Point((this.Width - 150) / 2, 50); // 调整Y坐标为50靠近顶部
|
btnCleanLogs.Location = new Point((this.Width - 150) / 2, 110);
|
||||||
btnCleanLogs.Font = new Font("Microsoft YaHei", 10);
|
btnCleanLogs.Font = new Font("Microsoft YaHei", 10);
|
||||||
btnCleanLogs.Anchor = AnchorStyles.Top; // 添加顶部锚点
|
btnCleanLogs.Anchor = AnchorStyles.Top;
|
||||||
btnCleanLogs.Click += (s, e) => CleanLogs();
|
btnCleanLogs.Click += (s, e) => CleanLogs();
|
||||||
this.Controls.Add(btnCleanLogs);
|
this.Controls.Add(btnCleanLogs);
|
||||||
|
|
||||||
|
ThemeManager.ThemeChanged += OnThemeChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SwitchTheme(ThemeManager.ThemeMode theme)
|
||||||
|
{
|
||||||
|
ThemeManager.CurrentTheme = theme;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnThemeChanged(ThemeManager.ThemeMode theme)
|
||||||
|
{
|
||||||
|
ThemeManager.ApplyTheme(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CleanLogs()
|
private void CleanLogs()
|
||||||
|
|||||||
12
TXT/Build.txt
Normal file
12
TXT/Build.txt
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
首先,如果希望编译程序,那么必须安装.NET8.0 SDK
|
||||||
|
下载链接:https://dotnet.microsoft.com/zh-cn/download/dotnet/thank-you/sdk-8.0.411-windows-x64-installer
|
||||||
|
|
||||||
|
使用一下指令编译
|
||||||
|
|
||||||
|
x86:
|
||||||
|
|
||||||
|
dotnet publish AppStore.csproj -c Release -r win-x86 --self-contained false /p:Optimize=true /p:DebugType=None
|
||||||
|
|
||||||
|
x64:
|
||||||
|
|
||||||
|
dotnet publish AppStore.csproj -c Release -r win-x64 --self-contained false /p:Optimize=true /p:DebugType=None
|
||||||
7
TXT/Run.txt
Normal file
7
TXT/Run.txt
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
如果希望运行,那么必须安装.NET8.0 SDK
|
||||||
|
|
||||||
|
下载链接:https://dotnet.microsoft.com/zh-cn/download/dotnet/thank-you/sdk-8.0.411-windows-x64-installer
|
||||||
|
|
||||||
|
使用一下指令运行:
|
||||||
|
|
||||||
|
dotnet run
|
||||||
127
ThemeManager.cs
Normal file
127
ThemeManager.cs
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace AppStore
|
||||||
|
{
|
||||||
|
public static class ThemeManager
|
||||||
|
{
|
||||||
|
public enum ThemeMode
|
||||||
|
{
|
||||||
|
Light,
|
||||||
|
Dark
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly string ThemeConfigPath = Path.Combine(
|
||||||
|
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
|
||||||
|
"zsyg", "kortapp-z", ".date", "theme.json");
|
||||||
|
|
||||||
|
private static ThemeMode _currentTheme = LoadTheme();
|
||||||
|
|
||||||
|
private static ThemeMode LoadTheme()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (File.Exists(ThemeConfigPath))
|
||||||
|
{
|
||||||
|
var json = File.ReadAllText(ThemeConfigPath);
|
||||||
|
return JsonSerializer.Deserialize<ThemeMode>(json);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// 忽略错误,使用默认主题
|
||||||
|
}
|
||||||
|
return ThemeMode.Light;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void SaveTheme(ThemeMode theme)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var dir = Path.GetDirectoryName(ThemeConfigPath);
|
||||||
|
if (!Directory.Exists(dir))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(dir);
|
||||||
|
}
|
||||||
|
var json = JsonSerializer.Serialize(theme);
|
||||||
|
File.WriteAllText(ThemeConfigPath, json);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// 忽略错误
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 浅色主题颜色
|
||||||
|
private static readonly Color LightBackground = Color.FromArgb(255, 255, 255);
|
||||||
|
private static readonly Color LightControlBackground = Color.FromArgb(240, 240, 240);
|
||||||
|
private static readonly Color LightText = Color.FromArgb(30, 30, 30);
|
||||||
|
private static readonly Color LightButtonHover = Color.FromArgb(230, 230, 230);
|
||||||
|
private static readonly Color LightButtonActive = Color.FromArgb(220, 220, 220);
|
||||||
|
|
||||||
|
// 深色主题颜色
|
||||||
|
private static readonly Color DarkBackground = Color.FromArgb(30, 30, 30);
|
||||||
|
private static readonly Color DarkControlBackground = Color.FromArgb(45, 45, 45);
|
||||||
|
private static readonly Color DarkText = Color.FromArgb(240, 240, 240);
|
||||||
|
private static readonly Color DarkButtonHover = Color.FromArgb(60, 60, 60);
|
||||||
|
private static readonly Color DarkButtonActive = Color.FromArgb(70, 70, 70);
|
||||||
|
|
||||||
|
public static event Action<ThemeMode> ThemeChanged = delegate {};
|
||||||
|
|
||||||
|
public static ThemeMode CurrentTheme
|
||||||
|
{
|
||||||
|
get => _currentTheme;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_currentTheme != value)
|
||||||
|
{
|
||||||
|
_currentTheme = value;
|
||||||
|
ThemeChanged?.Invoke(value);
|
||||||
|
SaveTheme(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Color BackgroundColor =>
|
||||||
|
_currentTheme == ThemeMode.Light ? LightBackground : DarkBackground;
|
||||||
|
|
||||||
|
public static Color ControlBackgroundColor =>
|
||||||
|
_currentTheme == ThemeMode.Light ? LightControlBackground : DarkControlBackground;
|
||||||
|
|
||||||
|
public static Color TextColor =>
|
||||||
|
_currentTheme == ThemeMode.Light ? LightText : DarkText;
|
||||||
|
|
||||||
|
public static Color ButtonHoverColor =>
|
||||||
|
_currentTheme == ThemeMode.Light ? LightButtonHover : DarkButtonHover;
|
||||||
|
|
||||||
|
public static Color ButtonActiveColor =>
|
||||||
|
_currentTheme == ThemeMode.Light ? LightButtonActive : DarkButtonActive;
|
||||||
|
|
||||||
|
public static void ApplyTheme(Control control)
|
||||||
|
{
|
||||||
|
ApplyThemeToControl(control);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ApplyThemeToControl(Control control)
|
||||||
|
{
|
||||||
|
control.BackColor = BackgroundColor;
|
||||||
|
control.ForeColor = TextColor;
|
||||||
|
|
||||||
|
if (control is Button button)
|
||||||
|
{
|
||||||
|
button.FlatStyle = FlatStyle.Flat;
|
||||||
|
button.FlatAppearance.BorderSize = 0;
|
||||||
|
button.FlatAppearance.MouseOverBackColor = ButtonHoverColor;
|
||||||
|
button.FlatAppearance.MouseDownBackColor = ButtonActiveColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (Control childControl in control.Controls)
|
||||||
|
{
|
||||||
|
ApplyThemeToControl(childControl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
; 有关创建 Inno Setup 脚本文件的详细信息,请参阅帮助文档!
|
; 有关创建 Inno Setup 脚本文件的详细信息,请参阅帮助文档!
|
||||||
|
|
||||||
#define MyAppName "kortapp-z"
|
#define MyAppName "kortapp-z"
|
||||||
#define MyAppVersion "1.0.9"
|
#define MyAppVersion "1.1.1"
|
||||||
#define MyAppPublisher "zsyg"
|
#define MyAppPublisher "zsyg"
|
||||||
#define MyAppURL "https://github.com/zs-yg/kortapp-z"
|
#define MyAppURL "https://github.com/zs-yg/kortapp-z"
|
||||||
#define MyAppExeName "kortapp.exe"
|
#define MyAppExeName "kortapp.exe"
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
; 有关创建 Inno Setup 脚本文件的详细信息,请参阅帮助文档!
|
; 有关创建 Inno Setup 脚本文件的详细信息,请参阅帮助文档!
|
||||||
|
|
||||||
#define MyAppName "kortapp-z"
|
#define MyAppName "kortapp-z"
|
||||||
#define MyAppVersion "1.0.9"
|
#define MyAppVersion "1.1.1"
|
||||||
#define MyAppPublisher "zsyg"
|
#define MyAppPublisher "zsyg"
|
||||||
#define MyAppURL "https://github.com/zs-yg/kortapp-z"
|
#define MyAppURL "https://github.com/zs-yg/kortapp-z"
|
||||||
#define MyAppExeName "kortapp.exe"
|
#define MyAppExeName "kortapp.exe"
|
||||||
|
|||||||
20
others/C/C++/Makefile
Normal file
20
others/C/C++/Makefile
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
CXX = g++
|
||||||
|
CXXFLAGS = -std=c++11 -Iinclude
|
||||||
|
LDFLAGS = -static -mwindows -lfltk -lole32 -luuid -lcomctl32 -lgdi32 -lwsock32 -lcomdlg32 -lwinspool
|
||||||
|
|
||||||
|
SRC = $(wildcard src/*.cpp)
|
||||||
|
OBJ = $(patsubst src/%.cpp,obj/%.o,$(SRC))
|
||||||
|
TARGET = password_generator
|
||||||
|
|
||||||
|
all: $(TARGET)
|
||||||
|
|
||||||
|
$(TARGET): $(OBJ)
|
||||||
|
$(CXX) $^ -o $@ $(LDFLAGS)
|
||||||
|
|
||||||
|
obj/%.o: src/%.cpp
|
||||||
|
$(CXX) $(CXXFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(OBJ) $(TARGET)
|
||||||
|
|
||||||
|
.PHONY: all clean
|
||||||
27
others/C/C++/include/password_generator.hpp
Normal file
27
others/C/C++/include/password_generator.hpp
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#ifndef PASSWORD_GENERATOR_HPP
|
||||||
|
#define PASSWORD_GENERATOR_HPP
|
||||||
|
|
||||||
|
#include "string.hpp"
|
||||||
|
|
||||||
|
class PasswordGenerator {
|
||||||
|
public:
|
||||||
|
enum Mode {
|
||||||
|
DIGITS, // 纯数字
|
||||||
|
ENGLISH, // 纯英文
|
||||||
|
SYMBOLS, // 纯符号
|
||||||
|
DIGITS_ENGLISH, // 数字+英文
|
||||||
|
DIGITS_SYMBOLS, // 数字+符号
|
||||||
|
ENGLISH_SYMBOLS // 英文+符号
|
||||||
|
};
|
||||||
|
|
||||||
|
PasswordGenerator();
|
||||||
|
String generate(int length, Mode mode = DIGITS);
|
||||||
|
|
||||||
|
private:
|
||||||
|
String generateDigits(int length);
|
||||||
|
String generateEnglish(int length);
|
||||||
|
String generateSymbols(int length);
|
||||||
|
String generateMixed(int length, const String& charSet);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PASSWORD_GENERATOR_HPP
|
||||||
28
others/C/C++/include/password_gui.hpp
Normal file
28
others/C/C++/include/password_gui.hpp
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#ifndef PASSWORD_GUI_HPP
|
||||||
|
#define PASSWORD_GUI_HPP
|
||||||
|
|
||||||
|
#include <FL/Fl.H>
|
||||||
|
#include <FL/Fl_Window.H>
|
||||||
|
#include <FL/Fl_Input.H>
|
||||||
|
#include <FL/Fl_Choice.H>
|
||||||
|
#include <FL/Fl_Button.H>
|
||||||
|
#include <FL/Fl_Output.H>
|
||||||
|
#include "password_generator.hpp"
|
||||||
|
|
||||||
|
class PasswordGUI {
|
||||||
|
public:
|
||||||
|
PasswordGUI();
|
||||||
|
void show();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Fl_Window* window;
|
||||||
|
Fl_Input* lengthInput;
|
||||||
|
Fl_Choice* modeChoice;
|
||||||
|
Fl_Button* generateButton;
|
||||||
|
Fl_Output* passwordOutput;
|
||||||
|
PasswordGenerator generator;
|
||||||
|
|
||||||
|
static void onGenerate(Fl_Widget* widget, void* data);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PASSWORD_GUI_HPP
|
||||||
25
others/C/C++/include/string.hpp
Normal file
25
others/C/C++/include/string.hpp
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
#ifndef STRING_HPP
|
||||||
|
#define STRING_HPP
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
class String {
|
||||||
|
public:
|
||||||
|
String();
|
||||||
|
String(const char* str);
|
||||||
|
String(const String& other);
|
||||||
|
~String();
|
||||||
|
|
||||||
|
size_t length() const;
|
||||||
|
const char* c_str() const;
|
||||||
|
|
||||||
|
String& operator=(const String& other);
|
||||||
|
String operator+(const String& other) const;
|
||||||
|
bool operator==(const String& other) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
char* data;
|
||||||
|
size_t len;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // STRING_HPP
|
||||||
7
others/C/C++/src/main.cpp
Normal file
7
others/C/C++/src/main.cpp
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#include "password_gui.hpp"
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
PasswordGUI gui;
|
||||||
|
gui.show();
|
||||||
|
return Fl::run();
|
||||||
|
}
|
||||||
96
others/C/C++/src/password_generator.cpp
Normal file
96
others/C/C++/src/password_generator.cpp
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
#include "password_generator.hpp"
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
PasswordGenerator::PasswordGenerator() {
|
||||||
|
srand(time(nullptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
String PasswordGenerator::generate(int length, Mode mode) {
|
||||||
|
if (length < 1 || length > 100) {
|
||||||
|
return String("无效长度(1-100)");
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (mode) {
|
||||||
|
case DIGITS:
|
||||||
|
return generateDigits(length);
|
||||||
|
case ENGLISH:
|
||||||
|
return generateEnglish(length);
|
||||||
|
case SYMBOLS:
|
||||||
|
return generateSymbols(length);
|
||||||
|
case DIGITS_ENGLISH: {
|
||||||
|
String charSet = String("0123456789") +
|
||||||
|
String("abcdefghijklmnopqrstuvwxyz") +
|
||||||
|
String("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
|
||||||
|
return generateMixed(length, charSet);
|
||||||
|
}
|
||||||
|
case DIGITS_SYMBOLS: {
|
||||||
|
String charSet = String("0123456789") + String("!@#$%^&*()_+-=[]{}|;:,.<>?");
|
||||||
|
return generateMixed(length, charSet);
|
||||||
|
}
|
||||||
|
case ENGLISH_SYMBOLS: {
|
||||||
|
String charSet = String("abcdefghijklmnopqrstuvwxyz") +
|
||||||
|
String("ABCDEFGHIJKLMNOPQRSTUVWXYZ") +
|
||||||
|
String("!@#$%^&*()_+-=[]{}|;:,.<>?");
|
||||||
|
return generateMixed(length, charSet);
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return String("不支持的模式");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String PasswordGenerator::generateDigits(int length) {
|
||||||
|
char* buffer = new char[length + 1];
|
||||||
|
for (int i = 0; i < length; ++i) {
|
||||||
|
buffer[i] = '0' + (rand() % 10);
|
||||||
|
}
|
||||||
|
buffer[length] = '\0';
|
||||||
|
|
||||||
|
String result(buffer);
|
||||||
|
delete[] buffer;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
String PasswordGenerator::generateEnglish(int length) {
|
||||||
|
char* buffer = new char[length + 1];
|
||||||
|
for (int i = 0; i < length; ++i) {
|
||||||
|
int choice = rand() % 2;
|
||||||
|
if (choice == 0) {
|
||||||
|
buffer[i] = 'a' + (rand() % 26); // 小写字母
|
||||||
|
} else {
|
||||||
|
buffer[i] = 'A' + (rand() % 26); // 大写字母
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buffer[length] = '\0';
|
||||||
|
|
||||||
|
String result(buffer);
|
||||||
|
delete[] buffer;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
String PasswordGenerator::generateSymbols(int length) {
|
||||||
|
const char symbols[] = "!@#$%^&*()_+-=[]{}|;:,.<>?";
|
||||||
|
const int symbolCount = sizeof(symbols) - 1; // 减去末尾的\0
|
||||||
|
|
||||||
|
char* buffer = new char[length + 1];
|
||||||
|
for (int i = 0; i < length; ++i) {
|
||||||
|
buffer[i] = symbols[rand() % symbolCount];
|
||||||
|
}
|
||||||
|
buffer[length] = '\0';
|
||||||
|
|
||||||
|
String result(buffer);
|
||||||
|
delete[] buffer;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
String PasswordGenerator::generateMixed(int length, const String& charSet) {
|
||||||
|
char* buffer = new char[length + 1];
|
||||||
|
for (int i = 0; i < length; ++i) {
|
||||||
|
buffer[i] = charSet.c_str()[rand() % charSet.length()];
|
||||||
|
}
|
||||||
|
buffer[length] = '\0';
|
||||||
|
|
||||||
|
String result(buffer);
|
||||||
|
delete[] buffer;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
36
others/C/C++/src/password_gui.cpp
Normal file
36
others/C/C++/src/password_gui.cpp
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
#include "password_gui.hpp"
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
PasswordGUI::PasswordGUI() {
|
||||||
|
window = new Fl_Window(400, 350, "密码生成器");
|
||||||
|
|
||||||
|
lengthInput = new Fl_Input(150, 50, 200, 30, "密码长度:");
|
||||||
|
modeChoice = new Fl_Choice(150, 90, 200, 30, "密码模式:");
|
||||||
|
modeChoice->add("纯数字");
|
||||||
|
modeChoice->add("纯英文");
|
||||||
|
modeChoice->add("纯符号");
|
||||||
|
modeChoice->add("数字+英文");
|
||||||
|
modeChoice->add("数字+符号");
|
||||||
|
modeChoice->add("英文+符号");
|
||||||
|
modeChoice->value(0); // 默认选择纯数字模式
|
||||||
|
|
||||||
|
generateButton = new Fl_Button(150, 140, 100, 40, "生成密码");
|
||||||
|
passwordOutput = new Fl_Output(100, 210, 250, 40, "生成结果:");
|
||||||
|
|
||||||
|
generateButton->callback(onGenerate, this);
|
||||||
|
window->end();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PasswordGUI::show() {
|
||||||
|
window->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PasswordGUI::onGenerate(Fl_Widget* widget, void* data) {
|
||||||
|
PasswordGUI* gui = static_cast<PasswordGUI*>(data);
|
||||||
|
const char* lengthStr = gui->lengthInput->value();
|
||||||
|
int length = atoi(lengthStr);
|
||||||
|
|
||||||
|
PasswordGenerator::Mode mode = static_cast<PasswordGenerator::Mode>(gui->modeChoice->value());
|
||||||
|
String password = gui->generator.generate(length, mode);
|
||||||
|
gui->passwordOutput->value(password.c_str());
|
||||||
|
}
|
||||||
51
others/C/C++/src/string.cpp
Normal file
51
others/C/C++/src/string.cpp
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
#include "string.hpp"
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
String::String() : data(nullptr), len(0) {}
|
||||||
|
|
||||||
|
String::String(const char* str) {
|
||||||
|
len = strlen(str);
|
||||||
|
data = new char[len + 1];
|
||||||
|
strcpy(data, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
String::String(const String& other) {
|
||||||
|
len = other.len;
|
||||||
|
data = new char[len + 1];
|
||||||
|
strcpy(data, other.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
String::~String() {
|
||||||
|
delete[] data;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t String::length() const {
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* String::c_str() const {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
String& String::operator=(const String& other) {
|
||||||
|
if (this != &other) {
|
||||||
|
delete[] data;
|
||||||
|
len = other.len;
|
||||||
|
data = new char[len + 1];
|
||||||
|
strcpy(data, other.data);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
String String::operator+(const String& other) const {
|
||||||
|
String result;
|
||||||
|
result.len = len + other.len;
|
||||||
|
result.data = new char[result.len + 1];
|
||||||
|
strcpy(result.data, data);
|
||||||
|
strcat(result.data, other.data);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool String::operator==(const String& other) const {
|
||||||
|
return strcmp(data, other.data) == 0;
|
||||||
|
}
|
||||||
BIN
resource/password_generator.exe
Normal file
BIN
resource/password_generator.exe
Normal file
Binary file not shown.
Reference in New Issue
Block a user