我也是刚刚使用walk这个组件,很多控件接口不熟悉,把我上次发的邮件群发器修改成图形界面的,线程发送邮件,gob库保存数据等。只提供作学习交流,仅供参考(界面很烂)。
接下来是main.go的代码:
- //Multi-SendEmailprojectmain.go
- packagemain
- import(
- "bufio"
- "encoding/gob"
- "errors"
- "fmt"
- "io"
- "net/smtp"
- "os"
- "strconv"
- "strings"
- "time"
- )
- import(
- "github.com/lxn/walk"
- ."github.com/lxn/walk/declarative"
- )
- typeShuJustruct{
- Namestring
- Pwdstring
- Hoststring
- Subjectstring
- Bodystring
- Sendstring
- }
- funcSendMail(user,password,host,to,subject,body,mailtypestring)error{
- fmt.Println("Sendto"+to)
- //fmt.Println(user,mailtype)
- hp:=strings.Split(host,":")
- auth:=smtp.PlainAuth("",user,hp[0])
- varcontent_typestring
- ifmailtype=="html"{
- content_type="Content-Type:text/html;charset=UTF-8"
- }else{
- content_type="Content-Type:text/plain;charset=UTF-8"
- }
- body=strings.TrimSpace(body)
- msg:=[]byte("To:"+to+"\r\nFrom:"+user+"<"+user+">\r\nSubject:"+subject+"\r\n"+content_type+"\r\n\r\n"+body)
- send_to:=strings.Split(to,";")
- err:=smtp.SendMail(host,auth,send_to,msg)
- iferr!=nil{
- fmt.Println(err.Error())
- }
- returnerr
- }
- funcreadLine2Array(filenamestring)([]string,error){
- result:=make([]string,0)
- file,err:=os.Open(filename)
- iferr!=nil{
- returnresult,errors.New("OpenfileFailed.")
- }
- deferfile.Close()
- bf:=bufio.NewReader(file)
- for{
- line,isPrefix,err1:=bf.ReadLine()
- iferr1!=nil{
- iferr1!=io.EOF{
- returnresult,errors.New("ReadLinenofinish")
- }
- break
- }
- ifisPrefix{
- returnresult,errors.New("Lineistoolong")
- }
- str:=string(line)
- result=append(result,str)
- }
- returnresult,nil
- }
- funcDelArrayVar(arr[]string,strstring)[]string{
- str=strings.TrimSpace(str)
- fori,v:=rangearr{
- v=strings.TrimSpace(v)
- ifv==str{
- ifi==len(arr){
- returnarr[0:i-1]
- }
- ifi==0{
- returnarr[1:len(arr)]
- }
- a1:=arr[0:i]
- a2:=arr[i+1:len(arr)]
- returnappend(a1,a2...)
- }
- }
- returnarr
- }
- funcLoadData(){
- fmt.Println("LoadData")
- file,err:=os.Open("data.dat")
- deferfile.Close()
- iferr!=nil{
- fmt.Println(err.Error())
- SJ.Name="用户名"
- SJ.Pwd="用户密码"
- SJ.Host="SMTP服务器:端口"
- SJ.Subject="邮件主题"
- SJ.Body="邮件内容"
- SJ.Send="要发送的邮箱,每行一个"
- return
- }
- dec:=gob.NewDecoder(file)
- err2:=dec.Decode(&SJ)
- iferr2!=nil{
- fmt.Println(err2.Error())
- SJ.Name="用户名"
- SJ.Pwd="用户密码"
- SJ.Host="SMTP服务器:端口"
- SJ.Subject="邮件主题"
- SJ.Body="邮件内容"
- SJ.Send="要发送的邮箱,每行一个"
- }
- }
- funcSaveData(){
- fmt.Println("SaveData")
- file,err:=os.Create("data.dat")
- deferfile.Close()
- iferr!=nil{
- fmt.Println(err)
- }
- enc:=gob.NewEncoder(file)
- err2:=enc.Encode(SJ)
- iferr2!=nil{
- fmt.Println(err2)
- }
- }
- varSJShuJu
- varruningbool
- varchEndchanbool
- funcmain(){
- LoadData()
- chEnd=make(chanbool)
- varemails,msgBox*walk.TextEdit
- varuser,subject*walk.LineEdit
- varstartBtn*walk.PushButton
- MainWindow{
- Title:"邮件群发器By一曲忧伤",MinSize:Size{800,600},Layout:HBox{},Children:[]Widget{
- TextEdit{AssignTo:&emails,Text:SJ.Send,ToolTipText:"待发送邮件列表,每行一个"},VSplitter{
- Children:[]Widget{
- LineEdit{AssignTo:&user,Text:SJ.Name,CueBanner:"请输入邮箱用户名"},LineEdit{AssignTo:&password,Text:SJ.Pwd,PasswordMode:true,CueBanner:"请输入邮箱登录密码"},LineEdit{AssignTo:&host,Text:SJ.Host,CueBanner:"SMTP服务器:端口"},LineEdit{AssignTo:&subject,Text:SJ.Subject,CueBanner:"请输入邮件主题……"},TextEdit{AssignTo:&body,Text:SJ.Body,ToolTipText:"请输入邮件内容",ColumnSpan:2},TextEdit{AssignTo:&msgBox,ReadOnly:true},PushButton{
- AssignTo:&startBtn,Text:"开始群发",OnClicked:func(){
- SJ.Name=user.Text()
- SJ.Pwd=password.Text()
- SJ.Host=host.Text()
- SJ.Subject=subject.Text()
- SJ.Body=body.Text()
- SJ.Send=emails.Text()
- SaveData()
- ifruning==false{
- runing=true
- startBtn.SetText("停止发送")
- gosendThread(msgBox,emails)
- }else{
- runing=false
- startBtn.SetText("开始群发")
- }
- },},}.Run()
- }
- funcsendThread(msgBox,es*walk.TextEdit){
- sendTo:=strings.Split(SJ.Send,"\r\n")
- susscess:=0
- count:=len(sendTo)
- forindex,to:=rangesendTo{
- ifruning==false{
- break
- }
- msgBox.SetText("发送到"+to+"..."+strconv.Itoa(int((float32(index)/float32(count))*100))+"%")
- err:=SendMail(SJ.Name,SJ.Pwd,SJ.Host,SJ.Subject,SJ.Body,"html")
- iferr!=nil{
- msgBox.AppendText("\r\n失败:"+err.Error()+"\r\n")
- iferr.Error()=="550MailBoxnotfoundoraccessdenied"{
- SJ.Send=strings.Join(DelArrayVar(strings.Split(SJ.Send,"\r\n"),to),"\r\n")
- es.SetText(SJ.Send)
- }
- time.Sleep(1*time.Second)
- continue
- }else{
- susscess++
- msgBox.AppendText("\r\n发送成功!")
- SJ.Send=strings.Join(DelArrayVar(strings.Split(SJ.Send,"\r\n")
- es.SetText(SJ.Send)
- }
- time.Sleep(1*time.Second)
- }
- SaveData()
- msgBox.SetText("停止发送!共成功"+strconv.Itoa(susscess)+"条\r\n")
- }
然后是walk程序所用的main.manifest,完全照抄官方的,还没研究其中意思:
- <?xmlversion="1.0"encoding="UTF-8"standalone="yes"?>
- <assemblyxmlns="urn:schemas-microsoft-com:asm.v1"manifestVersion="1.0">
- <assemblyIdentityversion="1.0.0.0"processorArchitecture="*"name="SomeFunkyNameHere"type="win32"/>
- <dependency>
- <dependentAssembly>
- <assemblyIdentitytype="win32"name="Microsoft.Windows.Common-Controls"version="6.0.0.0"processorArchitecture="*"publicKeyToken="6595b64144ccf1df"language="*"/>
- </dependentAssembly>
- </dependency>
- </assembly>
通过这个main.manifest执行(如果walk安装好了,应该就有这个命令):
- rsrc-manifestmain.manifest-orsrc.syso
上图是rsrc命令的参数列表,比如我为自已的程序加个ico图标:
- rsrc-manifestmain.manifest–icoicon.ico-orsrc.syso
附上软件运行截图:
总结:只要熟悉这些非常强大的第三方库,Go应该也可以做出非常不错的图形应用程序,对于接触C、C++过晚的朋友来说非常合适。