github.com/secoba/wails/v2@v2.6.4/internal/frontend/desktop/windows/winc/bitmap.go (about) 1 //go:build windows 2 3 /* 4 * Copyright (C) 2019 The Winc Authors. All Rights Reserved. 5 * Copyright (C) 2010-2013 Allen Dang. All Rights Reserved. 6 */ 7 8 package winc 9 10 import ( 11 "errors" 12 "unsafe" 13 14 "github.com/secoba/wails/v2/internal/frontend/desktop/windows/winc/w32" 15 ) 16 17 type Bitmap struct { 18 handle w32.HBITMAP 19 width, height int 20 } 21 22 func assembleBitmapFromHBITMAP(hbitmap w32.HBITMAP) (*Bitmap, error) { 23 var dib w32.DIBSECTION 24 if w32.GetObject(w32.HGDIOBJ(hbitmap), unsafe.Sizeof(dib), unsafe.Pointer(&dib)) == 0 { 25 return nil, errors.New("GetObject for HBITMAP failed") 26 } 27 28 return &Bitmap{ 29 handle: hbitmap, 30 width: int(dib.DsBmih.BiWidth), 31 height: int(dib.DsBmih.BiHeight), 32 }, nil 33 } 34 35 func NewBitmapFromFile(filepath string, background Color) (*Bitmap, error) { 36 var gpBitmap *uintptr 37 var err error 38 39 gpBitmap, err = w32.GdipCreateBitmapFromFile(filepath) 40 if err != nil { 41 return nil, err 42 } 43 defer w32.GdipDisposeImage(gpBitmap) 44 45 var hbitmap w32.HBITMAP 46 // Reverse RGB to BGR to satisfy gdiplus color schema. 47 hbitmap, err = w32.GdipCreateHBITMAPFromBitmap(gpBitmap, uint32(RGB(background.B(), background.G(), background.R()))) 48 if err != nil { 49 return nil, err 50 } 51 52 return assembleBitmapFromHBITMAP(hbitmap) 53 } 54 55 func NewBitmapFromResource(instance w32.HINSTANCE, resName *uint16, resType *uint16, background Color) (*Bitmap, error) { 56 var gpBitmap *uintptr 57 var err error 58 var hRes w32.HRSRC 59 60 hRes, err = w32.FindResource(w32.HMODULE(instance), resName, resType) 61 if err != nil { 62 return nil, err 63 } 64 resSize := w32.SizeofResource(w32.HMODULE(instance), hRes) 65 pResData := w32.LockResource(w32.LoadResource(w32.HMODULE(instance), hRes)) 66 resBuffer := w32.GlobalAlloc(w32.GMEM_MOVEABLE, resSize) 67 pResBuffer := w32.GlobalLock(resBuffer) 68 w32.MoveMemory(pResBuffer, pResData, resSize) 69 70 stream := w32.CreateStreamOnHGlobal(resBuffer, false) 71 72 gpBitmap, err = w32.GdipCreateBitmapFromStream(stream) 73 if err != nil { 74 return nil, err 75 } 76 defer stream.Release() 77 defer w32.GlobalUnlock(resBuffer) 78 defer w32.GlobalFree(resBuffer) 79 defer w32.GdipDisposeImage(gpBitmap) 80 81 var hbitmap w32.HBITMAP 82 // Reverse gform.RGB to BGR to satisfy gdiplus color schema. 83 hbitmap, err = w32.GdipCreateHBITMAPFromBitmap(gpBitmap, uint32(RGB(background.B(), background.G(), background.R()))) 84 if err != nil { 85 return nil, err 86 } 87 88 return assembleBitmapFromHBITMAP(hbitmap) 89 } 90 91 func (bm *Bitmap) Dispose() { 92 if bm.handle != 0 { 93 w32.DeleteObject(w32.HGDIOBJ(bm.handle)) 94 bm.handle = 0 95 } 96 } 97 98 func (bm *Bitmap) GetHBITMAP() w32.HBITMAP { 99 return bm.handle 100 } 101 102 func (bm *Bitmap) Size() (int, int) { 103 return bm.width, bm.height 104 } 105 106 func (bm *Bitmap) Height() int { 107 return bm.height 108 } 109 110 func (bm *Bitmap) Width() int { 111 return bm.width 112 }