有个私活,把一个 ahk 函数转成 rust 函数,预算 500

38 天前
 iliaoliao
下面是 ahk 函数,用到了一个 ahk 库 Gdip.ahk ,要求用 rust 和 windows-rs 库实现一个相同功能的函数。
实现出来了可以加我微信私聊,WX:bHgxMDc2OTg4OTQ0

```ahk
可视化(var0 := "0", var1 := "0", var2 := "0")
{ ;显示坐标
if !pToken := Gdip_Startup()
{
MsgBox, % 4096+262208, , Gdiplus 错误!, Gdiplus 无法启动.请确保系统中有 gdiplus.dll
return
}

Gui, GUILX: -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs
Gui, GUILX: Show, NA
Width := A_ScreenWidth
Height := A_ScreenHeight
hwnd1 := WinExist()
hbm := CreateDIBSection(Width, Height)
hdc := CreateCompatibleDC()
obm := SelectObject(hdc, hbm)
G := Gdip_GraphicsFromHDC(hdc)
pBrush1 := Gdip_CreatePen(0xFFFF0000, 1)
pBrush2 := Gdip_CreatePen(0xFF00FFFF, 1)
pBrush3 := Gdip_CreatePen(0xFFFFFF00, 1)

for k, v in var0
{
Gdip_DrawRectangle(G, pBrush1, v.x, v.y, v.w, v.h)
}

if var1
{
x := "", y := "", c := ""
For k, v in var1
{
if (y = "")
{
N := StrSplit(v,",")
x := N[1],y := N[2]
c .= "`n" . k . " : " . v
}
tx:=x
ty:=y-20
Gdip_TextToGraphics(G, k, "x" tx "y" ty "h20 Centre cFF00FF00 r4 s12 Left")
Gdip_DrawLine(G, pBrush2, x - 5, y, x - 1 , y)
Gdip_DrawLine(G, pBrush2, x + 5, y, x + 1 , y)
Gdip_DrawLine(G, pBrush2, x, y - 5, x, y - 1)
Gdip_DrawLine(G, pBrush2, x, y + 5, x, y + 1)
}
}
if var2
{
Gdip_DrawRectangle(G, pBrush3, var2.x - 5, var2.y - 5, var2.w + 10, var2.h + 10)
}
Gdip_DeleteBrush(pBrush1)
Gdip_DeleteBrush(pBrush2)
Gdip_DeleteBrush(pBrush3)
UpdateLayeredWindow(hwnd1, hdc, 0, 0, Width, Height)
SelectObject(hdc, obm)
DeleteObject(hbm)
DeleteDC(hdc)
Gdip_DeleteGraphics(G)
Gdip_Shutdown(pToken)
MsgBox, 4096, , % "点击确认关闭显示" c
Gui, GUILX: Destroy
return
}
```
1383 次点击
所在节点    外包
8 条回复
zdw189803631
38 天前
用 ai 转化下啊
iliaoliao
38 天前
@zdw189803631 曾经我也迷信 ai ,为此还开了个 plus 会员,但不尽人意啊..
zdw189803631
38 天前
肯定要自己改一些,当然如果完全不懂代码,那确实挺麻烦的
wangyaominde
38 天前
我用 Claude 直接把你的表述复制过去的,你看看能不能用:

我理解你想要将这个 AutoHotkey (AHK) 函数转换为使用 Rust 和 windows-rs 库的等效实现。这是一个涉及 Windows GUI 编程和图形绘制的复杂任务。我会为你创建一个基本的 Rust 实现,但请注意,由于功能的复杂性,这个实现可能需要进一步的优化和完善。

首先,让我们创建一个新的 Rust 项目并添加必要的依赖。



```rust
use windows::{
core::*,
Win32::Foundation::*,
Win32::Graphics::Gdi::*,
Win32::UI::WindowsAndMessaging::*,
};
use std::collections::HashMap;

struct Rect {
x: i32,
y: i32,
w: i32,
h: i32,
}

struct Point {
x: i32,
y: i32,
}

fn main() -> Result<()> {
unsafe {
let instance = GetModuleHandleA(None)?;
debug_assert!(instance.0 != 0);

let window_class = s!("window");

let wc = WNDCLASSA {
hCursor: LoadCursorW(None, IDC_ARROW)?,
hInstance: instance,
lpszClassName: window_class,
style: CS_HREDRAW | CS_VREDRAW,
lpfnWndProc: Some(wndproc),
..Default::default()
};

let atom = RegisterClassA(&wc);
debug_assert!(atom != 0);

let hwnd = CreateWindowExA(
WINDOW_EX_STYLE::default(),
window_class,
s!("Rust Visualization"),
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
None,
None,
instance,
None,
);

let mut message = MSG::default();

while GetMessageA(&mut message, HWND(0), 0, 0).into() {
DispatchMessageA(&message);
}

Ok(())
}
}

extern "system" fn wndproc(window: HWND, message: u32, wparam: WPARAM, lparam: LPARAM) -> LRESULT {
unsafe {
match message {
WM_PAINT => {
let mut ps = PAINTSTRUCT::default();
let hdc = BeginPaint(window, &mut ps);

// Example data (replace with actual data passed to the function)
let var0 = vec![Rect { x: 10, y: 10, w: 100, h: 100 }];
let mut var1 = HashMap::new();
var1.insert(String::from("Point1"), Point { x: 50, y: 50 });
let var2 = Rect { x: 200, y: 200, w: 50, h: 50 };

// Draw rectangles from var0
for rect in &var0 {
Rectangle(hdc, rect.x, rect.y, rect.x + rect.w, rect.y + rect.h);
}

// Draw points and labels from var1
for (label, point) in &var1 {
Ellipse(hdc, point.x - 5, point.y - 5, point.x + 5, point.y + 5);
TextOutA(hdc, point.x, point.y - 20, label.as_bytes());
}

// Draw rectangle from var2
Rectangle(hdc, var2.x - 5, var2.y - 5, var2.x + var2.w + 5, var2.y + var2.h + 5);

EndPaint(window, &ps);
LRESULT(0)
}
WM_DESTROY => {
PostQuitMessage(0);
LRESULT(0)
}
_ => DefWindowProcA(window, message, wparam, lparam),
}
}
}

```

这个 Rust 实现提供了一个基本框架,用于创建一个 Windows 窗口并在其中绘制一些基本图形。它大致对应于原始 AHK 脚本的功能,但有一些重要的区别和限制:

1. 这个实现使用 GDI 而不是 GDI+。GDI+ 在 Rust 中的使用更复杂,可能需要额外的库或更复杂的 FFI 。

2. 窗口创建和消息循环是显式的,而在 AHK 中这些通常是隐式处理的。

3. 绘图是在 WM_PAINT 消息处理程序中完成的,这是 Windows 编程的标准方法。

4. 这个实现没有包含透明窗口或分层窗口更新,这在原始 AHK 脚本中使用。

5. 文本渲染和一些更复杂的绘图操作被简化了。

6. 错误处理被简化了,在实际应用中应该更加健壮。

要使用这个代码,你需要在你的 Cargo.toml 文件中添加以下依赖:

```toml
[dependencies]
windows = { version = "0.48", features = ["Win32_Foundation", "Win32_Graphics_Gdi", "Win32_UI_WindowsAndMessaging"] }
```

这个实现提供了一个起点,但要完全复制原始 AHK 脚本的功能,还需要进行大量工作。你可能需要:

1. 实现更复杂的绘图功能。
2. 添加对透明窗口的支持。
3. 实现更复杂的用户交互。
4. 优化性能和资源使用。
iliaoliao
38 天前
@wangyaominde 谢谢大佬。晚上我回去用 windows 电脑试试
wyfig
38 天前
用 claude 应该可以直接转
LinYaXuan
38 天前
claude 的代码能力比 gpt4 强这么多啊,感觉自己续费的 gpt4 好冤大头。

按照我的理解这个脚本就是绘制矩形和圆形的,上面的 rust 代码简单修几个错误就能达成这个功能。不过我跑那个 ahk 脚本只能看到最后的"点击确认关闭显示"提示,没能看到绘制的图形。
iliaoliao
38 天前
@LinYaXuan 上面的 claude 代码差不多是我问几天 gpt 的答案了,但还是有个问题,怎么把参数传到 extern "system" fn wndproc 里面。
上面的 ahk 代码,需要依赖传入的参数才能绘制图形。参数大概的结构是 var0: {x,y,w,h}[] ; var1: {label1: {x, y}, label2: {x, y}} ; var2: {x,y,w,h};

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1064263

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX