lxn / walk

A Windows GUI toolkit for the Go Programming Language
Other
6.78k stars 885 forks source link

MainWindow Icon #757

Open Rookiebrother opened 3 years ago

Rookiebrother commented 3 years ago
    var ww *walk.MainWindow
var wv *walk.WebView
var icon,_ = walk.NewIconFromResourceId(3)
MainWindow{
    AssignTo: &ww,
    Title:    "Browser",
    MinSize:  Size{Width: 800, Height: 600},
    Layout:   VBox{MarginsZero: true},
    Children: []Widget{
        WebView{
            AssignTo: &wv,
            Name:     "wv",
            URL:      "https://github.com/lxn/walk",
        },
    },
}.Create()
_ = ww.SetIcon(icon)
ww.Run()

panic: runtime error: invalid memory address or nil pointer dereference [signal 0xc0000005 code=0x0 addr=0x28 pc=0x933585]

goroutine 1 [running, locked to thread]: github.com/lxn/walk.(Icon).Size(0x0, 0x60, 0x0) F:/Codeing/Golang/src/github.com/lxn/walk/icon.go:348 +0x5 github.com/lxn/walk.(FormBase).SetIcon(0xc000057000, 0xaa7140, 0x0, 0x0, 0x0) F:/Codeing/Golang/src/github.com/lxn/walk/form.go:524 +0x13e main.run() F:/Codeing/Golang/walkapp/main.go:105 +0x274 main.main() F:/Codeing/Golang/walkapp/main.go:37 +0x2c PS F:\Codeing\Golang\walkapp> .\walkapp.exe panic: runtime error: invalid memory address or nil pointer dereference [signal 0xc0000005 code=0x0 addr=0x28 pc=0x933585]

goroutine 1 [running, locked to thread]: github.com/lxn/walk.(Icon).Size(0x0, 0x60, 0x0) F:/Codeing/Golang/src/github.com/lxn/walk/icon.go:348 +0x5 github.com/lxn/walk.(FormBase).SetIcon(0xc000057000, 0xaa7140, 0x0, 0x0, 0x0) F:/Codeing/Golang/src/github.com/lxn/walk/form.go:524 +0x13e main.run() F:/Codeing/Golang/walkapp/main.go:105 +0x274 main.main() F:/Codeing/Golang/walkapp/main.go:37 +0x2c

Rookiebrother commented 3 years ago

Ask for help 😫

Rookiebrother commented 3 years ago

😫😫😫😫

evangwt commented 3 years ago

If walk .NewIconFromResourceId doesn't work, you can try this.

func main() {
    // ...
    // load icon
    hIcon, _ := loadIconFromResource(iconID)
    if hIcon != 0 {
        win.SendMessage(mw.Handle(), win.WM_SETICON, 1, uintptr(hIcon))
        win.SendMessage(mw.Handle(), win.WM_SETICON, 0, uintptr(hIcon))
    }
}

func loadIconFromResource(id uintptr) (win.HANDLE, error) {
    hIcon := win.LoadImage(
        win.GetModuleHandle(nil),
        win.MAKEINTRESOURCE(id),
        win.IMAGE_ICON,
        0, 0,
        win.LR_DEFAULTSIZE)
    if hIcon == 0 {
        return 0, errors.New("load icon failed")
    }

    return hIcon, nil
}
YanxinTang commented 3 years ago

Maybe you can try to change resource ID 3 to 2 if you are using akavel/rsrc v0.10

tc-hib commented 3 years ago

I don't know if this can help you but I made a tool that's like rsrc, but more complete (and working better so far ). It's go-winres. It lets you define any number of icons, and you name them explicitly, either by ID or by string. Tell me if you need some help.

I developed it from scratch, carefully following Microsoft spec, and comparing it with what Visual Studio produces.

It might not directly solve your problem, but at least you'll be sure what name your icon has.

tc-hib commented 3 years ago

Hello @Rookiebrother,

You must add a manifest that enables Common Controls v6, otherwise, LoadIconWithScaleDown does not exist (in Common Controls v5).

Add this to your manifest:

  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/>
    </dependentAssembly>
  </dependency>

if you want to try go-winres, here is a winres.json for a typical GUI manifest and an icon with ID 3:

{
  "RT_MANIFEST": {
    "#1": {
      "0409": {
        "dpi-awareness": "per monitor v2",
        "use-common-controls-v6": true
      }
    }
  },
  "RT_GROUP_ICON": {
    "APP" : {
      "0000": "you_desktop_icon.png"
    },
    "#3": {
      "0000": "your_window_icon.png"
    }
  },
}