惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

MongoDB | Blog
MongoDB | Blog
博客园 - 聂微东
Attack and Defense Labs
Attack and Defense Labs
WordPress大学
WordPress大学
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Spread Privacy
Spread Privacy
AI
AI
宝玉的分享
宝玉的分享
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
C
Cyber Attacks, Cyber Crime and Cyber Security
爱范儿
爱范儿
Help Net Security
Help Net Security
V
Visual Studio Blog
大猫的无限游戏
大猫的无限游戏
Forbes - Security
Forbes - Security
P
Privacy & Cybersecurity Law Blog
Project Zero
Project Zero
IT之家
IT之家
Hugging Face - Blog
Hugging Face - Blog
博客园 - 三生石上(FineUI控件)
S
SegmentFault 最新的问题
有赞技术团队
有赞技术团队
T
Troy Hunt's Blog
美团技术团队
T
Threatpost
K
Kaspersky official blog
V
V2EX
Scott Helme
Scott Helme
Vercel News
Vercel News
T
The Blog of Author Tim Ferriss
T
Tailwind CSS Blog
V
Vulnerabilities – Threatpost
Last Week in AI
Last Week in AI
PCI Perspectives
PCI Perspectives
Google Online Security Blog
Google Online Security Blog
Apple Machine Learning Research
Apple Machine Learning Research
Engineering at Meta
Engineering at Meta
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
I
InfoQ
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
酷 壳 – CoolShell
酷 壳 – CoolShell
GbyAI
GbyAI
L
LINUX DO - 最新话题
T
The Exploit Database - CXSecurity.com
L
LangChain Blog
S
Security @ Cisco Blogs
The Last Watchdog
The Last Watchdog
H
Hacker News: Front Page
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
TaoSecurity Blog
TaoSecurity Blog

博客园 - AllenDang

创业心得 - 从确定投资意向到开始发工资还有多远? 什么样的人适合创业公司? NoSql数据库使用半年后在设计上面的一些心得 Go语言实战 - 使用SendCloud群发邮件 用Go语言做产品半年的一些感觉 我是怎么拿到投资的 Go语言实战 - 我需要站内搜索 Go语言实战 - revel框架教程之CSRF(跨站请求伪造)保护 Go语言实战 - revel框架教程之缓存和Job Go语言实战 - 网站性能优化第一弹“七牛云存储” 坚持是什么? - 作为创业者在与投资人见面之后想到的 Go语言实战 - revel框架教程之MongDB的最佳搭档revmgo Go语言实战 - revel框架教程之权限控制 Go语言实战 - revel框架教程之用户注册 Go语言实战 - 创业进行时之创业伊始 我为什么喜欢Go语言 使用CGO封装Windows API 用Go写Windows桌面应用 - 使用资源文件 用Go写Windows桌面应用 - 使用Form
用Go写Windows桌面应用 - 使用窗体设计器
AllenDang · 2012-02-28 · via 博客园 - AllenDang

目前来说,用Go写Windows应用还没有非常成熟的设计器,习惯了C#那种强大的IDE,再过来看会觉得一朝回到解放前。而且gform现在的设计思路需要使用者对win32 api非常熟悉,否则用起来会非常难受。吐舌笑脸 这也是我一直在想改善方案的地方,毕竟一个类库要以好用为目标,只是我充满了OO思想的头脑还没有完全适应Go的设计方式,很多以前信手拈来的思路用到Go上就会出现问题,或者就算套上去了也会觉得与语言格格不入。最明显就是在努力了两周之后,我突然发现竟然在模拟类的继承,天!当时就感觉真的需要停下来了,否则按照现在的惯性做出来的东西肯定一塌糊涂。

关于gform这个框架我的思考还在继续进行,在弄清楚到底怎样才是Go的设计模式之后,我相信会对它进行一次大的重构。

好了,现在进入正题,用窗体设计器做界面。原理是还是MFC的老方法,在资源文件中做好对话框设计,然后在运行时attach上去。

打开ResEdit,添加一个对话框,然后在上面放好各种控件。下图中是一个我做的小工具的实际例子。

image

其中,为每个控件都设置一个有意义的ID。比如,上图中“过滤”右边的文本框,ID为“IDC_FILTER”。

保存之后会发现,ResEdit自动生成了一个与资源文件同名的头文件,如下所示。

image

打开这个头文件,发现里面其实只是简单的定义了控件ID的值,如下所示。

image

我们现在新建一个go文件,叫做app.go,把头文件中的常量定义全都复制进来,变成Go的常量定义,比如:

const (
    IDD_DIALOG1  = 104
    IDC_CLOSE= 1006
)

可以看到,对话框的ID是IDD_DIALOG1,好,我们现在可以用gform.NewDialogFromResId来把这个对话框读取出来。

func main() {
    gform.Init()

    mainform := gform.NewDialogFromResId(nil, IDD_DIALOG1)
    mainform.Show()

    gform.RunMainLoop()
}

运行一下看看,怎么样?看到窗体了吧。现在来试试相应按钮的事件,使用gform.AttachPushButton,之后相应OnLBUp(On Left Button Up即当鼠标左键弹起时)。

btnClose = gform.AttachPushButton(mainform, IDC_CLOSE)
btnClose.OnLBUp().Attach(btnClose_OnLBUp)

func btnClose_OnLBUp(arg *gform.EventArg) {

//事件响应代码写在这里

}

gform中的事件响应函数很想C#中的委托,每个事件都可以Attach多个事件处理函数,事件激发是会单线程依次调用。而事件响应函数只有一个参数,让我们来看看gform.EventArg的定义。

type EventArg struct {
    sender Controller
    data interface{}
}

sender顾名思义,代表激发事件的控件。data里面附带的就是事件信息,比如,鼠标按键事件,data就是MouseEventData类型,定义如下。

type MouseEventData struct {
    X, Y   int
    Button int
    Wheel  int
}

其他的事件都有自己的事件数据,这里就不一一例举了。Go的interface{}挺好用的,加上它的静态类型检查,很安全、高效。

这样就完成了,目前gform支持Label、Button、Combobox、Edit、ListView、ProgressBar(因为我写的小工具仅用到了这几个控件微笑)。之后支持的控件会慢慢变多。

下一篇会讲到如何自定义控件,先秀一下近期正在做的小软件的界面,还远远没有完工,但我自己挺满意的。呵呵

image