mirror of
https://github.com/fofolee/uTools-quickcommand.git
synced 2025-08-14 01:29:39 +08:00
优化windows下系统弹窗在高分屏下的显示,修复多处bug,去掉showsystemselectlist接口,调整runSharp接口,支持传参
This commit is contained in:
parent
0a8c24374a
commit
877d13958a
745
plugin/lib/csharp/dialog.cs
Normal file
745
plugin/lib/csharp/dialog.cs
Normal file
@ -0,0 +1,745 @@
|
|||||||
|
using System;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.IO;
|
||||||
|
using System.Drawing.Drawing2D;
|
||||||
|
|
||||||
|
public class DialogGenerator
|
||||||
|
{
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
private static extern bool SetProcessDPIAware();
|
||||||
|
|
||||||
|
private const int DEFAULT_WIDTH = 900;
|
||||||
|
private const int DEFAULT_HEIGHT = 350;
|
||||||
|
private const int PADDING = 30;
|
||||||
|
private const int BUTTON_HEIGHT = 50;
|
||||||
|
private const int BUTTON_WIDTH = 140;
|
||||||
|
private const int INPUT_HEIGHT = 40;
|
||||||
|
private const int SPACING = 20;
|
||||||
|
private const int EM_SETRECT = 0xB3;
|
||||||
|
|
||||||
|
private static void InitializeDPIAwareness()
|
||||||
|
{
|
||||||
|
if (Environment.OSVersion.Version.Major >= 6)
|
||||||
|
{
|
||||||
|
SetProcessDPIAware();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DialogResult Show(string[] args)
|
||||||
|
{
|
||||||
|
string type = GetArgumentValue(args, "-type");
|
||||||
|
string title = GetArgumentValue(args, "-title");
|
||||||
|
string content = GetArgumentValue(args, "-content");
|
||||||
|
string iconPath = GetArgumentValue(args, "-iconpath");
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(type) || string.IsNullOrEmpty(title))
|
||||||
|
{
|
||||||
|
MessageBox.Show("必须指定 -type 和 -title 参数");
|
||||||
|
return DialogResult.None;
|
||||||
|
}
|
||||||
|
|
||||||
|
Form dialog = CreateBaseDialog(title);
|
||||||
|
|
||||||
|
// 设置图标
|
||||||
|
if (!string.IsNullOrEmpty(iconPath) && File.Exists(iconPath))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (Bitmap bmp = new Bitmap(iconPath))
|
||||||
|
{
|
||||||
|
dialog.Icon = Icon.FromHandle(bmp.GetHicon());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show("加载图标失败: " + ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (type.ToLower())
|
||||||
|
{
|
||||||
|
case "message":
|
||||||
|
CreateMessageDialog(dialog, content);
|
||||||
|
break;
|
||||||
|
case "input":
|
||||||
|
CreateInputDialog(dialog, content);
|
||||||
|
break;
|
||||||
|
case "confirm":
|
||||||
|
CreateConfirmDialog(dialog, content);
|
||||||
|
break;
|
||||||
|
case "buttons":
|
||||||
|
CreateButtonsDialog(dialog, content);
|
||||||
|
break;
|
||||||
|
case "textarea":
|
||||||
|
CreateTextAreaDialog(dialog, content);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
MessageBox.Show("不支持的对话框类型");
|
||||||
|
return DialogResult.None;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dialog.ShowDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Form CreateBaseDialog(string title)
|
||||||
|
{
|
||||||
|
Form dialog = new Form();
|
||||||
|
dialog.Text = title;
|
||||||
|
dialog.Width = DEFAULT_WIDTH;
|
||||||
|
dialog.Height = DEFAULT_HEIGHT;
|
||||||
|
dialog.StartPosition = FormStartPosition.CenterScreen;
|
||||||
|
|
||||||
|
// 使用 Microsoft YaHei UI 字体
|
||||||
|
dialog.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point);
|
||||||
|
|
||||||
|
// 设置DPI感知
|
||||||
|
dialog.AutoScaleMode = AutoScaleMode.Dpi;
|
||||||
|
|
||||||
|
// 设置文本渲染质量
|
||||||
|
dialog.Paint += delegate(object sender, PaintEventArgs e) {
|
||||||
|
e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
|
||||||
|
};
|
||||||
|
|
||||||
|
return dialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CreateMessageDialog(Form dialog, string content)
|
||||||
|
{
|
||||||
|
const int MAX_CONTENT_HEIGHT = 500;
|
||||||
|
const int MIN_CONTENT_HEIGHT = 200;
|
||||||
|
int iconSize = 96;
|
||||||
|
|
||||||
|
// 先计算所需的内容高度
|
||||||
|
int requiredHeight = Math.Max(
|
||||||
|
TextRenderer.MeasureText(content,
|
||||||
|
new Font("Microsoft YaHei UI", 10F, FontStyle.Regular),
|
||||||
|
new Size(dialog.ClientSize.Width - PADDING * 3 - iconSize, int.MaxValue),
|
||||||
|
TextFormatFlags.WordBreak | TextFormatFlags.TextBoxControl
|
||||||
|
).Height + 20,
|
||||||
|
MIN_CONTENT_HEIGHT
|
||||||
|
);
|
||||||
|
|
||||||
|
int contentHeight = Math.Min(requiredHeight, MAX_CONTENT_HEIGHT);
|
||||||
|
dialog.Height = contentHeight + PADDING * 3 + BUTTON_HEIGHT;
|
||||||
|
|
||||||
|
// 创建内容面板
|
||||||
|
Panel contentPanel = new Panel
|
||||||
|
{
|
||||||
|
AutoScroll = false,
|
||||||
|
Width = dialog.ClientSize.Width - PADDING * 2,
|
||||||
|
Height = dialog.ClientSize.Height - PADDING * 3 - BUTTON_HEIGHT,
|
||||||
|
Location = new Point(PADDING, PADDING),
|
||||||
|
BackColor = SystemColors.Control
|
||||||
|
};
|
||||||
|
|
||||||
|
dialog.Controls.Add(contentPanel);
|
||||||
|
|
||||||
|
// 添加图标
|
||||||
|
PictureBox iconBox = new PictureBox
|
||||||
|
{
|
||||||
|
Width = iconSize,
|
||||||
|
Height = iconSize,
|
||||||
|
Location = new Point(0, 0),
|
||||||
|
SizeMode = PictureBoxSizeMode.Zoom,
|
||||||
|
BackColor = Color.Transparent
|
||||||
|
};
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Icon sysIcon = SystemIcons.Information;
|
||||||
|
Bitmap bmp = new Bitmap(iconSize, iconSize);
|
||||||
|
using (Graphics g = Graphics.FromImage(bmp))
|
||||||
|
{
|
||||||
|
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
||||||
|
g.SmoothingMode = SmoothingMode.AntiAlias;
|
||||||
|
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
||||||
|
g.DrawIcon(sysIcon, new Rectangle(0, 0, iconSize, iconSize));
|
||||||
|
}
|
||||||
|
iconBox.Image = bmp;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
iconBox.Visible = false;
|
||||||
|
}
|
||||||
|
contentPanel.Controls.Add(iconBox);
|
||||||
|
|
||||||
|
// 使用普通TextBox替代RichTextBox
|
||||||
|
TextBox messageBox = new TextBox
|
||||||
|
{
|
||||||
|
Text = content,
|
||||||
|
ReadOnly = true,
|
||||||
|
Multiline = true,
|
||||||
|
BorderStyle = BorderStyle.None,
|
||||||
|
BackColor = SystemColors.Control,
|
||||||
|
Location = new Point(iconSize + PADDING, 0),
|
||||||
|
Width = contentPanel.ClientSize.Width - iconSize - PADDING,
|
||||||
|
Height = contentPanel.Height,
|
||||||
|
Font = new Font("Microsoft YaHei UI", 10F, FontStyle.Regular),
|
||||||
|
WordWrap = true,
|
||||||
|
TabStop = false,
|
||||||
|
Cursor = Cursors.IBeam,
|
||||||
|
ScrollBars = requiredHeight > MAX_CONTENT_HEIGHT ? ScrollBars.Vertical : ScrollBars.None
|
||||||
|
};
|
||||||
|
|
||||||
|
// 隐藏光标但允许选择
|
||||||
|
messageBox.GotFocus += delegate(object sender, EventArgs e) {
|
||||||
|
if (messageBox.SelectionLength == 0)
|
||||||
|
{
|
||||||
|
NativeMethods.HideCaret(messageBox.Handle);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
contentPanel.Controls.Add(messageBox);
|
||||||
|
|
||||||
|
// 添加确定按钮
|
||||||
|
Button okButton = CreateStyledButton("确定", DialogResult.OK);
|
||||||
|
okButton.Location = new Point(
|
||||||
|
dialog.ClientSize.Width - BUTTON_WIDTH - PADDING,
|
||||||
|
dialog.ClientSize.Height - PADDING - BUTTON_HEIGHT
|
||||||
|
);
|
||||||
|
dialog.Controls.Add(okButton);
|
||||||
|
|
||||||
|
// 确保按钮始终在最上层
|
||||||
|
okButton.BringToFront();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CreateInputDialog(Form dialog, string content)
|
||||||
|
{
|
||||||
|
const int MAX_CONTENT_HEIGHT = 500;
|
||||||
|
const int MIN_CONTENT_HEIGHT = 200;
|
||||||
|
|
||||||
|
string[] prompts = content.Split(new[] { "|||||" }, StringSplitOptions.None);
|
||||||
|
var textBoxes = new System.Collections.Generic.List<TextBox>();
|
||||||
|
|
||||||
|
// 创建一个临时窗体和面板来准确计算高度
|
||||||
|
using (Form tempForm = new Form())
|
||||||
|
{
|
||||||
|
tempForm.Width = dialog.Width;
|
||||||
|
Panel tempPanel = new Panel
|
||||||
|
{
|
||||||
|
Width = dialog.ClientSize.Width - PADDING * 2,
|
||||||
|
AutoSize = true
|
||||||
|
};
|
||||||
|
tempForm.Controls.Add(tempPanel);
|
||||||
|
|
||||||
|
// 添加临时控件来计算实际高度
|
||||||
|
int currentY = (int)(PADDING * 1.5); // 起始位置
|
||||||
|
foreach (string prompt in prompts)
|
||||||
|
{
|
||||||
|
Label label = new Label
|
||||||
|
{
|
||||||
|
Text = prompt,
|
||||||
|
AutoSize = true,
|
||||||
|
Location = new Point(PADDING, currentY),
|
||||||
|
Font = new Font("Microsoft YaHei UI", 10F, FontStyle.Regular)
|
||||||
|
};
|
||||||
|
tempPanel.Controls.Add(label);
|
||||||
|
|
||||||
|
TextBox textBox = new TextBox
|
||||||
|
{
|
||||||
|
Width = tempPanel.Width - PADDING * 2,
|
||||||
|
Height = INPUT_HEIGHT,
|
||||||
|
Location = new Point(PADDING, currentY + label.Height + 5),
|
||||||
|
BorderStyle = BorderStyle.FixedSingle
|
||||||
|
};
|
||||||
|
tempPanel.Controls.Add(textBox);
|
||||||
|
|
||||||
|
currentY += label.Height + INPUT_HEIGHT + SPACING;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取实际需要的高度
|
||||||
|
int totalContentHeight = currentY + PADDING; // 添加底部边距
|
||||||
|
int requiredHeight = Math.Max(totalContentHeight, MIN_CONTENT_HEIGHT);
|
||||||
|
int contentHeight = Math.Min(requiredHeight, MAX_CONTENT_HEIGHT);
|
||||||
|
|
||||||
|
// 设置对话框高度,保持原有的总体布局
|
||||||
|
dialog.Height = contentHeight + PADDING * 3 + BUTTON_HEIGHT;
|
||||||
|
|
||||||
|
// 创建实际的内容面板
|
||||||
|
Panel contentPanel = new Panel
|
||||||
|
{
|
||||||
|
AutoScroll = false,
|
||||||
|
Width = dialog.ClientSize.Width - PADDING * 2,
|
||||||
|
Height = dialog.ClientSize.Height - PADDING * 3 - BUTTON_HEIGHT,
|
||||||
|
Location = new Point(PADDING, PADDING),
|
||||||
|
BackColor = SystemColors.Control
|
||||||
|
};
|
||||||
|
|
||||||
|
// 只有当实际内容超过最大高度时才启用滚动
|
||||||
|
if (requiredHeight > MAX_CONTENT_HEIGHT)
|
||||||
|
{
|
||||||
|
contentPanel.AutoScroll = true;
|
||||||
|
contentPanel.AutoScrollMinSize = new Size(0, requiredHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog.Controls.Add(contentPanel);
|
||||||
|
|
||||||
|
// 添加实际的输入控件
|
||||||
|
currentY = (int)(PADDING * 0.5);
|
||||||
|
bool needScroll = requiredHeight > MAX_CONTENT_HEIGHT;
|
||||||
|
int scrollWidth = needScroll ? SystemInformation.VerticalScrollBarWidth + 10 : 0;
|
||||||
|
|
||||||
|
foreach (string prompt in prompts)
|
||||||
|
{
|
||||||
|
Label label = new Label
|
||||||
|
{
|
||||||
|
Text = prompt,
|
||||||
|
AutoSize = true,
|
||||||
|
Location = new Point(0, currentY),
|
||||||
|
Font = new Font("Microsoft YaHei UI", 10F, FontStyle.Regular)
|
||||||
|
};
|
||||||
|
contentPanel.Controls.Add(label);
|
||||||
|
|
||||||
|
TextBox textBox = new TextBox
|
||||||
|
{
|
||||||
|
Width = contentPanel.ClientSize.Width - scrollWidth,
|
||||||
|
Height = INPUT_HEIGHT,
|
||||||
|
Location = new Point(0, currentY + label.Height + 5),
|
||||||
|
BorderStyle = BorderStyle.FixedSingle,
|
||||||
|
Font = new Font("Microsoft YaHei UI", 10F, FontStyle.Regular)
|
||||||
|
};
|
||||||
|
contentPanel.Controls.Add(textBox);
|
||||||
|
textBoxes.Add(textBox);
|
||||||
|
|
||||||
|
currentY += label.Height + INPUT_HEIGHT + SPACING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加确定按钮
|
||||||
|
Button okButton = CreateStyledButton("确定", DialogResult.OK);
|
||||||
|
okButton.Location = new Point(
|
||||||
|
dialog.ClientSize.Width - BUTTON_WIDTH - PADDING,
|
||||||
|
dialog.ClientSize.Height - PADDING - BUTTON_HEIGHT
|
||||||
|
);
|
||||||
|
|
||||||
|
// 处理确定按钮点击事件
|
||||||
|
okButton.Click += (sender, e) => {
|
||||||
|
bool hasInput = false;
|
||||||
|
foreach (var textBox in textBoxes)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(textBox.Text))
|
||||||
|
{
|
||||||
|
hasInput = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasInput)
|
||||||
|
{
|
||||||
|
Console.Write("[");
|
||||||
|
for (int i = 0; i < textBoxes.Count; i++)
|
||||||
|
{
|
||||||
|
string value = textBoxes[i].Text ?? "";
|
||||||
|
Console.Write("\"" + value.Replace("\"", "\\\"") + "\"");
|
||||||
|
if (i < textBoxes.Count - 1)
|
||||||
|
{
|
||||||
|
Console.Write(",");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Console.Write("]");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.Write("[]");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
dialog.Controls.Add(okButton);
|
||||||
|
okButton.BringToFront();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CreateConfirmDialog(Form dialog, string content)
|
||||||
|
{
|
||||||
|
const int MAX_CONTENT_HEIGHT = 500;
|
||||||
|
const int MIN_CONTENT_HEIGHT = 200;
|
||||||
|
int iconSize = 96;
|
||||||
|
|
||||||
|
// 先计算所需的内容高度
|
||||||
|
int requiredHeight = Math.Max(
|
||||||
|
TextRenderer.MeasureText(content,
|
||||||
|
new Font("Microsoft YaHei UI", 10F, FontStyle.Regular),
|
||||||
|
new Size(dialog.ClientSize.Width - PADDING * 3 - iconSize, int.MaxValue),
|
||||||
|
TextFormatFlags.WordBreak | TextFormatFlags.TextBoxControl
|
||||||
|
).Height + 20,
|
||||||
|
MIN_CONTENT_HEIGHT
|
||||||
|
);
|
||||||
|
|
||||||
|
int contentHeight = Math.Min(requiredHeight, MAX_CONTENT_HEIGHT);
|
||||||
|
dialog.Height = contentHeight + PADDING * 3 + BUTTON_HEIGHT;
|
||||||
|
|
||||||
|
// 创建内容面板
|
||||||
|
Panel contentPanel = new Panel
|
||||||
|
{
|
||||||
|
AutoScroll = false,
|
||||||
|
Width = dialog.ClientSize.Width - PADDING * 2,
|
||||||
|
Height = dialog.ClientSize.Height - PADDING * 3 - BUTTON_HEIGHT,
|
||||||
|
Location = new Point(PADDING, PADDING),
|
||||||
|
BackColor = SystemColors.Control
|
||||||
|
};
|
||||||
|
|
||||||
|
dialog.Controls.Add(contentPanel);
|
||||||
|
|
||||||
|
// 添加图标
|
||||||
|
PictureBox iconBox = new PictureBox
|
||||||
|
{
|
||||||
|
Width = iconSize,
|
||||||
|
Height = iconSize,
|
||||||
|
Location = new Point(0, 0),
|
||||||
|
SizeMode = PictureBoxSizeMode.Zoom,
|
||||||
|
BackColor = Color.Transparent
|
||||||
|
};
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Icon sysIcon = SystemIcons.Warning; // 改为警告图标
|
||||||
|
Bitmap bmp = new Bitmap(iconSize, iconSize);
|
||||||
|
using (Graphics g = Graphics.FromImage(bmp))
|
||||||
|
{
|
||||||
|
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
||||||
|
g.SmoothingMode = SmoothingMode.AntiAlias;
|
||||||
|
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
||||||
|
g.DrawIcon(sysIcon, new Rectangle(0, 0, iconSize, iconSize));
|
||||||
|
}
|
||||||
|
iconBox.Image = bmp;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
iconBox.Visible = false;
|
||||||
|
}
|
||||||
|
contentPanel.Controls.Add(iconBox);
|
||||||
|
|
||||||
|
// 使用TextBox显示内容
|
||||||
|
TextBox messageBox = new TextBox
|
||||||
|
{
|
||||||
|
Text = content,
|
||||||
|
ReadOnly = true,
|
||||||
|
Multiline = true,
|
||||||
|
BorderStyle = BorderStyle.None,
|
||||||
|
BackColor = SystemColors.Control,
|
||||||
|
Location = new Point(iconSize + PADDING, 0),
|
||||||
|
Width = contentPanel.ClientSize.Width - iconSize - PADDING,
|
||||||
|
Height = contentPanel.Height,
|
||||||
|
Font = new Font("Microsoft YaHei UI", 10F, FontStyle.Regular),
|
||||||
|
WordWrap = true,
|
||||||
|
TabStop = false,
|
||||||
|
Cursor = Cursors.IBeam,
|
||||||
|
ScrollBars = requiredHeight > MAX_CONTENT_HEIGHT ? ScrollBars.Vertical : ScrollBars.None
|
||||||
|
};
|
||||||
|
|
||||||
|
// 隐藏光标但允许选择
|
||||||
|
messageBox.GotFocus += delegate(object sender, EventArgs e) {
|
||||||
|
if (messageBox.SelectionLength == 0)
|
||||||
|
{
|
||||||
|
NativeMethods.HideCaret(messageBox.Handle);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
contentPanel.Controls.Add(messageBox);
|
||||||
|
|
||||||
|
// 添加确定和取消按钮
|
||||||
|
Button okButton = CreateStyledButton("确定", DialogResult.OK);
|
||||||
|
Button cancelButton = CreateStyledButton("取消", DialogResult.Cancel);
|
||||||
|
|
||||||
|
// 修改取消按钮样式为灰色
|
||||||
|
cancelButton.BackColor = Color.FromArgb(153, 153, 153);
|
||||||
|
cancelButton.MouseEnter += delegate(object sender, EventArgs e) {
|
||||||
|
cancelButton.BackColor = Color.FromArgb(133, 133, 133);
|
||||||
|
};
|
||||||
|
cancelButton.MouseLeave += delegate(object sender, EventArgs e) {
|
||||||
|
cancelButton.BackColor = Color.FromArgb(153, 153, 153);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 调整按钮位置,靠右对齐,确认在最右边
|
||||||
|
okButton.Location = new Point(
|
||||||
|
dialog.ClientSize.Width - BUTTON_WIDTH - PADDING,
|
||||||
|
dialog.ClientSize.Height - PADDING - BUTTON_HEIGHT
|
||||||
|
);
|
||||||
|
cancelButton.Location = new Point(
|
||||||
|
dialog.ClientSize.Width - BUTTON_WIDTH * 2 - PADDING * 2,
|
||||||
|
dialog.ClientSize.Height - PADDING - BUTTON_HEIGHT
|
||||||
|
);
|
||||||
|
|
||||||
|
// 处理按钮点击事件
|
||||||
|
okButton.Click += (sender, e) => {
|
||||||
|
Console.Write("true");
|
||||||
|
};
|
||||||
|
|
||||||
|
cancelButton.Click += (sender, e) => {
|
||||||
|
Console.Write("false");
|
||||||
|
};
|
||||||
|
|
||||||
|
// 处理窗口关闭事件
|
||||||
|
dialog.FormClosing += delegate(object sender, FormClosingEventArgs e) {
|
||||||
|
if (dialog.DialogResult == DialogResult.None)
|
||||||
|
{
|
||||||
|
Console.Write("{}");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
dialog.Controls.Add(okButton);
|
||||||
|
dialog.Controls.Add(cancelButton);
|
||||||
|
|
||||||
|
// 确保按钮始终在最上层
|
||||||
|
okButton.BringToFront();
|
||||||
|
cancelButton.BringToFront();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CreateButtonsDialog(Form dialog, string content)
|
||||||
|
{
|
||||||
|
const int MAX_CONTENT_HEIGHT = 500;
|
||||||
|
const int MIN_CONTENT_HEIGHT = 200;
|
||||||
|
|
||||||
|
string[] buttonTexts = content.Split(new[] { "|||||" }, StringSplitOptions.None);
|
||||||
|
|
||||||
|
// 计算所需的内容高度
|
||||||
|
int totalHeight = buttonTexts.Length * (BUTTON_HEIGHT + SPACING) - SPACING; // 减去最后一个按钮后的间距
|
||||||
|
int requiredHeight = Math.Max(totalHeight + PADDING * 2, MIN_CONTENT_HEIGHT); // 添加上下内边距
|
||||||
|
int contentHeight = Math.Min(requiredHeight, MAX_CONTENT_HEIGHT);
|
||||||
|
|
||||||
|
// 设置对话框高度,根据按钮数量添加底部空间
|
||||||
|
int bottomPadding = buttonTexts.Length > 1 ? Math.Min(buttonTexts.Length * 10, 50) : 0; // 根据按钮数量增加底部空间,但不超过PADDING
|
||||||
|
dialog.ClientSize = new Size(dialog.ClientSize.Width, contentHeight + bottomPadding);
|
||||||
|
|
||||||
|
// 创建内容面板
|
||||||
|
Panel contentPanel = new Panel
|
||||||
|
{
|
||||||
|
AutoScroll = false,
|
||||||
|
Width = dialog.ClientSize.Width - PADDING * 2,
|
||||||
|
Height = dialog.ClientSize.Height - PADDING * 2,
|
||||||
|
Location = new Point(PADDING, PADDING),
|
||||||
|
BackColor = SystemColors.Control
|
||||||
|
};
|
||||||
|
|
||||||
|
// 只有当实际内容超过最大高度时才启用滚动
|
||||||
|
if (requiredHeight > MAX_CONTENT_HEIGHT)
|
||||||
|
{
|
||||||
|
contentPanel.AutoScroll = true;
|
||||||
|
contentPanel.AutoScrollMinSize = new Size(0, totalHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog.Controls.Add(contentPanel);
|
||||||
|
|
||||||
|
// 添加按钮
|
||||||
|
int currentY = PADDING; // 从内边距开始
|
||||||
|
bool needScroll = requiredHeight > MAX_CONTENT_HEIGHT;
|
||||||
|
int scrollWidth = needScroll ? SystemInformation.VerticalScrollBarWidth + 10 : 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < buttonTexts.Length; i++)
|
||||||
|
{
|
||||||
|
Button button = new Button
|
||||||
|
{
|
||||||
|
Text = buttonTexts[i],
|
||||||
|
Width = contentPanel.ClientSize.Width - scrollWidth,
|
||||||
|
Height = BUTTON_HEIGHT,
|
||||||
|
Location = new Point(0, currentY),
|
||||||
|
Tag = i,
|
||||||
|
FlatStyle = FlatStyle.Flat,
|
||||||
|
BackColor = Color.FromArgb(0, 122, 204), // 使用蓝色背景
|
||||||
|
ForeColor = Color.White, // 白色文字
|
||||||
|
Font = new Font("Microsoft YaHei UI", 10F, FontStyle.Regular),
|
||||||
|
Cursor = Cursors.Hand,
|
||||||
|
TextAlign = ContentAlignment.MiddleCenter // 文字居中
|
||||||
|
};
|
||||||
|
|
||||||
|
// 设置边框
|
||||||
|
button.FlatAppearance.BorderSize = 0;
|
||||||
|
|
||||||
|
// 添加圆角效果
|
||||||
|
GraphicsPath path = new GraphicsPath();
|
||||||
|
int radius = 8; // 圆角半径
|
||||||
|
Rectangle rect = new Rectangle(0, 0, button.Width, button.Height);
|
||||||
|
path.AddArc(rect.X, rect.Y, radius * 2, radius * 2, 180, 90);
|
||||||
|
path.AddArc(rect.X + rect.Width - radius * 2, rect.Y, radius * 2, radius * 2, 270, 90);
|
||||||
|
path.AddArc(rect.X + rect.Width - radius * 2, rect.Y + rect.Height - radius * 2, radius * 2, radius * 2, 0, 90);
|
||||||
|
path.AddArc(rect.X, rect.Y + rect.Height - radius * 2, radius * 2, radius * 2, 90, 90);
|
||||||
|
path.CloseFigure();
|
||||||
|
button.Region = new Region(path);
|
||||||
|
|
||||||
|
// 修改鼠标悬停效果的颜色
|
||||||
|
button.MouseEnter += delegate(object sender, EventArgs e) {
|
||||||
|
button.BackColor = Color.FromArgb(0, 102, 184); // 深一点的蓝色
|
||||||
|
};
|
||||||
|
button.MouseLeave += delegate(object sender, EventArgs e) {
|
||||||
|
button.BackColor = Color.FromArgb(0, 122, 204); // 恢复原来的蓝色
|
||||||
|
};
|
||||||
|
|
||||||
|
// 修改文本绘制部分
|
||||||
|
button.Paint += delegate(object sender, PaintEventArgs e) {
|
||||||
|
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
|
||||||
|
using (GraphicsPath buttonPath = new GraphicsPath())
|
||||||
|
{
|
||||||
|
Rectangle newRect = new Rectangle(0, 0, button.Width, button.Height);
|
||||||
|
buttonPath.AddArc(newRect.X, newRect.Y, radius * 2, radius * 2, 180, 90);
|
||||||
|
buttonPath.AddArc(newRect.X + newRect.Width - radius * 2, newRect.Y, radius * 2, radius * 2, 270, 90);
|
||||||
|
buttonPath.AddArc(newRect.X + newRect.Width - radius * 2, newRect.Y + newRect.Height - radius * 2, radius * 2, radius * 2, 0, 90);
|
||||||
|
buttonPath.AddArc(newRect.X, newRect.Y + newRect.Height - radius * 2, radius * 2, radius * 2, 90, 90);
|
||||||
|
buttonPath.CloseFigure();
|
||||||
|
|
||||||
|
e.Graphics.FillPath(new SolidBrush(button.BackColor), buttonPath);
|
||||||
|
|
||||||
|
// 绘制文本(居中对齐)
|
||||||
|
StringFormat sf = new StringFormat();
|
||||||
|
sf.Alignment = StringAlignment.Center; // 水平居中
|
||||||
|
sf.LineAlignment = StringAlignment.Center; // 垂直居中
|
||||||
|
e.Graphics.DrawString(button.Text, button.Font, new SolidBrush(button.ForeColor), newRect, sf);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 添加按钮点击事件
|
||||||
|
button.Click += delegate(object sender, EventArgs e) {
|
||||||
|
Button clickedButton = (Button)sender;
|
||||||
|
int id = (int)clickedButton.Tag;
|
||||||
|
string text = clickedButton.Text;
|
||||||
|
Console.Write("{\"id\":" + id + ",\"text\":\"" + text.Replace("\"", "\\\"") + "\"}");
|
||||||
|
dialog.DialogResult = DialogResult.OK;
|
||||||
|
};
|
||||||
|
|
||||||
|
contentPanel.Controls.Add(button);
|
||||||
|
currentY += BUTTON_HEIGHT + SPACING;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理窗口关闭事件
|
||||||
|
dialog.FormClosing += delegate(object sender, FormClosingEventArgs e) {
|
||||||
|
if (dialog.DialogResult == DialogResult.None)
|
||||||
|
{
|
||||||
|
Console.Write("{}");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CreateTextAreaDialog(Form dialog, string content)
|
||||||
|
{
|
||||||
|
dialog.Height = 600; // 改为600
|
||||||
|
|
||||||
|
TextBox textArea = new TextBox
|
||||||
|
{
|
||||||
|
Multiline = true,
|
||||||
|
ScrollBars = ScrollBars.Vertical,
|
||||||
|
Width = dialog.ClientSize.Width - PADDING * 2,
|
||||||
|
Height = dialog.ClientSize.Height - PADDING * 3 - BUTTON_HEIGHT,
|
||||||
|
Location = new Point(PADDING, PADDING),
|
||||||
|
ForeColor = SystemColors.WindowText,
|
||||||
|
Text = content, // 使用传入的content作为默认文本
|
||||||
|
Font = new Font("Microsoft YaHei UI", 10F, FontStyle.Regular),
|
||||||
|
BorderStyle = BorderStyle.FixedSingle
|
||||||
|
};
|
||||||
|
|
||||||
|
dialog.Controls.Add(textArea);
|
||||||
|
|
||||||
|
// 添加确定按钮
|
||||||
|
Button okButton = CreateStyledButton("确定", DialogResult.OK);
|
||||||
|
okButton.Location = new Point(
|
||||||
|
dialog.ClientSize.Width - BUTTON_WIDTH - PADDING,
|
||||||
|
dialog.ClientSize.Height - PADDING - BUTTON_HEIGHT
|
||||||
|
);
|
||||||
|
|
||||||
|
// 处理确定按钮点击事件
|
||||||
|
okButton.Click += delegate(object sender, EventArgs e) {
|
||||||
|
Console.Write(textArea.Text ?? ""); // 直接输出文本,不加引号
|
||||||
|
};
|
||||||
|
|
||||||
|
dialog.Controls.Add(okButton);
|
||||||
|
okButton.BringToFront();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetArgumentValue(string[] args, string key)
|
||||||
|
{
|
||||||
|
int index = Array.IndexOf(args, key);
|
||||||
|
if (index >= 0 && index < args.Length - 1)
|
||||||
|
{
|
||||||
|
return args[index + 1];
|
||||||
|
}
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void StyleButton(Button button)
|
||||||
|
{
|
||||||
|
button.FlatStyle = FlatStyle.Flat;
|
||||||
|
button.FlatAppearance.BorderSize = 0;
|
||||||
|
button.BackColor = Color.FromArgb(0, 122, 204);
|
||||||
|
button.ForeColor = Color.White;
|
||||||
|
button.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular);
|
||||||
|
button.Cursor = Cursors.Hand;
|
||||||
|
button.Width = BUTTON_WIDTH;
|
||||||
|
button.Height = BUTTON_HEIGHT;
|
||||||
|
|
||||||
|
// 圆角绘制
|
||||||
|
GraphicsPath path = new GraphicsPath();
|
||||||
|
int radius = 8; // 圆角半径
|
||||||
|
Rectangle rect = new Rectangle(0, 0, button.Width, button.Height);
|
||||||
|
path.AddArc(rect.X, rect.Y, radius * 2, radius * 2, 180, 90);
|
||||||
|
path.AddArc(rect.X + rect.Width - radius * 2, rect.Y, radius * 2, radius * 2, 270, 90);
|
||||||
|
path.AddArc(rect.X + rect.Width - radius * 2, rect.Y + rect.Height - radius * 2, radius * 2, radius * 2, 0, 90);
|
||||||
|
path.AddArc(rect.X, rect.Y + rect.Height - radius * 2, radius * 2, radius * 2, 90, 90);
|
||||||
|
path.CloseFigure();
|
||||||
|
button.Region = new Region(path);
|
||||||
|
|
||||||
|
// 添加鼠标悬停效果
|
||||||
|
button.MouseEnter += delegate(object sender, EventArgs e) {
|
||||||
|
button.BackColor = Color.FromArgb(0, 102, 184);
|
||||||
|
};
|
||||||
|
button.MouseLeave += delegate(object sender, EventArgs e) {
|
||||||
|
button.BackColor = Color.FromArgb(0, 122, 204);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 自定义绘制
|
||||||
|
button.Paint += delegate(object sender, PaintEventArgs e) {
|
||||||
|
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
|
||||||
|
using (GraphicsPath buttonPath = new GraphicsPath())
|
||||||
|
{
|
||||||
|
Rectangle newRect = new Rectangle(0, 0, button.Width, button.Height);
|
||||||
|
buttonPath.AddArc(newRect.X, newRect.Y, radius * 2, radius * 2, 180, 90);
|
||||||
|
buttonPath.AddArc(newRect.X + newRect.Width - radius * 2, newRect.Y, radius * 2, radius * 2, 270, 90);
|
||||||
|
buttonPath.AddArc(newRect.X + newRect.Width - radius * 2, newRect.Y + newRect.Height - radius * 2, radius * 2, radius * 2, 0, 90);
|
||||||
|
buttonPath.AddArc(newRect.X, newRect.Y + newRect.Height - radius * 2, radius * 2, radius * 2, 90, 90);
|
||||||
|
buttonPath.CloseFigure();
|
||||||
|
|
||||||
|
e.Graphics.FillPath(new SolidBrush(button.BackColor), buttonPath);
|
||||||
|
|
||||||
|
// 绘制文本
|
||||||
|
StringFormat sf = new StringFormat();
|
||||||
|
sf.Alignment = StringAlignment.Center;
|
||||||
|
sf.LineAlignment = StringAlignment.Center;
|
||||||
|
e.Graphics.DrawString(button.Text, button.Font, new SolidBrush(button.ForeColor), newRect, sf);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Button CreateStyledButton(string text, DialogResult dialogResult)
|
||||||
|
{
|
||||||
|
Button button = new Button();
|
||||||
|
button.Text = text;
|
||||||
|
button.DialogResult = dialogResult;
|
||||||
|
StyleButton(button);
|
||||||
|
return button;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Main(string[] args)
|
||||||
|
{
|
||||||
|
InitializeDPIAwareness();
|
||||||
|
Application.EnableVisualStyles();
|
||||||
|
Application.SetCompatibleTextRenderingDefault(false);
|
||||||
|
Show(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class NativeMethods
|
||||||
|
{
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
public static extern bool HideCaret(IntPtr hWnd);
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, ref RECT lParam);
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct RECT
|
||||||
|
{
|
||||||
|
public int Left;
|
||||||
|
public int Top;
|
||||||
|
public int Right;
|
||||||
|
public int Bottom;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -10,12 +10,14 @@ const getQuickcommandTempFile = (ext, name, dir = "quickcommandTempDir") => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const getQuickcommandFolderFile = (name, ext) => {
|
const getQuickcommandFolderFile = (name, ext) => {
|
||||||
const quickcommandPath = path.join(
|
const folderPath = path.join(
|
||||||
window.utools.getPath("userData"),
|
window.utools.getPath("userData"),
|
||||||
"quickcommand"
|
"quickcommand"
|
||||||
);
|
);
|
||||||
if (!fs.existsSync(quickcommandPath)) fs.mkdirSync(quickcommandPath);
|
if (!fs.existsSync(folderPath)) {
|
||||||
return path.join(quickcommandPath, `${name}.${ext}`);
|
fs.mkdirSync(folderPath, { recursive: true });
|
||||||
|
}
|
||||||
|
return path.join(folderPath, `${name}.${ext}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = { getQuickcommandTempFile, getQuickcommandFolderFile };
|
module.exports = { getQuickcommandTempFile, getQuickcommandFolderFile };
|
||||||
|
@ -178,6 +178,53 @@ const quickcommand = {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 运行C#脚本
|
||||||
|
runCsharp: function (script, args = []) {
|
||||||
|
return new Promise((reslove, reject) => {
|
||||||
|
let cscPath = path.join(
|
||||||
|
process.env.WINDIR,
|
||||||
|
"Microsoft.NET",
|
||||||
|
"Framework",
|
||||||
|
"v4.0.30319",
|
||||||
|
"csc.exe"
|
||||||
|
);
|
||||||
|
if (!fs.existsSync(cscPath)) {
|
||||||
|
cscPath = path.join(
|
||||||
|
process.env.WINDIR,
|
||||||
|
"Microsoft.NET",
|
||||||
|
"Framework",
|
||||||
|
"v3.5",
|
||||||
|
"csc.exe"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (!fs.existsSync(cscPath)) {
|
||||||
|
return reject("未安装.NET Framework");
|
||||||
|
}
|
||||||
|
let tempCsharpFile = getQuickcommandTempFile("cs");
|
||||||
|
let tempBuildFile = getQuickcommandTempFile("exe");
|
||||||
|
|
||||||
|
fs.writeFile(tempCsharpFile, iconv.encode(script, "gbk"), (err) => {
|
||||||
|
if (err) return reject(err.toString());
|
||||||
|
// 添加命令行参数
|
||||||
|
const argsStr =
|
||||||
|
args.length > 0 ? " " + args.map((arg) => `"${arg}"`).join(" ") : "";
|
||||||
|
child_process.exec(
|
||||||
|
`${cscPath} /nologo /out:${tempBuildFile} ${tempCsharpFile} && ${tempBuildFile}${argsStr}`,
|
||||||
|
{
|
||||||
|
encoding: "buffer",
|
||||||
|
windowsHide: true,
|
||||||
|
},
|
||||||
|
(err, stdout) => {
|
||||||
|
if (err) reject(iconv.decode(stdout, "gbk"));
|
||||||
|
else reslove(iconv.decode(stdout, "gbk"));
|
||||||
|
fs.unlink(tempCsharpFile, () => {});
|
||||||
|
fs.unlink(tempBuildFile, () => {});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (process.platform === "win32") {
|
if (process.platform === "win32") {
|
||||||
@ -219,52 +266,6 @@ if (process.platform === "win32") {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// 运行C#脚本
|
|
||||||
quickcommand.runCsharp = function (script) {
|
|
||||||
return new Promise((reslove, reject) => {
|
|
||||||
// 找到csc.exe
|
|
||||||
let cscPath = path.join(
|
|
||||||
process.env.WINDIR,
|
|
||||||
"Microsoft.NET",
|
|
||||||
"Framework",
|
|
||||||
"v4.0.30319",
|
|
||||||
"csc.exe"
|
|
||||||
);
|
|
||||||
if (!fs.existsSync(cscPath)) {
|
|
||||||
cscPath = path.join(
|
|
||||||
process.env.WINDIR,
|
|
||||||
"Microsoft.NET",
|
|
||||||
"Framework",
|
|
||||||
"v3.5",
|
|
||||||
"csc.exe"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (!fs.existsSync(cscPath)) {
|
|
||||||
return reject("未安装.NET Framework");
|
|
||||||
}
|
|
||||||
// 写入临时文件
|
|
||||||
let tempCsharpFile = getQuickcommandTempFile("cs");
|
|
||||||
let tempBuildFile = getQuickcommandTempFile("exe");
|
|
||||||
|
|
||||||
fs.writeFile(tempCsharpFile, iconv.encode(script, "gbk"), (err) => {
|
|
||||||
if (err) return reject(err.toString());
|
|
||||||
// 运行csc.exe
|
|
||||||
child_process.exec(
|
|
||||||
`${cscPath} /nologo /out:${tempBuildFile} ${tempCsharpFile} && ${tempBuildFile}`,
|
|
||||||
{
|
|
||||||
encoding: "buffer",
|
|
||||||
windowsHide: true,
|
|
||||||
},
|
|
||||||
(err, stdout) => {
|
|
||||||
if (err) reject(iconv.decode(stdout, "gbk"));
|
|
||||||
else reslove(iconv.decode(stdout, "gbk"));
|
|
||||||
fs.unlink(tempCsharpFile, () => {});
|
|
||||||
fs.unlink(tempBuildFile, () => {});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
quickcommand.showSystemTextArea = systemDialog.showSystemTextArea;
|
quickcommand.showSystemTextArea = systemDialog.showSystemTextArea;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,7 +313,6 @@ if (process.platform !== "linux") {
|
|||||||
quickcommand.showSystemMessageBox = systemDialog.showSystemMessageBox;
|
quickcommand.showSystemMessageBox = systemDialog.showSystemMessageBox;
|
||||||
quickcommand.showSystemInputBox = systemDialog.showSystemInputBox;
|
quickcommand.showSystemInputBox = systemDialog.showSystemInputBox;
|
||||||
quickcommand.showSystemConfirmBox = systemDialog.showSystemConfirmBox;
|
quickcommand.showSystemConfirmBox = systemDialog.showSystemConfirmBox;
|
||||||
quickcommand.showSystemSelectList = systemDialog.showSystemSelectList;
|
|
||||||
quickcommand.showSystemButtonBox = systemDialog.showSystemButtonBox;
|
quickcommand.showSystemButtonBox = systemDialog.showSystemButtonBox;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,13 @@ const path = require("path");
|
|||||||
const { exec } = require("child_process");
|
const { exec } = require("child_process");
|
||||||
const { getQuickcommandFolderFile } = require("./getQuickcommandFile");
|
const { getQuickcommandFolderFile } = require("./getQuickcommandFile");
|
||||||
|
|
||||||
// 添加一个辅助函数来执行命令
|
// 读取 dialog.cs 模板
|
||||||
|
const dialogTemplate = fs.readFileSync(
|
||||||
|
path.join(__dirname, "csharp", "dialog.cs"),
|
||||||
|
"utf8"
|
||||||
|
);
|
||||||
|
|
||||||
|
// 辅助函数
|
||||||
const execCommand = (cmd) => {
|
const execCommand = (cmd) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
exec(cmd, (error, stdout, stderr) => {
|
exec(cmd, (error, stdout, stderr) => {
|
||||||
@ -16,7 +22,6 @@ const execCommand = (cmd) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// 添加一个辅助函数来检查命令是否存在
|
|
||||||
const checkZenity = async () => {
|
const checkZenity = async () => {
|
||||||
try {
|
try {
|
||||||
await execCommand("which zenity");
|
await execCommand("which zenity");
|
||||||
@ -29,137 +34,75 @@ const checkZenity = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 定义通用样式
|
|
||||||
const commonStyles = `
|
|
||||||
static void ApplyModernStyle(Form form) {
|
|
||||||
form.Font = new Font("Microsoft YaHei UI", 9F);
|
|
||||||
form.BackColor = Color.White;
|
|
||||||
form.Padding = new Padding(15);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ApplyButtonStyle(Button button) {
|
|
||||||
button.FlatStyle = FlatStyle.Flat;
|
|
||||||
button.BackColor = Color.FromArgb(0, 120, 212);
|
|
||||||
button.ForeColor = Color.White;
|
|
||||||
button.Font = new Font("Microsoft YaHei UI", 9F);
|
|
||||||
button.Cursor = Cursors.Hand;
|
|
||||||
button.FlatAppearance.BorderSize = 0;
|
|
||||||
button.Height = 30;
|
|
||||||
button.Width = 85;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ApplySecondaryButtonStyle(Button button) {
|
|
||||||
button.FlatStyle = FlatStyle.Flat;
|
|
||||||
button.BackColor = Color.FromArgb(240, 240, 240);
|
|
||||||
button.ForeColor = Color.Black;
|
|
||||||
button.Font = new Font("Microsoft YaHei UI", 9F);
|
|
||||||
button.Cursor = Cursors.Hand;
|
|
||||||
button.FlatAppearance.BorderSize = 1;
|
|
||||||
button.FlatAppearance.BorderColor = Color.FromArgb(200, 200, 200);
|
|
||||||
button.Height = 30;
|
|
||||||
button.Width = 85;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ApplyTextBoxStyle(TextBox textBox) {
|
|
||||||
textBox.BorderStyle = BorderStyle.FixedSingle;
|
|
||||||
textBox.Font = new Font("Microsoft YaHei UI", 9F);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ApplyLabelStyle(Label label) {
|
|
||||||
label.Font = new Font("Microsoft YaHei UI", 9F);
|
|
||||||
label.ForeColor = Color.FromArgb(51, 51, 51);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ApplyListBoxStyle(ListBox listBox) {
|
|
||||||
listBox.Font = new Font("Microsoft YaHei UI", 9F);
|
|
||||||
listBox.BorderStyle = BorderStyle.FixedSingle;
|
|
||||||
listBox.BackColor = Color.White;
|
|
||||||
}`;
|
|
||||||
|
|
||||||
const getQuickcommandIconPath = () => {
|
const getQuickcommandIconPath = () => {
|
||||||
try {
|
try {
|
||||||
const iconPath = getQuickcommandFolderFile("logo", "png");
|
const iconPath = getQuickcommandFolderFile("logo", "png");
|
||||||
if (!fs.existsSync(iconPath)) {
|
if (!fs.existsSync(iconPath)) {
|
||||||
fs.copyFileSync(path.join(__dirname, "..", "logo.png"), iconPath);
|
const sourcePath = path.join(__dirname, "..", "logo.png");
|
||||||
|
if (!fs.existsSync(sourcePath)) {
|
||||||
|
console.error("Source icon not found:", sourcePath);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
fs.copyFileSync(sourcePath, iconPath);
|
||||||
}
|
}
|
||||||
return iconPath;
|
return iconPath;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error("Error getting icon path:", error);
|
||||||
return null;
|
return "";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 修改对话框函数,使用新的 dialog.cs
|
||||||
const showSystemMessageBox = async function (content, title = "") {
|
const showSystemMessageBox = async function (content, title = "") {
|
||||||
|
try {
|
||||||
const iconPath = getQuickcommandIconPath();
|
const iconPath = getQuickcommandIconPath();
|
||||||
|
if (window.utools.isWindows()) {
|
||||||
|
const args = [
|
||||||
|
"-type",
|
||||||
|
"message",
|
||||||
|
"-title",
|
||||||
|
title,
|
||||||
|
"-content",
|
||||||
|
content.replace(/\r\n|\n/g, ""),
|
||||||
|
];
|
||||||
|
|
||||||
|
if (iconPath) {
|
||||||
|
args.push("-iconpath", iconPath.replace(/\\/g, "\\\\"));
|
||||||
|
}
|
||||||
|
|
||||||
|
const csharpCode = dialogTemplate;
|
||||||
|
const result = await this.runCsharp(csharpCode, args);
|
||||||
|
if (result && result.startsWith("Error:")) {
|
||||||
|
throw new Error(result.substring(7));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (window.utools.isMacOs()) {
|
if (window.utools.isMacOs()) {
|
||||||
let iconParam = "note";
|
let iconParam = "note";
|
||||||
if (iconPath) {
|
if (iconPath) {
|
||||||
const posixPath = iconPath.replace(/\\/g, "/");
|
const posixPath = iconPath.replace(/\\/g, "/");
|
||||||
iconParam = `alias POSIX file "${posixPath}"`;
|
iconParam = `alias POSIX file "${posixPath}"`;
|
||||||
}
|
}
|
||||||
const script = `display dialog "${content}" with title "${title}" buttons {"确定"} default button "确定" with icon ${iconParam}`;
|
const script = `display dialog "${content}" with title "${title}" buttons {"取消", "确定"} default button "确定" with icon ${iconParam}`;
|
||||||
await this.runAppleScript(script);
|
const result = await this.runAppleScript(script);
|
||||||
} else if (window.utools.isWindows()) {
|
return result.includes("button returned:确定");
|
||||||
const escapedIconPath = iconPath ? iconPath.replace(/\\/g, "\\\\") : null;
|
|
||||||
const csharpScript = `
|
|
||||||
using System;
|
|
||||||
using System.Windows.Forms;
|
|
||||||
using System.Drawing;
|
|
||||||
using System.IO;
|
|
||||||
class Program {
|
|
||||||
${commonStyles}
|
|
||||||
|
|
||||||
static void Main() {
|
|
||||||
Form form = new Form();
|
|
||||||
Label label = new Label();
|
|
||||||
Button okButton = new Button();
|
|
||||||
|
|
||||||
ApplyModernStyle(form);
|
|
||||||
form.Text = "${title}";
|
|
||||||
form.ClientSize = new Size(400, 130);
|
|
||||||
form.FormBorderStyle = FormBorderStyle.FixedDialog;
|
|
||||||
form.StartPosition = FormStartPosition.CenterScreen;
|
|
||||||
form.MaximizeBox = false;
|
|
||||||
form.MinimizeBox = false;
|
|
||||||
${
|
|
||||||
escapedIconPath
|
|
||||||
? `using (var bmp = new Bitmap("${escapedIconPath}"))
|
|
||||||
{
|
|
||||||
form.Icon = Icon.FromHandle(bmp.GetHicon());
|
|
||||||
}`
|
|
||||||
: ""
|
|
||||||
}
|
|
||||||
|
|
||||||
ApplyLabelStyle(label);
|
|
||||||
label.Text = "${content}";
|
|
||||||
label.SetBounds(15, 15, 370, 60);
|
|
||||||
label.AutoSize = true;
|
|
||||||
form.Controls.Add(label);
|
|
||||||
|
|
||||||
ApplyButtonStyle(okButton);
|
|
||||||
okButton.Text = "确定";
|
|
||||||
okButton.DialogResult = DialogResult.OK;
|
|
||||||
okButton.SetBounds(300, 80, 85, 30);
|
|
||||||
form.Controls.Add(okButton);
|
|
||||||
|
|
||||||
form.AcceptButton = okButton;
|
|
||||||
form.ShowDialog();
|
|
||||||
form.Dispose();
|
|
||||||
}
|
|
||||||
}`;
|
|
||||||
await this.runCsharp(csharpScript);
|
|
||||||
} else if (window.utools.isLinux()) {
|
} else if (window.utools.isLinux()) {
|
||||||
if (!(await checkZenity())) return;
|
if (!(await checkZenity())) return false;
|
||||||
try {
|
try {
|
||||||
const script = `zenity --info --title="${title}" --text="${content}" --width=400`;
|
const script = `zenity --info --title="${title}" --text="${content}" --width=400`;
|
||||||
await execCommand(script);
|
await execCommand(script);
|
||||||
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("执行 zenity 命令失败:", error);
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Dialog error:", error);
|
||||||
|
window.utools.showNotification(`对话框错误: ${error.message}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 系统级输入框
|
|
||||||
const showSystemInputBox = async function (placeholders, title = "") {
|
const showSystemInputBox = async function (placeholders, title = "") {
|
||||||
if (!Array.isArray(placeholders)) {
|
if (!Array.isArray(placeholders)) {
|
||||||
placeholders = [placeholders];
|
placeholders = [placeholders];
|
||||||
@ -189,79 +132,23 @@ const showSystemInputBox = async function (placeholders, title = "") {
|
|||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
} else if (window.utools.isWindows()) {
|
} else if (window.utools.isWindows()) {
|
||||||
const escapedIconPath = iconPath ? iconPath.replace(/\\/g, "\\\\") : null;
|
const args = [
|
||||||
const csharpScript = `
|
"-type",
|
||||||
using System;
|
"input",
|
||||||
using System.Windows.Forms;
|
"-title",
|
||||||
using System.Drawing;
|
title,
|
||||||
using System.IO;
|
"-content",
|
||||||
|
placeholders.join("|||||"),
|
||||||
|
];
|
||||||
|
|
||||||
class Program {
|
if (iconPath) {
|
||||||
${commonStyles}
|
args.push("-iconpath", iconPath.replace(/\\/g, "\\\\"));
|
||||||
|
|
||||||
static void Main() {
|
|
||||||
Form form = new Form();
|
|
||||||
ApplyModernStyle(form);
|
|
||||||
form.Text = "${title}";
|
|
||||||
form.ClientSize = new Size(350, ${45 + placeholders.length * 70});
|
|
||||||
form.FormBorderStyle = FormBorderStyle.FixedDialog;
|
|
||||||
form.StartPosition = FormStartPosition.CenterScreen;
|
|
||||||
form.MaximizeBox = false;
|
|
||||||
form.MinimizeBox = false;
|
|
||||||
${
|
|
||||||
escapedIconPath
|
|
||||||
? `using (var bmp = new Bitmap("${escapedIconPath}"))
|
|
||||||
{
|
|
||||||
form.Icon = Icon.FromHandle(bmp.GetHicon());
|
|
||||||
}`
|
|
||||||
: ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
${placeholders
|
const csharpCode = dialogTemplate;
|
||||||
.map(
|
const result = await this.runCsharp(csharpCode, args);
|
||||||
(placeholder, index) => `
|
console.log(result, JSON.parse(result));
|
||||||
Label label${index} = new Label();
|
return result ? JSON.parse(result) : null;
|
||||||
ApplyLabelStyle(label${index});
|
|
||||||
label${index}.Text = "${placeholder}";
|
|
||||||
label${index}.SetBounds(15, ${15 + index * 70}, 320, 20);
|
|
||||||
form.Controls.Add(label${index});
|
|
||||||
|
|
||||||
TextBox textBox${index} = new TextBox();
|
|
||||||
ApplyTextBoxStyle(textBox${index});
|
|
||||||
textBox${index}.SetBounds(15, ${40 + index * 70}, 320, 25);
|
|
||||||
form.Controls.Add(textBox${index});`
|
|
||||||
)
|
|
||||||
.join("\n")}
|
|
||||||
|
|
||||||
Button okButton = new Button();
|
|
||||||
ApplyButtonStyle(okButton);
|
|
||||||
okButton.Text = "确定";
|
|
||||||
okButton.DialogResult = DialogResult.OK;
|
|
||||||
okButton.SetBounds(160, ${20 + placeholders.length * 70}, 85, 30);
|
|
||||||
form.Controls.Add(okButton);
|
|
||||||
|
|
||||||
Button cancelButton = new Button();
|
|
||||||
ApplySecondaryButtonStyle(cancelButton);
|
|
||||||
cancelButton.Text = "取消";
|
|
||||||
cancelButton.DialogResult = DialogResult.Cancel;
|
|
||||||
cancelButton.SetBounds(250, ${
|
|
||||||
20 + placeholders.length * 70
|
|
||||||
}, 85, 30);
|
|
||||||
form.Controls.Add(cancelButton);
|
|
||||||
|
|
||||||
form.AcceptButton = okButton;
|
|
||||||
form.CancelButton = cancelButton;
|
|
||||||
|
|
||||||
if (form.ShowDialog() == DialogResult.OK) {
|
|
||||||
${placeholders
|
|
||||||
.map((_, index) => `Console.WriteLine(textBox${index}.Text);`)
|
|
||||||
.join("\n ")}
|
|
||||||
}
|
|
||||||
form.Dispose();
|
|
||||||
}
|
|
||||||
}`;
|
|
||||||
const result = await this.runCsharp(csharpScript);
|
|
||||||
return result.trim() || null;
|
|
||||||
} else if (window.utools.isLinux()) {
|
} else if (window.utools.isLinux()) {
|
||||||
if (!(await checkZenity())) return null;
|
if (!(await checkZenity())) return null;
|
||||||
const results = [];
|
const results = [];
|
||||||
@ -280,7 +167,6 @@ const showSystemInputBox = async function (placeholders, title = "") {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 系统级确认框
|
|
||||||
const showSystemConfirmBox = async function (content, title = "") {
|
const showSystemConfirmBox = async function (content, title = "") {
|
||||||
const iconPath = getQuickcommandIconPath();
|
const iconPath = getQuickcommandIconPath();
|
||||||
if (window.utools.isMacOs()) {
|
if (window.utools.isMacOs()) {
|
||||||
@ -293,65 +179,22 @@ const showSystemConfirmBox = async function (content, title = "") {
|
|||||||
const result = await this.runAppleScript(script);
|
const result = await this.runAppleScript(script);
|
||||||
return result.includes("button returned:确定");
|
return result.includes("button returned:确定");
|
||||||
} else if (window.utools.isWindows()) {
|
} else if (window.utools.isWindows()) {
|
||||||
const escapedIconPath = iconPath ? iconPath.replace(/\\/g, "\\\\") : null;
|
const args = [
|
||||||
const csharpScript = `
|
"-type",
|
||||||
using System;
|
"confirm",
|
||||||
using System.Windows.Forms;
|
"-title",
|
||||||
using System.Drawing;
|
title,
|
||||||
using System.IO;
|
"-content",
|
||||||
class Program {
|
content.replace(/\r\n|\n/g, "\\n"),
|
||||||
${commonStyles}
|
];
|
||||||
|
|
||||||
static void Main() {
|
if (iconPath) {
|
||||||
Form form = new Form();
|
args.push("-iconpath", iconPath.replace(/\\/g, "\\\\"));
|
||||||
Label label = new Label();
|
|
||||||
Button okButton = new Button();
|
|
||||||
Button cancelButton = new Button();
|
|
||||||
|
|
||||||
ApplyModernStyle(form);
|
|
||||||
form.Text = "${title}";
|
|
||||||
form.ClientSize = new Size(400, 130);
|
|
||||||
form.FormBorderStyle = FormBorderStyle.FixedDialog;
|
|
||||||
form.StartPosition = FormStartPosition.CenterScreen;
|
|
||||||
form.MaximizeBox = false;
|
|
||||||
form.MinimizeBox = false;
|
|
||||||
${
|
|
||||||
escapedIconPath
|
|
||||||
? `using (var bmp = new Bitmap("${escapedIconPath}"))
|
|
||||||
{
|
|
||||||
form.Icon = Icon.FromHandle(bmp.GetHicon());
|
|
||||||
}`
|
|
||||||
: ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ApplyLabelStyle(label);
|
const csharpCode = dialogTemplate;
|
||||||
label.Text = "${content}";
|
const result = await this.runCsharp(csharpCode, args);
|
||||||
label.SetBounds(15, 15, 370, 60);
|
return result === "true";
|
||||||
label.AutoSize = true;
|
|
||||||
form.Controls.Add(label);
|
|
||||||
|
|
||||||
ApplyButtonStyle(okButton);
|
|
||||||
okButton.Text = "确定";
|
|
||||||
okButton.DialogResult = DialogResult.OK;
|
|
||||||
okButton.SetBounds(210, 80, 85, 30);
|
|
||||||
form.Controls.Add(okButton);
|
|
||||||
|
|
||||||
ApplySecondaryButtonStyle(cancelButton);
|
|
||||||
cancelButton.Text = "取消";
|
|
||||||
cancelButton.DialogResult = DialogResult.Cancel;
|
|
||||||
cancelButton.SetBounds(300, 80, 85, 30);
|
|
||||||
form.Controls.Add(cancelButton);
|
|
||||||
|
|
||||||
form.AcceptButton = okButton;
|
|
||||||
form.CancelButton = cancelButton;
|
|
||||||
|
|
||||||
DialogResult result = form.ShowDialog();
|
|
||||||
Console.WriteLine(result == DialogResult.OK);
|
|
||||||
form.Dispose();
|
|
||||||
}
|
|
||||||
}`;
|
|
||||||
const result = await this.runCsharp(csharpScript);
|
|
||||||
return result.trim() === "True";
|
|
||||||
} else if (window.utools.isLinux()) {
|
} else if (window.utools.isLinux()) {
|
||||||
if (!(await checkZenity())) return false;
|
if (!(await checkZenity())) return false;
|
||||||
try {
|
try {
|
||||||
@ -364,216 +207,40 @@ const showSystemConfirmBox = async function (content, title = "") {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 系统级选择框
|
const showSystemButtonBox = async function (buttons, title = "") {
|
||||||
const showSystemSelectList = async function (items, title = "") {
|
|
||||||
const iconPath = getQuickcommandIconPath();
|
const iconPath = getQuickcommandIconPath();
|
||||||
if (window.utools.isMacOs()) {
|
if (window.utools.isMacOs()) {
|
||||||
const itemList = items.map((item) => `"${item}"`).join(", ");
|
const itemList = buttons.map((item) => `"${item}"`).join(", ");
|
||||||
const script = `choose from list {${itemList}} with title "${title}" with prompt "请选择:" default items {"${items[0]}"}`;
|
const script = `choose from list {${itemList}} with title "${title}" with prompt "请选择:" default items {"${buttons[0]}"}`;
|
||||||
const result = await this.runAppleScript(script);
|
const result = await this.runAppleScript(script);
|
||||||
if (result.includes("false")) return null;
|
if (result.includes("false")) return null;
|
||||||
const text = result.trim();
|
const text = result.trim();
|
||||||
const id = items.findIndex((item) => item === text);
|
const id = buttons.findIndex((item) => item === text);
|
||||||
return { id, text };
|
return { id, text };
|
||||||
} else if (window.utools.isWindows()) {
|
} else if (window.utools.isWindows()) {
|
||||||
const escapedIconPath = iconPath ? iconPath.replace(/\\/g, "\\\\") : null;
|
const args = [
|
||||||
const csharpScript = `
|
"-type",
|
||||||
using System;
|
"buttons",
|
||||||
using System.Windows.Forms;
|
"-title",
|
||||||
using System.Drawing;
|
title,
|
||||||
using System.IO;
|
"-content",
|
||||||
|
buttons.join("|||||"),
|
||||||
|
];
|
||||||
|
|
||||||
class Program {
|
|
||||||
${commonStyles}
|
|
||||||
|
|
||||||
static void Main() {
|
|
||||||
Form form = new Form();
|
|
||||||
ListBox listBox = new ListBox();
|
|
||||||
Button okButton = new Button();
|
|
||||||
Button cancelButton = new Button();
|
|
||||||
Label titleLabel = new Label();
|
|
||||||
|
|
||||||
ApplyModernStyle(form);
|
|
||||||
form.Text = "${title}";
|
|
||||||
form.ClientSize = new Size(350, 280);
|
|
||||||
form.FormBorderStyle = FormBorderStyle.FixedDialog;
|
|
||||||
form.StartPosition = FormStartPosition.CenterScreen;
|
|
||||||
form.MaximizeBox = false;
|
|
||||||
form.MinimizeBox = false;
|
|
||||||
${
|
|
||||||
escapedIconPath
|
|
||||||
? `using (var bmp = new Bitmap("${escapedIconPath}"))
|
|
||||||
{
|
|
||||||
form.Icon = Icon.FromHandle(bmp.GetHicon());
|
|
||||||
}`
|
|
||||||
: ""
|
|
||||||
}
|
|
||||||
|
|
||||||
titleLabel.Text = "请选择:";
|
|
||||||
titleLabel.AutoSize = true;
|
|
||||||
titleLabel.SetBounds(15, 15, 320, 20);
|
|
||||||
ApplyLabelStyle(titleLabel);
|
|
||||||
form.Controls.Add(titleLabel);
|
|
||||||
|
|
||||||
ApplyListBoxStyle(listBox);
|
|
||||||
listBox.SetBounds(15, 45, 320, 180);
|
|
||||||
${items
|
|
||||||
.map((item) => `listBox.Items.Add("${item}");`)
|
|
||||||
.join("\n ")}
|
|
||||||
listBox.SelectedIndex = 0;
|
|
||||||
form.Controls.Add(listBox);
|
|
||||||
|
|
||||||
ApplyButtonStyle(okButton);
|
|
||||||
okButton.Text = "确定";
|
|
||||||
okButton.DialogResult = DialogResult.OK;
|
|
||||||
okButton.SetBounds(160, 235, 85, 30);
|
|
||||||
form.Controls.Add(okButton);
|
|
||||||
|
|
||||||
ApplySecondaryButtonStyle(cancelButton);
|
|
||||||
cancelButton.Text = "取消";
|
|
||||||
cancelButton.DialogResult = DialogResult.Cancel;
|
|
||||||
cancelButton.SetBounds(250, 235, 85, 30);
|
|
||||||
form.Controls.Add(cancelButton);
|
|
||||||
|
|
||||||
form.AcceptButton = okButton;
|
|
||||||
form.CancelButton = cancelButton;
|
|
||||||
|
|
||||||
if (form.ShowDialog() == DialogResult.OK && listBox.SelectedItem != null) {
|
|
||||||
Console.WriteLine(listBox.SelectedIndex.ToString() + "|||||" + listBox.SelectedItem.ToString());
|
|
||||||
}
|
|
||||||
form.Dispose();
|
|
||||||
}
|
|
||||||
}`;
|
|
||||||
const result = await this.runCsharp(csharpScript);
|
|
||||||
if (result.trim()) {
|
|
||||||
const [id, text] = result.trim().split("|||||");
|
|
||||||
return { id: parseInt(id), text };
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
} else if (window.utools.isLinux()) {
|
|
||||||
if (!(await checkZenity())) return null;
|
|
||||||
try {
|
|
||||||
const itemsList = items
|
|
||||||
.map((item, index) => `"${index}" "${item}"`)
|
|
||||||
.join(" ");
|
|
||||||
const script = `zenity --list --title="${title}" --text="请选择:" --column="序号" --column="选项" ${itemsList} --width=400 --height=300`;
|
|
||||||
const result = await execCommand(script);
|
|
||||||
if (!result) return null;
|
|
||||||
const text = result.trim();
|
|
||||||
const id = items.findIndex((item) => item === text);
|
|
||||||
return { id, text };
|
|
||||||
} catch (error) {
|
|
||||||
console.error("执行 zenity 命令失败:", error);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 系统级按钮组弹窗
|
|
||||||
const showSystemButtonBox = async function (buttons, content = "", title = "") {
|
|
||||||
const iconPath = getQuickcommandIconPath();
|
|
||||||
if (window.utools.isMacOs()) {
|
|
||||||
try {
|
|
||||||
let iconParam = "note";
|
|
||||||
if (iconPath) {
|
if (iconPath) {
|
||||||
const posixPath = iconPath.replace(/\\/g, "/");
|
args.push("-iconpath", iconPath.replace(/\\/g, "\\\\"));
|
||||||
iconParam = `alias POSIX file "${posixPath}"`;
|
|
||||||
}
|
|
||||||
const buttonList = buttons.map((btn) => `"${btn}"`).join(", ");
|
|
||||||
const script = `display dialog "${content}" with title "${title}" buttons {${buttonList}} default button "${buttons[0]}" with icon ${iconParam}`;
|
|
||||||
const result = await this.runAppleScript(script);
|
|
||||||
const match = result.match(/button returned:(.+)/);
|
|
||||||
if (match) {
|
|
||||||
const text = match[1];
|
|
||||||
const id = buttons.findIndex((btn) => btn === text);
|
|
||||||
return { id, text };
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
} catch (error) {
|
|
||||||
window.utools.showNotification(error);
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
} else if (window.utools.isWindows()) {
|
|
||||||
const escapedIconPath = iconPath ? iconPath.replace(/\\/g, "\\\\") : null;
|
|
||||||
const csharpScript = `
|
|
||||||
using System;
|
|
||||||
using System.Windows.Forms;
|
|
||||||
using System.Drawing;
|
|
||||||
using System.IO;
|
|
||||||
|
|
||||||
class Program {
|
|
||||||
${commonStyles}
|
|
||||||
|
|
||||||
static void Main() {
|
|
||||||
Form form = new Form();
|
|
||||||
Label label = new Label();
|
|
||||||
FlowLayoutPanel buttonPanel = new FlowLayoutPanel();
|
|
||||||
|
|
||||||
ApplyModernStyle(form);
|
|
||||||
form.Text = "${title}";
|
|
||||||
form.ClientSize = new Size(400, 160);
|
|
||||||
form.FormBorderStyle = FormBorderStyle.FixedDialog;
|
|
||||||
form.StartPosition = FormStartPosition.CenterScreen;
|
|
||||||
form.MaximizeBox = false;
|
|
||||||
form.MinimizeBox = false;
|
|
||||||
${
|
|
||||||
escapedIconPath
|
|
||||||
? `using (var bmp = new Bitmap("${escapedIconPath}"))
|
|
||||||
{
|
|
||||||
form.Icon = Icon.FromHandle(bmp.GetHicon());
|
|
||||||
}`
|
|
||||||
: ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ApplyLabelStyle(label);
|
const csharpCode = dialogTemplate;
|
||||||
label.Text = "${content}";
|
const result = await this.runCsharp(csharpCode, args);
|
||||||
label.SetBounds(15, 15, 370, 60);
|
if (result) {
|
||||||
label.AutoSize = true;
|
return JSON.parse(result);
|
||||||
form.Controls.Add(label);
|
|
||||||
|
|
||||||
buttonPanel.SetBounds(15, 90, 370, 40);
|
|
||||||
buttonPanel.FlowDirection = FlowDirection.RightToLeft;
|
|
||||||
buttonPanel.WrapContents = false;
|
|
||||||
buttonPanel.BackColor = Color.White;
|
|
||||||
form.Controls.Add(buttonPanel);
|
|
||||||
|
|
||||||
${buttons
|
|
||||||
.map(
|
|
||||||
(btn, index) => `
|
|
||||||
Button button${index} = new Button();
|
|
||||||
button${index}.Text = "${btn}";
|
|
||||||
button${index}.DialogResult = DialogResult.OK;
|
|
||||||
button${index}.Tag = "${index}";
|
|
||||||
${
|
|
||||||
index === 0 ? "ApplyButtonStyle" : "ApplySecondaryButtonStyle"
|
|
||||||
}(button${index});
|
|
||||||
button${index}.Margin = new Padding(5, 0, 0, 0);
|
|
||||||
buttonPanel.Controls.Add(button${index});`
|
|
||||||
)
|
|
||||||
.join("\n")}
|
|
||||||
|
|
||||||
DialogResult result = form.ShowDialog();
|
|
||||||
if (result == DialogResult.OK) {
|
|
||||||
foreach (Button btn in buttonPanel.Controls) {
|
|
||||||
if (btn.DialogResult == result) {
|
|
||||||
Console.WriteLine(btn.Tag.ToString() + "|||||" + btn.Text);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
form.Dispose();
|
|
||||||
}
|
|
||||||
}`;
|
|
||||||
const result = await this.runCsharp(csharpScript);
|
|
||||||
if (result.trim()) {
|
|
||||||
const [id, text] = result.trim().split("|||||");
|
|
||||||
return { id: parseInt(id), text };
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
} else if (window.utools.isLinux()) {
|
} else if (window.utools.isLinux()) {
|
||||||
if (!(await checkZenity())) return null;
|
if (!(await checkZenity())) return null;
|
||||||
try {
|
try {
|
||||||
const script1 = `zenity --info --title="${title}" --text="${content}" --width=400`;
|
const script1 = `zenity --info --title="${title}" --width=400`;
|
||||||
await execCommand(script1);
|
await execCommand(script1);
|
||||||
|
|
||||||
const itemsList = buttons
|
const itemsList = buttons
|
||||||
@ -592,95 +259,29 @@ const showSystemButtonBox = async function (buttons, content = "", title = "") {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 系统级文本区域弹窗
|
const showSystemTextArea = async function (defaultText = "", title = "") {
|
||||||
const showSystemTextArea = async function (
|
|
||||||
placeholder = "",
|
|
||||||
defaultText = "",
|
|
||||||
title = ""
|
|
||||||
) {
|
|
||||||
const iconPath = getQuickcommandIconPath();
|
const iconPath = getQuickcommandIconPath();
|
||||||
if (window.utools.isWindows()) {
|
if (window.utools.isWindows()) {
|
||||||
const escapedIconPath = iconPath ? iconPath.replace(/\\/g, "\\\\") : null;
|
const args = [
|
||||||
const csharpScript = `
|
"-type",
|
||||||
using System;
|
"textarea",
|
||||||
using System.Windows.Forms;
|
"-title",
|
||||||
using System.Drawing;
|
title,
|
||||||
using System.IO;
|
"-content",
|
||||||
|
defaultText,
|
||||||
|
];
|
||||||
|
|
||||||
class Program {
|
if (iconPath) {
|
||||||
${commonStyles}
|
args.push("-iconpath", iconPath.replace(/\\/g, "\\\\"));
|
||||||
|
|
||||||
static void Main() {
|
|
||||||
Form form = new Form();
|
|
||||||
TextBox textBox = new TextBox();
|
|
||||||
Button okButton = new Button();
|
|
||||||
Button cancelButton = new Button();
|
|
||||||
Label label = new Label();
|
|
||||||
|
|
||||||
ApplyModernStyle(form);
|
|
||||||
form.Text = "${title}";
|
|
||||||
form.ClientSize = new Size(450, 320);
|
|
||||||
form.FormBorderStyle = FormBorderStyle.FixedDialog;
|
|
||||||
form.StartPosition = FormStartPosition.CenterScreen;
|
|
||||||
form.MaximizeBox = false;
|
|
||||||
form.MinimizeBox = false;
|
|
||||||
${
|
|
||||||
escapedIconPath
|
|
||||||
? `using (var bmp = new Bitmap("${escapedIconPath}"))
|
|
||||||
{
|
|
||||||
form.Icon = Icon.FromHandle(bmp.GetHicon());
|
|
||||||
}`
|
|
||||||
: ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ApplyLabelStyle(label);
|
const csharpCode = dialogTemplate;
|
||||||
label.Text = "${placeholder}";
|
const result = await this.runCsharp(csharpCode, args);
|
||||||
label.SetBounds(15, 15, 420, 20);
|
return result || null;
|
||||||
form.Controls.Add(label);
|
|
||||||
|
|
||||||
ApplyTextBoxStyle(textBox);
|
|
||||||
textBox.Multiline = true;
|
|
||||||
textBox.ScrollBars = ScrollBars.Vertical;
|
|
||||||
textBox.SetBounds(15, 45, 420, 220);
|
|
||||||
textBox.Text = "${defaultText}";
|
|
||||||
textBox.AcceptsReturn = true;
|
|
||||||
form.Controls.Add(textBox);
|
|
||||||
|
|
||||||
ApplyButtonStyle(okButton);
|
|
||||||
okButton.Text = "确定";
|
|
||||||
okButton.DialogResult = DialogResult.OK;
|
|
||||||
okButton.SetBounds(260, 275, 85, 30);
|
|
||||||
form.Controls.Add(okButton);
|
|
||||||
|
|
||||||
ApplySecondaryButtonStyle(cancelButton);
|
|
||||||
cancelButton.Text = "取消";
|
|
||||||
cancelButton.DialogResult = DialogResult.Cancel;
|
|
||||||
cancelButton.SetBounds(350, 275, 85, 30);
|
|
||||||
form.Controls.Add(cancelButton);
|
|
||||||
|
|
||||||
form.AcceptButton = null;
|
|
||||||
form.CancelButton = cancelButton;
|
|
||||||
|
|
||||||
form.KeyPreview = true;
|
|
||||||
form.KeyDown += (sender, e) => {
|
|
||||||
if (e.KeyCode == Keys.Enter && e.Control) {
|
|
||||||
okButton.PerformClick();
|
|
||||||
e.Handled = true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (form.ShowDialog() == DialogResult.OK) {
|
|
||||||
Console.WriteLine(textBox.Text);
|
|
||||||
}
|
|
||||||
form.Dispose();
|
|
||||||
}
|
|
||||||
}`;
|
|
||||||
const result = await this.runCsharp(csharpScript);
|
|
||||||
return result.trim() || null;
|
|
||||||
} else if (window.utools.isLinux()) {
|
} else if (window.utools.isLinux()) {
|
||||||
if (!(await checkZenity())) return null;
|
if (!(await checkZenity())) return null;
|
||||||
try {
|
try {
|
||||||
const script = `zenity --text-info --title="${title}" --text="${placeholder}" --editable --width=450 --height=350 --filename=<(echo "${defaultText}")`;
|
const script = `zenity --text-info --title="${title}" --editable --width=450 --height=350 --filename=<(echo "${defaultText}")`;
|
||||||
const result = await execCommand(script);
|
const result = await execCommand(script);
|
||||||
return result ? result.trim() : null;
|
return result ? result.trim() : null;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -694,7 +295,6 @@ module.exports = {
|
|||||||
showSystemMessageBox,
|
showSystemMessageBox,
|
||||||
showSystemInputBox,
|
showSystemInputBox,
|
||||||
showSystemConfirmBox,
|
showSystemConfirmBox,
|
||||||
showSystemSelectList,
|
|
||||||
showSystemButtonBox,
|
showSystemButtonBox,
|
||||||
showSystemTextArea,
|
showSystemTextArea,
|
||||||
};
|
};
|
||||||
|
@ -200,30 +200,11 @@ export const uiCommands = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: "quickcommand.showSelectList",
|
value: "quickcommand.showSelectList",
|
||||||
label: "uTools选择列表",
|
label: "选择列表",
|
||||||
desc: "显示一个支持搜索的选项列表,可以动态更新选项",
|
desc: "显示一个支持搜索的选项列表,可以动态更新选项",
|
||||||
component: "SelectListEditor",
|
component: "SelectListEditor",
|
||||||
isAsync: true,
|
isAsync: true,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
value: "quickcommand.showSystemSelectList",
|
|
||||||
label: "系统选择列表",
|
|
||||||
desc: "选择列表(系统)",
|
|
||||||
isAsync: true,
|
|
||||||
config: [
|
|
||||||
{
|
|
||||||
label: "选项",
|
|
||||||
component: "ArrayEditor",
|
|
||||||
width: 12,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "标题",
|
|
||||||
component: "VariableInput",
|
|
||||||
defaultValue: newVarInputVal("str", "请选择"),
|
|
||||||
width: 12,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
value: "quickcommand.showTextArea",
|
value: "quickcommand.showTextArea",
|
||||||
label: "文本框",
|
label: "文本框",
|
||||||
@ -231,6 +212,11 @@ export const uiCommands = {
|
|||||||
isAsync: true,
|
isAsync: true,
|
||||||
outputVariable: "textareaValue",
|
outputVariable: "textareaValue",
|
||||||
saveOutput: true,
|
saveOutput: true,
|
||||||
|
subCommands: [
|
||||||
|
{
|
||||||
|
value: "quickcommand.showTextArea",
|
||||||
|
icon: "call_to_action",
|
||||||
|
label: "插件内弹窗",
|
||||||
config: [
|
config: [
|
||||||
{
|
{
|
||||||
label: "文本框占位符",
|
label: "文本框占位符",
|
||||||
@ -245,16 +231,25 @@ export const uiCommands = {
|
|||||||
width: 6,
|
width: 6,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
subCommands: [
|
|
||||||
{
|
|
||||||
value: "quickcommand.showTextArea",
|
|
||||||
icon: "call_to_action",
|
|
||||||
label: "插件内弹窗",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: "quickcommand.showSystemTextArea",
|
value: "quickcommand.showSystemTextArea",
|
||||||
icon: "report",
|
icon: "report",
|
||||||
label: "系统弹窗(Mac不支持)",
|
label: "系统弹窗(Mac不支持)",
|
||||||
|
config: [
|
||||||
|
{
|
||||||
|
label: "文本框默认值",
|
||||||
|
component: "VariableInput",
|
||||||
|
defaultValue: newVarInputVal("str"),
|
||||||
|
width: 6,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "标题",
|
||||||
|
component: "VariableInput",
|
||||||
|
defaultValue: newVarInputVal("str", "请输入"),
|
||||||
|
width: 6,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
26
src/plugins/monaco/types/quickcommand.api.d.ts
vendored
26
src/plugins/monaco/types/quickcommand.api.d.ts
vendored
@ -549,30 +549,12 @@ interface quickcommandApi {
|
|||||||
*/
|
*/
|
||||||
showSystemConfirmBox(content: string, title?: string): Promise<boolean>;
|
showSystemConfirmBox(content: string, title?: string): Promise<boolean>;
|
||||||
|
|
||||||
/**
|
|
||||||
* 显示一个系统级选择列表,返回选择的项的索引和文本(不支持Linux)
|
|
||||||
*
|
|
||||||
* ```js
|
|
||||||
* quickcommand.showSystemSelectList(["选项1", "选项2", "选项3"], "请选择").then(result => {
|
|
||||||
* if (result) {
|
|
||||||
* console.log(`选择了第${result.id + 1}个选项:${result.text}`)
|
|
||||||
* }
|
|
||||||
* })
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* @param items 选项列表
|
|
||||||
* @param title 标题,默认为空
|
|
||||||
*/
|
|
||||||
showSystemSelectList(
|
|
||||||
items: string[],
|
|
||||||
title?: string
|
|
||||||
): Promise<{ id: number; text: string } | null>;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 显示一个系统级按钮组对话框,返回点击的按钮的索引和文本(不支持Linux)
|
* 显示一个系统级按钮组对话框,返回点击的按钮的索引和文本(不支持Linux)
|
||||||
*
|
*
|
||||||
* ```js
|
* ```js
|
||||||
* quickcommand.showSystemButtonBox(["保存", "不保存", "取消"], "是否保存更改?", "保存确认").then(result => {
|
* quickcommand.showSystemButtonBox(["保存", "不保存", "取消"], "保存确认").then(result => {
|
||||||
* if (result) {
|
* if (result) {
|
||||||
* console.log(`点击了第${result.id + 1}个按钮:${result.text}`)
|
* console.log(`点击了第${result.id + 1}个按钮:${result.text}`)
|
||||||
* }
|
* }
|
||||||
@ -580,12 +562,10 @@ interface quickcommandApi {
|
|||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* @param buttons 按钮文本数组
|
* @param buttons 按钮文本数组
|
||||||
* @param content 对话框内容
|
|
||||||
* @param title 标题,默认为空
|
* @param title 标题,默认为空
|
||||||
*/
|
*/
|
||||||
showSystemButtonBox(
|
showSystemButtonBox(
|
||||||
buttons: string[],
|
buttons: string[],
|
||||||
content: string,
|
|
||||||
title?: string
|
title?: string
|
||||||
): Promise<{ id: number; text: string } | null>;
|
): Promise<{ id: number; text: string } | null>;
|
||||||
|
|
||||||
@ -593,19 +573,17 @@ interface quickcommandApi {
|
|||||||
* 显示一个系统级多行文本输入框(仅Windows支持)
|
* 显示一个系统级多行文本输入框(仅Windows支持)
|
||||||
*
|
*
|
||||||
* ```js
|
* ```js
|
||||||
* quickcommand.showSystemTextArea("请输入多行文本:", "默认内容", "文本编辑").then(text => {
|
* quickcommand.showSystemTextArea("默认内容", "文本编辑").then(text => {
|
||||||
* if (text) {
|
* if (text) {
|
||||||
* console.log("输入的文本:", text)
|
* console.log("输入的文本:", text)
|
||||||
* }
|
* }
|
||||||
* })
|
* })
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* @param placeholder 提示文本,默认为空
|
|
||||||
* @param defaultText 默认文本,默认为空
|
* @param defaultText 默认文本,默认为空
|
||||||
* @param title 标题,默认为空
|
* @param title 标题,默认为空
|
||||||
*/
|
*/
|
||||||
showSystemTextArea(
|
showSystemTextArea(
|
||||||
placeholder?: string,
|
|
||||||
defaultText?: string,
|
defaultText?: string,
|
||||||
title?: string
|
title?: string
|
||||||
): Promise<string | null>;
|
): Promise<string | null>;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user