传统 AHK Gui 很适合快速做工具,但界面一旦需要统一主题、复杂布局、侧边栏、现代控件和更完整的视觉层次,代码会迅速变得难维护。AHK-XAML 的思路是让 AHK 继续负责业务和事件,用 XAML 与 WPF 负责界面结构和渲染。

本批资源包含 AutoHotkey v1 移植版,运行基线是 AutoHotkey v1 U64。它通过独立的 WPF daemon 进程工作:AHK 生成界面描述,C# WPF Host 创建窗口,事件和状态再通过 IPC 回到 AHK。它不是给传统 Gui 换一层皮肤,而是一套 AHK 到 WPF 的桥接框架。

它带来的实际能力

  • 使用 Grid、StackPanel、DockPanel、ScrollViewer 等 WPF 布局;
  • 统一使用颜色、字体、边框、圆角、阴影和控件模板;
  • 通过链式 API 创建控件并绑定 AHK v1 回调;
  • 提供侧边栏、标签页、Snackbar、Flyout 等常用组件;
  • 可选接入 WebView2、AvalonEdit、文档组件和 shader 效果;
  • 附带多个基础、组件展示和仿制界面示例。

 

ahk-xaml-main_V1\examples\clones\vscode_v1.ahk 示例演示图

 

先说清楚它和原生 WPF 的区别

底层确实由 WPF 渲染,但写代码时并不是在开发完整的 C# WPF 程序。原生 WPF 中的 DataContext、Binding、Command、DependencyProperty、MVVM、ObservableCollection 和设计器工作流,在这套封装里并没有原样提供。常用方式仍是 AHK 事件回调,加上 Query()、Update() 等接口更新界面。

因此它适合需要现代界面、组件化布局和中等复杂交互的 AHK 工具;只做几个输入框和按钮时,传统 AHK Gui 更轻。需要完整 MVVM、复杂数据绑定、第三方 WPF 控件生态和高频实时动画时,原生 C# WPF 仍然更合适。

v1 版本的边界

v1 移植版只支持外部 daemon,不支持进程内 CLR/WPF 托管。WebView2、AvalonEdit、文档编辑器和 DirectX 9 shader 默认关闭,启用前要按配置文件准备额外依赖。由于 v1 的 unset、类型和超级全局变量语义与 v2 不同,调用方还应避开项目保留的全局变量名。

当前素材中有多组经过解析和窗口启动检查的 v1 示例。新手建议从 Minimal 或下面的 minimal_wrapper 开始,先看控件创建、Track()、On() 和 Update(),再进入复杂组件与仿制界面。

示例运行时会启动配套 WPF daemon。结束 AHK 主脚本后,宿主进程应随之退出;若自行改造启动流程,要同时处理异常退出和进程清理。

打包库和示例的下载地址:

蓝奏云:https://wwbtw.lanzouu.com/isu4t3wswp2d  提取码:ahk6

百度网盘:https://pan.baidu.com/s/1dkOgcGNseyA0zCQwXwXIYQ?pwd=ahk6  提取码:ahk6

 

demo代码片段展示:

#Requires AutoHotkey v1.1.37+
#Persistent
#Include <XAML_GUI>
#Include <XAML_Components>
app := new XAML_GUI("Minimal AHK GUI")

app.sidebarPanel.Add("TextBlock").Text("QUICK SETTINGS").Margin("0,15,0,15").Foreground("{DynamicResource TextSub}").FontSize(11).FontWeight("Bold")
app.sidebarPanel.Toggle("TglCenter", "Center Align", false)
    .Track()
    .On("Click", Func("MinimalWrapper_OnToggleCenter"))

app.tabs.Visibility("Collapsed")
panel := app.main.Add("StackPanel").Grid_Row(1).Margin("40,20,40,20")

panel.Add("TextBlock").Name("TxtTitle").Text("Welcome to the Minimal UI!").Use("PageTitle").Margin("0,0,0,10")
panel.Add("TextBlock").Name("TxtDesc").Text("Notice how much heavy lifting is done for you. No DllCalls, no manual rendering, just clean, object-oriented UI building.").Use("BodyText").Margin("0,0,0,25")

panel.Add("TextBlock").Name("TxtLabel").Text("ENTER YOUR NAME").Foreground("{DynamicResource TextSub}").FontSize(11).FontWeight("Bold").Margin("0,0,0,8").HorizontalAlignment("Left")
panel.Add("TextBox").Name("TxtName").Width(300).HorizontalAlignment("Left").Margin("0,0,0,15").Track()

panel.Add("Button").Name("BtnSubmit").Content("Say Hello").Use("PrimaryBtn").Width(120).Height(32).HorizontalAlignment("Left")
    .On("Click", Func("MinimalWrapper_OnSubmitClick"))

ui := app.Compile()
ui.xaml := StrReplace(ui.xaml, "Width=""940"" Height=""700""", "Width=""600"" Height=""420""")
app.Show()
return

MinimalWrapper_OnToggleCenter(state, ctrl, event) {
    global app
    isCenter := state.HasKey("TglCenter") && state["TglCenter"] == "True"
    align := isCenter ? "Center" : "Left"

    app.host.Update("TxtTitle", "TextAlignment", align)
    app.host.Update("TxtDesc", "TextAlignment", align)
    app.host.Update("TxtLabel", "HorizontalAlignment", align)
    app.host.Update("TxtName", "HorizontalAlignment", align)
    app.host.Update("BtnSubmit", "HorizontalAlignment", align)
}

MinimalWrapper_OnSubmitClick(state, ctrl, event) {
    global app
    name := state.HasKey("TxtName") && state["TxtName"] != "" ? state["TxtName"] : "Stranger"
    app.ShowSnackbar("Hello there, " name "!")
}

 

声明:站内资源为整理优化好的代码上传分享与学习研究,如果是开源代码基本都会标明出处,方便大家扩展学习路径。请不要恶意搬运,破坏站长辛苦整理维护的劳动成果。本站为爱好者分享站点,所有内容不作为商业行为。如若本站上传内容侵犯了原著者的合法权益,请联系我们进行删除下架。