Icons (windows), see #35.

This commit is contained in:
Nuno Cruces 2022-07-27 00:25:18 +01:00
parent 62e66e7fbd
commit 7ac67006b5
3 changed files with 26 additions and 34 deletions

View file

@ -231,11 +231,6 @@ const (
DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 = ^uintptr(4) + 1 DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 = ^uintptr(4) + 1
DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED = ^uintptr(5) + 1 DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED = ^uintptr(5) + 1
// LoadImage type
IMAGE_BITMAP = 0
IMAGE_ICON = 1
IMAGE_CURSOR = 2
// LoadIcon resources // LoadIcon resources
IDI_APPLICATION = 32512 IDI_APPLICATION = 32512
IDI_ERROR = 32513 IDI_ERROR = 32513
@ -398,7 +393,6 @@ type CWPRETSTRUCT struct {
//sys getWindowTextLength(wnd HWND) (ret int, err error) = user32.GetWindowTextLengthW //sys getWindowTextLength(wnd HWND) (ret int, err error) = user32.GetWindowTextLengthW
//sys IsDialogMessage(wnd HWND, msg *MSG) (ok bool) = user32.IsDialogMessageW //sys IsDialogMessage(wnd HWND, msg *MSG) (ok bool) = user32.IsDialogMessageW
//sys LoadIcon(instance Handle, resource uintptr) (ret Handle, err error) = user32.LoadIconW //sys LoadIcon(instance Handle, resource uintptr) (ret Handle, err error) = user32.LoadIconW
//sys LoadImage(instance Handle, name *uint16, typ int, cx int, cy int, load int) (ret Handle, err error) = user32.LoadImageW
//sys PostQuitMessage(exitCode int) = user32.PostQuitMessage //sys PostQuitMessage(exitCode int) = user32.PostQuitMessage
//sys RegisterClassEx(cls *WNDCLASSEX) (err error) = user32.RegisterClassExW //sys RegisterClassEx(cls *WNDCLASSEX) (err error) = user32.RegisterClassExW
//sys ReleaseDC(wnd HWND, dc Handle) (ok bool) = user32.ReleaseDC //sys ReleaseDC(wnd HWND, dc Handle) (ok bool) = user32.ReleaseDC

View file

@ -89,7 +89,6 @@ var (
procGetWindowTextW = moduser32.NewProc("GetWindowTextW") procGetWindowTextW = moduser32.NewProc("GetWindowTextW")
procIsDialogMessageW = moduser32.NewProc("IsDialogMessageW") procIsDialogMessageW = moduser32.NewProc("IsDialogMessageW")
procLoadIconW = moduser32.NewProc("LoadIconW") procLoadIconW = moduser32.NewProc("LoadIconW")
procLoadImageW = moduser32.NewProc("LoadImageW")
procPostQuitMessage = moduser32.NewProc("PostQuitMessage") procPostQuitMessage = moduser32.NewProc("PostQuitMessage")
procRegisterClassExW = moduser32.NewProc("RegisterClassExW") procRegisterClassExW = moduser32.NewProc("RegisterClassExW")
procReleaseDC = moduser32.NewProc("ReleaseDC") procReleaseDC = moduser32.NewProc("ReleaseDC")
@ -433,15 +432,6 @@ func LoadIcon(instance Handle, resource uintptr) (ret Handle, err error) {
return return
} }
func LoadImage(instance Handle, name *uint16, typ int, cx int, cy int, load int) (ret Handle, err error) {
r0, _, e1 := syscall.Syscall6(procLoadImageW.Addr(), 6, uintptr(instance), uintptr(unsafe.Pointer(name)), uintptr(typ), uintptr(cx), uintptr(cy), uintptr(load))
ret = Handle(r0)
if ret == 0 {
err = errnoErr(e1)
}
return
}
func PostQuitMessage(exitCode int) { func PostQuitMessage(exitCode int) {
syscall.Syscall(procPostQuitMessage.Addr(), 1, uintptr(exitCode), 0, 0) syscall.Syscall(procPostQuitMessage.Addr(), 1, uintptr(exitCode), 0, 0)
return return

View file

@ -3,6 +3,7 @@ package zenity
import ( import (
"bytes" "bytes"
"context" "context"
"io"
"os" "os"
"path/filepath" "path/filepath"
"runtime" "runtime"
@ -13,7 +14,6 @@ import (
"unsafe" "unsafe"
"github.com/ncruces/zenity/internal/win" "github.com/ncruces/zenity/internal/win"
"golang.org/x/sys/windows"
) )
const ( const (
@ -278,40 +278,48 @@ func getIcon(i any) (icon icon, err error) {
return icon, nil return icon, nil
} }
data, err := os.ReadFile(path) file, err := os.Open(path)
if err != nil {
return icon, err
}
defer file.Close()
var peek [8]byte
_, err = file.ReadAt(peek[:], 0)
if err != nil { if err != nil {
return icon, err return icon, err
} }
switch { if bytes.Equal(peek[:], []byte("\x89PNG\r\n\x1a\n")) {
case bytes.HasPrefix(data, []byte("\x00\x00\x01\x00")): data, err := io.ReadAll(file)
icon.handle, err = win.LoadImage(0, if err != nil {
strptr(path), return icon, err
win.IMAGE_ICON, 0, 0, }
win.LR_LOADFROMFILE|win.LR_DEFAULTSIZE)
icon.destroy = true
case bytes.HasPrefix(data, []byte("\x89PNG\r\n\x1a\n")):
icon.handle, err = win.CreateIconFromResourceEx( icon.handle, err = win.CreateIconFromResourceEx(
data, true, 0x00030000, 0, 0, data, true, 0x00030000, 0, 0,
win.LR_DEFAULTSIZE) win.LR_DEFAULTSIZE)
icon.destroy = true
case bytes.HasPrefix(data, []byte("MZ")):
var instance windows.Handle
instance, err = win.GetModuleHandle(nil)
if err != nil { if err != nil {
break return icon, err
}
} else {
instance, err := win.GetModuleHandle(nil)
if err != nil {
return icon, err
} }
path, err = filepath.Abs(path) path, err = filepath.Abs(path)
if err != nil { if err != nil {
break return icon, err
} }
var i uint16 var i uint16
icon.handle, err = win.ExtractAssociatedIcon( icon.handle, err = win.ExtractAssociatedIcon(
instance, strptr(path), &i) instance, strptr(path), &i)
icon.destroy = true if err != nil {
}
return icon, err return icon, err
} }
}
icon.destroy = true
return icon, nil
}
func (i *icon) delete() { func (i *icon) delete() {
if i.handle != 0 && i.destroy { if i.handle != 0 && i.destroy {