Repository: tadvi/winc Branch: master Commit: 33fdab6e7e58 Files: 114 Total size: 394.0 KB Directory structure: gitextract_bzexg7vw/ ├── .gitignore ├── AUTHORS ├── LICENSE ├── README.md ├── app.go ├── bitmap.go ├── brush.go ├── buttons.go ├── canvas.go ├── color.go ├── combobox.go ├── commondlgs.go ├── controlbase.go ├── controller.go ├── dialog.go ├── edit.go ├── event.go ├── eventdata.go ├── eventmanager.go ├── examples/ │ ├── sample_contextmenu/ │ │ ├── app.manifest │ │ ├── main.go │ │ ├── release.bat │ │ └── rsrc.syso │ ├── sample_control/ │ │ ├── main.go │ │ └── topform.go │ ├── sample_docking/ │ │ ├── app.manifest │ │ ├── main.go │ │ ├── release.bat │ │ └── rsrc.syso │ ├── sample_hello/ │ │ └── main.go │ ├── sample_image/ │ │ ├── app.manifest │ │ ├── main.go │ │ ├── release.bat │ │ └── rsrc.syso │ ├── sample_imagebox/ │ │ ├── app.manifest │ │ ├── main.go │ │ ├── release.bat │ │ └── rsrc.syso │ ├── sample_listview/ │ │ ├── app.manifest │ │ ├── main.go │ │ ├── release.bat │ │ └── rsrc.syso │ ├── sample_minimal/ │ │ └── main.go │ ├── sample_scrollview/ │ │ ├── app.manifest │ │ ├── main.go │ │ ├── release.bat │ │ └── rsrc.syso │ ├── sample_slider/ │ │ ├── app.manifest │ │ ├── main.go │ │ ├── release.bat │ │ └── rsrc.syso │ ├── sample_splitview/ │ │ ├── app.manifest │ │ ├── layout.json │ │ ├── main.go │ │ ├── release.bat │ │ └── rsrc.syso │ ├── sample_tab/ │ │ ├── app.manifest │ │ ├── main.go │ │ ├── release.bat │ │ └── rsrc.syso │ └── sample_treeview/ │ ├── app.manifest │ ├── main.go │ ├── release.bat │ └── rsrc.syso ├── font.go ├── form.go ├── globalvars.go ├── go.mod ├── icon.go ├── imagelist.go ├── imageview.go ├── imageviewbox.go ├── init.go ├── keyboard.go ├── label.go ├── layout.go ├── listview.go ├── menu.go ├── mousecontrol.go ├── msghandlerregistry.go ├── panel.go ├── path.go ├── pen.go ├── progressbar.go ├── rect.go ├── resizer.go ├── scrollview.go ├── slider.go ├── tabview.go ├── toolbar.go ├── tooltip.go ├── treeview.go ├── utils.go ├── w32/ │ ├── comctl32.go │ ├── comdlg32.go │ ├── constants.go │ ├── gdi32.go │ ├── gdiplus.go │ ├── idispatch.go │ ├── istream.go │ ├── iunknown.go │ ├── kernel32.go │ ├── ole32.go │ ├── oleaut32.go │ ├── shcore.go │ ├── shell32.go │ ├── shlwapi.go │ ├── toolbar.go │ ├── typedef.go │ ├── user32.go │ ├── utils.go │ ├── uxtheme.go │ └── vars.go └── wndproc.go ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ # Binaries for programs and plugins *.exe *.exe~ *.dll *.so *.dylib # Test binary, build with `go test -c` *.test # Output of the go coverage tool, specifically when used with LiteIDE *.out ================================================ FILE: AUTHORS ================================================ # This is the official list of 'Winc' authors for copyright purposes. # Names should be added to this file as # Name or Organization # The email address is not required for organizations. # Please keep the list sorted. # Contributors # ============ Tad Vizbaras ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2019 winc Authors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # winc Common library for Go GUI apps on Windows. It is for Windows OS only. This makes library smaller than some other UI libraries for Go. Design goals: minimalism and simplicity. ## Dependencies No other dependencies except Go standard library. ## Building If you want to package icon files and other resources into binary **rsrc** tool is recommended: rsrc -manifest app.manifest -ico=app.ico,application_edit.ico,application_error.ico -o rsrc.syso Here app.manifest is XML file in format: ``` ``` Most Windows applications do not display command prompt. Build your Go project with flag to indicate that it is Windows GUI binary: go build -ldflags="-H windowsgui" ## Samples Best way to learn how to use the library is to look at the included **examples** projects. ## Setup 1. Make sure you have a working Go installation and build environment, see more for details on page below. http://golang.org/doc/install 2. go get github.com/tadvi/winc ## Icons When rsrc is used to pack icons into binary it displays IDs of the packed icons. ``` rsrc -manifest app.manifest -ico=app.ico,lightning.ico,edit.ico,application_error.ico -o rsrc.syso Manifest ID: 1 Icon app.ico ID: 10 Icon lightning.ico ID: 13 Icon edit.ico ID: 16 Icon application_error.ico ID: 19 ``` Use IDs to reference packed icons. ``` const myIcon = 13 btn.SetResIcon(myIcon) // Set icon on the button. ``` Included source **examples** use basic building via `release.bat` files. Note that icon IDs are order dependent. So if you change they order in -ico flag then icon IDs will be different. If you want to keep order the same, just add new icons to the end of -ico comma separated list. ## Layout Manager SimpleDock is default layout manager. Current design of docking and split views allows building simple apps but if you need to have multiple split views in few different directions you might need to create your own layout manager. Important point is to have **one** control inside SimpleDock set to dock as **Fill**. Controls that are not set to any docking get placed using SetPos() function. So you can have Panel set to dock at the Top and then have another dock to arrange controls inside that Panel or have controls placed using SetPos() at fixed positions. ![Example layout with two toolbars and status bar](dock_topbottom.png) This is basic layout. Instead of toolbars and status bar you can have Panel or any other control that can resize. Panel can have its own internal Dock that will arrange other controls inside of it. ![Example layout with two toolbars and navigation on the left](dock_topleft.png) This is layout with extra control(s) on the left. Left side is usually treeview or listview. The rule is simple: you either dock controls using SimpleDock OR use SetPos() to set them at fixed positions. That's it. At some point **winc** may get more sophisticated layout manager. ## Dialog Screens Dialog screens are not based on Windows resource files (.rc). They are just windows with controls placed at fixed coordinates. This works fine for dialog screens up to 10-14 controls. # Minimal Demo ``` package main import ( "github.com/tadvi/winc" ) func main() { mainWindow := winc.NewForm(nil) mainWindow.SetSize(400, 300) // (width, height) mainWindow.SetText("Hello World Demo") edt := winc.NewEdit(mainWindow) edt.SetPos(10, 20) // Most Controls have default size unless SetSize is called. edt.SetText("edit text") btn := winc.NewPushButton(mainWindow) btn.SetText("Show or Hide") btn.SetPos(40, 50) // (x, y) btn.SetSize(100, 40) // (width, height) btn.OnClick().Bind(func(e *winc.Event) { if edt.Visible() { edt.Hide() } else { edt.Show() } }) mainWindow.Center() mainWindow.Show() mainWindow.OnClose().Bind(wndOnClose) winc.RunMainLoop() // Must call to start event loop. } func wndOnClose(arg *winc.Event) { winc.Exit() } ``` ![Hello World](examples/hello.png) Result of running sample_minimal. ## Create Your Own It is good practice to create your own controls based on existing structures and event model. Library contains some of the controls built that way: IconButton (button.go), ErrorPanel (panel.go), MultiEdit (edit.go), etc. Please look at existing controls as examples before building your own. When designing your own controls keep in mind that types have to be converted from Go into Win32 API and back. This is usually due to string UTF8 and UTF16 conversions. But there are other types of conversions too. When developing your own controls you might also need to: import "github.com/tadvi/winc/w32" w32 has Win32 API low level constants and functions. Look at **sample_control** for example of custom built window. ## Companion Package [Go package for Windows Systray icon, menu and notifications](https://github.com/tadvi/systray) ## Credits This library is built on [AllenDang/gform Windows GUI framework for Go](https://github.com/AllenDang/gform) **winc** takes most design decisions from **gform** and adds many more controls and code samples to it. ================================================ FILE: app.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. * Copyright (C) 2010-2013 Allen Dang. All Rights Reserved. */ package winc import ( "runtime" "unsafe" "github.com/tadvi/winc/w32" ) var ( // resource compilation tool assigns app.ico ID of 3 // rsrc -manifest app.manifest -ico app.ico -o rsrc.syso AppIconID = 3 ) func init() { runtime.LockOSThread() gAppInstance = w32.GetModuleHandle("") if gAppInstance == 0 { panic("Error occurred in App.Init") } // Initialize the common controls var initCtrls w32.INITCOMMONCONTROLSEX initCtrls.DwSize = uint32(unsafe.Sizeof(initCtrls)) initCtrls.DwICC = w32.ICC_LISTVIEW_CLASSES | w32.ICC_PROGRESS_CLASS | w32.ICC_TAB_CLASSES | w32.ICC_TREEVIEW_CLASSES | w32.ICC_BAR_CLASSES w32.InitCommonControlsEx(&initCtrls) } // SetAppIconID sets recource icon ID for the apps windows. func SetAppIcon(appIconID int) { AppIconID = appIconID } func GetAppInstance() w32.HINSTANCE { return gAppInstance } func PreTranslateMessage(msg *w32.MSG) bool { // This functions is called by the MessageLoop. It processes the // keyboard accelerator keys and calls Controller.PreTranslateMessage for // keyboard and mouse events. processed := false if (msg.Message >= w32.WM_KEYFIRST && msg.Message <= w32.WM_KEYLAST) || (msg.Message >= w32.WM_MOUSEFIRST && msg.Message <= w32.WM_MOUSELAST) { if msg.Hwnd != 0 { if controller := GetMsgHandler(msg.Hwnd); controller != nil { // Search the chain of parents for pretranslated messages. for p := controller; p != nil; p = p.Parent() { if processed = p.PreTranslateMessage(msg); processed { break } } } } } return processed } // RunMainLoop processes messages in main application loop. func RunMainLoop() int { var m w32.MSG for w32.GetMessage(&m, 0, 0, 0) != 0 { if !PreTranslateMessage(&m) { w32.TranslateMessage(&m) w32.DispatchMessage(&m) } } w32.GdiplusShutdown() return int(m.WParam) } // PostMessages processes recent messages. Sometimes helpful for instant window refresh. func PostMessages() { var m w32.MSG for i := 0; i < 10; i++ { if w32.GetMessage(&m, 0, 0, 0) != 0 { if !PreTranslateMessage(&m) { w32.TranslateMessage(&m) w32.DispatchMessage(&m) } } } } func Exit() { w32.PostQuitMessage(0) } ================================================ FILE: bitmap.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. * Copyright (C) 2010-2013 Allen Dang. All Rights Reserved. */ package winc import ( "errors" "unsafe" "github.com/tadvi/winc/w32" ) type Bitmap struct { handle w32.HBITMAP width, height int } func assembleBitmapFromHBITMAP(hbitmap w32.HBITMAP) (*Bitmap, error) { var dib w32.DIBSECTION if w32.GetObject(w32.HGDIOBJ(hbitmap), unsafe.Sizeof(dib), unsafe.Pointer(&dib)) == 0 { return nil, errors.New("GetObject for HBITMAP failed") } return &Bitmap{ handle: hbitmap, width: int(dib.DsBmih.BiWidth), height: int(dib.DsBmih.BiHeight), }, nil } func NewBitmapFromFile(filepath string, background Color) (*Bitmap, error) { var gpBitmap *uintptr var err error gpBitmap, err = w32.GdipCreateBitmapFromFile(filepath) if err != nil { return nil, err } defer w32.GdipDisposeImage(gpBitmap) var hbitmap w32.HBITMAP // Reverse RGB to BGR to satisfy gdiplus color schema. hbitmap, err = w32.GdipCreateHBITMAPFromBitmap(gpBitmap, uint32(RGB(background.B(), background.G(), background.R()))) if err != nil { return nil, err } return assembleBitmapFromHBITMAP(hbitmap) } func NewBitmapFromResource(instance w32.HINSTANCE, resName *uint16, resType *uint16, background Color) (*Bitmap, error) { var gpBitmap *uintptr var err error var hRes w32.HRSRC hRes, err = w32.FindResource(w32.HMODULE(instance), resName, resType) if err != nil { return nil, err } resSize := w32.SizeofResource(w32.HMODULE(instance), hRes) pResData := w32.LockResource(w32.LoadResource(w32.HMODULE(instance), hRes)) resBuffer := w32.GlobalAlloc(w32.GMEM_MOVEABLE, resSize) pResBuffer := w32.GlobalLock(resBuffer) w32.MoveMemory(pResBuffer, pResData, resSize) stream := w32.CreateStreamOnHGlobal(resBuffer, false) gpBitmap, err = w32.GdipCreateBitmapFromStream(stream) if err != nil { return nil, err } defer stream.Release() defer w32.GlobalUnlock(resBuffer) defer w32.GlobalFree(resBuffer) defer w32.GdipDisposeImage(gpBitmap) var hbitmap w32.HBITMAP // Reverse gform.RGB to BGR to satisfy gdiplus color schema. hbitmap, err = w32.GdipCreateHBITMAPFromBitmap(gpBitmap, uint32(RGB(background.B(), background.G(), background.R()))) if err != nil { return nil, err } return assembleBitmapFromHBITMAP(hbitmap) } func (bm *Bitmap) Dispose() { if bm.handle != 0 { w32.DeleteObject(w32.HGDIOBJ(bm.handle)) bm.handle = 0 } } func (bm *Bitmap) GetHBITMAP() w32.HBITMAP { return bm.handle } func (bm *Bitmap) Size() (int, int) { return bm.width, bm.height } func (bm *Bitmap) Height() int { return bm.height } func (bm *Bitmap) Width() int { return bm.width } ================================================ FILE: brush.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. * Copyright (C) 2010-2013 Allen Dang. All Rights Reserved. */ package winc import ( "github.com/tadvi/winc/w32" ) var DefaultBackgroundBrush = NewSystemColorBrush(w32.COLOR_BTNFACE) type Brush struct { hBrush w32.HBRUSH logBrush w32.LOGBRUSH } func NewSolidColorBrush(color Color) *Brush { lb := w32.LOGBRUSH{LbStyle: w32.BS_SOLID, LbColor: w32.COLORREF(color)} hBrush := w32.CreateBrushIndirect(&lb) if hBrush == 0 { panic("Faild to create solid color brush") } return &Brush{hBrush, lb} } func NewSystemColorBrush(colorIndex int) *Brush { //lb := w32.LOGBRUSH{LbStyle: w32.BS_SOLID, LbColor: w32.COLORREF(colorIndex)} lb := w32.LOGBRUSH{LbStyle: w32.BS_NULL} hBrush := w32.GetSysColorBrush(colorIndex) if hBrush == 0 { panic("GetSysColorBrush failed") } return &Brush{hBrush, lb} } func NewHatchedColorBrush(color Color) *Brush { lb := w32.LOGBRUSH{LbStyle: w32.BS_HATCHED, LbColor: w32.COLORREF(color)} hBrush := w32.CreateBrushIndirect(&lb) if hBrush == 0 { panic("Faild to create solid color brush") } return &Brush{hBrush, lb} } func NewNullBrush() *Brush { lb := w32.LOGBRUSH{LbStyle: w32.BS_NULL} hBrush := w32.CreateBrushIndirect(&lb) if hBrush == 0 { panic("Failed to create null brush") } return &Brush{hBrush, lb} } func (br *Brush) GetHBRUSH() w32.HBRUSH { return br.hBrush } func (br *Brush) GetLOGBRUSH() *w32.LOGBRUSH { return &br.logBrush } func (br *Brush) Dispose() { if br.hBrush != 0 { w32.DeleteObject(w32.HGDIOBJ(br.hBrush)) br.hBrush = 0 } } ================================================ FILE: buttons.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. * Copyright (C) 2010-2013 Allen Dang. All Rights Reserved. */ package winc import ( "fmt" "github.com/tadvi/winc/w32" ) type Button struct { ControlBase onClick EventManager } func (bt *Button) OnClick() *EventManager { return &bt.onClick } func (bt *Button) WndProc(msg uint32, wparam, lparam uintptr) uintptr { switch msg { case w32.WM_COMMAND: bt.onClick.Fire(NewEvent(bt, nil)) /*case w32.WM_LBUTTONDOWN: w32.SetCapture(bt.Handle()) case w32.WM_LBUTTONUP: w32.ReleaseCapture()*/ /*case win.WM_GETDLGCODE: println("GETDLGCODE")*/ } return w32.DefWindowProc(bt.hwnd, msg, wparam, lparam) //return bt.W32Control.WndProc(msg, wparam, lparam) } func (bt *Button) Checked() bool { result := w32.SendMessage(bt.hwnd, w32.BM_GETCHECK, 0, 0) return result == w32.BST_CHECKED } func (bt *Button) SetChecked(checked bool) { wparam := w32.BST_CHECKED if !checked { wparam = w32.BST_UNCHECKED } w32.SendMessage(bt.hwnd, w32.BM_SETCHECK, uintptr(wparam), 0) } // SetIcon sets icon on the button. Recommended icons are 32x32 with 32bit color depth. func (bt *Button) SetIcon(ico *Icon) { w32.SendMessage(bt.hwnd, w32.BM_SETIMAGE, w32.IMAGE_ICON, uintptr(ico.handle)) } func (bt *Button) SetResIcon(iconID uint16) { if ico, err := NewIconFromResource(GetAppInstance(), iconID); err == nil { bt.SetIcon(ico) return } panic(fmt.Sprintf("missing icon with icon ID: %d", iconID)) } type PushButton struct { Button } func NewPushButton(parent Controller) *PushButton { pb := new(PushButton) pb.InitControl("BUTTON", parent, 0, w32.BS_PUSHBUTTON|w32.WS_TABSTOP|w32.WS_VISIBLE|w32.WS_CHILD) RegMsgHandler(pb) pb.SetFont(DefaultFont) pb.SetText("Button") pb.SetSize(100, 22) return pb } // SetDefault is used for dialogs to set default button. func (pb *PushButton) SetDefault() { pb.SetAndClearStyleBits(w32.BS_DEFPUSHBUTTON, w32.BS_PUSHBUTTON) } // IconButton does not display text, requires SetResIcon call. type IconButton struct { Button } func NewIconButton(parent Controller) *IconButton { pb := new(IconButton) pb.InitControl("BUTTON", parent, 0, w32.BS_ICON|w32.WS_TABSTOP|w32.WS_VISIBLE|w32.WS_CHILD) RegMsgHandler(pb) pb.SetFont(DefaultFont) // even if text would be set it would not be displayed pb.SetText("") pb.SetSize(100, 22) return pb } type CheckBox struct { Button } func NewCheckBox(parent Controller) *CheckBox { cb := new(CheckBox) cb.InitControl("BUTTON", parent, 0, w32.WS_TABSTOP|w32.WS_VISIBLE|w32.WS_CHILD|w32.BS_AUTOCHECKBOX) RegMsgHandler(cb) cb.SetFont(DefaultFont) cb.SetText("CheckBox") cb.SetSize(100, 22) return cb } type RadioButton struct { Button } func NewRadioButton(parent Controller) *RadioButton { rb := new(RadioButton) rb.InitControl("BUTTON", parent, 0, w32.WS_TABSTOP|w32.WS_VISIBLE|w32.WS_CHILD|w32.BS_AUTORADIOBUTTON) RegMsgHandler(rb) rb.SetFont(DefaultFont) rb.SetText("RadioButton") rb.SetSize(100, 22) return rb } type GroupBox struct { Button } func NewGroupBox(parent Controller) *GroupBox { gb := new(GroupBox) gb.InitControl("BUTTON", parent, 0, w32.WS_CHILD|w32.WS_VISIBLE|w32.WS_GROUP|w32.BS_GROUPBOX) RegMsgHandler(gb) gb.SetFont(DefaultFont) gb.SetText("GroupBox") gb.SetSize(100, 100) return gb } ================================================ FILE: canvas.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. * Copyright (C) 2010-2013 Allen Dang. All Rights Reserved. */ package winc import ( "fmt" "github.com/tadvi/winc/w32" ) type Canvas struct { hwnd w32.HWND hdc w32.HDC doNotDispose bool } var nullBrush = NewNullBrush() func NewCanvasFromHwnd(hwnd w32.HWND) *Canvas { hdc := w32.GetDC(hwnd) if hdc == 0 { panic(fmt.Sprintf("Create canvas from %v failed.", hwnd)) } return &Canvas{hwnd: hwnd, hdc: hdc, doNotDispose: false} } func NewCanvasFromHDC(hdc w32.HDC) *Canvas { if hdc == 0 { panic("Cannot create canvas from invalid HDC.") } return &Canvas{hdc: hdc, doNotDispose: true} } func (ca *Canvas) Dispose() { if !ca.doNotDispose && ca.hdc != 0 { if ca.hwnd == 0 { w32.DeleteDC(ca.hdc) } else { w32.ReleaseDC(ca.hwnd, ca.hdc) } ca.hdc = 0 } } func (ca *Canvas) DrawBitmap(bmp *Bitmap, x, y int) { cdc := w32.CreateCompatibleDC(0) defer w32.DeleteDC(cdc) hbmpOld := w32.SelectObject(cdc, w32.HGDIOBJ(bmp.GetHBITMAP())) defer w32.SelectObject(cdc, w32.HGDIOBJ(hbmpOld)) w, h := bmp.Size() w32.BitBlt(ca.hdc, x, y, w, h, cdc, 0, 0, w32.SRCCOPY) } func (ca *Canvas) DrawStretchedBitmap(bmp *Bitmap, rect *Rect) { cdc := w32.CreateCompatibleDC(0) defer w32.DeleteDC(cdc) hbmpOld := w32.SelectObject(cdc, w32.HGDIOBJ(bmp.GetHBITMAP())) defer w32.SelectObject(cdc, w32.HGDIOBJ(hbmpOld)) w, h := bmp.Size() rc := rect.GetW32Rect() w32.StretchBlt(ca.hdc, int(rc.Left), int(rc.Top), int(rc.Right), int(rc.Bottom), cdc, 0, 0, w, h, w32.SRCCOPY) } func (ca *Canvas) DrawIcon(ico *Icon, x, y int) bool { return w32.DrawIcon(ca.hdc, x, y, ico.Handle()) } // DrawFillRect draw and fill rectangle with color. func (ca *Canvas) DrawFillRect(rect *Rect, pen *Pen, brush *Brush) { w32Rect := rect.GetW32Rect() previousPen := w32.SelectObject(ca.hdc, w32.HGDIOBJ(pen.GetHPEN())) defer w32.SelectObject(ca.hdc, previousPen) previousBrush := w32.SelectObject(ca.hdc, w32.HGDIOBJ(brush.GetHBRUSH())) defer w32.SelectObject(ca.hdc, previousBrush) w32.Rectangle(ca.hdc, w32Rect.Left, w32Rect.Top, w32Rect.Right, w32Rect.Bottom) } func (ca *Canvas) DrawRect(rect *Rect, pen *Pen) { w32Rect := rect.GetW32Rect() previousPen := w32.SelectObject(ca.hdc, w32.HGDIOBJ(pen.GetHPEN())) defer w32.SelectObject(ca.hdc, previousPen) // nullBrush is used to make interior of the rect transparent previousBrush := w32.SelectObject(ca.hdc, w32.HGDIOBJ(nullBrush.GetHBRUSH())) defer w32.SelectObject(ca.hdc, previousBrush) w32.Rectangle(ca.hdc, w32Rect.Left, w32Rect.Top, w32Rect.Right, w32Rect.Bottom) } func (ca *Canvas) FillRect(rect *Rect, brush *Brush) { w32.FillRect(ca.hdc, rect.GetW32Rect(), brush.GetHBRUSH()) } func (ca *Canvas) DrawEllipse(rect *Rect, pen *Pen) { w32Rect := rect.GetW32Rect() previousPen := w32.SelectObject(ca.hdc, w32.HGDIOBJ(pen.GetHPEN())) defer w32.SelectObject(ca.hdc, previousPen) // nullBrush is used to make interior of the rect transparent previousBrush := w32.SelectObject(ca.hdc, w32.HGDIOBJ(nullBrush.GetHBRUSH())) defer w32.SelectObject(ca.hdc, previousBrush) w32.Ellipse(ca.hdc, w32Rect.Left, w32Rect.Top, w32Rect.Right, w32Rect.Bottom) } // DrawFillEllipse draw and fill ellipse with color. func (ca *Canvas) DrawFillEllipse(rect *Rect, pen *Pen, brush *Brush) { w32Rect := rect.GetW32Rect() previousPen := w32.SelectObject(ca.hdc, w32.HGDIOBJ(pen.GetHPEN())) defer w32.SelectObject(ca.hdc, previousPen) previousBrush := w32.SelectObject(ca.hdc, w32.HGDIOBJ(brush.GetHBRUSH())) defer w32.SelectObject(ca.hdc, previousBrush) w32.Ellipse(ca.hdc, w32Rect.Left, w32Rect.Top, w32Rect.Right, w32Rect.Bottom) } func (ca *Canvas) DrawLine(x, y, x2, y2 int, pen *Pen) { w32.MoveToEx(ca.hdc, x, y, nil) previousPen := w32.SelectObject(ca.hdc, w32.HGDIOBJ(pen.GetHPEN())) defer w32.SelectObject(ca.hdc, previousPen) w32.LineTo(ca.hdc, int32(x2), int32(y2)) } // Refer win32 DrawText document for uFormat. func (ca *Canvas) DrawText(text string, rect *Rect, format uint, font *Font, textColor Color) { previousFont := w32.SelectObject(ca.hdc, w32.HGDIOBJ(font.GetHFONT())) defer w32.SelectObject(ca.hdc, w32.HGDIOBJ(previousFont)) previousBkMode := w32.SetBkMode(ca.hdc, w32.TRANSPARENT) defer w32.SetBkMode(ca.hdc, previousBkMode) previousTextColor := w32.SetTextColor(ca.hdc, w32.COLORREF(textColor)) defer w32.SetTextColor(ca.hdc, previousTextColor) w32.DrawText(ca.hdc, text, len(text), rect.GetW32Rect(), format) } ================================================ FILE: color.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. * Copyright (C) 2010-2013 Allen Dang. All Rights Reserved. */ package winc type Color uint32 func RGB(r, g, b byte) Color { return Color(uint32(r) | uint32(g)<<8 | uint32(b)<<16) } func (c Color) R() byte { return byte(c & 0xff) } func (c Color) G() byte { return byte((c >> 8) & 0xff) } func (c Color) B() byte { return byte((c >> 16) & 0xff) } ================================================ FILE: combobox.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. */ package winc import ( "syscall" "unsafe" "github.com/tadvi/winc/w32" ) type ComboBox struct { ControlBase onSelectedChange EventManager } func NewComboBox(parent Controller) *ComboBox { cb := new(ComboBox) cb.InitControl("COMBOBOX", parent, 0, w32.WS_CHILD|w32.WS_VISIBLE|w32.WS_TABSTOP|w32.WS_VSCROLL|w32.CBS_DROPDOWNLIST) RegMsgHandler(cb) cb.SetFont(DefaultFont) cb.SetSize(200, 400) return cb } func (cb *ComboBox) DeleteAllItems() bool { return w32.SendMessage(cb.hwnd, w32.CB_RESETCONTENT, 0, 0) == w32.TRUE } func (cb *ComboBox) InsertItem(index int, str string) bool { lp := uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(str))) return w32.SendMessage(cb.hwnd, w32.CB_INSERTSTRING, uintptr(index), lp) != w32.CB_ERR } func (cb *ComboBox) DeleteItem(index int) bool { return w32.SendMessage(cb.hwnd, w32.CB_DELETESTRING, uintptr(index), 0) != w32.CB_ERR } func (cb *ComboBox) SelectedItem() int { return int(int32(w32.SendMessage(cb.hwnd, w32.CB_GETCURSEL, 0, 0))) } func (cb *ComboBox) SetSelectedItem(value int) bool { return int(int32(w32.SendMessage(cb.hwnd, w32.CB_SETCURSEL, uintptr(value), 0))) == value } func (cb *ComboBox) OnSelectedChange() *EventManager { return &cb.onSelectedChange } // Message processer func (cb *ComboBox) WndProc(msg uint32, wparam, lparam uintptr) uintptr { switch msg { case w32.WM_COMMAND: code := w32.HIWORD(uint32(wparam)) switch code { case w32.CBN_SELCHANGE: cb.onSelectedChange.Fire(NewEvent(cb, nil)) } } return w32.DefWindowProc(cb.hwnd, msg, wparam, lparam) //return cb.W32Control.WndProc(msg, wparam, lparam) } ================================================ FILE: commondlgs.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. * Copyright (C) 2010-2013 Allen Dang. All Rights Reserved. */ package winc import ( "fmt" "syscall" "unsafe" "github.com/tadvi/winc/w32" ) func genOFN(parent Controller, title, filter string, filterIndex uint, initialDir string, buf []uint16) *w32.OPENFILENAME { var ofn w32.OPENFILENAME ofn.StructSize = uint32(unsafe.Sizeof(ofn)) ofn.Owner = parent.Handle() if filter != "" { filterBuf := make([]uint16, len(filter)+1) copy(filterBuf, syscall.StringToUTF16(filter)) // Replace '|' with the expected '\0' for i, c := range filterBuf { if byte(c) == '|' { filterBuf[i] = uint16(0) } } ofn.Filter = &filterBuf[0] ofn.FilterIndex = uint32(filterIndex) } ofn.File = &buf[0] ofn.MaxFile = uint32(len(buf)) if initialDir != "" { ofn.InitialDir = syscall.StringToUTF16Ptr(initialDir) } if title != "" { ofn.Title = syscall.StringToUTF16Ptr(title) } ofn.Flags = w32.OFN_FILEMUSTEXIST return &ofn } func ShowOpenFileDlg(parent Controller, title, filter string, filterIndex uint, initialDir string) (filePath string, accepted bool) { buf := make([]uint16, 1024) ofn := genOFN(parent, title, filter, filterIndex, initialDir, buf) if accepted = w32.GetOpenFileName(ofn); accepted { filePath = syscall.UTF16ToString(buf) } return } func ShowSaveFileDlg(parent Controller, title, filter string, filterIndex uint, initialDir string) (filePath string, accepted bool) { buf := make([]uint16, 1024) ofn := genOFN(parent, title, filter, filterIndex, initialDir, buf) if accepted = w32.GetSaveFileName(ofn); accepted { filePath = syscall.UTF16ToString(buf) } return } func ShowBrowseFolderDlg(parent Controller, title string) (folder string, accepted bool) { var bi w32.BROWSEINFO bi.Owner = parent.Handle() bi.Title = syscall.StringToUTF16Ptr(title) bi.Flags = w32.BIF_RETURNONLYFSDIRS | w32.BIF_NEWDIALOGSTYLE w32.CoInitialize() ret := w32.SHBrowseForFolder(&bi) w32.CoUninitialize() folder = w32.SHGetPathFromIDList(ret) accepted = folder != "" return } // MsgBoxOkCancel basic pop up message. Returns 1 for OK and 2 for CANCEL. func MsgBoxOkCancel(parent Controller, title, caption string) int { return MsgBox(parent, title, caption, w32.MB_ICONEXCLAMATION|w32.MB_OKCANCEL) } func MsgBoxYesNo(parent Controller, title, caption string) int { return MsgBox(parent, title, caption, w32.MB_ICONEXCLAMATION|w32.MB_YESNO) } func MsgBoxOk(parent Controller, title, caption string) { MsgBox(parent, title, caption, w32.MB_ICONINFORMATION|w32.MB_OK) } // Warningf is generic warning message with OK and Cancel buttons. Returns 1 for OK. func Warningf(parent Controller, format string, data ...interface{}) int { caption := fmt.Sprintf(format, data...) return MsgBox(parent, "Warning", caption, w32.MB_ICONWARNING|w32.MB_OKCANCEL) } // Printf is generic info message with OK button. func Printf(parent Controller, format string, data ...interface{}) { caption := fmt.Sprintf(format, data...) MsgBox(parent, "Information", caption, w32.MB_ICONINFORMATION|w32.MB_OK) } // Errorf is generic error message with OK button. func Errorf(parent Controller, format string, data ...interface{}) { caption := fmt.Sprintf(format, data...) MsgBox(parent, "Error", caption, w32.MB_ICONERROR|w32.MB_OK) } func MsgBox(parent Controller, title, caption string, flags uint) int { var result int if parent != nil { result = w32.MessageBox(parent.Handle(), caption, title, flags) } else { result = w32.MessageBox(0, caption, title, flags) } return result } ================================================ FILE: controlbase.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. * Copyright (C) 2010-2013 Allen Dang. All Rights Reserved. */ package winc import ( "fmt" "syscall" "unsafe" "github.com/tadvi/winc/w32" ) type ControlBase struct { hwnd w32.HWND font *Font parent Controller contextMenu *MenuItem isForm bool minWidth, minHeight int maxWidth, maxHeight int // General events onCreate EventManager onClose EventManager // Focus events onKillFocus EventManager onSetFocus EventManager // Drag and drop events onDropFiles EventManager // Mouse events onLBDown EventManager onLBUp EventManager onLBDbl EventManager onMBDown EventManager onMBUp EventManager onRBDown EventManager onRBUp EventManager onRBDbl EventManager onMouseMove EventManager // use MouseControl to capture onMouseHover and onMouseLeave events. onMouseHover EventManager onMouseLeave EventManager // Keyboard events onKeyUp EventManager // Paint events onPaint EventManager onSize EventManager } // initControl is called by controls: edit, button, treeview, listview, and so on. func (cba *ControlBase) InitControl(className string, parent Controller, exstyle, style uint) { cba.hwnd = CreateWindow(className, parent, exstyle, style) if cba.hwnd == 0 { panic("cannot create window for " + className) } cba.parent = parent } // InitWindow is called by custom window based controls such as split, panel, etc. func (cba *ControlBase) InitWindow(className string, parent Controller, exstyle, style uint) { RegClassOnlyOnce(className) cba.hwnd = CreateWindow(className, parent, exstyle, style) if cba.hwnd == 0 { panic("cannot create window for " + className) } cba.parent = parent } // SetTheme for TreeView and ListView controls. func (cba *ControlBase) SetTheme(appName string) error { if hr := w32.SetWindowTheme(cba.hwnd, syscall.StringToUTF16Ptr(appName), nil); w32.FAILED(hr) { return fmt.Errorf("SetWindowTheme %d", hr) } return nil } func (cba *ControlBase) Handle() w32.HWND { return cba.hwnd } func (cba *ControlBase) SetHandle(hwnd w32.HWND) { cba.hwnd = hwnd } func (cba *ControlBase) GetWindowDPI() (w32.UINT, w32.UINT) { monitor := w32.MonitorFromWindow(cba.hwnd, w32.MONITOR_DEFAULTTOPRIMARY) var dpiX, dpiY w32.UINT w32.GetDPIForMonitor(monitor, w32.MDT_EFFECTIVE_DPI, &dpiX, &dpiY) return dpiX, dpiY } func (cba *ControlBase) SetAndClearStyleBits(set, clear uint32) error { style := uint32(w32.GetWindowLong(cba.hwnd, w32.GWL_STYLE)) if style == 0 { return fmt.Errorf("GetWindowLong") } if newStyle := style&^clear | set; newStyle != style { if w32.SetWindowLong(cba.hwnd, w32.GWL_STYLE, newStyle) == 0 { return fmt.Errorf("SetWindowLong") } } return nil } func (cba *ControlBase) SetIsForm(isform bool) { cba.isForm = isform } func (cba *ControlBase) SetText(caption string) { w32.SetWindowText(cba.hwnd, caption) } func (cba *ControlBase) Text() string { return w32.GetWindowText(cba.hwnd) } func (cba *ControlBase) Close() { UnRegMsgHandler(cba.hwnd) w32.DestroyWindow(cba.hwnd) } func (cba *ControlBase) SetTranslucentBackground() { var accent = w32.ACCENT_POLICY{ AccentState: w32.ACCENT_ENABLE_BLURBEHIND, } var data w32.WINDOWCOMPOSITIONATTRIBDATA data.Attrib = w32.WCA_ACCENT_POLICY data.PvData = unsafe.Pointer(&accent) data.CbData = unsafe.Sizeof(accent) w32.SetWindowCompositionAttribute(cba.hwnd, &data) } func min(a, b int) int { if a < b { return a } return b } func max(a, b int) int { if a > b { return a } return b } func (cba *ControlBase) clampSize(width, height int) (int, int) { if cba.minWidth != 0 { width = max(width, cba.minWidth) } if cba.maxWidth != 0 { width = min(width, cba.maxWidth) } if cba.minHeight != 0 { height = max(height, cba.minHeight) } if cba.maxHeight != 0 { height = min(height, cba.maxHeight) } return width, height } func (cba *ControlBase) SetSize(width, height int) { x, y := cba.Pos() width, height = cba.clampSize(width, height) w32.MoveWindow(cba.hwnd, x, y, width, height, true) } func (cba *ControlBase) SetMinSize(width, height int) { cba.minWidth = width cba.minHeight = height // Ensure we set max if min > max if cba.maxWidth > 0 { cba.maxWidth = max(cba.minWidth, cba.maxWidth) } if cba.maxHeight > 0 { cba.maxHeight = max(cba.minHeight, cba.maxHeight) } x, y := cba.Pos() currentWidth, currentHeight := cba.Size() clampedWidth, clampedHeight := cba.clampSize(currentWidth, currentHeight) if clampedWidth != currentWidth || clampedHeight != currentHeight { w32.MoveWindow(cba.hwnd, x, y, clampedWidth, clampedHeight, true) } } func (cba *ControlBase) SetMaxSize(width, height int) { cba.maxWidth = width cba.maxHeight = height // Ensure we set min if max > min if cba.minWidth > 0 { cba.minWidth = min(cba.maxWidth, cba.minWidth) } if cba.maxHeight > 0 { cba.minHeight = min(cba.maxHeight, cba.minHeight) } x, y := cba.Pos() currentWidth, currentHeight := cba.Size() clampedWidth, clampedHeight := cba.clampSize(currentWidth, currentHeight) if clampedWidth != currentWidth || clampedHeight != currentHeight { w32.MoveWindow(cba.hwnd, x, y, clampedWidth, clampedHeight, true) } } func (cba *ControlBase) Size() (width, height int) { rect := w32.GetWindowRect(cba.hwnd) width = int(rect.Right - rect.Left) height = int(rect.Bottom - rect.Top) return } func (cba *ControlBase) Width() int { rect := w32.GetWindowRect(cba.hwnd) return int(rect.Right - rect.Left) } func (cba *ControlBase) Height() int { rect := w32.GetWindowRect(cba.hwnd) return int(rect.Bottom - rect.Top) } func (cba *ControlBase) SetPos(x, y int) { info := getMonitorInfo(cba.hwnd) workRect := info.RcWork w32.SetWindowPos(cba.hwnd, w32.HWND_TOP, int(workRect.Left)+x, int(workRect.Top)+y, 0, 0, w32.SWP_NOSIZE) } func (cba *ControlBase) Pos() (x, y int) { rect := w32.GetWindowRect(cba.hwnd) x = int(rect.Left) y = int(rect.Top) if !cba.isForm && cba.parent != nil { x, y, _ = w32.ScreenToClient(cba.parent.Handle(), x, y) } return } func (cba *ControlBase) Visible() bool { return w32.IsWindowVisible(cba.hwnd) } func (cba *ControlBase) ToggleVisible() bool { visible := w32.IsWindowVisible(cba.hwnd) if visible { cba.Hide() } else { cba.Show() } return !visible } func (cba *ControlBase) ContextMenu() *MenuItem { return cba.contextMenu } func (cba *ControlBase) SetContextMenu(menu *MenuItem) { cba.contextMenu = menu } func (cba *ControlBase) Bounds() *Rect { rect := w32.GetWindowRect(cba.hwnd) if cba.isForm { return &Rect{*rect} } return ScreenToClientRect(cba.hwnd, rect) } func (cba *ControlBase) ClientRect() *Rect { rect := w32.GetClientRect(cba.hwnd) return ScreenToClientRect(cba.hwnd, rect) } func (cba *ControlBase) ClientWidth() int { rect := w32.GetClientRect(cba.hwnd) return int(rect.Right - rect.Left) } func (cba *ControlBase) ClientHeight() int { rect := w32.GetClientRect(cba.hwnd) return int(rect.Bottom - rect.Top) } func (cba *ControlBase) Show() { w32.ShowWindow(cba.hwnd, w32.SW_SHOWDEFAULT) } func (cba *ControlBase) Hide() { w32.ShowWindow(cba.hwnd, w32.SW_HIDE) } func (cba *ControlBase) Enabled() bool { return w32.IsWindowEnabled(cba.hwnd) } func (cba *ControlBase) SetEnabled(b bool) { w32.EnableWindow(cba.hwnd, b) } func (cba *ControlBase) SetFocus() { w32.SetFocus(cba.hwnd) } func (cba *ControlBase) Invalidate(erase bool) { // pRect := w32.GetClientRect(cba.hwnd) // if cba.isForm { // w32.InvalidateRect(cba.hwnd, pRect, erase) // } else { // rc := ScreenToClientRect(cba.hwnd, pRect) // w32.InvalidateRect(cba.hwnd, rc.GetW32Rect(), erase) // } w32.InvalidateRect(cba.hwnd, nil, erase) } func (cba *ControlBase) Parent() Controller { return cba.parent } func (cba *ControlBase) SetParent(parent Controller) { cba.parent = parent } func (cba *ControlBase) Font() *Font { return cba.font } func (cba *ControlBase) SetFont(font *Font) { w32.SendMessage(cba.hwnd, w32.WM_SETFONT, uintptr(font.hfont), 1) cba.font = font } func (cba *ControlBase) EnableDragAcceptFiles(b bool) { w32.DragAcceptFiles(cba.hwnd, b) } func (cba *ControlBase) InvokeRequired() bool { if cba.hwnd == 0 { return false } windowThreadId, _ := w32.GetWindowThreadProcessId(cba.hwnd) currentThreadId := w32.GetCurrentThread() return windowThreadId != currentThreadId } func (cba *ControlBase) PreTranslateMessage(msg *w32.MSG) bool { if msg.Message == w32.WM_GETDLGCODE { println("pretranslate, WM_GETDLGCODE") } return false } //Events func (cba *ControlBase) OnCreate() *EventManager { return &cba.onCreate } func (cba *ControlBase) OnClose() *EventManager { return &cba.onClose } func (cba *ControlBase) OnKillFocus() *EventManager { return &cba.onKillFocus } func (cba *ControlBase) OnSetFocus() *EventManager { return &cba.onSetFocus } func (cba *ControlBase) OnDropFiles() *EventManager { return &cba.onDropFiles } func (cba *ControlBase) OnLBDown() *EventManager { return &cba.onLBDown } func (cba *ControlBase) OnLBUp() *EventManager { return &cba.onLBUp } func (cba *ControlBase) OnLBDbl() *EventManager { return &cba.onLBDbl } func (cba *ControlBase) OnMBDown() *EventManager { return &cba.onMBDown } func (cba *ControlBase) OnMBUp() *EventManager { return &cba.onMBUp } func (cba *ControlBase) OnRBDown() *EventManager { return &cba.onRBDown } func (cba *ControlBase) OnRBUp() *EventManager { return &cba.onRBUp } func (cba *ControlBase) OnRBDbl() *EventManager { return &cba.onRBDbl } func (cba *ControlBase) OnMouseMove() *EventManager { return &cba.onMouseMove } func (cba *ControlBase) OnMouseHover() *EventManager { return &cba.onMouseHover } func (cba *ControlBase) OnMouseLeave() *EventManager { return &cba.onMouseLeave } func (cba *ControlBase) OnPaint() *EventManager { return &cba.onPaint } func (cba *ControlBase) OnSize() *EventManager { return &cba.onSize } func (cba *ControlBase) OnKeyUp() *EventManager { return &cba.onKeyUp } ================================================ FILE: controller.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. * Copyright (C) 2010-2013 Allen Dang. All Rights Reserved. */ package winc import ( "github.com/tadvi/winc/w32" ) type Controller interface { Text() string Enabled() bool SetFocus() Handle() w32.HWND Invalidate(erase bool) Parent() Controller Pos() (x, y int) Size() (w, h int) Height() int Width() int Visible() bool Bounds() *Rect ClientRect() *Rect SetText(s string) SetEnabled(b bool) SetPos(x, y int) SetSize(w, h int) EnableDragAcceptFiles(b bool) Show() Hide() ContextMenu() *MenuItem SetContextMenu(menu *MenuItem) Font() *Font SetFont(font *Font) InvokeRequired() bool PreTranslateMessage(msg *w32.MSG) bool WndProc(msg uint32, wparam, lparam uintptr) uintptr //General events OnCreate() *EventManager OnClose() *EventManager // Focus events OnKillFocus() *EventManager OnSetFocus() *EventManager //Drag and drop events OnDropFiles() *EventManager //Mouse events OnLBDown() *EventManager OnLBUp() *EventManager OnLBDbl() *EventManager OnMBDown() *EventManager OnMBUp() *EventManager OnRBDown() *EventManager OnRBUp() *EventManager OnRBDbl() *EventManager OnMouseMove() *EventManager // OnMouseLeave and OnMouseHover does not fire unless control called internalTrackMouseEvent. // Use MouseControl for a how to example. OnMouseHover() *EventManager OnMouseLeave() *EventManager //Keyboard events OnKeyUp() *EventManager //Paint events OnPaint() *EventManager OnSize() *EventManager } ================================================ FILE: dialog.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. * Copyright (C) 2010-2013 Allen Dang. All Rights Reserved. */ package winc import "github.com/tadvi/winc/w32" // Dialog displayed as z-order top window until closed. // It also disables parent window so it can not be clicked. type Dialog struct { Form isModal bool btnOk *PushButton btnCancel *PushButton onLoad EventManager onOk EventManager onCancel EventManager } func NewDialog(parent Controller) *Dialog { dlg := new(Dialog) dlg.isForm = true dlg.isModal = true RegClassOnlyOnce("winc_Dialog") dlg.hwnd = CreateWindow("winc_Dialog", parent, w32.WS_EX_CONTROLPARENT, /* IMPORTANT */ w32.WS_SYSMENU|w32.WS_CAPTION|w32.WS_THICKFRAME /*|w32.WS_BORDER|w32.WS_POPUP*/) dlg.parent = parent // dlg might fail if icon resource is not embedded in the binary if ico, err := NewIconFromResource(GetAppInstance(), uint16(AppIconID)); err == nil { dlg.SetIcon(0, ico) } // Dlg forces display of focus rectangles, as soon as the user starts to type. w32.SendMessage(dlg.hwnd, w32.WM_CHANGEUISTATE, w32.UIS_INITIALIZE, 0) RegMsgHandler(dlg) dlg.SetFont(DefaultFont) dlg.SetText("Form") dlg.SetSize(200, 100) return dlg } func (dlg *Dialog) SetModal(modal bool) { dlg.isModal = modal } // SetButtons wires up dialog events to buttons. btnCancel can be nil. func (dlg *Dialog) SetButtons(btnOk *PushButton, btnCancel *PushButton) { dlg.btnOk = btnOk dlg.btnOk.SetDefault() dlg.btnCancel = btnCancel } // Events func (dlg *Dialog) OnLoad() *EventManager { return &dlg.onLoad } func (dlg *Dialog) OnOk() *EventManager { return &dlg.onOk } func (dlg *Dialog) OnCancel() *EventManager { return &dlg.onCancel } // PreTranslateMessage handles dialog specific messages. IMPORTANT. func (dlg *Dialog) PreTranslateMessage(msg *w32.MSG) bool { if msg.Message >= w32.WM_KEYFIRST && msg.Message <= w32.WM_KEYLAST { if w32.IsDialogMessage(dlg.hwnd, msg) { return true } } return false } // Show dialog performs special setup for dialog windows. func (dlg *Dialog) Show() { if dlg.isModal { dlg.Parent().SetEnabled(false) } dlg.onLoad.Fire(NewEvent(dlg, nil)) dlg.Form.Show() } // Close dialog when you done with it. func (dlg *Dialog) Close() { if dlg.isModal { dlg.Parent().SetEnabled(true) } dlg.ControlBase.Close() } func (dlg *Dialog) cancel() { if dlg.btnCancel != nil { dlg.btnCancel.onClick.Fire(NewEvent(dlg.btnCancel, nil)) } dlg.onCancel.Fire(NewEvent(dlg, nil)) } func (dlg *Dialog) WndProc(msg uint32, wparam, lparam uintptr) uintptr { switch msg { case w32.WM_COMMAND: switch w32.LOWORD(uint32(wparam)) { case w32.IDOK: if dlg.btnOk != nil { dlg.btnOk.onClick.Fire(NewEvent(dlg.btnOk, nil)) } dlg.onOk.Fire(NewEvent(dlg, nil)) return w32.TRUE case w32.IDCANCEL: dlg.cancel() return w32.TRUE } case w32.WM_CLOSE: dlg.cancel() // use onCancel or dlg.btnCancel.OnClick to close return 0 case w32.WM_DESTROY: if dlg.isModal { dlg.Parent().SetEnabled(true) } } return w32.DefWindowProc(dlg.hwnd, msg, wparam, lparam) } ================================================ FILE: edit.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. * Copyright (C) 2010-2013 Allen Dang. All Rights Reserved. */ package winc import "github.com/tadvi/winc/w32" type Edit struct { ControlBase onChange EventManager } const passwordChar = '*' const nopasswordChar = ' ' func NewEdit(parent Controller) *Edit { edt := new(Edit) edt.InitControl("EDIT", parent, w32.WS_EX_CLIENTEDGE, w32.WS_CHILD|w32.WS_VISIBLE|w32.WS_TABSTOP|w32.ES_LEFT| w32.ES_AUTOHSCROLL) RegMsgHandler(edt) edt.SetFont(DefaultFont) edt.SetSize(200, 22) return edt } // Events. func (ed *Edit) OnChange() *EventManager { return &ed.onChange } // Public methods. func (ed *Edit) SetReadOnly(isReadOnly bool) { w32.SendMessage(ed.hwnd, w32.EM_SETREADONLY, uintptr(w32.BoolToBOOL(isReadOnly)), 0) } //Public methods func (ed *Edit) SetPassword(isPassword bool) { if isPassword { w32.SendMessage(ed.hwnd, w32.EM_SETPASSWORDCHAR, uintptr(passwordChar), 0) } else { w32.SendMessage(ed.hwnd, w32.EM_SETPASSWORDCHAR, 0, 0) } } func (ed *Edit) WndProc(msg uint32, wparam, lparam uintptr) uintptr { switch msg { case w32.WM_COMMAND: switch w32.HIWORD(uint32(wparam)) { case w32.EN_CHANGE: ed.onChange.Fire(NewEvent(ed, nil)) } /*case w32.WM_GETDLGCODE: println("Edit") if wparam == w32.VK_RETURN { return w32.DLGC_WANTALLKEYS }*/ } return w32.DefWindowProc(ed.hwnd, msg, wparam, lparam) } // MultiEdit is multiline text edit. type MultiEdit struct { ControlBase onChange EventManager } func NewMultiEdit(parent Controller) *MultiEdit { med := new(MultiEdit) med.InitControl("EDIT", parent, w32.WS_EX_CLIENTEDGE, w32.WS_CHILD|w32.WS_VISIBLE|w32.WS_TABSTOP|w32.ES_LEFT| w32.WS_VSCROLL|w32.WS_HSCROLL|w32.ES_MULTILINE|w32.ES_WANTRETURN|w32.ES_AUTOHSCROLL|w32.ES_AUTOVSCROLL) RegMsgHandler(med) med.SetFont(DefaultFont) med.SetSize(200, 400) return med } // Events func (med *MultiEdit) OnChange() *EventManager { return &med.onChange } // Public methods func (med *MultiEdit) SetReadOnly(isReadOnly bool) { w32.SendMessage(med.hwnd, w32.EM_SETREADONLY, uintptr(w32.BoolToBOOL(isReadOnly)), 0) } func (med *MultiEdit) AddLine(text string) { if len(med.Text()) == 0 { med.SetText(text) } else { med.SetText(med.Text() + "\r\n" + text) } } func (med *MultiEdit) WndProc(msg uint32, wparam, lparam uintptr) uintptr { switch msg { case w32.WM_COMMAND: switch w32.HIWORD(uint32(wparam)) { case w32.EN_CHANGE: med.onChange.Fire(NewEvent(med, nil)) } } return w32.DefWindowProc(med.hwnd, msg, wparam, lparam) } ================================================ FILE: event.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. * Copyright (C) 2010-2013 Allen Dang. All Rights Reserved. */ package winc type Event struct { Sender Controller Data interface{} } func NewEvent(sender Controller, data interface{}) *Event { return &Event{Sender: sender, Data: data} } ================================================ FILE: eventdata.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. * Copyright (C) 2010-2013 Allen Dang. All Rights Reserved. */ package winc import ( "github.com/tadvi/winc/w32" ) type RawMsg struct { Hwnd w32.HWND Msg uint32 WParam, LParam uintptr } type MouseEventData struct { X, Y int Button int Wheel int } type DropFilesEventData struct { X, Y int Files []string } type PaintEventData struct { Canvas *Canvas } type LabelEditEventData struct { Item ListItem Text string //PszText *uint16 } /*type LVDBLClickEventData struct { NmItem *w32.NMITEMACTIVATE }*/ type KeyUpEventData struct { VKey, Code int } type SizeEventData struct { Type uint X, Y int } ================================================ FILE: eventmanager.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. * Copyright (C) 2010-2013 Allen Dang. All Rights Reserved. */ package winc type EventHandler func(arg *Event) type EventManager struct { handler EventHandler } func (evm *EventManager) Fire(arg *Event) { if evm.handler != nil { evm.handler(arg) } } func (evm *EventManager) Bind(handler EventHandler) { evm.handler = handler } ================================================ FILE: examples/sample_contextmenu/app.manifest ================================================ ================================================ FILE: examples/sample_contextmenu/main.go ================================================ package main import ( "fmt" "github.com/tadvi/winc" ) func btnOnClick(arg *winc.Event) { fmt.Println("Button clicked") } func wndOnClose(arg *winc.Event) { winc.Exit() } // Item for the treeview. type Item struct { T string } func (item Item) Text() string { return item.T } func (item Item) ImageIndex() int { return 0 } func main() { mainWindow := winc.NewForm(nil) dock := winc.NewSimpleDock(mainWindow) mainWindow.SetLayout(dock) mainWindow.SetSize(700, 600) mainWindow.SetText("Controls Demo") menu := mainWindow.NewMenu() fileMn := menu.AddSubMenu("File") fileMn.AddItem("New", winc.NoShortcut) editMn := menu.AddSubMenu("Edit") cutMn := editMn.AddItem("Cut", winc.Shortcut{winc.ModControl, winc.KeyX}) copyMn := editMn.AddItem("Copy", winc.NoShortcut) pasteMn := editMn.AddItem("Paste", winc.NoShortcut) menu.Show() copyMn.SetCheckable(true) copyMn.SetChecked(true) pasteMn.SetEnabled(false) tabs := winc.NewMultiPanel(mainWindow) tabs.SetPos(10, 10) tabs.SetSize(100, 92) tree := winc.NewTreeView(mainWindow) tree.SetPos(10, 80) p := &Item{"First Item"} tree.InsertItem(p, nil, nil) sec := &Item{"Second"} if err := tree.InsertItem(sec, p, nil); err != nil { panic(err) } if err := tree.InsertItem(&Item{"Third"}, p, nil); err != nil { panic(err) } if err := tree.InsertItem(&Item{"Fourth"}, p, nil); err != nil { panic(err) } for i := 0; i < 50; i++ { if err := tree.InsertItem(&Item{"after second"}, sec, nil); err != nil { panic(err) } } tree.Expand(p) tree.OnCollapse().Bind(func(e *winc.Event) { println("collapse") }) // Pop up menu. popupMn := winc.NewContextMenu() cutAllMn := popupMn.AddItemCheckable("Cut All", winc.NoShortcut) cutAllMn.SetChecked(true) copyAllMn := popupMn.AddItem("Copy All", winc.NoShortcut) copyAllMn.SetEnabled(false) _ = popupMn.AddItem("Paste All", winc.NoShortcut) // Attach pop up menu to the treeview. tree.SetContextMenu(popupMn) cutAllMn.OnClick().Bind(func(e *winc.Event) { fmt.Println("cutAllMn") }) copyAllMn.OnClick().Bind(func(e *winc.Event) { fmt.Println("copyAllMn") }) cutMn.OnClick().Bind(func(e *winc.Event) { println("cut click") ok := tree.EnsureVisible(p) fmt.Println("result of EnsureVisible", ok) }) panel := winc.NewPanel(tabs) tabs.AddPanel(panel) panelDock := winc.NewSimpleDock(panel) panel.SetLayout(panelDock) panel.SetPos(0, 0) panelErr := winc.NewErrorPanel(panel) panelErr.SetPos(140, 10) panelErr.SetSize(200, 32) panelErr.ShowAsError(false) edt := winc.NewEdit(panel) edt.SetPos(10, 535) edt.SetText("some text") btn := winc.NewPushButton(panel) btn.SetText("Button") btn.SetSize(100, 40) btn.OnClick().Bind(func(e *winc.Event) { if edt.Visible() { edt.Hide() } else { edt.Show() } }) btn.SetResIcon(13) panelDock.Dock(btn, winc.Top) panelDock.Dock(edt, winc.Top) panelDock.Dock(panelErr, winc.Top) dock.Dock(tree, winc.Left) dock.Dock(tabs, winc.Top) mainWindow.Center() mainWindow.Show() mainWindow.OnClose().Bind(wndOnClose) winc.RunMainLoop() } ================================================ FILE: examples/sample_contextmenu/release.bat ================================================ rsrc -manifest app.manifest -ico=app.ico,application_lightning.ico,application_edit.ico,application_error.ico -o rsrc.syso go build -ldflags="-H windowsgui" ================================================ FILE: examples/sample_control/main.go ================================================ package main import ( "github.com/tadvi/winc" ) func main() { mainWindow := NewTopForm(nil) // Our TopForm control gets created here. mainWindow.SetSize(400, 300) mainWindow.SetText("Hello World Demo") edt := winc.NewEdit(mainWindow) edt.SetPos(10, 20) // Most Controls have default size unless SetSize is called. edt.SetText("edit text") btn := winc.NewPushButton(mainWindow) btn.SetText("Show or Hide") btn.SetPos(40, 50) btn.SetSize(100, 40) btn.OnClick().Bind(func(e *winc.Event) { if edt.Visible() { edt.Hide() } else { edt.Show() } }) mainWindow.Center() mainWindow.Show() mainWindow.OnClose().Bind(wndOnClose) winc.RunMainLoop() // Must call to start event loop. } func wndOnClose(arg *winc.Event) { winc.Exit() } ================================================ FILE: examples/sample_control/topform.go ================================================ package main import ( "github.com/tadvi/winc" "github.com/tadvi/winc/w32" ) // TopForm displayed as topmost window until closed. // By itself this is not very useful since Form has function EnableTopMost() making form topmost. // This is just an example showing how custom window Form can be implemented inside your package. type TopForm struct { winc.Form onLoad winc.EventManager } func NewTopForm(parent winc.Controller) *TopForm { dlg := new(TopForm) dlg.SetIsForm(true) winc.RegClassOnlyOnce("my_TopForm") dlg.SetHandle(winc.CreateWindow("my_TopForm", parent, w32.WS_EX_DLGMODALFRAME|w32.WS_EX_TOPMOST, w32.WS_VISIBLE|w32.WS_SYSMENU|w32.WS_CAPTION)) dlg.SetParent(parent) // dlg might fail if icon resource is not embedded in the binary if ico, err := winc.NewIconFromResource(winc.GetAppInstance(), uint16(winc.AppIconID)); err == nil { dlg.SetIcon(0, ico) } // Dlg forces display of focus rectangles, as soon as the user starts to type. w32.SendMessage(dlg.Handle(), w32.WM_CHANGEUISTATE, w32.UIS_INITIALIZE, 0) winc.RegMsgHandler(dlg) dlg.SetFont(winc.DefaultFont) dlg.SetText("Form") return dlg } // Events func (dlg *TopForm) OnLoad() *winc.EventManager { return &dlg.onLoad } func (dlg *TopForm) Show() { dlg.onLoad.Fire(winc.NewEvent(dlg, nil)) dlg.Form.Show() } func (dlg *TopForm) WndProc(msg uint32, wparam, lparam uintptr) uintptr { switch msg { case w32.WM_CLOSE: dlg.Close() case w32.WM_DESTROY: if dlg.Parent() == nil { winc.Exit() } } return w32.DefWindowProc(dlg.Handle(), msg, wparam, lparam) } ================================================ FILE: examples/sample_docking/app.manifest ================================================ ================================================ FILE: examples/sample_docking/main.go ================================================ package main import ( "fmt" "github.com/tadvi/winc" ) func btnOnClick(arg *winc.Event) { fmt.Println("Button clicked") } func wndOnClose(arg *winc.Event) { winc.Exit() } type Item struct { T string } func (item Item) Text() string { return item.T } func (item Item) ImageIndex() int { return 0 } func main() { //winc.Init() mainWindow := winc.NewForm(nil) dock := winc.NewSimpleDock(mainWindow) mainWindow.SetLayout(dock) mainWindow.SetSize(700, 600) mainWindow.SetText("Controls Demo") menu := mainWindow.NewMenu() fileMn := menu.AddSubMenu("File") fileMn.AddItem("New", winc.NoShortcut) editMn := menu.AddSubMenu("Edit") cutMn := editMn.AddItem("Cut", winc.Shortcut{winc.ModControl, winc.KeyX}) copyMn := editMn.AddItem("Copy", winc.NoShortcut) pasteMn := editMn.AddItem("Paste", winc.NoShortcut) menu.Show() copyMn.SetCheckable(true) copyMn.SetChecked(true) pasteMn.SetEnabled(false) tabs := winc.NewMultiPanel(mainWindow) tabs.SetPos(10, 10) tabs.SetSize(100, 92) tree := winc.NewTreeView(mainWindow) tree.SetPos(10, 80) p := &Item{"First Item"} tree.InsertItem(p, nil, nil) sec := &Item{"Second"} if err := tree.InsertItem(sec, p, nil); err != nil { panic(err) } if err := tree.InsertItem(&Item{"Third"}, p, nil); err != nil { panic(err) } if err := tree.InsertItem(&Item{"Fourth"}, p, nil); err != nil { panic(err) } for i := 0; i < 50; i++ { if err := tree.InsertItem(&Item{"after second"}, sec, nil); err != nil { panic(err) } } tree.Expand(p) tree.OnCollapse().Bind(func(e *winc.Event) { println("collapse") }) cutMn.OnClick().Bind(func(e *winc.Event) { println("cut click") ok := tree.EnsureVisible(p) fmt.Println("result of EnsureVisible", ok) }) panel := winc.NewPanel(tabs) tabs.AddPanel(panel) panelDock := winc.NewSimpleDock(panel) panel.SetLayout(panelDock) panel.SetPos(0, 0) panelErr := winc.NewErrorPanel(panel) panelErr.SetPos(140, 10) panelErr.SetSize(200, 32) panelErr.ShowAsError(false) edt := winc.NewEdit(panel) edt.SetPos(10, 535) edt.SetText("some text") btn := winc.NewPushButton(panel) btn.SetText("Button") btn.SetSize(100, 40) btn.OnClick().Bind(func(e *winc.Event) { if edt.Visible() { edt.Hide() } else { edt.Show() } }) btn.SetResIcon(13) panelDock.Dock(btn, winc.Top) panelDock.Dock(edt, winc.Top) panelDock.Dock(panelErr, winc.Top) dock.Dock(tree, winc.Left) dock.Dock(tabs, winc.Top) mainWindow.Center() mainWindow.Show() mainWindow.OnClose().Bind(wndOnClose) winc.RunMainLoop() } ================================================ FILE: examples/sample_docking/release.bat ================================================ rsrc -manifest app.manifest -ico=app.ico,application_lightning.ico,application_edit.ico,application_error.ico -o rsrc.syso go build -ldflags="-H windowsgui" ================================================ FILE: examples/sample_hello/main.go ================================================ package main import ( "github.com/tadvi/winc" ) func main() { mainWindow := winc.NewForm(nil) mainWindow.SetSize(400, 300) mainWindow.SetText("Hello World Demo") // Main window menu. Context menus on controls also available. menu := mainWindow.NewMenu() fileMn := menu.AddSubMenu("File") fileMn.AddItem("New", winc.Shortcut{winc.ModControl, winc.KeyN}) editMn := menu.AddSubMenu("Edit") cutMn := editMn.AddItem("Cut", winc.Shortcut{winc.ModControl, winc.KeyX}) copyMn := editMn.AddItem("Copy", winc.NoShortcut) pasteMn := editMn.AddItem("Paste", winc.NoShortcut) menu.Show() // Menu items can be disabled and checked. copyMn.SetCheckable(true) copyMn.SetChecked(true) pasteMn.SetEnabled(false) cutMn.OnClick().Bind(func(e *winc.Event) { winc.MsgBoxOk(mainWindow, "Cut", "Click event") }) edt := winc.NewEdit(mainWindow) edt.SetPos(10, 20) // Most Controls have default size unless SetSize is called. edt.SetText("edit text") btn := winc.NewPushButton(mainWindow) btn.SetText("Show or Hide") btn.SetPos(40, 50) btn.SetSize(100, 40) btn.OnClick().Bind(func(e *winc.Event) { if edt.Visible() { edt.Hide() } else { edt.Show() } }) mainWindow.Center() mainWindow.Show() mainWindow.OnClose().Bind(wndOnClose) winc.RunMainLoop() // Must call to start event loop. } func wndOnClose(arg *winc.Event) { winc.Exit() } ================================================ FILE: examples/sample_image/app.manifest ================================================ ================================================ FILE: examples/sample_image/main.go ================================================ package main import ( "fmt" "github.com/tadvi/winc" ) func btnOnClick(arg *winc.Event) { fmt.Println("Button clicked") } func wndOnClose(arg *winc.Event) { winc.Exit() } func main() { mainWindow := winc.NewForm(nil) dock := winc.NewSimpleDock(mainWindow) mainWindow.SetSize(700, 600) mainWindow.SetText("Controls Demo") menu := mainWindow.NewMenu() fileMn := menu.AddSubMenu("File") fileMn.AddItem("New", winc.NoShortcut) editMn := menu.AddSubMenu("Edit") cutMn := editMn.AddItem("Cut", winc.Shortcut{winc.ModControl, winc.KeyX}) copyMn := editMn.AddItem("Copy", winc.NoShortcut) pasteMn := editMn.AddItem("Paste", winc.NoShortcut) menu.Show() copyMn.SetCheckable(true) copyMn.SetChecked(true) pasteMn.SetEnabled(false) cutMn.OnClick().Bind(func(e *winc.Event) { println("cut click") }) imlistTb := winc.NewImageList(16, 16) imlistTb.AddResIcon(10) imlistTb.AddResIcon(12) imlistTb.AddResIcon(15) toolbar := winc.NewToolbar(mainWindow) toolbar.SetImageList(imlistTb) addBtn := toolbar.AddButton("Add", 1) toolbar.AddSeparator() runBtn := toolbar.AddButton("Run", 2) toolbar.Show() runBtn.OnClick().Bind(func(e *winc.Event) { println("runBtn click") }) scroll := winc.NewScrollView(mainWindow) imgv := winc.NewImageView(scroll) scroll.SetChild(imgv) addBtn.OnClick().Bind(func(e *winc.Event) { if filePath, ok := winc.ShowOpenFileDlg(mainWindow, "Select EDI X12 file", "All files (*.*)|*.*", 0, ""); ok { if err := imgv.DrawImageFile(filePath); err != nil { winc.Errorf(mainWindow, "Error: %s", err) } scroll.Invalidate(true) } }) dock.Dock(toolbar, winc.Top) // toolbars always dock to the top dock.Dock(scroll, winc.Fill) mainWindow.Center() mainWindow.Show() dock.Update() mainWindow.OnClose().Bind(wndOnClose) winc.RunMainLoop() } ================================================ FILE: examples/sample_image/release.bat ================================================ rsrc -manifest app.manifest -ico=app.ico,add.ico,application_lightning.ico,application_edit.ico,application_error.ico -o rsrc.syso go build -ldflags="-H windowsgui" ================================================ FILE: examples/sample_imagebox/app.manifest ================================================ ================================================ FILE: examples/sample_imagebox/main.go ================================================ package main import ( "fmt" "github.com/tadvi/winc" ) func btnOnClick(arg *winc.Event) { fmt.Println("Button clicked") } func wndOnClose(arg *winc.Event) { winc.Exit() } func main() { mainWindow := winc.NewForm(nil) dock := winc.NewSimpleDock(mainWindow) mainWindow.SetSize(700, 600) mainWindow.SetText("Controls Demo") menu := mainWindow.NewMenu() fileMn := menu.AddSubMenu("File") fileMn.AddItem("New", winc.NoShortcut) editMn := menu.AddSubMenu("Edit") cutMn := editMn.AddItem("Cut", winc.Shortcut{winc.ModControl, winc.KeyX}) copyMn := editMn.AddItem("Copy", winc.NoShortcut) pasteMn := editMn.AddItem("Paste", winc.NoShortcut) menu.Show() copyMn.SetCheckable(true) copyMn.SetChecked(true) pasteMn.SetEnabled(false) cutMn.OnClick().Bind(func(e *winc.Event) { println("cut click") }) imlistTb := winc.NewImageList(16, 16) imlistTb.AddResIcon(10) imlistTb.AddResIcon(12) imlistTb.AddResIcon(15) toolbar := winc.NewToolbar(mainWindow) toolbar.SetImageList(imlistTb) addBtn := toolbar.AddButton("Add", 1) toolbar.AddSeparator() runBtn := toolbar.AddButton("Run", 2) toolbar.Show() runBtn.OnClick().Bind(func(e *winc.Event) { println("runBtn click") }) scroll := winc.NewScrollView(mainWindow) imgv := winc.NewImageViewBox(scroll) scroll.SetChild(imgv) addBtn.OnClick().Bind(func(e *winc.Event) { if filePath, ok := winc.ShowOpenFileDlg(mainWindow, "Select EDI X12 file", "All files (*.*)|*.*", 0, ""); ok { if err := imgv.DrawImageFile(filePath); err != nil { winc.Errorf(mainWindow, "Error: %s", err) } scroll.Invalidate(true) } }) dock.Dock(toolbar, winc.Top) // toolbars always dock to the top dock.Dock(scroll, winc.Fill) mainWindow.Center() mainWindow.Show() dock.Update() mainWindow.OnClose().Bind(wndOnClose) winc.RunMainLoop() } ================================================ FILE: examples/sample_imagebox/release.bat ================================================ rsrc -manifest app.manifest -ico=app.ico,add.ico,application_lightning.ico,application_edit.ico,application_error.ico -o rsrc.syso go build -ldflags="-H windowsgui" ================================================ FILE: examples/sample_listview/app.manifest ================================================ ================================================ FILE: examples/sample_listview/main.go ================================================ package main import ( "fmt" "github.com/tadvi/winc" ) func btnOnClick(arg *winc.Event) { fmt.Println("Button clicked") } func wndOnClose(arg *winc.Event) { winc.Exit() } type Item struct { T []string checked bool } func (item Item) Text() []string { return item.T } func (item *Item) SetText(s string) { item.T[0] = s } func (item Item) Checked() bool { return item.checked } func (item *Item) SetChecked(checked bool) { item.checked = checked } func (item Item) ImageIndex() int { return 0 } func main() { mainWindow := winc.NewForm(nil) dock := winc.NewSimpleDock(mainWindow) mainWindow.SetSize(700, 600) mainWindow.SetText("Controls Demo") none := winc.Shortcut{} imlist := winc.NewImageList(16, 16) imlist.AddResIcon(16) imlist.AddResIcon(10) imlist.AddResIcon(13) ls := winc.NewListView(mainWindow) ls.SetImageList(imlist) ls.EnableEditLabels(false) ls.SetCheckBoxes(true) //ls.EnableFullRowSelect(true) //ls.EnableHotTrack(true) //ls.EnableSortHeader(true) //ls.EnableSortAscending(true) ls.AddColumn("One", 120) ls.AddColumn("Two", 120) ls.SetPos(10, 180) p1 := &Item{[]string{"First Item", "A"}, true} ls.AddItem(p1) p2 := &Item{[]string{"Second Item", "B"}, true} ls.AddItem(p2) p3 := &Item{[]string{"Third Item", "C"}, true} ls.AddItem(p3) for i := 0; i < 200; i++ { p4 := &Item{[]string{"Fourth Item", "D"}, false} ls.AddItem(p4) } menu := mainWindow.NewMenu() fileMn := menu.AddSubMenu("File") fileMn.AddItem("New", none) editMn := menu.AddSubMenu("Edit") delMn := editMn.AddItem("Delete", winc.Shortcut{winc.ModControl, winc.KeyX}) delAllMn := editMn.AddItem("Delete All", none) menu.Show() ls.OnEndLabelEdit().Bind(func(e *winc.Event) { println("edited", e) // acccept label edit event! //d := e.Data.(*winc.LabelEditEventData) //d.Item.SetText(d.Text) //fmt.Println(d.Item.Text()) }) delMn.OnClick().Bind(func(e *winc.Event) { items := ls.SelectedItems() for _, it := range items { fmt.Println(it) } }) delAllMn.OnClick().Bind(func(e *winc.Event) { ls.DeleteAllItems() }) ls.OnClick().Bind(func(e *winc.Event) { println("onClick listview") }) dock.Dock(ls, winc.Fill) mainWindow.Center() mainWindow.Show() mainWindow.OnClose().Bind(wndOnClose) winc.RunMainLoop() } ================================================ FILE: examples/sample_listview/release.bat ================================================ rsrc -manifest app.manifest -ico=app.ico,application_lightning.ico,application_edit.ico,application_error.ico -o rsrc.syso go build -ldflags="-H windowsgui" ================================================ FILE: examples/sample_minimal/main.go ================================================ package main import ( "github.com/tadvi/winc" ) func main() { mainWindow := winc.NewForm(nil) mainWindow.SetSize(400, 300) mainWindow.SetText("Hello World Demo") edt := winc.NewEdit(mainWindow) edt.SetPos(10, 20) // Most Controls have default size unless SetSize is called. edt.SetText("edit text") btn := winc.NewPushButton(mainWindow) btn.SetText("Show or Hide") btn.SetPos(40, 50) btn.SetSize(100, 40) btn.OnClick().Bind(func(e *winc.Event) { if edt.Visible() { edt.Hide() } else { edt.Show() } }) mainWindow.Center() mainWindow.Show() mainWindow.OnClose().Bind(wndOnClose) winc.RunMainLoop() // Must call to start event loop. } func wndOnClose(arg *winc.Event) { winc.Exit() } ================================================ FILE: examples/sample_scrollview/app.manifest ================================================ ================================================ FILE: examples/sample_scrollview/main.go ================================================ package main import ( "fmt" "github.com/tadvi/winc" ) func btnOnClick(arg *winc.Event) { //edt.SetCaption("Got you !!!") fmt.Println("Button clicked") } func wndOnClose(arg *winc.Event) { winc.Exit() } type Item struct { T string } func (item Item) Text() string { return item.T } func (item Item) ImageIndex() int { return 1 } func main() { mainWindow := winc.NewForm(nil) dock := winc.NewSimpleDock(mainWindow) mainWindow.SetLayout(dock) mainWindow.SetSize(540, 540) mainWindow.SetText("Controls Demo") menu := mainWindow.NewMenu() fileMn := menu.AddSubMenu("File") fileMn.AddItem("New", winc.NoShortcut) editMn := menu.AddSubMenu("Edit") cutMn := editMn.AddItem("Cut", winc.Shortcut{winc.ModControl, winc.KeyX}) copyMn := editMn.AddItem("Copy", winc.NoShortcut) pasteMn := editMn.AddItem("Paste", winc.NoShortcut) menu.Show() copyMn.SetCheckable(true) copyMn.SetChecked(true) pasteMn.SetEnabled(false) cutMn.OnClick().Bind(func(e *winc.Event) { println("cut click") }) imlist := winc.NewImageList(16, 16) imlist.AddResIcon(10) imlist.AddResIcon(12) imlist.AddResIcon(15) scroll := winc.NewScrollView(mainWindow) tree := winc.NewTreeView(scroll) scroll.SetChild(&tree.ControlBase) //scroll.Show() tree.SetImageList(imlist) tree.SetPos(10, 80) tree.SetSize(800, 800) p := &Item{"First Item"} tree.InsertItem(p, nil, nil) sec := &Item{"Second"} if err := tree.InsertItem(sec, p, nil); err != nil { panic(err) } if err := tree.InsertItem(&Item{"Third"}, p, nil); err != nil { panic(err) } if err := tree.InsertItem(&Item{"Fourth"}, p, nil); err != nil { panic(err) } for i := 0; i < 50; i++ { if err := tree.InsertItem(&Item{"after second"}, sec, nil); err != nil { panic(err) } } tree.Expand(p) tree.OnCollapse().Bind(func(e *winc.Event) { println("collapse") }) imlistTb := winc.NewImageList(16, 16) imlistTb.AddResIcon(10) imlistTb.AddResIcon(12) imlistTb.AddResIcon(15) toolbar := winc.NewToolbar(mainWindow) toolbar.SetImageList(imlistTb) addBtn := toolbar.AddButton("Add", 1) toolbar.AddSeparator() runBtn := toolbar.AddButton("Run", 2) toolbar.Show() runBtn.OnClick().Bind(func(e *winc.Event) { println("runBtn click") }) addBtn.OnClick().Bind(func(e *winc.Event) { println("addBtn click") }) dock.Dock(toolbar, winc.Top) // toolbars always dock to the top dock.Dock(scroll, winc.Fill) mainWindow.Center() dock.Update() mainWindow.Show() mainWindow.OnClose().Bind(wndOnClose) winc.RunMainLoop() } ================================================ FILE: examples/sample_scrollview/release.bat ================================================ rsrc -manifest app.manifest -ico=app.ico,add.ico,application_lightning.ico,application_edit.ico,application_error.ico -o rsrc.syso go build -ldflags="-H windowsgui" ================================================ FILE: examples/sample_slider/app.manifest ================================================ ================================================ FILE: examples/sample_slider/main.go ================================================ package main import ( "fmt" "github.com/tadvi/winc" ) func btnOnClick(arg *winc.Event) { fmt.Println("Button clicked") } func wndOnClose(arg *winc.Event) { winc.Exit() } func main() { mainWindow := winc.NewForm(nil) dock := winc.NewSimpleDock(mainWindow) //mainWindow.SetLayout(dock) mainWindow.SetSize(700, 600) mainWindow.SetText("Controls Demo") menu := mainWindow.NewMenu() fileMn := menu.AddSubMenu("File") fileMn.AddItem("New", winc.NoShortcut) editMn := menu.AddSubMenu("Edit") cutMn := editMn.AddItem("Cut", winc.Shortcut{winc.ModControl, winc.KeyX}) copyMn := editMn.AddItem("Copy", winc.NoShortcut) pasteMn := editMn.AddItem("Paste", winc.NoShortcut) menu.Show() copyMn.SetCheckable(true) copyMn.SetChecked(true) pasteMn.SetEnabled(false) cutMn.OnClick().Bind(func(e *winc.Event) { println("cut click") }) imlistTb := winc.NewImageList(16, 16) imlistTb.AddResIcon(10) imlistTb.AddResIcon(12) imlistTb.AddResIcon(15) toolbar := winc.NewToolbar(mainWindow) toolbar.SetImageList(imlistTb) addBtn := toolbar.AddButton("Add", 1) toolbar.AddSeparator() runBtn := toolbar.AddButton("Run Now Fast", 2) toolbar.Show() runBtn.OnClick().Bind(func(e *winc.Event) { println("runBtn click") }) dock.Dock(toolbar, winc.Top) // toolbars always dock to the top //dock.Dock(tree, winc.Fill) slide := winc.NewSlider(mainWindow) slide.SetPos(10, 50) slide.OnScroll().Bind(func(e *winc.Event) { println(slide.Value()) }) addBtn.OnClick().Bind(func(e *winc.Event) { println("addBtn click") slide.SetValue(30) }) //track.SetRange(0, 100) //track.SetValue(20) mainWindow.Center() mainWindow.Show() dock.Update() mainWindow.OnClose().Bind(wndOnClose) winc.RunMainLoop() } ================================================ FILE: examples/sample_slider/release.bat ================================================ rsrc -manifest app.manifest -ico=app.ico,add.ico,application_lightning.ico,application_edit.ico,application_error.ico -o rsrc.syso go build -ldflags="-H windowsgui" ================================================ FILE: examples/sample_splitview/app.manifest ================================================ ================================================ FILE: examples/sample_splitview/layout.json ================================================ {"WindowState":"0 1 -1 -1 -1 -1 610 228 1310 828","Controls":[{"X":0,"Y":0,"Width":684,"Height":40},{"X":0,"Y":40,"Width":522,"Height":501},{"X":522,"Y":40,"Width":20,"Height":501},{"X":542,"Y":40,"Width":142,"Height":501}]} ================================================ FILE: examples/sample_splitview/main.go ================================================ package main import ( "fmt" "github.com/tadvi/winc" ) func btnOnClick(arg *winc.Event) { //edt.SetCaption("Got you !!!") fmt.Println("Button clicked") } func wndOnClose(arg *winc.Event) { winc.Exit() } func main() { mainWindow := winc.NewForm(nil) mainWindow.SetSize(700, 600) mainWindow.SetText("Controls Demo") //none := winc.Shortcut{} menu := mainWindow.NewMenu() fileMn := menu.AddSubMenu("File") fileMn.AddItem("New", winc.NoShortcut) editMn := menu.AddSubMenu("Edit") delMn := editMn.AddItem("Delete", winc.Shortcut{winc.ModControl, winc.KeyX}) delAllMn := editMn.AddItem("Delete All", winc.NoShortcut) menu.Show() delMn.OnClick().Bind(func(e *winc.Event) { dlg := winc.NewDialog(mainWindow) dlg.Center() dlg.Show() }) delAllMn.OnClick().Bind(func(e *winc.Event) { dlg := winc.NewDialog(mainWindow) dlg.Center() dlg.Show() }) toolbar := winc.NewPanel(mainWindow) toolbar.SetPos(0, 0) toolbar.SetSize(100, 40) btnRun := winc.NewIconButton(toolbar) btnRun.SetText(" Run") btnRun.SetPos(2, 2) btnRun.SetSize(98, 38) btnRun.SetResIcon(15) btnRun.OnClick().Bind(func(e *winc.Event) { println("event OnClick") }) //tipRun := winc.NewToolTip(mainWindow) //tipRun.AddTool(btnRun, "Run project") btnEdit := winc.NewPushButton(toolbar) btnEdit.SetText(" Edit") btnEdit.SetPos(102, 2) btnEdit.SetSize(98, 38) btnEdit.SetResIcon(18) left := winc.NewMultiEdit(mainWindow) left.SetPos(5, 5) right := winc.NewMultiEdit(mainWindow) right.SetPos(50, 100) split := winc.NewVResizer(mainWindow) split.SetControl(left, right, winc.Left, 150) // --- Add controls to Dock, LoadStateFile and Show window in this order mainWindow.Center() mainWindow.Show() dock := winc.NewSimpleDock(mainWindow) //mainWindow.SetLayout(dock) dock.Dock(toolbar, winc.Top) dock.Dock(left, winc.Left) dock.Dock(split, winc.Left) dock.Dock(right, winc.Fill) // if err := dock.LoadStateFile("layout.json"); err != nil { // log.Println(err) // } mainWindow.OnClose().Bind(func(e *winc.Event) { dock.SaveStateFile("layout.json") // error gets ignored winc.Exit() }) dock.Update() winc.RunMainLoop() // --- end of Dock and main window management } ================================================ FILE: examples/sample_splitview/release.bat ================================================ rsrc -manifest app.manifest -ico=app.ico,add.ico,run.ico,edit.ico,error.ico -o rsrc.syso go build -ldflags="-H windowsgui" ================================================ FILE: examples/sample_tab/app.manifest ================================================ ================================================ FILE: examples/sample_tab/main.go ================================================ package main import ( "fmt" "github.com/tadvi/winc" ) func btnOnClick(arg *winc.Event) { fmt.Println("Button clicked") } func wndOnClose(arg *winc.Event) { winc.Exit() } type Item struct { T []string checked bool } func (item Item) Text() []string { return item.T } func (item *Item) SetText(s string) { item.T[0] = s } func (item Item) Checked() bool { return item.checked } func (item *Item) SetChecked(checked bool) { item.checked = checked } func (item Item) ImageIndex() int { return 0 } func main() { mainWindow := winc.NewForm(nil) dock := winc.NewSimpleDock(mainWindow) mainWindow.SetSize(700, 600) mainWindow.SetText("Controls Demo") menu := mainWindow.NewMenu() fileMn := menu.AddSubMenu("File") fileMn.AddItem("New", winc.NoShortcut) editMn := menu.AddSubMenu("Edit") cutMn := editMn.AddItem("Cut", winc.Shortcut{winc.ModControl, winc.KeyX}) copyMn := editMn.AddItem("Copy", winc.NoShortcut) pasteMn := editMn.AddItem("Paste", winc.NoShortcut) menu.Show() copyMn.SetCheckable(true) copyMn.SetChecked(true) pasteMn.SetEnabled(false) cutMn.OnClick().Bind(func(e *winc.Event) { println("cut click") }) imlistTb := winc.NewImageList(16, 16) imlistTb.AddResIcon(10) imlistTb.AddResIcon(12) imlistTb.AddResIcon(15) // --- Toolbar toolbar := winc.NewToolbar(mainWindow) toolbar.SetImageList(imlistTb) addBtn := toolbar.AddButton("Add", 1) toolbar.AddSeparator() runBtn := toolbar.AddButton("Run Now Fast", 2) toolbar.Show() runBtn.OnClick().Bind(func(e *winc.Event) { println("runBtn click") }) addBtn.OnClick().Bind(func(e *winc.Event) { println("addBtn click") }) // --- Tabs tabs := winc.NewTabView(mainWindow) panel1 := tabs.AddPanel("First") panel2 := tabs.AddPanel("Second") panel3 := tabs.AddPanel("Third") panel4 := tabs.AddPanel("Fourth") edt := winc.NewEdit(panel1) edt.SetPos(100, 10) edt2 := winc.NewEdit(panel2) edt2.SetPos(40, 10) btn := winc.NewPushButton(panel3) btn.OnClick().Bind(func(e *winc.Event) { println("click") }) imlist := winc.NewImageList(16, 16) imlist.AddResIcon(12) ls := winc.NewListView(panel4) ls.SetImageList(imlist) ls.EnableEditLabels(false) ls.SetCheckBoxes(true) //ls.EnableFullRowSelect(true) //ls.EnableHotTrack(true) //ls.EnableSortHeader(true) //ls.EnableSortAscending(true) ls.AddColumn("One", 120) ls.AddColumn("Two", 120) ls.SetPos(10, 180) p1 := &Item{[]string{"First Item", "A"}, true} ls.AddItem(p1) p2 := &Item{[]string{"Second Item", "B"}, true} ls.AddItem(p2) p3 := &Item{[]string{"Third Item", "C"}, true} ls.AddItem(p3) for i := 0; i < 200; i++ { p4 := &Item{[]string{"Fourth Item", "D"}, false} ls.AddItem(p4) } // --- Dock dock2 := winc.NewSimpleDock(panel4) dock2.Dock(ls, winc.Fill) tabs.SetCurrent(0) dock.Dock(toolbar, winc.Top) // toolbars always dock to the top dock.Dock(tabs, winc.Top) // tabs should prefer docking at the top dock.Dock(tabs.Panels(), winc.Fill) // tab panels dock just below tabs and fill area mainWindow.Center() mainWindow.Show() mainWindow.OnClose().Bind(wndOnClose) winc.RunMainLoop() } ================================================ FILE: examples/sample_tab/release.bat ================================================ rsrc -manifest app.manifest -ico=app.ico,add.ico,application_lightning.ico,application_edit.ico,application_error.ico -o rsrc.syso go build -ldflags="-H windowsgui" ================================================ FILE: examples/sample_treeview/app.manifest ================================================ ================================================ FILE: examples/sample_treeview/main.go ================================================ package main import ( "fmt" "github.com/tadvi/winc" ) func btnOnClick(arg *winc.Event) { fmt.Println("Button clicked") } func wndOnClose(arg *winc.Event) { winc.Exit() } type Item struct { T string } func (item Item) Text() string { return item.T } func (item Item) ImageIndex() int { return 1 } func main() { mainWindow := winc.NewForm(nil) dock := winc.NewSimpleDock(mainWindow) mainWindow.SetLayout(dock) mainWindow.SetSize(700, 600) mainWindow.SetText("Controls Demo") menu := mainWindow.NewMenu() fileMn := menu.AddSubMenu("File") fileMn.AddItem("New", winc.NoShortcut) editMn := menu.AddSubMenu("Edit") cutMn := editMn.AddItem("Cut", winc.Shortcut{winc.ModControl, winc.KeyX}) copyMn := editMn.AddItem("Copy", winc.NoShortcut) pasteMn := editMn.AddItem("Paste", winc.NoShortcut) menu.Show() copyMn.SetCheckable(true) copyMn.SetChecked(true) pasteMn.SetEnabled(false) cutMn.OnClick().Bind(func(e *winc.Event) { println("cut click") }) imlist := winc.NewImageList(16, 16) imlist.AddResIcon(10) imlist.AddResIcon(12) imlist.AddResIcon(15) tree := winc.NewTreeView(mainWindow) tree.SetImageList(imlist) tree.SetPos(10, 80) p := &Item{"First Item"} tree.InsertItem(p, nil, nil) sec := &Item{"Second"} if err := tree.InsertItem(sec, p, nil); err != nil { panic(err) } if err := tree.InsertItem(&Item{"Third"}, p, nil); err != nil { panic(err) } if err := tree.InsertItem(&Item{"Fourth"}, p, nil); err != nil { panic(err) } for i := 0; i < 50; i++ { if err := tree.InsertItem(&Item{"after second"}, sec, nil); err != nil { panic(err) } } tree.Expand(p) tree.OnCollapse().Bind(func(e *winc.Event) { println("collapse") }) imlistTb := winc.NewImageList(16, 16) imlistTb.AddResIcon(10) imlistTb.AddResIcon(12) imlistTb.AddResIcon(15) toolbar := winc.NewToolbar(mainWindow) toolbar.SetImageList(imlistTb) addBtn := toolbar.AddButton("Add", 1) toolbar.AddSeparator() runBtn := toolbar.AddButton("Run", 2) toolbar.Show() runBtn.OnClick().Bind(func(e *winc.Event) { println("runBtn click") }) addBtn.OnClick().Bind(func(e *winc.Event) { println("addBtn click") }) dock.Dock(toolbar, winc.Top) // toolbars always dock to the top dock.Dock(tree, winc.Fill) mainWindow.Center() mainWindow.Show() dock.Update() mainWindow.OnClose().Bind(wndOnClose) winc.RunMainLoop() } ================================================ FILE: examples/sample_treeview/release.bat ================================================ rsrc -manifest app.manifest -ico=app.ico,add.ico,application_lightning.ico,application_edit.ico,application_error.ico -o rsrc.syso go build -ldflags="-H windowsgui" ================================================ FILE: font.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. * Copyright (C) 2010-2013 Allen Dang. All Rights Reserved. */ package winc import ( "syscall" "github.com/tadvi/winc/w32" ) const ( FontBold byte = 0x01 FontItalic byte = 0x02 FontUnderline byte = 0x04 FontStrikeOut byte = 0x08 ) func init() { DefaultFont = NewFont("MS Shell Dlg 2", 8, 0) } type Font struct { hfont w32.HFONT family string pointSize int style byte } func NewFont(family string, pointSize int, style byte) *Font { if style > FontBold|FontItalic|FontUnderline|FontStrikeOut { panic("Invalid font style") } //Retrive screen DPI hDC := w32.GetDC(0) defer w32.ReleaseDC(0, hDC) screenDPIY := w32.GetDeviceCaps(hDC, w32.LOGPIXELSY) font := Font{ family: family, pointSize: pointSize, style: style, } font.hfont = font.createForDPI(screenDPIY) if font.hfont == 0 { panic("CreateFontIndirect failed") } return &font } func (fnt *Font) createForDPI(dpi int) w32.HFONT { var lf w32.LOGFONT lf.Height = int32(-w32.MulDiv(fnt.pointSize, dpi, 72)) if fnt.style&FontBold > 0 { lf.Weight = w32.FW_BOLD } else { lf.Weight = w32.FW_NORMAL } if fnt.style&FontItalic > 0 { lf.Italic = 1 } if fnt.style&FontUnderline > 0 { lf.Underline = 1 } if fnt.style&FontStrikeOut > 0 { lf.StrikeOut = 1 } lf.CharSet = w32.DEFAULT_CHARSET lf.OutPrecision = w32.OUT_TT_PRECIS lf.ClipPrecision = w32.CLIP_DEFAULT_PRECIS lf.Quality = w32.CLEARTYPE_QUALITY lf.PitchAndFamily = w32.VARIABLE_PITCH | w32.FF_SWISS src := syscall.StringToUTF16(fnt.family) dest := lf.FaceName[:] copy(dest, src) return w32.CreateFontIndirect(&lf) } func (fnt *Font) GetHFONT() w32.HFONT { return fnt.hfont } func (fnt *Font) Bold() bool { return fnt.style&FontBold > 0 } func (fnt *Font) Dispose() { if fnt.hfont != 0 { w32.DeleteObject(w32.HGDIOBJ(fnt.hfont)) } } func (fnt *Font) Family() string { return fnt.family } func (fnt *Font) Italic() bool { return fnt.style&FontItalic > 0 } func (fnt *Font) StrikeOut() bool { return fnt.style&FontStrikeOut > 0 } func (fnt *Font) Underline() bool { return fnt.style&FontUnderline > 0 } func (fnt *Font) Style() byte { return fnt.style } ================================================ FILE: form.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. * Copyright (C) 2010-2013 Allen Dang. All Rights Reserved. */ package winc import ( "github.com/tadvi/winc/w32" "unsafe" ) type LayoutManager interface { Update() } // A Form is main window of the application. type Form struct { ControlBase layoutMng LayoutManager // Fullscreen / Unfullscreen isFullscreen bool previousWindowStyle uint32 previousWindowPlacement w32.WINDOWPLACEMENT } func NewCustomForm(parent Controller, exStyle int, dwStyle uint) *Form { fm := new(Form) RegClassOnlyOnce("winc_Form") fm.isForm = true if exStyle == 0 { exStyle = w32.WS_EX_CONTROLPARENT | w32.WS_EX_APPWINDOW } if dwStyle == 0 { dwStyle = w32.WS_OVERLAPPEDWINDOW } fm.hwnd = CreateWindow("winc_Form", parent, uint(exStyle), dwStyle) fm.parent = parent // this might fail if icon resource is not embedded in the binary if ico, err := NewIconFromResource(GetAppInstance(), uint16(AppIconID)); err == nil { fm.SetIcon(0, ico) } // This forces display of focus rectangles, as soon as the user starts to type. w32.SendMessage(fm.hwnd, w32.WM_CHANGEUISTATE, w32.UIS_INITIALIZE, 0) RegMsgHandler(fm) fm.SetFont(DefaultFont) fm.SetText("Form") return fm } func NewForm(parent Controller) *Form { fm := new(Form) RegClassOnlyOnce("winc_Form") fm.isForm = true fm.hwnd = CreateWindow("winc_Form", parent, w32.WS_EX_CONTROLPARENT|w32.WS_EX_APPWINDOW, w32.WS_OVERLAPPEDWINDOW) fm.parent = parent // this might fail if icon resource is not embedded in the binary if ico, err := NewIconFromResource(GetAppInstance(), uint16(AppIconID)); err == nil { fm.SetIcon(0, ico) } // This forces display of focus rectangles, as soon as the user starts to type. w32.SendMessage(fm.hwnd, w32.WM_CHANGEUISTATE, w32.UIS_INITIALIZE, 0) RegMsgHandler(fm) fm.SetFont(DefaultFont) fm.SetText("Form") return fm } func (fm *Form) SetLayout(mng LayoutManager) { fm.layoutMng = mng } // UpdateLayout refresh layout. func (fm *Form) UpdateLayout() { if fm.layoutMng != nil { fm.layoutMng.Update() } } func (fm *Form) NewMenu() *Menu { hMenu := w32.CreateMenu() if hMenu == 0 { panic("failed CreateMenu") } m := &Menu{hMenu: hMenu, hwnd: fm.hwnd} if !w32.SetMenu(fm.hwnd, hMenu) { panic("failed SetMenu") } return m } func (fm *Form) DisableIcon() { windowInfo := getWindowInfo(fm.hwnd) frameless := windowInfo.IsPopup() if frameless { return } exStyle := w32.GetWindowLong(fm.hwnd, w32.GWL_EXSTYLE) w32.SetWindowLong(fm.hwnd, w32.GWL_EXSTYLE, uint32(exStyle|w32.WS_EX_DLGMODALFRAME)) w32.SetWindowPos(fm.hwnd, 0, 0, 0, 0, 0, uint( w32.SWP_FRAMECHANGED| w32.SWP_NOMOVE| w32.SWP_NOSIZE| w32.SWP_NOZORDER), ) } func (fm *Form) Maximise() { w32.ShowWindow(fm.hwnd, w32.SW_MAXIMIZE) } func (fm *Form) Minimise() { w32.ShowWindow(fm.hwnd, w32.SW_MINIMIZE) } func (fm *Form) Restore() { w32.ShowWindow(fm.hwnd, w32.SW_RESTORE) } // Public methods func (fm *Form) Center() { windowInfo := getWindowInfo(fm.hwnd) frameless := windowInfo.IsPopup() info := getMonitorInfo(fm.hwnd) workRect := info.RcWork screenMiddleW := workRect.Left + (workRect.Right-workRect.Left)/2 screenMiddleH := workRect.Top + (workRect.Bottom-workRect.Top)/2 var winRect *w32.RECT if !frameless { winRect = w32.GetWindowRect(fm.hwnd) } else { winRect = w32.GetClientRect(fm.hwnd) } winWidth := winRect.Right - winRect.Left winHeight := winRect.Bottom - winRect.Top windowX := screenMiddleW - (winWidth / 2) windowY := screenMiddleH - (winHeight / 2) w32.SetWindowPos(fm.hwnd, w32.HWND_TOP, int(windowX), int(windowY), int(winWidth), int(winHeight), w32.SWP_NOSIZE) } func (fm *Form) Fullscreen() { if fm.isFullscreen { return } fm.previousWindowStyle = uint32(w32.GetWindowLongPtr(fm.hwnd, w32.GWL_STYLE)) monitor := w32.MonitorFromWindow(fm.hwnd, w32.MONITOR_DEFAULTTOPRIMARY) var monitorInfo w32.MONITORINFO monitorInfo.CbSize = uint32(unsafe.Sizeof(monitorInfo)) if !w32.GetMonitorInfo(monitor, &monitorInfo) { return } if !w32.GetWindowPlacement(fm.hwnd, &fm.previousWindowPlacement) { return } w32.SetWindowLong(fm.hwnd, w32.GWL_STYLE, fm.previousWindowStyle & ^uint32(w32.WS_OVERLAPPEDWINDOW)) w32.SetWindowPos(fm.hwnd, w32.HWND_TOP, int(monitorInfo.RcMonitor.Left), int(monitorInfo.RcMonitor.Top), int(monitorInfo.RcMonitor.Right-monitorInfo.RcMonitor.Left), int(monitorInfo.RcMonitor.Bottom-monitorInfo.RcMonitor.Top), w32.SWP_NOOWNERZORDER|w32.SWP_FRAMECHANGED) fm.isFullscreen = true } func (fm *Form) UnFullscreen() { if !fm.isFullscreen { return } w32.SetWindowLong(fm.hwnd, w32.GWL_STYLE, fm.previousWindowStyle) w32.SetWindowPlacement(fm.hwnd, &fm.previousWindowPlacement) w32.SetWindowPos(fm.hwnd, 0, 0, 0, 0, 0, w32.SWP_NOMOVE|w32.SWP_NOSIZE|w32.SWP_NOZORDER|w32.SWP_NOOWNERZORDER|w32.SWP_FRAMECHANGED) fm.isFullscreen = false } // IconType: 1 - ICON_BIG; 0 - ICON_SMALL func (fm *Form) SetIcon(iconType int, icon *Icon) { if iconType > 1 { panic("IconType is invalid") } w32.SendMessage(fm.hwnd, w32.WM_SETICON, uintptr(iconType), uintptr(icon.Handle())) } func (fm *Form) EnableMaxButton(b bool) { ToggleStyle(fm.hwnd, b, w32.WS_MAXIMIZEBOX) } func (fm *Form) EnableMinButton(b bool) { ToggleStyle(fm.hwnd, b, w32.WS_MINIMIZEBOX) } func (fm *Form) EnableSizable(b bool) { ToggleStyle(fm.hwnd, b, w32.WS_THICKFRAME) } func (fm *Form) EnableDragMove(_ bool) { //fm.isDragMove = b } func (fm *Form) EnableTopMost(b bool) { tag := w32.HWND_NOTOPMOST if b { tag = w32.HWND_TOPMOST } w32.SetWindowPos(fm.hwnd, tag, 0, 0, 0, 0, w32.SWP_NOMOVE|w32.SWP_NOSIZE) } func (fm *Form) WndProc(msg uint32, wparam, lparam uintptr) uintptr { switch msg { case w32.WM_COMMAND: if lparam == 0 && w32.HIWORD(uint32(wparam)) == 0 { // Menu support. actionID := uint16(w32.LOWORD(uint32(wparam))) if action, ok := actionsByID[actionID]; ok { action.onClick.Fire(NewEvent(fm, nil)) } } case w32.WM_KEYDOWN: // Accelerator support. key := Key(wparam) if uint32(lparam)>>30 == 0 { // Using TranslateAccelerators refused to work, so we handle them // ourselves, at least for now. shortcut := Shortcut{ModifiersDown(), key} if action, ok := shortcut2Action[shortcut]; ok { if action.Enabled() { action.onClick.Fire(NewEvent(fm, nil)) } } } case w32.WM_CLOSE: return 0 case w32.WM_DESTROY: w32.PostQuitMessage(0) return 0 case w32.WM_SIZE, w32.WM_PAINT: if fm.layoutMng != nil { fm.layoutMng.Update() } case w32.WM_GETMINMAXINFO: if fm.minWidth != 0 || fm.maxWidth != 0 || fm.minHeight != 0 || fm.maxHeight != 0 { dpix, dpiy := fm.GetWindowDPI() DPIScaleX := dpix / 96.0 DPIScaleY := dpiy / 96.0 mmi := (*w32.MINMAXINFO)(unsafe.Pointer(lparam)) if fm.minWidth > 0 && fm.minHeight > 0 { mmi.PtMinTrackSize.X = int32(fm.minWidth * int(DPIScaleX)) mmi.PtMinTrackSize.Y = int32(fm.minHeight * int(DPIScaleY)) } if fm.maxWidth > 0 && fm.maxHeight > 0 { mmi.PtMaxSize.X = int32(fm.maxWidth * int(DPIScaleX)) mmi.PtMaxSize.Y = int32(fm.maxHeight * int(DPIScaleY)) mmi.PtMaxTrackSize.X = int32(fm.maxWidth * int(DPIScaleX)) mmi.PtMaxTrackSize.Y = int32(fm.maxHeight * int(DPIScaleY)) } return 0 } } return w32.DefWindowProc(fm.hwnd, msg, wparam, lparam) } ================================================ FILE: globalvars.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. * Copyright (C) 2010-2013 Allen Dang. All Rights Reserved. */ package winc import ( "syscall" "github.com/tadvi/winc/w32" ) //Private global variables. var ( gAppInstance w32.HINSTANCE gControllerRegistry map[w32.HWND]Controller gRegisteredClasses []string ) //Public global variables. var ( GeneralWndprocCallBack = syscall.NewCallback(generalWndProc) DefaultFont *Font ) ================================================ FILE: go.mod ================================================ module github.com/tadvi/winc go 1.12 ================================================ FILE: icon.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. * Copyright (C) 2010-2013 Allen Dang. All Rights Reserved. */ package winc import ( "errors" "fmt" "syscall" "github.com/tadvi/winc/w32" ) type Icon struct { handle w32.HICON } func NewIconFromFile(path string) (*Icon, error) { ico := new(Icon) var err error if ico.handle = w32.LoadIcon(0, syscall.StringToUTF16Ptr(path)); ico.handle == 0 { err = errors.New(fmt.Sprintf("Cannot load icon from %s", path)) } return ico, err } func NewIconFromResource(instance w32.HINSTANCE, resId uint16) (*Icon, error) { ico := new(Icon) var err error if ico.handle = w32.LoadIcon(instance, w32.MakeIntResource(resId)); ico.handle == 0 { err = errors.New(fmt.Sprintf("Cannot load icon from resource with id %v", resId)) } return ico, err } func ExtractIcon(fileName string, index int) (*Icon, error) { ico := new(Icon) var err error if ico.handle = w32.ExtractIcon(fileName, index); ico.handle == 0 || ico.handle == 1 { err = errors.New(fmt.Sprintf("Cannot extract icon from %s at index %v", fileName, index)) } return ico, err } func (ic *Icon) Destroy() bool { return w32.DestroyIcon(ic.handle) } func (ic *Icon) Handle() w32.HICON { return ic.handle } ================================================ FILE: imagelist.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. * Copyright (C) 2010-2013 Allen Dang. All Rights Reserved. */ package winc import ( "fmt" "github.com/tadvi/winc/w32" ) type ImageList struct { handle w32.HIMAGELIST } func NewImageList(cx, cy int) *ImageList { return newImageList(cx, cy, w32.ILC_COLOR32, 0, 0) } func newImageList(cx, cy int, flags uint, cInitial, cGrow int) *ImageList { imgl := new(ImageList) imgl.handle = w32.ImageList_Create(cx, cy, flags, cInitial, cGrow) return imgl } func (im *ImageList) Handle() w32.HIMAGELIST { return im.handle } func (im *ImageList) Destroy() bool { return w32.ImageList_Destroy(im.handle) } func (im *ImageList) SetImageCount(uNewCount uint) bool { return w32.ImageList_SetImageCount(im.handle, uNewCount) } func (im *ImageList) ImageCount() int { return w32.ImageList_GetImageCount(im.handle) } func (im *ImageList) AddIcon(icon *Icon) int { return w32.ImageList_AddIcon(im.handle, icon.Handle()) } func (im *ImageList) AddResIcon(iconID uint16) { if ico, err := NewIconFromResource(GetAppInstance(), iconID); err == nil { im.AddIcon(ico) return } panic(fmt.Sprintf("missing icon with icon ID: %d", iconID)) } func (im *ImageList) RemoveAll() bool { return w32.ImageList_RemoveAll(im.handle) } func (im *ImageList) Remove(i int) bool { return w32.ImageList_Remove(im.handle, i) } ================================================ FILE: imageview.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. */ package winc import "github.com/tadvi/winc/w32" type ImageView struct { ControlBase bmp *Bitmap } func NewImageView(parent Controller) *ImageView { iv := new(ImageView) iv.InitWindow("winc_ImageView", parent, w32.WS_EX_CONTROLPARENT, w32.WS_CHILD|w32.WS_VISIBLE) RegMsgHandler(iv) iv.SetFont(DefaultFont) iv.SetText("") iv.SetSize(200, 65) return iv } func (iv *ImageView) DrawImageFile(filepath string) error { bmp, err := NewBitmapFromFile(filepath, RGB(255, 255, 0)) if err != nil { return err } iv.bmp = bmp return nil } func (iv *ImageView) DrawImage(bmp *Bitmap) { iv.bmp = bmp } func (iv *ImageView) WndProc(msg uint32, wparam, lparam uintptr) uintptr { switch msg { case w32.WM_SIZE, w32.WM_SIZING: iv.Invalidate(true) case w32.WM_ERASEBKGND: return 1 // important case w32.WM_PAINT: if iv.bmp != nil { canvas := NewCanvasFromHwnd(iv.hwnd) defer canvas.Dispose() iv.SetSize(iv.bmp.Size()) canvas.DrawBitmap(iv.bmp, 0, 0) } } return w32.DefWindowProc(iv.hwnd, msg, wparam, lparam) } ================================================ FILE: imageviewbox.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. */ package winc import ( "fmt" "time" "github.com/tadvi/winc/w32" ) type direction int const ( DirNone direction = iota DirX DirY DirX2 DirY2 ) var ImageBoxPen = NewPen(w32.PS_GEOMETRIC, 2, NewSolidColorBrush(RGB(140, 140, 220))) var ImageBoxHiPen = NewPen(w32.PS_GEOMETRIC, 2, NewSolidColorBrush(RGB(220, 140, 140))) var ImageBoxMarkBrush = NewSolidColorBrush(RGB(40, 40, 40)) var ImageBoxMarkPen = NewPen(w32.PS_GEOMETRIC, 2, ImageBoxMarkBrush) type ImageBox struct { Name string Type int X, Y, X2, Y2 int underMouse bool // dynamic value } func (b *ImageBox) Rect() *Rect { return NewRect(b.X, b.Y, b.X2, b.Y2) } // ImageViewBox is image view with boxes. type ImageViewBox struct { ControlBase bmp *Bitmap mouseLeft bool modified bool // used by GUI to see if any image box modified add bool Boxes []*ImageBox // might be persisted to file dragBox *ImageBox selBox *ImageBox dragStartX, dragStartY int resize direction onSelectedChange EventManager onAdd EventManager onModify EventManager } func NewImageViewBox(parent Controller) *ImageViewBox { iv := new(ImageViewBox) iv.InitWindow("winc_ImageViewBox", parent, w32.WS_EX_CONTROLPARENT, w32.WS_CHILD|w32.WS_VISIBLE) RegMsgHandler(iv) iv.SetFont(DefaultFont) iv.SetText("") iv.SetSize(200, 65) return iv } func (iv *ImageViewBox) OnSelectedChange() *EventManager { return &iv.onSelectedChange } func (iv *ImageViewBox) OnAdd() *EventManager { return &iv.onAdd } func (iv *ImageViewBox) OnModify() *EventManager { return &iv.onModify } func (iv *ImageViewBox) IsModified() bool { return iv.modified } func (iv *ImageViewBox) SetModified(modified bool) { iv.modified = modified } func (iv *ImageViewBox) IsLoaded() bool { return iv.bmp != nil } func (iv *ImageViewBox) AddMode() bool { return iv.add } func (iv *ImageViewBox) SetAddMode(add bool) { iv.add = add } func (iv *ImageViewBox) HasSelected() bool { return iv.selBox != nil && iv.bmp != nil } func (iv *ImageViewBox) wasModified() { iv.modified = true iv.onModify.Fire(NewEvent(iv, nil)) } func (iv *ImageViewBox) DeleteSelected() { if iv.selBox != nil { for i, b := range iv.Boxes { if b == iv.selBox { iv.Boxes = append(iv.Boxes[:i], iv.Boxes[i+1:]...) iv.selBox = nil iv.Invalidate(true) iv.wasModified() iv.onSelectedChange.Fire(NewEvent(iv, nil)) return } } } } func (iv *ImageViewBox) NameSelected() string { if iv.selBox != nil { return iv.selBox.Name } return "" } func (iv *ImageViewBox) SetNameSelected(name string) { if iv.selBox != nil { iv.selBox.Name = name iv.wasModified() } } func (iv *ImageViewBox) TypeSelected() int { if iv.selBox != nil { return iv.selBox.Type } return 0 } func (iv *ImageViewBox) SetTypeSelected(typ int) { if iv.selBox != nil { iv.selBox.Type = typ iv.wasModified() } } func (ib *ImageViewBox) updateHighlight(x, y int) bool { var changed bool for _, b := range ib.Boxes { under := x >= b.X && y >= b.Y && x <= b.X2 && y <= b.Y2 if b.underMouse != under { changed = true } b.underMouse = under /*if sel { break // allow only one to be underMouse }*/ } return changed } func (ib *ImageViewBox) isUnderMouse(x, y int) *ImageBox { for _, b := range ib.Boxes { if x >= b.X && y >= b.Y && x <= b.X2 && y <= b.Y2 { return b } } return nil } func (ib *ImageViewBox) getCursor(x, y int) uint16 { for _, b := range ib.Boxes { switch d := ib.resizingDirection(b, x, y); d { case DirY, DirY2: return w32.IDC_SIZENS case DirX, DirX2: return w32.IDC_SIZEWE } // w32.IDC_SIZEALL or w32.IDC_SIZE for resize } return w32.IDC_ARROW } func (ib *ImageViewBox) resizingDirection(b *ImageBox, x, y int) direction { if b == nil { return DirNone } switch { case b.X == x || b.X == x-1 || b.X == x+1: return DirX case b.X2 == x || b.X2 == x-1 || b.X2 == x+1: return DirX2 case b.Y == y || b.Y == y-1 || b.Y == y+1: return DirY case b.Y2 == y || b.Y2 == y-1 || b.Y2 == y+1: return DirY2 } return DirNone } func (ib *ImageViewBox) resizeToDirection(b *ImageBox, x, y int) { switch ib.resize { case DirX: b.X = x case DirY: b.Y = y case DirX2: b.X2 = x case DirY2: b.Y2 = y } } func (ib *ImageViewBox) drag(b *ImageBox, x, y int) { w, h := b.X2-b.X, b.Y2-b.Y nx := ib.dragStartX - b.X ny := ib.dragStartY - b.Y b.X = x - nx b.Y = y - ny b.X2 = b.X + w b.Y2 = b.Y + h ib.dragStartX, ib.dragStartY = x, y } func (iv *ImageViewBox) DrawImageFile(filepath string) (err error) { iv.bmp, err = NewBitmapFromFile(filepath, RGB(255, 255, 0)) iv.selBox = nil iv.modified = false iv.onSelectedChange.Fire(NewEvent(iv, nil)) iv.onModify.Fire(NewEvent(iv, nil)) return } func (iv *ImageViewBox) DrawImage(bmp *Bitmap) { iv.bmp = bmp iv.selBox = nil iv.modified = false iv.onSelectedChange.Fire(NewEvent(iv, nil)) iv.onModify.Fire(NewEvent(iv, nil)) } func (iv *ImageViewBox) WndProc(msg uint32, wparam, lparam uintptr) uintptr { switch msg { case w32.WM_SIZE, w32.WM_SIZING: iv.Invalidate(true) case w32.WM_ERASEBKGND: return 1 // important case w32.WM_CREATE: internalTrackMouseEvent(iv.hwnd) case w32.WM_PAINT: if iv.bmp != nil { canvas := NewCanvasFromHwnd(iv.hwnd) defer canvas.Dispose() iv.SetSize(iv.bmp.Size()) canvas.DrawBitmap(iv.bmp, 0, 0) for _, b := range iv.Boxes { // old code used NewSystemColorBrush(w32.COLOR_BTNFACE) w32.COLOR_WINDOW pen := ImageBoxPen if b.underMouse { pen = ImageBoxHiPen } canvas.DrawRect(b.Rect(), pen) if b == iv.selBox { x1 := []int{b.X, b.X2, b.X2, b.X} y1 := []int{b.Y, b.Y, b.Y2, b.Y2} for i := 0; i < len(x1); i++ { r := NewRect(x1[i]-2, y1[i]-2, x1[i]+2, y1[i]+2) canvas.DrawFillRect(r, ImageBoxMarkPen, ImageBoxMarkBrush) } } } } case w32.WM_MOUSEMOVE: x, y := genPoint(lparam) if iv.dragBox != nil { if iv.resize == DirNone { iv.drag(iv.dragBox, x, y) iv.wasModified() } else { iv.resizeToDirection(iv.dragBox, x, y) iv.wasModified() } iv.Invalidate(true) } else { if !iv.add { w32.SetCursor(w32.LoadCursor(0, w32.MakeIntResource(iv.getCursor(x, y)))) } // do not call repaint if underMouse item did not change. if iv.updateHighlight(x, y) { iv.Invalidate(true) } } if iv.mouseLeft { internalTrackMouseEvent(iv.hwnd) iv.mouseLeft = false } case w32.WM_MOUSELEAVE: iv.dragBox = nil iv.mouseLeft = true iv.updateHighlight(-1, -1) iv.Invalidate(true) case w32.WM_LBUTTONUP: iv.dragBox = nil case w32.WM_LBUTTONDOWN: x, y := genPoint(lparam) if iv.add { now := time.Now() s := fmt.Sprintf("field%s", now.Format("020405")) b := &ImageBox{Name: s, underMouse: true, X: x, Y: y, X2: x + 150, Y2: y + 30} iv.Boxes = append(iv.Boxes, b) iv.selBox = b iv.wasModified() iv.onAdd.Fire(NewEvent(iv, nil)) } else { iv.dragBox = iv.isUnderMouse(x, y) iv.selBox = iv.dragBox iv.dragStartX, iv.dragStartY = x, y iv.resize = iv.resizingDirection(iv.dragBox, x, y) } iv.Invalidate(true) iv.onSelectedChange.Fire(NewEvent(iv, nil)) case w32.WM_RBUTTONDOWN: } return w32.DefWindowProc(iv.hwnd, msg, wparam, lparam) } ================================================ FILE: init.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. * Copyright (C) 2010-2013 Allen Dang. All Rights Reserved. */ package winc import ( "github.com/tadvi/winc/w32" ) func init() { gControllerRegistry = make(map[w32.HWND]Controller) gRegisteredClasses = make([]string, 0) var si w32.GdiplusStartupInput si.GdiplusVersion = 1 w32.GdiplusStartup(&si, nil) } ================================================ FILE: keyboard.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. * Copyright (C) 2010-2013 Allen Dang. All Rights Reserved. */ package winc import ( "bytes" "github.com/tadvi/winc/w32" ) type Key uint16 func (k Key) String() string { return key2string[k] } const ( KeyLButton Key = w32.VK_LBUTTON KeyRButton Key = w32.VK_RBUTTON KeyCancel Key = w32.VK_CANCEL KeyMButton Key = w32.VK_MBUTTON KeyXButton1 Key = w32.VK_XBUTTON1 KeyXButton2 Key = w32.VK_XBUTTON2 KeyBack Key = w32.VK_BACK KeyTab Key = w32.VK_TAB KeyClear Key = w32.VK_CLEAR KeyReturn Key = w32.VK_RETURN KeyShift Key = w32.VK_SHIFT KeyControl Key = w32.VK_CONTROL KeyAlt Key = w32.VK_MENU KeyMenu Key = w32.VK_MENU KeyPause Key = w32.VK_PAUSE KeyCapital Key = w32.VK_CAPITAL KeyKana Key = w32.VK_KANA KeyHangul Key = w32.VK_HANGUL KeyJunja Key = w32.VK_JUNJA KeyFinal Key = w32.VK_FINAL KeyHanja Key = w32.VK_HANJA KeyKanji Key = w32.VK_KANJI KeyEscape Key = w32.VK_ESCAPE KeyConvert Key = w32.VK_CONVERT KeyNonconvert Key = w32.VK_NONCONVERT KeyAccept Key = w32.VK_ACCEPT KeyModeChange Key = w32.VK_MODECHANGE KeySpace Key = w32.VK_SPACE KeyPrior Key = w32.VK_PRIOR KeyNext Key = w32.VK_NEXT KeyEnd Key = w32.VK_END KeyHome Key = w32.VK_HOME KeyLeft Key = w32.VK_LEFT KeyUp Key = w32.VK_UP KeyRight Key = w32.VK_RIGHT KeyDown Key = w32.VK_DOWN KeySelect Key = w32.VK_SELECT KeyPrint Key = w32.VK_PRINT KeyExecute Key = w32.VK_EXECUTE KeySnapshot Key = w32.VK_SNAPSHOT KeyInsert Key = w32.VK_INSERT KeyDelete Key = w32.VK_DELETE KeyHelp Key = w32.VK_HELP Key0 Key = 0x30 Key1 Key = 0x31 Key2 Key = 0x32 Key3 Key = 0x33 Key4 Key = 0x34 Key5 Key = 0x35 Key6 Key = 0x36 Key7 Key = 0x37 Key8 Key = 0x38 Key9 Key = 0x39 KeyA Key = 0x41 KeyB Key = 0x42 KeyC Key = 0x43 KeyD Key = 0x44 KeyE Key = 0x45 KeyF Key = 0x46 KeyG Key = 0x47 KeyH Key = 0x48 KeyI Key = 0x49 KeyJ Key = 0x4A KeyK Key = 0x4B KeyL Key = 0x4C KeyM Key = 0x4D KeyN Key = 0x4E KeyO Key = 0x4F KeyP Key = 0x50 KeyQ Key = 0x51 KeyR Key = 0x52 KeyS Key = 0x53 KeyT Key = 0x54 KeyU Key = 0x55 KeyV Key = 0x56 KeyW Key = 0x57 KeyX Key = 0x58 KeyY Key = 0x59 KeyZ Key = 0x5A KeyLWIN Key = w32.VK_LWIN KeyRWIN Key = w32.VK_RWIN KeyApps Key = w32.VK_APPS KeySleep Key = w32.VK_SLEEP KeyNumpad0 Key = w32.VK_NUMPAD0 KeyNumpad1 Key = w32.VK_NUMPAD1 KeyNumpad2 Key = w32.VK_NUMPAD2 KeyNumpad3 Key = w32.VK_NUMPAD3 KeyNumpad4 Key = w32.VK_NUMPAD4 KeyNumpad5 Key = w32.VK_NUMPAD5 KeyNumpad6 Key = w32.VK_NUMPAD6 KeyNumpad7 Key = w32.VK_NUMPAD7 KeyNumpad8 Key = w32.VK_NUMPAD8 KeyNumpad9 Key = w32.VK_NUMPAD9 KeyMultiply Key = w32.VK_MULTIPLY KeyAdd Key = w32.VK_ADD KeySeparator Key = w32.VK_SEPARATOR KeySubtract Key = w32.VK_SUBTRACT KeyDecimal Key = w32.VK_DECIMAL KeyDivide Key = w32.VK_DIVIDE KeyF1 Key = w32.VK_F1 KeyF2 Key = w32.VK_F2 KeyF3 Key = w32.VK_F3 KeyF4 Key = w32.VK_F4 KeyF5 Key = w32.VK_F5 KeyF6 Key = w32.VK_F6 KeyF7 Key = w32.VK_F7 KeyF8 Key = w32.VK_F8 KeyF9 Key = w32.VK_F9 KeyF10 Key = w32.VK_F10 KeyF11 Key = w32.VK_F11 KeyF12 Key = w32.VK_F12 KeyF13 Key = w32.VK_F13 KeyF14 Key = w32.VK_F14 KeyF15 Key = w32.VK_F15 KeyF16 Key = w32.VK_F16 KeyF17 Key = w32.VK_F17 KeyF18 Key = w32.VK_F18 KeyF19 Key = w32.VK_F19 KeyF20 Key = w32.VK_F20 KeyF21 Key = w32.VK_F21 KeyF22 Key = w32.VK_F22 KeyF23 Key = w32.VK_F23 KeyF24 Key = w32.VK_F24 KeyNumlock Key = w32.VK_NUMLOCK KeyScroll Key = w32.VK_SCROLL KeyLShift Key = w32.VK_LSHIFT KeyRShift Key = w32.VK_RSHIFT KeyLControl Key = w32.VK_LCONTROL KeyRControl Key = w32.VK_RCONTROL KeyLAlt Key = w32.VK_LMENU KeyLMenu Key = w32.VK_LMENU KeyRAlt Key = w32.VK_RMENU KeyRMenu Key = w32.VK_RMENU KeyBrowserBack Key = w32.VK_BROWSER_BACK KeyBrowserForward Key = w32.VK_BROWSER_FORWARD KeyBrowserRefresh Key = w32.VK_BROWSER_REFRESH KeyBrowserStop Key = w32.VK_BROWSER_STOP KeyBrowserSearch Key = w32.VK_BROWSER_SEARCH KeyBrowserFavorites Key = w32.VK_BROWSER_FAVORITES KeyBrowserHome Key = w32.VK_BROWSER_HOME KeyVolumeMute Key = w32.VK_VOLUME_MUTE KeyVolumeDown Key = w32.VK_VOLUME_DOWN KeyVolumeUp Key = w32.VK_VOLUME_UP KeyMediaNextTrack Key = w32.VK_MEDIA_NEXT_TRACK KeyMediaPrevTrack Key = w32.VK_MEDIA_PREV_TRACK KeyMediaStop Key = w32.VK_MEDIA_STOP KeyMediaPlayPause Key = w32.VK_MEDIA_PLAY_PAUSE KeyLaunchMail Key = w32.VK_LAUNCH_MAIL KeyLaunchMediaSelect Key = w32.VK_LAUNCH_MEDIA_SELECT KeyLaunchApp1 Key = w32.VK_LAUNCH_APP1 KeyLaunchApp2 Key = w32.VK_LAUNCH_APP2 KeyOEM1 Key = w32.VK_OEM_1 KeyOEMPlus Key = w32.VK_OEM_PLUS KeyOEMComma Key = w32.VK_OEM_COMMA KeyOEMMinus Key = w32.VK_OEM_MINUS KeyOEMPeriod Key = w32.VK_OEM_PERIOD KeyOEM2 Key = w32.VK_OEM_2 KeyOEM3 Key = w32.VK_OEM_3 KeyOEM4 Key = w32.VK_OEM_4 KeyOEM5 Key = w32.VK_OEM_5 KeyOEM6 Key = w32.VK_OEM_6 KeyOEM7 Key = w32.VK_OEM_7 KeyOEM8 Key = w32.VK_OEM_8 KeyOEM102 Key = w32.VK_OEM_102 KeyProcessKey Key = w32.VK_PROCESSKEY KeyPacket Key = w32.VK_PACKET KeyAttn Key = w32.VK_ATTN KeyCRSel Key = w32.VK_CRSEL KeyEXSel Key = w32.VK_EXSEL KeyErEOF Key = w32.VK_EREOF KeyPlay Key = w32.VK_PLAY KeyZoom Key = w32.VK_ZOOM KeyNoName Key = w32.VK_NONAME KeyPA1 Key = w32.VK_PA1 KeyOEMClear Key = w32.VK_OEM_CLEAR ) var key2string = map[Key]string{ KeyLButton: "LButton", KeyRButton: "RButton", KeyCancel: "Cancel", KeyMButton: "MButton", KeyXButton1: "XButton1", KeyXButton2: "XButton2", KeyBack: "Back", KeyTab: "Tab", KeyClear: "Clear", KeyReturn: "Return", KeyShift: "Shift", KeyControl: "Control", KeyAlt: "Alt / Menu", KeyPause: "Pause", KeyCapital: "Capital", KeyKana: "Kana / Hangul", KeyJunja: "Junja", KeyFinal: "Final", KeyHanja: "Hanja / Kanji", KeyEscape: "Escape", KeyConvert: "Convert", KeyNonconvert: "Nonconvert", KeyAccept: "Accept", KeyModeChange: "ModeChange", KeySpace: "Space", KeyPrior: "Prior", KeyNext: "Next", KeyEnd: "End", KeyHome: "Home", KeyLeft: "Left", KeyUp: "Up", KeyRight: "Right", KeyDown: "Down", KeySelect: "Select", KeyPrint: "Print", KeyExecute: "Execute", KeySnapshot: "Snapshot", KeyInsert: "Insert", KeyDelete: "Delete", KeyHelp: "Help", Key0: "0", Key1: "1", Key2: "2", Key3: "3", Key4: "4", Key5: "5", Key6: "6", Key7: "7", Key8: "8", Key9: "9", KeyA: "A", KeyB: "B", KeyC: "C", KeyD: "D", KeyE: "E", KeyF: "F", KeyG: "G", KeyH: "H", KeyI: "I", KeyJ: "J", KeyK: "K", KeyL: "L", KeyM: "M", KeyN: "N", KeyO: "O", KeyP: "P", KeyQ: "Q", KeyR: "R", KeyS: "S", KeyT: "T", KeyU: "U", KeyV: "V", KeyW: "W", KeyX: "X", KeyY: "Y", KeyZ: "Z", KeyLWIN: "LWIN", KeyRWIN: "RWIN", KeyApps: "Apps", KeySleep: "Sleep", KeyNumpad0: "Numpad0", KeyNumpad1: "Numpad1", KeyNumpad2: "Numpad2", KeyNumpad3: "Numpad3", KeyNumpad4: "Numpad4", KeyNumpad5: "Numpad5", KeyNumpad6: "Numpad6", KeyNumpad7: "Numpad7", KeyNumpad8: "Numpad8", KeyNumpad9: "Numpad9", KeyMultiply: "Multiply", KeyAdd: "Add", KeySeparator: "Separator", KeySubtract: "Subtract", KeyDecimal: "Decimal", KeyDivide: "Divide", KeyF1: "F1", KeyF2: "F2", KeyF3: "F3", KeyF4: "F4", KeyF5: "F5", KeyF6: "F6", KeyF7: "F7", KeyF8: "F8", KeyF9: "F9", KeyF10: "F10", KeyF11: "F11", KeyF12: "F12", KeyF13: "F13", KeyF14: "F14", KeyF15: "F15", KeyF16: "F16", KeyF17: "F17", KeyF18: "F18", KeyF19: "F19", KeyF20: "F20", KeyF21: "F21", KeyF22: "F22", KeyF23: "F23", KeyF24: "F24", KeyNumlock: "Numlock", KeyScroll: "Scroll", KeyLShift: "LShift", KeyRShift: "RShift", KeyLControl: "LControl", KeyRControl: "RControl", KeyLMenu: "LMenu", KeyRMenu: "RMenu", KeyBrowserBack: "BrowserBack", KeyBrowserForward: "BrowserForward", KeyBrowserRefresh: "BrowserRefresh", KeyBrowserStop: "BrowserStop", KeyBrowserSearch: "BrowserSearch", KeyBrowserFavorites: "BrowserFavorites", KeyBrowserHome: "BrowserHome", KeyVolumeMute: "VolumeMute", KeyVolumeDown: "VolumeDown", KeyVolumeUp: "VolumeUp", KeyMediaNextTrack: "MediaNextTrack", KeyMediaPrevTrack: "MediaPrevTrack", KeyMediaStop: "MediaStop", KeyMediaPlayPause: "MediaPlayPause", KeyLaunchMail: "LaunchMail", KeyLaunchMediaSelect: "LaunchMediaSelect", KeyLaunchApp1: "LaunchApp1", KeyLaunchApp2: "LaunchApp2", KeyOEM1: "OEM1", KeyOEMPlus: "OEMPlus", KeyOEMComma: "OEMComma", KeyOEMMinus: "OEMMinus", KeyOEMPeriod: "OEMPeriod", KeyOEM2: "OEM2", KeyOEM3: "OEM3", KeyOEM4: "OEM4", KeyOEM5: "OEM5", KeyOEM6: "OEM6", KeyOEM7: "OEM7", KeyOEM8: "OEM8", KeyOEM102: "OEM102", KeyProcessKey: "ProcessKey", KeyPacket: "Packet", KeyAttn: "Attn", KeyCRSel: "CRSel", KeyEXSel: "EXSel", KeyErEOF: "ErEOF", KeyPlay: "Play", KeyZoom: "Zoom", KeyNoName: "NoName", KeyPA1: "PA1", KeyOEMClear: "OEMClear", } type Modifiers byte func (m Modifiers) String() string { return modifiers2string[m] } var modifiers2string = map[Modifiers]string{ ModShift: "Shift", ModControl: "Ctrl", ModControl | ModShift: "Ctrl+Shift", ModAlt: "Alt", ModAlt | ModShift: "Alt+Shift", ModAlt | ModControl | ModShift: "Alt+Ctrl+Shift", } const ( ModShift Modifiers = 1 << iota ModControl ModAlt ) func ModifiersDown() Modifiers { var m Modifiers if ShiftDown() { m |= ModShift } if ControlDown() { m |= ModControl } if AltDown() { m |= ModAlt } return m } type Shortcut struct { Modifiers Modifiers Key Key } func (s Shortcut) String() string { m := s.Modifiers.String() if m == "" { return s.Key.String() } b := new(bytes.Buffer) b.WriteString(m) b.WriteRune('+') b.WriteString(s.Key.String()) return b.String() } func AltDown() bool { return w32.GetKeyState(int32(KeyAlt))>>15 != 0 } func ControlDown() bool { return w32.GetKeyState(int32(KeyControl))>>15 != 0 } func ShiftDown() bool { return w32.GetKeyState(int32(KeyShift))>>15 != 0 } ================================================ FILE: label.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. */ package winc import ( "github.com/tadvi/winc/w32" ) type Label struct { ControlBase } func NewLabel(parent Controller) *Label { lb := new(Label) lb.InitControl("STATIC", parent, 0, w32.WS_CHILD|w32.WS_VISIBLE|w32.SS_LEFTNOWORDWRAP) RegMsgHandler(lb) lb.SetFont(DefaultFont) lb.SetText("Label") lb.SetSize(100, 25) return lb } func (lb *Label) WndProc(msg uint32, wparam, lparam uintptr) uintptr { return w32.DefWindowProc(lb.hwnd, msg, wparam, lparam) } ================================================ FILE: layout.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. */ package winc import ( "encoding/json" "fmt" "io" "os" "sort" "unsafe" "github.com/tadvi/winc/w32" ) // Dockable component must satisfy interface to be docked. type Dockable interface { Handle() w32.HWND Pos() (x, y int) Width() int Height() int Visible() bool SetPos(x, y int) SetSize(width, height int) OnMouseMove() *EventManager OnLBUp() *EventManager } // DockAllow is window, panel or other component that satisfies interface. type DockAllow interface { Handle() w32.HWND ClientWidth() int ClientHeight() int SetLayout(mng LayoutManager) } // Various layout managers type Direction int const ( Top Direction = iota Bottom Left Right Fill ) type LayoutControl struct { child Dockable dir Direction } type LayoutControls []*LayoutControl type SimpleDock struct { parent DockAllow layoutCtl LayoutControls loadedState bool } // DockState gets saved and loaded from json type CtlState struct { X, Y, Width, Height int } type LayoutState struct { WindowState string Controls []*CtlState } func (lc LayoutControls) Len() int { return len(lc) } func (lc LayoutControls) Swap(i, j int) { lc[i], lc[j] = lc[j], lc[i] } func (lc LayoutControls) Less(i, j int) bool { return lc[i].dir < lc[j].dir } func NewSimpleDock(parent DockAllow) *SimpleDock { d := &SimpleDock{parent: parent} parent.SetLayout(d) return d } // Layout management for the child controls. func (sd *SimpleDock) Dock(child Dockable, dir Direction) { sd.layoutCtl = append(sd.layoutCtl, &LayoutControl{child, dir}) } // SaveState of the layout. Only works for Docks with parent set to main form. func (sd *SimpleDock) SaveState(w io.Writer) error { var ls LayoutState var wp w32.WINDOWPLACEMENT wp.Length = uint32(unsafe.Sizeof(wp)) if !w32.GetWindowPlacement(sd.parent.Handle(), &wp) { return fmt.Errorf("GetWindowPlacement failed") } ls.WindowState = fmt.Sprint( wp.Flags, wp.ShowCmd, wp.PtMinPosition.X, wp.PtMinPosition.Y, wp.PtMaxPosition.X, wp.PtMaxPosition.Y, wp.RcNormalPosition.Left, wp.RcNormalPosition.Top, wp.RcNormalPosition.Right, wp.RcNormalPosition.Bottom) for _, c := range sd.layoutCtl { x, y := c.child.Pos() w, h := c.child.Width(), c.child.Height() ctl := &CtlState{X: x, Y: y, Width: w, Height: h} ls.Controls = append(ls.Controls, ctl) } if err := json.NewEncoder(w).Encode(ls); err != nil { return err } return nil } // LoadState of the layout. Only works for Docks with parent set to main form. func (sd *SimpleDock) LoadState(r io.Reader) error { var ls LayoutState if err := json.NewDecoder(r).Decode(&ls); err != nil { return err } var wp w32.WINDOWPLACEMENT if _, err := fmt.Sscan(ls.WindowState, &wp.Flags, &wp.ShowCmd, &wp.PtMinPosition.X, &wp.PtMinPosition.Y, &wp.PtMaxPosition.X, &wp.PtMaxPosition.Y, &wp.RcNormalPosition.Left, &wp.RcNormalPosition.Top, &wp.RcNormalPosition.Right, &wp.RcNormalPosition.Bottom); err != nil { return err } wp.Length = uint32(unsafe.Sizeof(wp)) if !w32.SetWindowPlacement(sd.parent.Handle(), &wp) { return fmt.Errorf("SetWindowPlacement failed") } // if number of controls in the saved layout does not match // current number on screen - something changed and we do not reload // rest of control sizes from json if len(sd.layoutCtl) != len(ls.Controls) { return nil } for i, c := range sd.layoutCtl { c.child.SetPos(ls.Controls[i].X, ls.Controls[i].Y) c.child.SetSize(ls.Controls[i].Width, ls.Controls[i].Height) } return nil } // SaveStateFile convenience function. func (sd *SimpleDock) SaveStateFile(file string) error { f, err := os.Create(file) if err != nil { return err } return sd.SaveState(f) } // LoadStateFile loads state ignores error if file is not found. func (sd *SimpleDock) LoadStateFile(file string) error { f, err := os.Open(file) if err != nil { return nil // if file is not found or not accessible ignore it } return sd.LoadState(f) } // Update is called to resize child items based on layout directions. func (sd *SimpleDock) Update() { sort.Stable(sd.layoutCtl) x, y := 0, 0 w, h := sd.parent.ClientWidth(), sd.parent.ClientHeight() winw, winh := w, h for _, c := range sd.layoutCtl { // Non visible controls do not preserve space. if !c.child.Visible() { continue } switch c.dir { case Top: c.child.SetPos(x, y) c.child.SetSize(w, c.child.Height()) h -= c.child.Height() y += c.child.Height() case Bottom: c.child.SetPos(x, winh-c.child.Height()) c.child.SetSize(w, c.child.Height()) h -= c.child.Height() winh -= c.child.Height() case Left: c.child.SetPos(x, y) c.child.SetSize(c.child.Width(), h) w -= c.child.Width() x += c.child.Width() case Right: c.child.SetPos(winw-c.child.Width(), y) c.child.SetSize(c.child.Width(), h) w -= c.child.Width() winw -= c.child.Width() case Fill: // fill available space c.child.SetPos(x, y) c.child.SetSize(w, h) } //c.child.Invalidate(true) } } ================================================ FILE: listview.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. */ package winc import ( "errors" "fmt" "syscall" "unsafe" "github.com/tadvi/winc/w32" ) // ListItem represents an item in a ListView widget. type ListItem interface { Text() []string // Text returns the text of the multi-column item. ImageIndex() int // ImageIndex is used only if SetImageList is called on the listview } // ListItemChecker is used for checkbox support in ListView. type ListItemChecker interface { Checked() bool SetChecked(checked bool) } // ListItemSetter is used in OnEndLabelEdit event. type ListItemSetter interface { SetText(s string) // set first item in the array via LabelEdit event } // StringListItem is helper for basic string lists. type StringListItem struct { ID int Data string Check bool } func (s StringListItem) Text() []string { return []string{s.Data} } func (s StringListItem) Checked() bool { return s.Check } func (s StringListItem) SetChecked(checked bool) { s.Check = checked } func (s StringListItem) ImageIndex() int { return 0 } type ListView struct { ControlBase iml *ImageList lastIndex int cols int // count of columns item2Handle map[ListItem]uintptr handle2Item map[uintptr]ListItem onEndLabelEdit EventManager onDoubleClick EventManager onClick EventManager onKeyDown EventManager onItemChanging EventManager onItemChanged EventManager onCheckChanged EventManager onViewChange EventManager onEndScroll EventManager } func NewListView(parent Controller) *ListView { lv := new(ListView) lv.InitControl("SysListView32", parent /*w32.WS_EX_CLIENTEDGE*/, 0, w32.WS_CHILD|w32.WS_VISIBLE|w32.WS_TABSTOP|w32.LVS_REPORT|w32.LVS_EDITLABELS|w32.LVS_SHOWSELALWAYS) lv.item2Handle = make(map[ListItem]uintptr) lv.handle2Item = make(map[uintptr]ListItem) RegMsgHandler(lv) lv.SetFont(DefaultFont) lv.SetSize(200, 400) if err := lv.SetTheme("Explorer"); err != nil { // theme error is ignored } return lv } // FIXME: Changes the state of an item in a list-view control. Refer LVM_SETITEMSTATE message. func (lv *ListView) setItemState(i int, state, mask uint) { var item w32.LVITEM item.State, item.StateMask = uint32(state), uint32(mask) w32.SendMessage(lv.hwnd, w32.LVM_SETITEMSTATE, uintptr(i), uintptr(unsafe.Pointer(&item))) } func (lv *ListView) EnableSingleSelect(enable bool) { ToggleStyle(lv.hwnd, enable, w32.LVS_SINGLESEL) } func (lv *ListView) EnableSortHeader(enable bool) { ToggleStyle(lv.hwnd, enable, w32.LVS_NOSORTHEADER) } func (lv *ListView) EnableSortAscending(enable bool) { ToggleStyle(lv.hwnd, enable, w32.LVS_SORTASCENDING) } func (lv *ListView) EnableEditLabels(enable bool) { ToggleStyle(lv.hwnd, enable, w32.LVS_EDITLABELS) } func (lv *ListView) EnableFullRowSelect(enable bool) { if enable { w32.SendMessage(lv.hwnd, w32.LVM_SETEXTENDEDLISTVIEWSTYLE, 0, w32.LVS_EX_FULLROWSELECT) } else { w32.SendMessage(lv.hwnd, w32.LVM_SETEXTENDEDLISTVIEWSTYLE, w32.LVS_EX_FULLROWSELECT, 0) } } func (lv *ListView) EnableDoubleBuffer(enable bool) { if enable { w32.SendMessage(lv.hwnd, w32.LVM_SETEXTENDEDLISTVIEWSTYLE, 0, w32.LVS_EX_DOUBLEBUFFER) } else { w32.SendMessage(lv.hwnd, w32.LVM_SETEXTENDEDLISTVIEWSTYLE, w32.LVS_EX_DOUBLEBUFFER, 0) } } func (lv *ListView) EnableHotTrack(enable bool) { if enable { w32.SendMessage(lv.hwnd, w32.LVM_SETEXTENDEDLISTVIEWSTYLE, 0, w32.LVS_EX_TRACKSELECT) } else { w32.SendMessage(lv.hwnd, w32.LVM_SETEXTENDEDLISTVIEWSTYLE, w32.LVS_EX_TRACKSELECT, 0) } } func (lv *ListView) SetItemCount(count int) bool { return w32.SendMessage(lv.hwnd, w32.LVM_SETITEMCOUNT, uintptr(count), 0) != 0 } func (lv *ListView) ItemCount() int { return int(w32.SendMessage(lv.hwnd, w32.LVM_GETITEMCOUNT, 0, 0)) } func (lv *ListView) ItemAt(x, y int) ListItem { hti := w32.LVHITTESTINFO{Pt: w32.POINT{int32(x), int32(y)}} w32.SendMessage(lv.hwnd, w32.LVM_HITTEST, 0, uintptr(unsafe.Pointer(&hti))) return lv.findItemByIndex(int(hti.IItem)) } func (lv *ListView) Items() (list []ListItem) { for item := range lv.item2Handle { list = append(list, item) } return list } func (lv *ListView) AddColumn(caption string, width int) { var lc w32.LVCOLUMN lc.Mask = w32.LVCF_TEXT if width != 0 { lc.Mask = lc.Mask | w32.LVCF_WIDTH lc.Cx = int32(width) } lc.PszText = syscall.StringToUTF16Ptr(caption) lv.insertLvColumn(&lc, lv.cols) lv.cols++ } // StretchLastColumn makes the last column take up all remaining horizontal // space of the *ListView. // The effect of this is not persistent. func (lv *ListView) StretchLastColumn() error { if lv.cols == 0 { return nil } if w32.SendMessage(lv.hwnd, w32.LVM_SETCOLUMNWIDTH, uintptr(lv.cols-1), w32.LVSCW_AUTOSIZE_USEHEADER) == 0 { //panic("LVM_SETCOLUMNWIDTH failed") } return nil } // CheckBoxes returns if the *TableView has check boxes. func (lv *ListView) CheckBoxes() bool { return w32.SendMessage(lv.hwnd, w32.LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0)&w32.LVS_EX_CHECKBOXES > 0 } // SetCheckBoxes sets if the *TableView has check boxes. func (lv *ListView) SetCheckBoxes(value bool) { exStyle := w32.SendMessage(lv.hwnd, w32.LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0) oldStyle := exStyle if value { exStyle |= w32.LVS_EX_CHECKBOXES } else { exStyle &^= w32.LVS_EX_CHECKBOXES } if exStyle != oldStyle { w32.SendMessage(lv.hwnd, w32.LVM_SETEXTENDEDLISTVIEWSTYLE, 0, exStyle) } mask := w32.SendMessage(lv.hwnd, w32.LVM_GETCALLBACKMASK, 0, 0) if value { mask |= w32.LVIS_STATEIMAGEMASK } else { mask &^= w32.LVIS_STATEIMAGEMASK } if w32.SendMessage(lv.hwnd, w32.LVM_SETCALLBACKMASK, mask, 0) == w32.FALSE { panic("SendMessage(LVM_SETCALLBACKMASK)") } } func (lv *ListView) applyImage(lc *w32.LVITEM, imIndex int) { if lv.iml != nil { lc.Mask |= w32.LVIF_IMAGE lc.IImage = int32(imIndex) } } func (lv *ListView) AddItem(item ListItem) { lv.InsertItem(item, lv.ItemCount()) } func (lv *ListView) InsertItem(item ListItem, index int) { text := item.Text() li := &w32.LVITEM{ Mask: w32.LVIF_TEXT | w32.LVIF_PARAM, PszText: syscall.StringToUTF16Ptr(text[0]), IItem: int32(index), } lv.lastIndex++ ix := new(int) *ix = lv.lastIndex li.LParam = uintptr(*ix) lv.handle2Item[li.LParam] = item lv.item2Handle[item] = li.LParam lv.applyImage(li, item.ImageIndex()) lv.insertLvItem(li) for i := 1; i < len(text); i++ { li.Mask = w32.LVIF_TEXT li.PszText = syscall.StringToUTF16Ptr(text[i]) li.ISubItem = int32(i) lv.setLvItem(li) } } func (lv *ListView) UpdateItem(item ListItem) bool { lparam, ok := lv.item2Handle[item] if !ok { return false } index := lv.findIndexByItem(item) if index == -1 { return false } text := item.Text() li := &w32.LVITEM{ Mask: w32.LVIF_TEXT | w32.LVIF_PARAM, PszText: syscall.StringToUTF16Ptr(text[0]), LParam: lparam, IItem: int32(index), } lv.applyImage(li, item.ImageIndex()) lv.setLvItem(li) for i := 1; i < len(text); i++ { li.Mask = w32.LVIF_TEXT li.PszText = syscall.StringToUTF16Ptr(text[i]) li.ISubItem = int32(i) lv.setLvItem(li) } return true } func (lv *ListView) insertLvColumn(lvColumn *w32.LVCOLUMN, iCol int) { w32.SendMessage(lv.hwnd, w32.LVM_INSERTCOLUMN, uintptr(iCol), uintptr(unsafe.Pointer(lvColumn))) } func (lv *ListView) insertLvItem(lvItem *w32.LVITEM) { w32.SendMessage(lv.hwnd, w32.LVM_INSERTITEM, 0, uintptr(unsafe.Pointer(lvItem))) } func (lv *ListView) setLvItem(lvItem *w32.LVITEM) { w32.SendMessage(lv.hwnd, w32.LVM_SETITEM, 0, uintptr(unsafe.Pointer(lvItem))) } func (lv *ListView) DeleteAllItems() bool { if w32.SendMessage(lv.hwnd, w32.LVM_DELETEALLITEMS, 0, 0) == w32.TRUE { lv.item2Handle = make(map[ListItem]uintptr) lv.handle2Item = make(map[uintptr]ListItem) return true } return false } func (lv *ListView) DeleteItem(item ListItem) error { index := lv.findIndexByItem(item) if index == -1 { return errors.New("item not found") } if w32.SendMessage(lv.hwnd, w32.LVM_DELETEITEM, uintptr(index), 0) == 0 { return errors.New("SendMessage(TVM_DELETEITEM) failed") } h := lv.item2Handle[item] delete(lv.item2Handle, item) delete(lv.handle2Item, h) return nil } func (lv *ListView) findIndexByItem(item ListItem) int { lparam, ok := lv.item2Handle[item] if !ok { return -1 } it := &w32.LVFINDINFO{ Flags: w32.LVFI_PARAM, LParam: lparam, } var i int = -1 return int(w32.SendMessage(lv.hwnd, w32.LVM_FINDITEM, uintptr(i), uintptr(unsafe.Pointer(it)))) } func (lv *ListView) findItemByIndex(i int) ListItem { it := &w32.LVITEM{ Mask: w32.LVIF_PARAM, IItem: int32(i), } if w32.SendMessage(lv.hwnd, w32.LVM_GETITEM, 0, uintptr(unsafe.Pointer(it))) == w32.TRUE { if item, ok := lv.handle2Item[it.LParam]; ok { return item } } return nil } func (lv *ListView) EnsureVisible(item ListItem) bool { if i := lv.findIndexByItem(item); i != -1 { return w32.SendMessage(lv.hwnd, w32.LVM_ENSUREVISIBLE, uintptr(i), 1) == 0 } return false } func (lv *ListView) SelectedItem() ListItem { if items := lv.SelectedItems(); len(items) > 0 { return items[0] } return nil } func (lv *ListView) SetSelectedItem(item ListItem) bool { if i := lv.findIndexByItem(item); i > -1 { lv.SetSelectedIndex(i) return true } return false } // mask is used to set the LVITEM.Mask for ListView.GetItem which indicates which attributes you'd like to receive // of LVITEM. func (lv *ListView) SelectedItems() []ListItem { var items []ListItem var i int = -1 for { if i = int(w32.SendMessage(lv.hwnd, w32.LVM_GETNEXTITEM, uintptr(i), uintptr(w32.LVNI_SELECTED))); i == -1 { break } if item := lv.findItemByIndex(i); item != nil { items = append(items, item) } } return items } func (lv *ListView) SelectedCount() uint { return uint(w32.SendMessage(lv.hwnd, w32.LVM_GETSELECTEDCOUNT, 0, 0)) } // GetSelectedIndex first selected item index. Returns -1 if no item is selected. func (lv *ListView) SelectedIndex() int { var i int = -1 return int(w32.SendMessage(lv.hwnd, w32.LVM_GETNEXTITEM, uintptr(i), uintptr(w32.LVNI_SELECTED))) } // Set i to -1 to select all items. func (lv *ListView) SetSelectedIndex(i int) { lv.setItemState(i, w32.LVIS_SELECTED, w32.LVIS_SELECTED) } func (lv *ListView) SetImageList(imageList *ImageList) { w32.SendMessage(lv.hwnd, w32.LVM_SETIMAGELIST, w32.LVSIL_SMALL, uintptr(imageList.Handle())) lv.iml = imageList } // Event publishers func (lv *ListView) OnEndLabelEdit() *EventManager { return &lv.onEndLabelEdit } func (lv *ListView) OnDoubleClick() *EventManager { return &lv.onDoubleClick } func (lv *ListView) OnClick() *EventManager { return &lv.onClick } func (lv *ListView) OnKeyDown() *EventManager { return &lv.onKeyDown } func (lv *ListView) OnItemChanging() *EventManager { return &lv.onItemChanging } func (lv *ListView) OnItemChanged() *EventManager { return &lv.onItemChanged } func (lv *ListView) OnCheckChanged() *EventManager { return &lv.onCheckChanged } func (lv *ListView) OnViewChange() *EventManager { return &lv.onViewChange } func (lv *ListView) OnEndScroll() *EventManager { return &lv.onEndScroll } // Message processer func (lv *ListView) WndProc(msg uint32, wparam, lparam uintptr) uintptr { switch msg { /*case w32.WM_ERASEBKGND: lv.StretchLastColumn() println("case w32.WM_ERASEBKGND") return 1*/ case w32.WM_NOTIFY: nm := (*w32.NMHDR)(unsafe.Pointer(lparam)) code := int32(nm.Code) switch code { case w32.LVN_BEGINLABELEDITW: // println("Begin label edit") case w32.LVN_ENDLABELEDITW: nmdi := (*w32.NMLVDISPINFO)(unsafe.Pointer(lparam)) if nmdi.Item.PszText != nil { fmt.Println(nmdi.Item.PszText, nmdi.Item) if item, ok := lv.handle2Item[nmdi.Item.LParam]; ok { lv.onEndLabelEdit.Fire(NewEvent(lv, &LabelEditEventData{Item: item, Text: w32.UTF16PtrToString(nmdi.Item.PszText)})) } return w32.TRUE } case w32.NM_DBLCLK: lv.onDoubleClick.Fire(NewEvent(lv, nil)) case w32.NM_CLICK: ac := (*w32.NMITEMACTIVATE)(unsafe.Pointer(lparam)) var hti w32.LVHITTESTINFO hti.Pt = w32.POINT{ac.PtAction.X, ac.PtAction.Y} w32.SendMessage(lv.hwnd, w32.LVM_HITTEST, 0, uintptr(unsafe.Pointer(&hti))) if hti.Flags == w32.LVHT_ONITEMSTATEICON { if item := lv.findItemByIndex(int(hti.IItem)); item != nil { if item, ok := item.(ListItemChecker); ok { checked := !item.Checked() item.SetChecked(checked) lv.onCheckChanged.Fire(NewEvent(lv, item)) if w32.SendMessage(lv.hwnd, w32.LVM_UPDATE, uintptr(hti.IItem), 0) == w32.FALSE { panic("SendMessage(LVM_UPDATE)") } } } } hti.Pt = w32.POINT{ac.PtAction.X, ac.PtAction.Y} w32.SendMessage(lv.hwnd, w32.LVM_SUBITEMHITTEST, 0, uintptr(unsafe.Pointer(&hti))) lv.onClick.Fire(NewEvent(lv, hti.ISubItem)) case w32.LVN_KEYDOWN: nmkey := (*w32.NMLVKEYDOWN)(unsafe.Pointer(lparam)) if nmkey.WVKey == w32.VK_SPACE && lv.CheckBoxes() { if item := lv.SelectedItem(); item != nil { if item, ok := item.(ListItemChecker); ok { checked := !item.Checked() item.SetChecked(checked) lv.onCheckChanged.Fire(NewEvent(lv, item)) } index := lv.findIndexByItem(item) if w32.SendMessage(lv.hwnd, w32.LVM_UPDATE, uintptr(index), 0) == w32.FALSE { panic("SendMessage(LVM_UPDATE)") } } } lv.onKeyDown.Fire(NewEvent(lv, nmkey.WVKey)) key := nmkey.WVKey w32.SendMessage(lv.Parent().Handle(), w32.WM_KEYDOWN, uintptr(key), 0) case w32.LVN_ITEMCHANGING: // This event also fires when listview has changed via code. nmlv := (*w32.NMLISTVIEW)(unsafe.Pointer(lparam)) item := lv.findItemByIndex(int(nmlv.IItem)) lv.onItemChanging.Fire(NewEvent(lv, item)) case w32.LVN_ITEMCHANGED: // This event also fires when listview has changed via code. nmlv := (*w32.NMLISTVIEW)(unsafe.Pointer(lparam)) item := lv.findItemByIndex(int(nmlv.IItem)) lv.onItemChanged.Fire(NewEvent(lv, item)) case w32.LVN_GETDISPINFO: nmdi := (*w32.NMLVDISPINFO)(unsafe.Pointer(lparam)) if nmdi.Item.StateMask&w32.LVIS_STATEIMAGEMASK > 0 { if item, ok := lv.handle2Item[nmdi.Item.LParam]; ok { if item, ok := item.(ListItemChecker); ok { checked := item.Checked() if checked { nmdi.Item.State = 0x2000 } else { nmdi.Item.State = 0x1000 } } } } lv.onViewChange.Fire(NewEvent(lv, nil)) case w32.LVN_ENDSCROLL: lv.onEndScroll.Fire(NewEvent(lv, nil)) } } return w32.DefWindowProc(lv.hwnd, msg, wparam, lparam) } ================================================ FILE: menu.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. */ package winc import ( "fmt" "syscall" "unsafe" "github.com/tadvi/winc/w32" ) var ( nextMenuItemID uint16 = 3 actionsByID = make(map[uint16]*MenuItem) shortcut2Action = make(map[Shortcut]*MenuItem) menuItems = make(map[w32.HMENU][]*MenuItem) radioGroups = make(map[*MenuItem]*RadioGroup) initialised bool ) var NoShortcut = Shortcut{} // Menu for main window and context menus on controls. // Most methods used for both main window menu and context menu. type Menu struct { hMenu w32.HMENU hwnd w32.HWND // hwnd might be nil if it is context menu. } type MenuItem struct { hMenu w32.HMENU hSubMenu w32.HMENU // Non zero if this item is in itself a submenu. text string toolTip string image *Bitmap shortcut Shortcut enabled bool checkable bool checked bool isRadio bool id uint16 onClick EventManager } type RadioGroup struct { members []*MenuItem hwnd w32.HWND } func NewContextMenu() *MenuItem { hMenu := w32.CreatePopupMenu() if hMenu == 0 { panic("failed CreateMenu") } item := &MenuItem{ hMenu: hMenu, hSubMenu: hMenu, } return item } func (m *Menu) Dispose() { if m.hMenu != 0 { w32.DestroyMenu(m.hMenu) m.hMenu = 0 } } func (m *Menu) IsDisposed() bool { return m.hMenu == 0 } func initMenuItemInfoFromAction(mii *w32.MENUITEMINFO, a *MenuItem) { mii.CbSize = uint32(unsafe.Sizeof(*mii)) mii.FMask = w32.MIIM_FTYPE | w32.MIIM_ID | w32.MIIM_STATE | w32.MIIM_STRING if a.image != nil { mii.FMask |= w32.MIIM_BITMAP mii.HbmpItem = a.image.handle } if a.IsSeparator() { mii.FType = w32.MFT_SEPARATOR } else { mii.FType = w32.MFT_STRING var text string if s := a.shortcut; s.Key != 0 { text = fmt.Sprintf("%s\t%s", a.text, s.String()) shortcut2Action[a.shortcut] = a } else { text = a.text } mii.DwTypeData = syscall.StringToUTF16Ptr(text) mii.Cch = uint32(len([]rune(a.text))) } mii.WID = uint32(a.id) if a.Enabled() { mii.FState &^= w32.MFS_DISABLED } else { mii.FState |= w32.MFS_DISABLED } if a.Checkable() { mii.FMask |= w32.MIIM_CHECKMARKS } if a.Checked() { mii.FState |= w32.MFS_CHECKED } if a.hSubMenu != 0 { mii.FMask |= w32.MIIM_SUBMENU mii.HSubMenu = a.hSubMenu } } // Show menu on the main window. func (m *Menu) Show() { initialised = true updateRadioGroups() if !w32.DrawMenuBar(m.hwnd) { panic("DrawMenuBar failed") } } // AddSubMenu returns item that is used as submenu to perform AddItem(s). func (m *Menu) AddSubMenu(text string) *MenuItem { hSubMenu := w32.CreateMenu() if hSubMenu == 0 { panic("failed CreateMenu") } return addMenuItem(m.hMenu, hSubMenu, text, Shortcut{}, nil, false) } // This method will iterate through the menu items, group radio items together, build a // quick access map and set the initial items func updateRadioGroups() { if !initialised { return } radioItemsChecked := []*MenuItem{} radioGroups = make(map[*MenuItem]*RadioGroup) var currentRadioGroupMembers []*MenuItem // Iterate the menus for _, menu := range menuItems { menuLength := len(menu) for index, menuItem := range menu { if menuItem.isRadio { currentRadioGroupMembers = append(currentRadioGroupMembers, menuItem) if menuItem.checked { radioItemsChecked = append(radioItemsChecked, menuItem) } // If end of menu if index == menuLength-1 { radioGroup := &RadioGroup{ members: currentRadioGroupMembers, hwnd: menuItem.hMenu, } // Save the group to each member iin the radiomap for _, member := range currentRadioGroupMembers { radioGroups[member] = radioGroup } currentRadioGroupMembers = []*MenuItem{} } continue } // Not a radio item if len(currentRadioGroupMembers) > 0 { radioGroup := &RadioGroup{ members: currentRadioGroupMembers, hwnd: menuItem.hMenu, } // Save the group to each member iin the radiomap for _, member := range currentRadioGroupMembers { radioGroups[member] = radioGroup } currentRadioGroupMembers = []*MenuItem{} } } } // Enable the checked items for _, item := range radioItemsChecked { radioGroup := radioGroups[item] startID := radioGroup.members[0].id endID := radioGroup.members[len(radioGroup.members)-1].id w32.SelectRadioMenuItem(item.id, startID, endID, radioGroup.hwnd) } } func (mi *MenuItem) OnClick() *EventManager { return &mi.onClick } func (mi *MenuItem) AddSeparator() { addMenuItem(mi.hSubMenu, 0, "-", Shortcut{}, nil, false) } // AddItem adds plain menu item. func (mi *MenuItem) AddItem(text string, shortcut Shortcut) *MenuItem { return addMenuItem(mi.hSubMenu, 0, text, shortcut, nil, false) } // AddItemCheckable adds plain menu item that can have a checkmark. func (mi *MenuItem) AddItemCheckable(text string, shortcut Shortcut) *MenuItem { return addMenuItem(mi.hSubMenu, 0, text, shortcut, nil, true) } // AddItemRadio adds plain menu item that can have a checkmark and is part of a radio group. func (mi *MenuItem) AddItemRadio(text string, shortcut Shortcut) *MenuItem { menuItem := addMenuItem(mi.hSubMenu, 0, text, shortcut, nil, true) menuItem.isRadio = true return menuItem } // AddItemWithBitmap adds menu item with shortcut and bitmap. func (mi *MenuItem) AddItemWithBitmap(text string, shortcut Shortcut, image *Bitmap) *MenuItem { return addMenuItem(mi.hSubMenu, 0, text, shortcut, image, false) } // AddSubMenu adds a submenu. func (mi *MenuItem) AddSubMenu(text string) *MenuItem { hSubMenu := w32.CreatePopupMenu() if hSubMenu == 0 { panic("failed CreatePopupMenu") } return addMenuItem(mi.hSubMenu, hSubMenu, text, Shortcut{}, nil, false) } // AddItem to the menu, set text to "-" for separators. func addMenuItem(hMenu, hSubMenu w32.HMENU, text string, shortcut Shortcut, image *Bitmap, checkable bool) *MenuItem { item := &MenuItem{ hMenu: hMenu, hSubMenu: hSubMenu, text: text, shortcut: shortcut, image: image, enabled: true, id: nextMenuItemID, checkable: checkable, isRadio: false, //visible: true, } nextMenuItemID++ actionsByID[item.id] = item menuItems[hMenu] = append(menuItems[hMenu], item) var mii w32.MENUITEMINFO initMenuItemInfoFromAction(&mii, item) index := -1 if !w32.InsertMenuItem(hMenu, uint32(index), true, &mii) { panic("InsertMenuItem failed") } return item } func indexInObserver(a *MenuItem) int { var idx int for _, mi := range menuItems[a.hMenu] { if mi == a { return idx } idx++ } return -1 } func findMenuItemByID(id int) *MenuItem { return actionsByID[uint16(id)] } func (mi *MenuItem) update() { var mii w32.MENUITEMINFO initMenuItemInfoFromAction(&mii, mi) if !w32.SetMenuItemInfo(mi.hMenu, uint32(indexInObserver(mi)), true, &mii) { panic("SetMenuItemInfo failed") } if mi.isRadio { mi.updateRadioGroup() } } func (mi *MenuItem) IsSeparator() bool { return mi.text == "-" } func (mi *MenuItem) SetSeparator() { mi.text = "-" } func (mi *MenuItem) Enabled() bool { return mi.enabled } func (mi *MenuItem) SetEnabled(b bool) { mi.enabled = b; mi.update() } func (mi *MenuItem) Checkable() bool { return mi.checkable } func (mi *MenuItem) SetCheckable(b bool) { mi.checkable = b; mi.update() } func (mi *MenuItem) Checked() bool { return mi.checked } func (mi *MenuItem) SetChecked(b bool) { if mi.isRadio { radioGroup := radioGroups[mi] if radioGroup != nil { for _, member := range radioGroup.members { member.checked = false } } } mi.checked = b mi.update() } func (mi *MenuItem) Text() string { return mi.text } func (mi *MenuItem) SetText(s string) { mi.text = s; mi.update() } func (mi *MenuItem) Image() *Bitmap { return mi.image } func (mi *MenuItem) SetImage(b *Bitmap) { mi.image = b; mi.update() } func (mi *MenuItem) ToolTip() string { return mi.toolTip } func (mi *MenuItem) SetToolTip(s string) { mi.toolTip = s; mi.update() } func (mi *MenuItem) updateRadioGroup() { radioGroup := radioGroups[mi] if radioGroup == nil { return } startID := radioGroup.members[0].id endID := radioGroup.members[len(radioGroup.members)-1].id w32.SelectRadioMenuItem(mi.id, startID, endID, radioGroup.hwnd) } ================================================ FILE: mousecontrol.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. */ package winc import ( "github.com/tadvi/winc/w32" ) // MouseControl used for creating custom controls that need mouse hover or mouse leave events. type MouseControl struct { ControlBase isMouseLeft bool } func (cc *MouseControl) Init(parent Controller, className string, exStyle, style uint) { RegClassOnlyOnce(className) cc.hwnd = CreateWindow(className, parent, exStyle, style) cc.parent = parent RegMsgHandler(cc) cc.isMouseLeft = true cc.SetFont(DefaultFont) } func (cc *MouseControl) WndProc(msg uint32, wparam, lparam uintptr) uintptr { sender := GetMsgHandler(cc.hwnd) switch msg { case w32.WM_CREATE: internalTrackMouseEvent(cc.hwnd) cc.onCreate.Fire(NewEvent(sender, nil)) case w32.WM_CLOSE: cc.onClose.Fire(NewEvent(sender, nil)) case w32.WM_MOUSEMOVE: //if cc.isMouseLeft { cc.onMouseHover.Fire(NewEvent(sender, nil)) //internalTrackMouseEvent(cc.hwnd) cc.isMouseLeft = false //} case w32.WM_MOUSELEAVE: cc.onMouseLeave.Fire(NewEvent(sender, nil)) cc.isMouseLeft = true } return w32.DefWindowProc(cc.hwnd, msg, wparam, lparam) } ================================================ FILE: msghandlerregistry.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. * Copyright (C) 2010-2013 Allen Dang. All Rights Reserved. */ package winc import ( "github.com/tadvi/winc/w32" ) func RegMsgHandler(controller Controller) { gControllerRegistry[controller.Handle()] = controller } func UnRegMsgHandler(hwnd w32.HWND) { delete(gControllerRegistry, hwnd) } func GetMsgHandler(hwnd w32.HWND) Controller { if controller, isExists := gControllerRegistry[hwnd]; isExists { return controller } return nil } ================================================ FILE: panel.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. */ package winc import ( "fmt" "github.com/tadvi/winc/w32" ) type Panel struct { ControlBase layoutMng LayoutManager } func NewPanel(parent Controller) *Panel { pa := new(Panel) RegClassOnlyOnce("winc_Panel") pa.hwnd = CreateWindow("winc_Panel", parent, w32.WS_EX_CONTROLPARENT, w32.WS_CHILD|w32.WS_VISIBLE) pa.parent = parent RegMsgHandler(pa) pa.SetFont(DefaultFont) pa.SetText("") pa.SetSize(200, 65) return pa } // SetLayout panel implements DockAllow interface. func (pa *Panel) SetLayout(mng LayoutManager) { pa.layoutMng = mng } func (pa *Panel) WndProc(msg uint32, wparam, lparam uintptr) uintptr { switch msg { case w32.WM_SIZE, w32.WM_PAINT: if pa.layoutMng != nil { pa.layoutMng.Update() } } return w32.DefWindowProc(pa.hwnd, msg, wparam, lparam) } var errorPanelPen = NewPen(w32.PS_GEOMETRIC, 2, NewSolidColorBrush(RGB(255, 128, 128))) var errorPanelOkPen = NewPen(w32.PS_GEOMETRIC, 2, NewSolidColorBrush(RGB(220, 220, 220))) // ErrorPanel shows errors or important messages. // It is meant to stand out of other on screen controls. type ErrorPanel struct { ControlBase pen *Pen margin int } // NewErrorPanel. func NewErrorPanel(parent Controller) *ErrorPanel { f := new(ErrorPanel) f.init(parent) f.SetFont(DefaultFont) f.SetText("No errors") f.SetSize(200, 65) f.margin = 5 f.pen = errorPanelOkPen return f } func (epa *ErrorPanel) init(parent Controller) { RegClassOnlyOnce("winc_ErrorPanel") epa.hwnd = CreateWindow("winc_ErrorPanel", parent, w32.WS_EX_CONTROLPARENT, w32.WS_CHILD|w32.WS_VISIBLE) epa.parent = parent RegMsgHandler(epa) } func (epa *ErrorPanel) SetMargin(margin int) { epa.margin = margin } func (epa *ErrorPanel) Printf(format string, v ...interface{}) { epa.SetText(fmt.Sprintf(format, v...)) epa.ShowAsError(false) } func (epa *ErrorPanel) Errorf(format string, v ...interface{}) { epa.SetText(fmt.Sprintf(format, v...)) epa.ShowAsError(true) } func (epa *ErrorPanel) ShowAsError(show bool) { if show { epa.pen = errorPanelPen } else { epa.pen = errorPanelOkPen } epa.Invalidate(true) } func (epa *ErrorPanel) WndProc(msg uint32, wparam, lparam uintptr) uintptr { switch msg { case w32.WM_ERASEBKGND: canvas := NewCanvasFromHDC(w32.HDC(wparam)) r := epa.Bounds() r.rect.Left += int32(epa.margin) r.rect.Right -= int32(epa.margin) r.rect.Top += int32(epa.margin) r.rect.Bottom -= int32(epa.margin) // old code used NewSystemColorBrush(w32.COLOR_BTNFACE) canvas.DrawFillRect(r, epa.pen, NewSystemColorBrush(w32.COLOR_WINDOW)) r.rect.Left += 5 canvas.DrawText(epa.Text(), r, 0, epa.Font(), RGB(0, 0, 0)) canvas.Dispose() return 1 } return w32.DefWindowProc(epa.hwnd, msg, wparam, lparam) } // MultiPanel contains other panels and only makes one of them visible. type MultiPanel struct { ControlBase current int panels []*Panel } func NewMultiPanel(parent Controller) *MultiPanel { mpa := new(MultiPanel) RegClassOnlyOnce("winc_MultiPanel") mpa.hwnd = CreateWindow("winc_MultiPanel", parent, w32.WS_EX_CONTROLPARENT, w32.WS_CHILD|w32.WS_VISIBLE) mpa.parent = parent RegMsgHandler(mpa) mpa.SetFont(DefaultFont) mpa.SetText("") mpa.SetSize(300, 200) mpa.current = -1 return mpa } func (mpa *MultiPanel) Count() int { return len(mpa.panels) } // AddPanel adds panels to the internal list, first panel is visible all others are hidden. func (mpa *MultiPanel) AddPanel(panel *Panel) { if len(mpa.panels) > 0 { panel.Hide() } mpa.current = 0 mpa.panels = append(mpa.panels, panel) } // ReplacePanel replaces panel, useful for refreshing controls on screen. func (mpa *MultiPanel) ReplacePanel(index int, panel *Panel) { mpa.panels[index] = panel } // DeletePanel removed panel. func (mpa *MultiPanel) DeletePanel(index int) { mpa.panels = append(mpa.panels[:index], mpa.panels[index+1:]...) } func (mpa *MultiPanel) Current() int { return mpa.current } func (mpa *MultiPanel) SetCurrent(index int) { if index >= len(mpa.panels) { panic("index greater than number of panels") } if mpa.current == -1 { panic("no current panel, add panels first") } for i := range mpa.panels { if i != index { mpa.panels[i].Hide() mpa.panels[i].Invalidate(true) } } mpa.panels[index].Show() mpa.panels[index].Invalidate(true) mpa.current = index } func (mpa *MultiPanel) WndProc(msg uint32, wparam, lparam uintptr) uintptr { switch msg { case w32.WM_SIZE: // resize contained panels for _, p := range mpa.panels { p.SetPos(0, 0) p.SetSize(mpa.Size()) } } return w32.DefWindowProc(mpa.hwnd, msg, wparam, lparam) } ================================================ FILE: path.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. * Copyright (C) 2010-2013 Allen Dang. All Rights Reserved. */ package winc import ( "fmt" "os" "path/filepath" "syscall" "github.com/tadvi/winc/w32" ) func knownFolderPath(id w32.CSIDL) (string, error) { var buf [w32.MAX_PATH]uint16 if !w32.SHGetSpecialFolderPath(0, &buf[0], id, false) { return "", fmt.Errorf("SHGetSpecialFolderPath failed") } return syscall.UTF16ToString(buf[0:]), nil } func AppDataPath() (string, error) { return knownFolderPath(w32.CSIDL_APPDATA) } func CommonAppDataPath() (string, error) { return knownFolderPath(w32.CSIDL_COMMON_APPDATA) } func LocalAppDataPath() (string, error) { return knownFolderPath(w32.CSIDL_LOCAL_APPDATA) } // EnsureAppDataPath uses AppDataPath to ensure storage for local settings and databases. func EnsureAppDataPath(company, product string) (string, error) { path, err := AppDataPath() if err != nil { return path, err } p := filepath.Join(path, company, product) if _, err := os.Stat(p); os.IsNotExist(err) { // path/to/whatever does not exist if err := os.MkdirAll(p, os.ModePerm); err != nil { return p, err } } return p, nil } func DriveNames() ([]string, error) { bufLen := w32.GetLogicalDriveStrings(0, nil) if bufLen == 0 { return nil, fmt.Errorf("GetLogicalDriveStrings failed") } buf := make([]uint16, bufLen+1) bufLen = w32.GetLogicalDriveStrings(bufLen+1, &buf[0]) if bufLen == 0 { return nil, fmt.Errorf("GetLogicalDriveStrings failed") } var names []string for i := 0; i < len(buf)-2; { name := syscall.UTF16ToString(buf[i:]) names = append(names, name) i += len(name) + 1 } return names, nil } ================================================ FILE: pen.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. * Copyright (C) 2010-2013 Allen Dang. All Rights Reserved. */ package winc import ( "github.com/tadvi/winc/w32" ) type Pen struct { hPen w32.HPEN style uint brush *Brush } func NewPen(style uint, width uint, brush *Brush) *Pen { if brush == nil { panic("Brush cannot be nil") } hPen := w32.ExtCreatePen(style, width, brush.GetLOGBRUSH(), 0, nil) if hPen == 0 { panic("Failed to create pen") } return &Pen{hPen, style, brush} } func NewNullPen() *Pen { lb := w32.LOGBRUSH{LbStyle: w32.BS_NULL} hPen := w32.ExtCreatePen(w32.PS_COSMETIC|w32.PS_NULL, 1, &lb, 0, nil) if hPen == 0 { panic("failed to create null brush") } return &Pen{hPen: hPen} } func (pen *Pen) Style() uint { return pen.style } func (pen *Pen) Brush() *Brush { return pen.brush } func (pen *Pen) GetHPEN() w32.HPEN { return pen.hPen } func (pen *Pen) Dispose() { if pen.hPen != 0 { w32.DeleteObject(w32.HGDIOBJ(pen.hPen)) pen.hPen = 0 } } ================================================ FILE: progressbar.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. */ package winc import ( "github.com/tadvi/winc/w32" ) type ProgressBar struct { ControlBase } func NewProgressBar(parent Controller) *ProgressBar { pb := new(ProgressBar) pb.InitControl(w32.PROGRESS_CLASS, parent, 0, w32.WS_CHILD|w32.WS_VISIBLE) RegMsgHandler(pb) pb.SetSize(200, 22) return pb } func (pr *ProgressBar) Value() int { ret := w32.SendMessage(pr.hwnd, w32.PBM_GETPOS, 0, 0) return int(ret) } func (pr *ProgressBar) SetValue(v int) { w32.SendMessage(pr.hwnd, w32.PBM_SETPOS, uintptr(v), 0) } func (pr *ProgressBar) Range() (min, max uint) { min = uint(w32.SendMessage(pr.hwnd, w32.PBM_GETRANGE, uintptr(w32.BoolToBOOL(true)), 0)) max = uint(w32.SendMessage(pr.hwnd, w32.PBM_GETRANGE, uintptr(w32.BoolToBOOL(false)), 0)) return } func (pr *ProgressBar) SetRange(min, max int) { w32.SendMessage(pr.hwnd, w32.PBM_SETRANGE32, uintptr(min), uintptr(max)) } func (pr *ProgressBar) WndProc(msg uint32, wparam, lparam uintptr) uintptr { return w32.DefWindowProc(pr.hwnd, msg, wparam, lparam) } ================================================ FILE: rect.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. * Copyright (C) 2010-2013 Allen Dang. All Rights Reserved. */ package winc import ( "github.com/tadvi/winc/w32" ) type Rect struct { rect w32.RECT } func NewEmptyRect() *Rect { var newRect Rect w32.SetRectEmpty(&newRect.rect) return &newRect } func NewRect(left, top, right, bottom int) *Rect { var newRect Rect w32.SetRectEmpty(&newRect.rect) newRect.Set(left, top, right, bottom) return &newRect } func (re *Rect) Data() (left, top, right, bottom int32) { left = re.rect.Left top = re.rect.Top right = re.rect.Right bottom = re.rect.Bottom return } func (re *Rect) Width() int { return int(re.rect.Right - re.rect.Left) } func (re *Rect) Height() int { return int(re.rect.Bottom - re.rect.Top) } func (re *Rect) GetW32Rect() *w32.RECT { return &re.rect } func (re *Rect) Set(left, top, right, bottom int) { w32.SetRect(&re.rect, left, top, right, bottom) } func (re *Rect) IsEqual(rect *Rect) bool { return w32.EqualRect(&re.rect, &rect.rect) } func (re *Rect) Inflate(x, y int) { w32.InflateRect(&re.rect, x, y) } func (re *Rect) Intersect(src *Rect) { w32.IntersectRect(&re.rect, &re.rect, &src.rect) } func (re *Rect) IsEmpty() bool { return w32.IsRectEmpty(&re.rect) } func (re *Rect) Offset(x, y int) { w32.OffsetRect(&re.rect, x, y) } func (re *Rect) IsPointIn(x, y int) bool { return w32.PtInRect(&re.rect, x, y) } func (re *Rect) Substract(src *Rect) { w32.SubtractRect(&re.rect, &re.rect, &src.rect) } func (re *Rect) Union(src *Rect) { w32.UnionRect(&re.rect, &re.rect, &src.rect) } ================================================ FILE: resizer.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. */ package winc import ( "github.com/tadvi/winc/w32" ) type VResizer struct { ControlBase control1 Dockable control2 Dockable dir Direction mouseLeft bool drag bool } func NewVResizer(parent Controller) *VResizer { sp := new(VResizer) RegClassOnlyOnce("winc_VResizer") sp.hwnd = CreateWindow("winc_VResizer", parent, w32.WS_EX_CONTROLPARENT, w32.WS_CHILD|w32.WS_VISIBLE) sp.parent = parent sp.mouseLeft = true RegMsgHandler(sp) sp.SetFont(DefaultFont) sp.SetText("") sp.SetSize(20, 100) return sp } func (sp *VResizer) SetControl(control1, control2 Dockable, dir Direction, minSize int) { sp.control1 = control1 sp.control2 = control2 if dir != Left && dir != Right { panic("invalid direction") } sp.dir = dir // TODO(vi): ADDED /*internalTrackMouseEvent(control1.Handle()) internalTrackMouseEvent(control2.Handle()) control1.OnMouseMove().Bind(func(e *Event) { if sp.drag { x := e.Data.(*MouseEventData).X sp.update(x) w32.SetCursor(w32.LoadCursor(0, w32.MakeIntResource(w32.IDC_SIZEWE))) } fmt.Println("control1.OnMouseMove") }) control2.OnMouseMove().Bind(func(e *Event) { if sp.drag { x := e.Data.(*MouseEventData).X sp.update(x) w32.SetCursor(w32.LoadCursor(0, w32.MakeIntResource(w32.IDC_SIZEWE))) } fmt.Println("control2.OnMouseMove") }) control1.OnLBUp().Bind(func(e *Event) { sp.drag = false sp.mouseLeft = true fmt.Println("control1.OnLBUp") }) control2.OnLBUp().Bind(func(e *Event) { sp.drag = false sp.mouseLeft = true fmt.Println("control2.OnLBUp") })*/ // ---- finish ADDED } func (sp *VResizer) update(x int) { pos := x - 10 w1, h1 := sp.control1.Width(), sp.control1.Height() if sp.dir == Left { w1 += pos } else { w1 -= pos } sp.control1.SetSize(w1, h1) fm := sp.parent.(*Form) fm.UpdateLayout() w32.SetCursor(w32.LoadCursor(0, w32.MakeIntResource(w32.IDC_ARROW))) } func (sp *VResizer) WndProc(msg uint32, wparam, lparam uintptr) uintptr { switch msg { case w32.WM_CREATE: internalTrackMouseEvent(sp.hwnd) case w32.WM_MOUSEMOVE: if sp.drag { x, _ := genPoint(lparam) sp.update(x) } else { w32.SetCursor(w32.LoadCursor(0, w32.MakeIntResource(w32.IDC_SIZEWE))) } if sp.mouseLeft { internalTrackMouseEvent(sp.hwnd) sp.mouseLeft = false } case w32.WM_MOUSELEAVE: sp.drag = false sp.mouseLeft = true case w32.WM_LBUTTONUP: sp.drag = false case w32.WM_LBUTTONDOWN: sp.drag = true } return w32.DefWindowProc(sp.hwnd, msg, wparam, lparam) } type HResizer struct { ControlBase control1 Dockable control2 Dockable dir Direction mouseLeft bool drag bool } func NewHResizer(parent Controller) *HResizer { sp := new(HResizer) RegClassOnlyOnce("winc_HResizer") sp.hwnd = CreateWindow("winc_HResizer", parent, w32.WS_EX_CONTROLPARENT, w32.WS_CHILD|w32.WS_VISIBLE) sp.parent = parent sp.mouseLeft = true RegMsgHandler(sp) sp.SetFont(DefaultFont) sp.SetText("") sp.SetSize(100, 20) return sp } func (sp *HResizer) SetControl(control1, control2 Dockable, dir Direction, minSize int) { sp.control1 = control1 sp.control2 = control2 if dir != Top && dir != Bottom { panic("invalid direction") } sp.dir = dir } func (sp *HResizer) update(y int) { pos := y - 10 w1, h1 := sp.control1.Width(), sp.control1.Height() if sp.dir == Top { h1 += pos } else { h1 -= pos } sp.control1.SetSize(w1, h1) fm := sp.parent.(*Form) fm.UpdateLayout() w32.SetCursor(w32.LoadCursor(0, w32.MakeIntResource(w32.IDC_ARROW))) } func (sp *HResizer) WndProc(msg uint32, wparam, lparam uintptr) uintptr { switch msg { case w32.WM_CREATE: internalTrackMouseEvent(sp.hwnd) case w32.WM_MOUSEMOVE: if sp.drag { _, y := genPoint(lparam) sp.update(y) } else { w32.SetCursor(w32.LoadCursor(0, w32.MakeIntResource(w32.IDC_SIZENS))) } if sp.mouseLeft { internalTrackMouseEvent(sp.hwnd) sp.mouseLeft = false } case w32.WM_MOUSELEAVE: sp.drag = false sp.mouseLeft = true case w32.WM_LBUTTONUP: sp.drag = false case w32.WM_LBUTTONDOWN: sp.drag = true } return w32.DefWindowProc(sp.hwnd, msg, wparam, lparam) } ================================================ FILE: scrollview.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. */ package winc import ( "unsafe" "github.com/tadvi/winc/w32" ) type ScrollView struct { ControlBase child Dockable } func NewScrollView(parent Controller) *ScrollView { sv := new(ScrollView) RegClassOnlyOnce("winc_ScrollView") sv.hwnd = CreateWindow("winc_ScrollView", parent, w32.WS_EX_CONTROLPARENT, w32.WS_CHILD|w32.WS_HSCROLL|w32.WS_VISIBLE|w32.WS_VSCROLL) sv.parent = parent RegMsgHandler(sv) sv.SetFont(DefaultFont) sv.SetText("") sv.SetSize(200, 200) return sv } func (sv *ScrollView) SetChild(child Dockable) { sv.child = child } func (sv *ScrollView) UpdateScrollBars() { w, h := sv.child.Width(), sv.child.Height() sw, sh := sv.Size() var si w32.SCROLLINFO si.CbSize = uint32(unsafe.Sizeof(si)) si.FMask = w32.SIF_PAGE | w32.SIF_RANGE si.NMax = int32(w - 1) si.NPage = uint32(sw) w32.SetScrollInfo(sv.hwnd, w32.SB_HORZ, &si, true) x := sv.scroll(w32.SB_HORZ, w32.SB_THUMBPOSITION) si.NMax = int32(h) si.NPage = uint32(sh) w32.SetScrollInfo(sv.hwnd, w32.SB_VERT, &si, true) y := sv.scroll(w32.SB_VERT, w32.SB_THUMBPOSITION) sv.child.SetPos(x, y) } func (sv *ScrollView) scroll(sb int32, cmd uint16) int { var pos int32 var si w32.SCROLLINFO si.CbSize = uint32(unsafe.Sizeof(si)) si.FMask = w32.SIF_PAGE | w32.SIF_POS | w32.SIF_RANGE | w32.SIF_TRACKPOS w32.GetScrollInfo(sv.hwnd, sb, &si) pos = si.NPos switch cmd { case w32.SB_LINELEFT: // == win.SB_LINEUP pos -= 20 case w32.SB_LINERIGHT: // == win.SB_LINEDOWN pos += 20 case w32.SB_PAGELEFT: // == win.SB_PAGEUP pos -= int32(si.NPage) case w32.SB_PAGERIGHT: // == win.SB_PAGEDOWN pos += int32(si.NPage) case w32.SB_THUMBTRACK: pos = si.NTrackPos } if pos < 0 { pos = 0 } if pos > si.NMax+1-int32(si.NPage) { pos = si.NMax + 1 - int32(si.NPage) } si.FMask = w32.SIF_POS si.NPos = pos w32.SetScrollInfo(sv.hwnd, sb, &si, true) return -int(pos) } func (sv *ScrollView) WndProc(msg uint32, wparam, lparam uintptr) uintptr { if sv.child != nil { switch msg { case w32.WM_PAINT: sv.UpdateScrollBars() case w32.WM_HSCROLL: x, y := sv.child.Pos() x = sv.scroll(w32.SB_HORZ, w32.LOWORD(uint32(wparam))) sv.child.SetPos(x, y) case w32.WM_VSCROLL: x, y := sv.child.Pos() y = sv.scroll(w32.SB_VERT, w32.LOWORD(uint32(wparam))) sv.child.SetPos(x, y) case w32.WM_SIZE, w32.WM_SIZING: sv.UpdateScrollBars() } } return w32.DefWindowProc(sv.hwnd, msg, wparam, lparam) } ================================================ FILE: slider.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. */ package winc import "github.com/tadvi/winc/w32" type Slider struct { ControlBase prevPos int onScroll EventManager } func NewSlider(parent Controller) *Slider { tb := new(Slider) tb.InitControl("msctls_trackbar32", parent, 0, w32.WS_TABSTOP|w32.WS_VISIBLE|w32.WS_CHILD /*|w32.TBS_AUTOTICKS*/) RegMsgHandler(tb) tb.SetFont(DefaultFont) tb.SetText("Slider") tb.SetSize(200, 32) tb.SetRange(0, 100) tb.SetPage(10) return tb } func (tb *Slider) OnScroll() *EventManager { return &tb.onScroll } func (tb *Slider) Value() int { ret := w32.SendMessage(tb.hwnd, w32.TBM_GETPOS, 0, 0) return int(ret) } func (tb *Slider) SetValue(v int) { tb.prevPos = v w32.SendMessage(tb.hwnd, w32.TBM_SETPOS, uintptr(w32.BoolToBOOL(true)), uintptr(v)) } func (tb *Slider) Range() (min, max int) { min = int(w32.SendMessage(tb.hwnd, w32.TBM_GETRANGEMIN, 0, 0)) max = int(w32.SendMessage(tb.hwnd, w32.TBM_GETRANGEMAX, 0, 0)) return min, max } func (tb *Slider) SetRange(min, max int) { w32.SendMessage(tb.hwnd, w32.TBM_SETRANGE, uintptr(w32.BoolToBOOL(true)), uintptr(w32.MAKELONG(uint16(min), uint16(max)))) } func (tb *Slider) SetPage(pagesize int) { w32.SendMessage(tb.hwnd, w32.TBM_SETPAGESIZE, 0, uintptr(pagesize)) } func (tb *Slider) WndProc(msg uint32, wparam, lparam uintptr) uintptr { /* // REMOVE: // following code did not work, used workaround below code := w32.LOWORD(uint32(wparam)) switch code { case w32.TB_ENDTRACK: tb.onScroll.Fire(NewEvent(tb, nil)) }*/ newPos := tb.Value() if newPos != tb.prevPos { tb.onScroll.Fire(NewEvent(tb, nil)) tb.prevPos = newPos } return w32.DefWindowProc(tb.hwnd, msg, wparam, lparam) } ================================================ FILE: tabview.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. */ package winc import ( "syscall" "unsafe" "github.com/tadvi/winc/w32" ) // TabView creates MultiPanel internally and manages tabs as panels. type TabView struct { ControlBase panels *MultiPanel onSelectedChange EventManager } func NewTabView(parent Controller) *TabView { tv := new(TabView) tv.InitControl("SysTabControl32", parent, 0, w32.WS_CHILD|w32.WS_VISIBLE|w32.WS_TABSTOP|w32.WS_CLIPSIBLINGS) RegMsgHandler(tv) tv.panels = NewMultiPanel(parent) tv.SetFont(DefaultFont) tv.SetSize(200, 24) return tv } func (tv *TabView) Panels() *MultiPanel { return tv.panels } func (tv *TabView) tcitemFromPage(panel *Panel) *w32.TCITEM { text := syscall.StringToUTF16(panel.Text()) item := &w32.TCITEM{ Mask: w32.TCIF_TEXT, PszText: &text[0], CchTextMax: int32(len(text)), } return item } func (tv *TabView) AddPanel(text string) *Panel { panel := NewPanel(tv.panels) panel.SetText(text) item := tv.tcitemFromPage(panel) index := tv.panels.Count() idx := int(w32.SendMessage(tv.hwnd, w32.TCM_INSERTITEM, uintptr(index), uintptr(unsafe.Pointer(item)))) if idx == -1 { panic("SendMessage(TCM_INSERTITEM) failed") } tv.panels.AddPanel(panel) tv.SetCurrent(idx) return panel } func (tv *TabView) DeletePanel(index int) { w32.SendMessage(tv.hwnd, w32.TCM_DELETEITEM, uintptr(index), 0) tv.panels.DeletePanel(index) switch { case tv.panels.Count() > index: tv.SetCurrent(index) case tv.panels.Count() == 0: tv.SetCurrent(0) } } func (tv *TabView) Current() int { return tv.panels.Current() } func (tv *TabView) SetCurrent(index int) { if index < 0 || index >= tv.panels.Count() { panic("invalid index") } if ret := int(w32.SendMessage(tv.hwnd, w32.TCM_SETCURSEL, uintptr(index), 0)); ret == -1 { panic("SendMessage(TCM_SETCURSEL) failed") } tv.panels.SetCurrent(index) } func (tv *TabView) WndProc(msg uint32, wparam, lparam uintptr) uintptr { switch msg { case w32.WM_NOTIFY: nmhdr := (*w32.NMHDR)(unsafe.Pointer(lparam)) switch int32(nmhdr.Code) { case w32.TCN_SELCHANGE: cur := int(w32.SendMessage(tv.hwnd, w32.TCM_GETCURSEL, 0, 0)) tv.SetCurrent(cur) tv.onSelectedChange.Fire(NewEvent(tv, nil)) } } return w32.DefWindowProc(tv.hwnd, msg, wparam, lparam) } ================================================ FILE: toolbar.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. */ package winc import ( "syscall" "unsafe" "github.com/tadvi/winc/w32" ) type Toolbar struct { ControlBase iml *ImageList buttons []*ToolButton } type ToolButton struct { tb *Toolbar text string enabled bool checkable bool checked bool image int onClick EventManager } func (bt *ToolButton) OnClick() *EventManager { return &bt.onClick } func (bt *ToolButton) update() { bt.tb.update(bt) } func (bt *ToolButton) IsSeparator() bool { return bt.text == "-" } func (bt *ToolButton) SetSeparator() { bt.text = "-" } func (bt *ToolButton) Enabled() bool { return bt.enabled } func (bt *ToolButton) SetEnabled(b bool) { bt.enabled = b; bt.update() } func (bt *ToolButton) Checkable() bool { return bt.checkable } func (bt *ToolButton) SetCheckable(b bool) { bt.checkable = b; bt.update() } func (bt *ToolButton) Checked() bool { return bt.checked } func (bt *ToolButton) SetChecked(b bool) { bt.checked = b; bt.update() } func (bt *ToolButton) Text() string { return bt.text } func (bt *ToolButton) SetText(s string) { bt.text = s; bt.update() } func (bt *ToolButton) Image() int { return bt.image } func (bt *ToolButton) SetImage(i int) { bt.image = i; bt.update() } // NewHToolbar creates horizontal toolbar with text on same line as image. func NewHToolbar(parent Controller) *Toolbar { return newToolbar(parent, w32.CCS_NODIVIDER|w32.TBSTYLE_FLAT|w32.TBSTYLE_TOOLTIPS|w32.TBSTYLE_WRAPABLE| w32.WS_CHILD|w32.TBSTYLE_LIST) } // NewToolbar creates toolbar with text below the image. func NewToolbar(parent Controller) *Toolbar { return newToolbar(parent, w32.CCS_NODIVIDER|w32.TBSTYLE_FLAT|w32.TBSTYLE_TOOLTIPS|w32.TBSTYLE_WRAPABLE| w32.WS_CHILD /*|w32.TBSTYLE_TRANSPARENT*/) } func newToolbar(parent Controller, style uint) *Toolbar { tb := new(Toolbar) tb.InitControl("ToolbarWindow32", parent, 0, style) exStyle := w32.SendMessage(tb.hwnd, w32.TB_GETEXTENDEDSTYLE, 0, 0) exStyle |= w32.TBSTYLE_EX_DRAWDDARROWS | w32.TBSTYLE_EX_MIXEDBUTTONS w32.SendMessage(tb.hwnd, w32.TB_SETEXTENDEDSTYLE, 0, exStyle) RegMsgHandler(tb) tb.SetFont(DefaultFont) tb.SetPos(0, 0) tb.SetSize(200, 40) return tb } func (tb *Toolbar) SetImageList(imageList *ImageList) { w32.SendMessage(tb.hwnd, w32.TB_SETIMAGELIST, 0, uintptr(imageList.Handle())) tb.iml = imageList } func (tb *Toolbar) initButton(btn *ToolButton, state, style *byte, image *int32, text *uintptr) { *style |= w32.BTNS_AUTOSIZE if btn.checked { *state |= w32.TBSTATE_CHECKED } if btn.enabled { *state |= w32.TBSTATE_ENABLED } if btn.checkable { *style |= w32.BTNS_CHECK } if len(btn.Text()) > 0 { *style |= w32.BTNS_SHOWTEXT } if btn.IsSeparator() { *style = w32.BTNS_SEP } *image = int32(btn.Image()) *text = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(btn.Text()))) } func (tb *Toolbar) update(btn *ToolButton) { tbbi := w32.TBBUTTONINFO{ DwMask: w32.TBIF_IMAGE | w32.TBIF_STATE | w32.TBIF_STYLE | w32.TBIF_TEXT, } tbbi.CbSize = uint32(unsafe.Sizeof(tbbi)) var i int for i = range tb.buttons { if tb.buttons[i] == btn { break } } tb.initButton(btn, &tbbi.FsState, &tbbi.FsStyle, &tbbi.IImage, &tbbi.PszText) if w32.SendMessage(tb.hwnd, w32.TB_SETBUTTONINFO, uintptr(i), uintptr(unsafe.Pointer(&tbbi))) == 0 { panic("SendMessage(TB_SETBUTTONINFO) failed") } } func (tb *Toolbar) AddSeparator() { tb.AddButton("-", 0) } // AddButton creates and adds button to the toolbar. Use returned toolbutton to setup OnClick event. func (tb *Toolbar) AddButton(text string, image int) *ToolButton { bt := &ToolButton{ tb: tb, // points to parent text: text, image: image, enabled: true, } tb.buttons = append(tb.buttons, bt) index := len(tb.buttons) - 1 tbb := w32.TBBUTTON{ IdCommand: int32(index), } tb.initButton(bt, &tbb.FsState, &tbb.FsStyle, &tbb.IBitmap, &tbb.IString) w32.SendMessage(tb.hwnd, w32.TB_BUTTONSTRUCTSIZE, uintptr(unsafe.Sizeof(tbb)), 0) if w32.SendMessage(tb.hwnd, w32.TB_INSERTBUTTON, uintptr(index), uintptr(unsafe.Pointer(&tbb))) == w32.FALSE { panic("SendMessage(TB_ADDBUTTONS)") } w32.SendMessage(tb.hwnd, w32.TB_AUTOSIZE, 0, 0) return bt } func (tb *Toolbar) WndProc(msg uint32, wparam, lparam uintptr) uintptr { switch msg { case w32.WM_COMMAND: switch w32.HIWORD(uint32(wparam)) { case w32.BN_CLICKED: id := uint16(w32.LOWORD(uint32(wparam))) btn := tb.buttons[id] btn.onClick.Fire(NewEvent(tb, nil)) } } return w32.DefWindowProc(tb.hwnd, msg, wparam, lparam) } ================================================ FILE: tooltip.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. * Copyright (C) 2010-2013 Allen Dang. All Rights Reserved. */ package winc import ( "syscall" "unsafe" "github.com/tadvi/winc/w32" ) type ToolTip struct { ControlBase } func NewToolTip(parent Controller) *ToolTip { tp := new(ToolTip) tp.InitControl("tooltips_class32", parent, w32.WS_EX_TOPMOST, w32.WS_POPUP|w32.TTS_NOPREFIX|w32.TTS_ALWAYSTIP) w32.SetWindowPos(tp.Handle(), w32.HWND_TOPMOST, 0, 0, 0, 0, w32.SWP_NOMOVE|w32.SWP_NOSIZE|w32.SWP_NOACTIVATE) return tp } func (tp *ToolTip) SetTip(tool Controller, tip string) bool { var ti w32.TOOLINFO ti.CbSize = uint32(unsafe.Sizeof(ti)) if tool.Parent() != nil { ti.Hwnd = tool.Parent().Handle() } ti.UFlags = w32.TTF_IDISHWND | w32.TTF_SUBCLASS /* | TTF_ABSOLUTE */ ti.UId = uintptr(tool.Handle()) ti.LpszText = syscall.StringToUTF16Ptr(tip) return w32.SendMessage(tp.Handle(), w32.TTM_ADDTOOL, 0, uintptr(unsafe.Pointer(&ti))) != w32.FALSE } func (tp *ToolTip) WndProc(msg uint, wparam, lparam uintptr) uintptr { return w32.DefWindowProc(tp.hwnd, uint32(msg), wparam, lparam) } ================================================ FILE: treeview.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. */ package winc import ( "errors" "syscall" "unsafe" "github.com/tadvi/winc/w32" ) // TreeItem represents an item in a TreeView widget. type TreeItem interface { Text() string // Text returns the text of the item. ImageIndex() int // ImageIndex is used only if SetImageList is called on the treeview } type treeViewItemInfo struct { handle w32.HTREEITEM child2Handle map[TreeItem]w32.HTREEITEM } // StringTreeItem is helper for basic string lists. type StringTreeItem struct { Data string Image int } func (s StringTreeItem) Text() string { return s.Data } func (s StringTreeItem) ImageIndex() int { return s.Image } type TreeView struct { ControlBase iml *ImageList item2Info map[TreeItem]*treeViewItemInfo handle2Item map[w32.HTREEITEM]TreeItem currItem TreeItem onSelectedChange EventManager onExpand EventManager onCollapse EventManager onViewChange EventManager } func NewTreeView(parent Controller) *TreeView { tv := new(TreeView) tv.InitControl("SysTreeView32", parent, 0, w32.WS_CHILD|w32.WS_VISIBLE| w32.WS_BORDER|w32.TVS_HASBUTTONS|w32.TVS_LINESATROOT|w32.TVS_SHOWSELALWAYS| w32.TVS_TRACKSELECT /*|w32.WS_EX_CLIENTEDGE*/) tv.item2Info = make(map[TreeItem]*treeViewItemInfo) tv.handle2Item = make(map[w32.HTREEITEM]TreeItem) RegMsgHandler(tv) tv.SetFont(DefaultFont) tv.SetSize(200, 400) if err := tv.SetTheme("Explorer"); err != nil { // theme error is ignored } return tv } func (tv *TreeView) EnableDoubleBuffer(enable bool) { if enable { w32.SendMessage(tv.hwnd, w32.TVM_SETEXTENDEDSTYLE, 0, w32.TVS_EX_DOUBLEBUFFER) } else { w32.SendMessage(tv.hwnd, w32.TVM_SETEXTENDEDSTYLE, w32.TVS_EX_DOUBLEBUFFER, 0) } } // SelectedItem is current selected item after OnSelectedChange event. func (tv *TreeView) SelectedItem() TreeItem { return tv.currItem } func (tv *TreeView) SetSelectedItem(item TreeItem) bool { var handle w32.HTREEITEM if item != nil { if info := tv.item2Info[item]; info == nil { return false // invalid item } else { handle = info.handle } } if w32.SendMessage(tv.hwnd, w32.TVM_SELECTITEM, w32.TVGN_CARET, uintptr(handle)) == 0 { return false // set selected failed } tv.currItem = item return true } func (tv *TreeView) ItemAt(x, y int) TreeItem { hti := w32.TVHITTESTINFO{Pt: w32.POINT{int32(x), int32(y)}} w32.SendMessage(tv.hwnd, w32.TVM_HITTEST, 0, uintptr(unsafe.Pointer(&hti))) if item, ok := tv.handle2Item[hti.HItem]; ok { return item } return nil } func (tv *TreeView) Items() (list []TreeItem) { for item := range tv.item2Info { list = append(list, item) } return list } func (tv *TreeView) InsertItem(item, parent, insertAfter TreeItem) error { var tvins w32.TVINSERTSTRUCT tvi := &tvins.Item tvi.Mask = w32.TVIF_TEXT // w32.TVIF_CHILDREN | w32.TVIF_TEXT tvi.PszText = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(item.Text()))) // w32.LPSTR_TEXTCALLBACK tvi.CChildren = 0 // w32.I_CHILDRENCALLBACK if parent == nil { tvins.HParent = w32.TVI_ROOT } else { info := tv.item2Info[parent] if info == nil { return errors.New("winc: invalid parent") } tvins.HParent = info.handle } if insertAfter == nil { tvins.HInsertAfter = w32.TVI_LAST } else { info := tv.item2Info[insertAfter] if info == nil { return errors.New("winc: invalid prev item") } tvins.HInsertAfter = info.handle } tv.applyImage(tvi, item) hItem := w32.HTREEITEM(w32.SendMessage(tv.hwnd, w32.TVM_INSERTITEM, 0, uintptr(unsafe.Pointer(&tvins)))) if hItem == 0 { return errors.New("winc: TVM_INSERTITEM failed") } tv.item2Info[item] = &treeViewItemInfo{hItem, make(map[TreeItem]w32.HTREEITEM)} tv.handle2Item[hItem] = item return nil } func (tv *TreeView) UpdateItem(item TreeItem) bool { it := tv.item2Info[item] if it == nil { return false } tvi := &w32.TVITEM{ Mask: w32.TVIF_TEXT, HItem: it.handle, PszText: uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(item.Text()))), } tv.applyImage(tvi, item) if w32.SendMessage(tv.hwnd, w32.TVM_SETITEM, 0, uintptr(unsafe.Pointer(tvi))) == 0 { return false } return true } func (tv *TreeView) DeleteItem(item TreeItem) bool { it := tv.item2Info[item] if it == nil { return false } if w32.SendMessage(tv.hwnd, w32.TVM_DELETEITEM, 0, uintptr(it.handle)) == 0 { return false } delete(tv.item2Info, item) delete(tv.handle2Item, it.handle) return true } func (tv *TreeView) DeleteAllItems() bool { if w32.SendMessage(tv.hwnd, w32.TVM_DELETEITEM, 0, 0) == 0 { return false } tv.item2Info = make(map[TreeItem]*treeViewItemInfo) tv.handle2Item = make(map[w32.HTREEITEM]TreeItem) return true } func (tv *TreeView) Expand(item TreeItem) bool { if w32.SendMessage(tv.hwnd, w32.TVM_EXPAND, w32.TVE_EXPAND, uintptr(tv.item2Info[item].handle)) == 0 { return false } return true } func (tv *TreeView) Collapse(item TreeItem) bool { if w32.SendMessage(tv.hwnd, w32.TVM_EXPAND, w32.TVE_COLLAPSE, uintptr(tv.item2Info[item].handle)) == 0 { return false } return true } func (tv *TreeView) EnsureVisible(item TreeItem) bool { if info := tv.item2Info[item]; info != nil { return w32.SendMessage(tv.hwnd, w32.TVM_ENSUREVISIBLE, 0, uintptr(info.handle)) != 0 } return false } func (tv *TreeView) SetImageList(imageList *ImageList) { w32.SendMessage(tv.hwnd, w32.TVM_SETIMAGELIST, 0, uintptr(imageList.Handle())) tv.iml = imageList } func (tv *TreeView) applyImage(tc *w32.TVITEM, item TreeItem) { if tv.iml != nil { tc.Mask |= w32.TVIF_IMAGE | w32.TVIF_SELECTEDIMAGE tc.IImage = int32(item.ImageIndex()) tc.ISelectedImage = int32(item.ImageIndex()) } } func (tv *TreeView) OnSelectedChange() *EventManager { return &tv.onSelectedChange } func (tv *TreeView) OnExpand() *EventManager { return &tv.onExpand } func (tv *TreeView) OnCollapse() *EventManager { return &tv.onCollapse } func (tv *TreeView) OnViewChange() *EventManager { return &tv.onViewChange } // Message processer func (tv *TreeView) WndProc(msg uint32, wparam, lparam uintptr) uintptr { switch msg { case w32.WM_NOTIFY: nm := (*w32.NMHDR)(unsafe.Pointer(lparam)) switch nm.Code { case w32.TVN_ITEMEXPANDED: nmtv := (*w32.NMTREEVIEW)(unsafe.Pointer(lparam)) switch nmtv.Action { case w32.TVE_COLLAPSE: tv.onCollapse.Fire(NewEvent(tv, nil)) case w32.TVE_COLLAPSERESET: case w32.TVE_EXPAND: tv.onExpand.Fire(NewEvent(tv, nil)) case w32.TVE_EXPANDPARTIAL: case w32.TVE_TOGGLE: } case w32.TVN_SELCHANGED: nmtv := (*w32.NMTREEVIEW)(unsafe.Pointer(lparam)) tv.currItem = tv.handle2Item[nmtv.ItemNew.HItem] tv.onSelectedChange.Fire(NewEvent(tv, nil)) case w32.TVN_GETDISPINFO: tv.onViewChange.Fire(NewEvent(tv, nil)) } } return w32.DefWindowProc(tv.hwnd, msg, wparam, lparam) } ================================================ FILE: utils.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. * Copyright (C) 2010-2013 Allen Dang. All Rights Reserved. */ package winc import ( "fmt" "syscall" "unsafe" "github.com/tadvi/winc/w32" ) func internalTrackMouseEvent(hwnd w32.HWND) { var tme w32.TRACKMOUSEEVENT tme.CbSize = uint32(unsafe.Sizeof(tme)) tme.DwFlags = w32.TME_LEAVE tme.HwndTrack = hwnd tme.DwHoverTime = w32.HOVER_DEFAULT w32.TrackMouseEvent(&tme) } func ToggleStyle(hwnd w32.HWND, b bool, style int) { originalStyle := int(w32.GetWindowLongPtr(hwnd, w32.GWL_STYLE)) if originalStyle != 0 { if b { originalStyle |= style } else { originalStyle ^= style } w32.SetWindowLongPtr(hwnd, w32.GWL_STYLE, uintptr(originalStyle)) } } func ToggleExStyle(hwnd w32.HWND, b bool, style int) { originalStyle := int(w32.GetWindowLongPtr(hwnd, w32.GWL_EXSTYLE)) if originalStyle != 0 { if b { originalStyle |= style } else { originalStyle ^= style } w32.SetWindowLongPtr(hwnd, w32.GWL_EXSTYLE, uintptr(originalStyle)) } } func CreateWindow(className string, parent Controller, exStyle, style uint) w32.HWND { instance := GetAppInstance() var parentHwnd w32.HWND if parent != nil { parentHwnd = parent.Handle() } var hwnd w32.HWND hwnd = w32.CreateWindowEx( exStyle, syscall.StringToUTF16Ptr(className), nil, style, w32.CW_USEDEFAULT, w32.CW_USEDEFAULT, w32.CW_USEDEFAULT, w32.CW_USEDEFAULT, parentHwnd, 0, instance, nil) if hwnd == 0 { errStr := fmt.Sprintf("Error occurred in CreateWindow(%s, %v, %d, %d)", className, parent, exStyle, style) panic(errStr) } return hwnd } func RegisterClass(className string, wndproc uintptr) { instance := GetAppInstance() icon := w32.LoadIcon(instance, w32.MakeIntResource(w32.IDI_APPLICATION)) var wc w32.WNDCLASSEX wc.Size = uint32(unsafe.Sizeof(wc)) wc.Style = w32.CS_HREDRAW | w32.CS_VREDRAW wc.WndProc = wndproc wc.Instance = instance wc.Background = w32.COLOR_BTNFACE + 1 wc.Icon = icon wc.Cursor = w32.LoadCursor(0, w32.MakeIntResource(w32.IDC_ARROW)) wc.ClassName = syscall.StringToUTF16Ptr(className) wc.MenuName = nil wc.IconSm = icon if ret := w32.RegisterClassEx(&wc); ret == 0 { panic(syscall.GetLastError()) } } func getMonitorInfo(hwnd w32.HWND) *w32.MONITORINFO { currentMonitor := w32.MonitorFromWindow(hwnd, w32.MONITOR_DEFAULTTONEAREST) var info w32.MONITORINFO info.CbSize = uint32(unsafe.Sizeof(info)) w32.GetMonitorInfo(currentMonitor, &info) return &info } func getWindowInfo(hwnd w32.HWND) *w32.WINDOWINFO { var info w32.WINDOWINFO info.CbSize = uint32(unsafe.Sizeof(info)) w32.GetWindowInfo(hwnd, &info) return &info } func RegClassOnlyOnce(className string) { isExists := false for _, class := range gRegisteredClasses { if class == className { isExists = true break } } if !isExists { RegisterClass(className, GeneralWndprocCallBack) gRegisteredClasses = append(gRegisteredClasses, className) } } func ScreenToClientRect(hwnd w32.HWND, rect *w32.RECT) *Rect { l, t, r, b := rect.Left, rect.Top, rect.Right, rect.Bottom l1, t1, _ := w32.ScreenToClient(hwnd, int(l), int(t)) r1, b1, _ := w32.ScreenToClient(hwnd, int(r), int(b)) return NewRect(l1, t1, r1, b1) } ================================================ FILE: w32/comctl32.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. * Copyright (C) 2010-2012 The W32 Authors. All Rights Reserved. */ package w32 import ( "syscall" "unsafe" ) var ( modcomctl32 = syscall.NewLazyDLL("comctl32.dll") procInitCommonControlsEx = modcomctl32.NewProc("InitCommonControlsEx") procImageList_Create = modcomctl32.NewProc("ImageList_Create") procImageList_Destroy = modcomctl32.NewProc("ImageList_Destroy") procImageList_GetImageCount = modcomctl32.NewProc("ImageList_GetImageCount") procImageList_SetImageCount = modcomctl32.NewProc("ImageList_SetImageCount") procImageList_Add = modcomctl32.NewProc("ImageList_Add") procImageList_ReplaceIcon = modcomctl32.NewProc("ImageList_ReplaceIcon") procImageList_Remove = modcomctl32.NewProc("ImageList_Remove") procTrackMouseEvent = modcomctl32.NewProc("_TrackMouseEvent") ) func InitCommonControlsEx(lpInitCtrls *INITCOMMONCONTROLSEX) bool { ret, _, _ := procInitCommonControlsEx.Call( uintptr(unsafe.Pointer(lpInitCtrls))) return ret != 0 } func ImageList_Create(cx, cy int, flags uint, cInitial, cGrow int) HIMAGELIST { ret, _, _ := procImageList_Create.Call( uintptr(cx), uintptr(cy), uintptr(flags), uintptr(cInitial), uintptr(cGrow)) if ret == 0 { panic("Create image list failed") } return HIMAGELIST(ret) } func ImageList_Destroy(himl HIMAGELIST) bool { ret, _, _ := procImageList_Destroy.Call( uintptr(himl)) return ret != 0 } func ImageList_GetImageCount(himl HIMAGELIST) int { ret, _, _ := procImageList_GetImageCount.Call( uintptr(himl)) return int(ret) } func ImageList_SetImageCount(himl HIMAGELIST, uNewCount uint) bool { ret, _, _ := procImageList_SetImageCount.Call( uintptr(himl), uintptr(uNewCount)) return ret != 0 } func ImageList_Add(himl HIMAGELIST, hbmImage, hbmMask HBITMAP) int { ret, _, _ := procImageList_Add.Call( uintptr(himl), uintptr(hbmImage), uintptr(hbmMask)) return int(ret) } func ImageList_ReplaceIcon(himl HIMAGELIST, i int, hicon HICON) int { ret, _, _ := procImageList_ReplaceIcon.Call( uintptr(himl), uintptr(i), uintptr(hicon)) return int(ret) } func ImageList_AddIcon(himl HIMAGELIST, hicon HICON) int { return ImageList_ReplaceIcon(himl, -1, hicon) } func ImageList_Remove(himl HIMAGELIST, i int) bool { ret, _, _ := procImageList_Remove.Call( uintptr(himl), uintptr(i)) return ret != 0 } func ImageList_RemoveAll(himl HIMAGELIST) bool { return ImageList_Remove(himl, -1) } func TrackMouseEvent(tme *TRACKMOUSEEVENT) bool { ret, _, _ := procTrackMouseEvent.Call( uintptr(unsafe.Pointer(tme))) return ret != 0 } ================================================ FILE: w32/comdlg32.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. * Copyright (C) 2010-2012 The W32 Authors. All Rights Reserved. */ package w32 import ( "syscall" "unsafe" ) var ( modcomdlg32 = syscall.NewLazyDLL("comdlg32.dll") procGetSaveFileName = modcomdlg32.NewProc("GetSaveFileNameW") procGetOpenFileName = modcomdlg32.NewProc("GetOpenFileNameW") procCommDlgExtendedError = modcomdlg32.NewProc("CommDlgExtendedError") ) func GetOpenFileName(ofn *OPENFILENAME) bool { ret, _, _ := procGetOpenFileName.Call( uintptr(unsafe.Pointer(ofn))) return ret != 0 } func GetSaveFileName(ofn *OPENFILENAME) bool { ret, _, _ := procGetSaveFileName.Call( uintptr(unsafe.Pointer(ofn))) return ret != 0 } func CommDlgExtendedError() uint { ret, _, _ := procCommDlgExtendedError.Call() return uint(ret) } ================================================ FILE: w32/constants.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. * Copyright (C) 2010-2012 The W32 Authors. All Rights Reserved. */ package w32 const ( FALSE = 0 TRUE = 1 ) const ( NO_ERROR = 0 ERROR_SUCCESS = 0 ERROR_FILE_NOT_FOUND = 2 ERROR_PATH_NOT_FOUND = 3 ERROR_ACCESS_DENIED = 5 ERROR_INVALID_HANDLE = 6 ERROR_BAD_FORMAT = 11 ERROR_INVALID_NAME = 123 ERROR_MORE_DATA = 234 ERROR_NO_MORE_ITEMS = 259 ERROR_INVALID_SERVICE_CONTROL = 1052 ERROR_SERVICE_REQUEST_TIMEOUT = 1053 ERROR_SERVICE_NO_THREAD = 1054 ERROR_SERVICE_DATABASE_LOCKED = 1055 ERROR_SERVICE_ALREADY_RUNNING = 1056 ERROR_SERVICE_DISABLED = 1058 ERROR_SERVICE_DOES_NOT_EXIST = 1060 ERROR_SERVICE_CANNOT_ACCEPT_CTRL = 1061 ERROR_SERVICE_NOT_ACTIVE = 1062 ERROR_DATABASE_DOES_NOT_EXIST = 1065 ERROR_SERVICE_DEPENDENCY_FAIL = 1068 ERROR_SERVICE_LOGON_FAILED = 1069 ERROR_SERVICE_MARKED_FOR_DELETE = 1072 ERROR_SERVICE_DEPENDENCY_DELETED = 1075 ) const ( SE_ERR_FNF = 2 SE_ERR_PNF = 3 SE_ERR_ACCESSDENIED = 5 SE_ERR_OOM = 8 SE_ERR_DLLNOTFOUND = 32 SE_ERR_SHARE = 26 SE_ERR_ASSOCINCOMPLETE = 27 SE_ERR_DDETIMEOUT = 28 SE_ERR_DDEFAIL = 29 SE_ERR_DDEBUSY = 30 SE_ERR_NOASSOC = 31 ) const ( CW_USEDEFAULT = ^0x7fffffff ) const ( IMAGE_BITMAP = 0 IMAGE_ICON = 1 IMAGE_CURSOR = 2 IMAGE_ENHMETAFILE = 3 ) // ShowWindow constants const ( SW_HIDE = 0 SW_NORMAL = 1 SW_SHOWNORMAL = 1 SW_SHOWMINIMIZED = 2 SW_MAXIMIZE = 3 SW_SHOWMAXIMIZED = 3 SW_SHOWNOACTIVATE = 4 SW_SHOW = 5 SW_MINIMIZE = 6 SW_SHOWMINNOACTIVE = 7 SW_SHOWNA = 8 SW_RESTORE = 9 SW_SHOWDEFAULT = 10 SW_FORCEMINIMIZE = 11 ) // Window class styles const ( CS_VREDRAW = 0x00000001 CS_HREDRAW = 0x00000002 CS_KEYCVTWINDOW = 0x00000004 CS_DBLCLKS = 0x00000008 CS_OWNDC = 0x00000020 CS_CLASSDC = 0x00000040 CS_PARENTDC = 0x00000080 CS_NOKEYCVT = 0x00000100 CS_NOCLOSE = 0x00000200 CS_SAVEBITS = 0x00000800 CS_BYTEALIGNCLIENT = 0x00001000 CS_BYTEALIGNWINDOW = 0x00002000 CS_GLOBALCLASS = 0x00004000 CS_IME = 0x00010000 CS_DROPSHADOW = 0x00020000 ) // Predefined cursor constants const ( IDC_ARROW = 32512 IDC_IBEAM = 32513 IDC_WAIT = 32514 IDC_CROSS = 32515 IDC_UPARROW = 32516 IDC_SIZENWSE = 32642 IDC_SIZENESW = 32643 IDC_SIZEWE = 32644 IDC_SIZENS = 32645 IDC_SIZEALL = 32646 IDC_NO = 32648 IDC_HAND = 32649 IDC_APPSTARTING = 32650 IDC_HELP = 32651 IDC_ICON = 32641 IDC_SIZE = 32640 ) // Predefined icon constants const ( IDI_APPLICATION = 32512 IDI_HAND = 32513 IDI_QUESTION = 32514 IDI_EXCLAMATION = 32515 IDI_ASTERISK = 32516 IDI_WINLOGO = 32517 IDI_WARNING = IDI_EXCLAMATION IDI_ERROR = IDI_HAND IDI_INFORMATION = IDI_ASTERISK ) // Button style constants const ( BS_3STATE = 5 BS_AUTO3STATE = 6 BS_AUTOCHECKBOX = 3 BS_AUTORADIOBUTTON = 9 BS_BITMAP = 128 BS_BOTTOM = 0x800 BS_CENTER = 0x300 BS_CHECKBOX = 2 BS_DEFPUSHBUTTON = 1 BS_GROUPBOX = 7 BS_ICON = 64 BS_LEFT = 256 BS_LEFTTEXT = 32 BS_MULTILINE = 0x2000 BS_NOTIFY = 0x4000 BS_OWNERDRAW = 0xB BS_PUSHBUTTON = 0 BS_PUSHLIKE = 4096 BS_RADIOBUTTON = 4 BS_RIGHT = 512 BS_RIGHTBUTTON = 32 BS_TEXT = 0 BS_TOP = 0x400 BS_USERBUTTON = 8 BS_VCENTER = 0xC00 BS_FLAT = 0x8000 BS_SPLITBUTTON = 0x000C // >= Vista BS_DEFSPLITBUTTON = 0x000D // >= Vista ) // Button state constants const ( BST_CHECKED = 1 BST_INDETERMINATE = 2 BST_UNCHECKED = 0 BST_FOCUS = 8 BST_PUSHED = 4 ) // Predefined brushes constants const ( COLOR_3DDKSHADOW = 21 COLOR_3DFACE = 15 COLOR_3DHILIGHT = 20 COLOR_3DHIGHLIGHT = 20 COLOR_3DLIGHT = 22 COLOR_BTNHILIGHT = 20 COLOR_3DSHADOW = 16 COLOR_ACTIVEBORDER = 10 COLOR_ACTIVECAPTION = 2 COLOR_APPWORKSPACE = 12 COLOR_BACKGROUND = 1 COLOR_DESKTOP = 1 COLOR_BTNFACE = 15 COLOR_BTNHIGHLIGHT = 20 COLOR_BTNSHADOW = 16 COLOR_BTNTEXT = 18 COLOR_CAPTIONTEXT = 9 COLOR_GRAYTEXT = 17 COLOR_HIGHLIGHT = 13 COLOR_HIGHLIGHTTEXT = 14 COLOR_INACTIVEBORDER = 11 COLOR_INACTIVECAPTION = 3 COLOR_INACTIVECAPTIONTEXT = 19 COLOR_INFOBK = 24 COLOR_INFOTEXT = 23 COLOR_MENU = 4 COLOR_MENUTEXT = 7 COLOR_SCROLLBAR = 0 COLOR_WINDOW = 5 COLOR_WINDOWFRAME = 6 COLOR_WINDOWTEXT = 8 COLOR_HOTLIGHT = 26 COLOR_GRADIENTACTIVECAPTION = 27 COLOR_GRADIENTINACTIVECAPTION = 28 ) // Button message constants const ( BM_CLICK = 245 BM_GETCHECK = 240 BM_GETIMAGE = 246 BM_GETSTATE = 242 BM_SETCHECK = 241 BM_SETIMAGE = 247 BM_SETSTATE = 243 BM_SETSTYLE = 244 ) // Button notifications const ( BN_CLICKED = 0 BN_PAINT = 1 BN_HILITE = 2 BN_PUSHED = BN_HILITE BN_UNHILITE = 3 BN_UNPUSHED = BN_UNHILITE BN_DISABLE = 4 BN_DOUBLECLICKED = 5 BN_DBLCLK = BN_DOUBLECLICKED BN_SETFOCUS = 6 BN_KILLFOCUS = 7 ) // TrackPopupMenu[Ex] flags const ( TPM_CENTERALIGN = 0x0004 TPM_LEFTALIGN = 0x0000 TPM_RIGHTALIGN = 0x0008 TPM_BOTTOMALIGN = 0x0020 TPM_TOPALIGN = 0x0000 TPM_VCENTERALIGN = 0x0010 TPM_NONOTIFY = 0x0080 TPM_RETURNCMD = 0x0100 TPM_LEFTBUTTON = 0x0000 TPM_RIGHTBUTTON = 0x0002 TPM_HORNEGANIMATION = 0x0800 TPM_HORPOSANIMATION = 0x0400 TPM_NOANIMATION = 0x4000 TPM_VERNEGANIMATION = 0x2000 TPM_VERPOSANIMATION = 0x1000 TPM_HORIZONTAL = 0x0000 TPM_VERTICAL = 0x0040 ) // GetWindowLong and GetWindowLongPtr constants const ( GWL_EXSTYLE = -20 GWL_STYLE = -16 GWL_WNDPROC = -4 GWLP_WNDPROC = -4 GWL_HINSTANCE = -6 GWLP_HINSTANCE = -6 GWL_HWNDPARENT = -8 GWLP_HWNDPARENT = -8 GWL_ID = -12 GWLP_ID = -12 GWL_USERDATA = -21 GWLP_USERDATA = -21 ) // Window style constants const ( WS_OVERLAPPED = 0x00000000 WS_POPUP = 0x80000000 WS_CHILD = 0x40000000 WS_MINIMIZE = 0x20000000 WS_VISIBLE = 0x10000000 WS_DISABLED = 0x08000000 WS_CLIPSIBLINGS = 0x04000000 WS_CLIPCHILDREN = 0x02000000 WS_MAXIMIZE = 0x01000000 WS_CAPTION = 0x00C00000 WS_BORDER = 0x00800000 WS_DLGFRAME = 0x00400000 WS_VSCROLL = 0x00200000 WS_HSCROLL = 0x00100000 WS_SYSMENU = 0x00080000 WS_THICKFRAME = 0x00040000 WS_GROUP = 0x00020000 WS_TABSTOP = 0x00010000 WS_MINIMIZEBOX = 0x00020000 WS_MAXIMIZEBOX = 0x00010000 WS_TILED = 0x00000000 WS_ICONIC = 0x20000000 WS_SIZEBOX = 0x00040000 WS_OVERLAPPEDWINDOW = 0x00000000 | 0x00C00000 | 0x00080000 | 0x00040000 | 0x00020000 | 0x00010000 WS_POPUPWINDOW = 0x80000000 | 0x00800000 | 0x00080000 WS_CHILDWINDOW = 0x40000000 ) // Extended window style constants const ( WS_EX_DLGMODALFRAME = 0x00000001 WS_EX_NOPARENTNOTIFY = 0x00000004 WS_EX_TOPMOST = 0x00000008 WS_EX_ACCEPTFILES = 0x00000010 WS_EX_TRANSPARENT = 0x00000020 WS_EX_MDICHILD = 0x00000040 WS_EX_TOOLWINDOW = 0x00000080 WS_EX_WINDOWEDGE = 0x00000100 WS_EX_CLIENTEDGE = 0x00000200 WS_EX_CONTEXTHELP = 0x00000400 WS_EX_RIGHT = 0x00001000 WS_EX_LEFT = 0x00000000 WS_EX_RTLREADING = 0x00002000 WS_EX_LTRREADING = 0x00000000 WS_EX_LEFTSCROLLBAR = 0x00004000 WS_EX_RIGHTSCROLLBAR = 0x00000000 WS_EX_CONTROLPARENT = 0x00010000 WS_EX_STATICEDGE = 0x00020000 WS_EX_APPWINDOW = 0x00040000 WS_EX_OVERLAPPEDWINDOW = 0x00000100 | 0x00000200 WS_EX_PALETTEWINDOW = 0x00000100 | 0x00000080 | 0x00000008 WS_EX_LAYERED = 0x00080000 WS_EX_NOINHERITLAYOUT = 0x00100000 WS_EX_NOREDIRECTIONBITMAP = 0x00200000 WS_EX_LAYOUTRTL = 0x00400000 WS_EX_NOACTIVATE = 0x08000000 ) // Window message constants const ( WM_APP = 32768 WM_ACTIVATE = 6 WM_ACTIVATEAPP = 28 WM_AFXFIRST = 864 WM_AFXLAST = 895 WM_ASKCBFORMATNAME = 780 WM_CANCELJOURNAL = 75 WM_CANCELMODE = 31 WM_CAPTURECHANGED = 533 WM_CHANGECBCHAIN = 781 WM_CHAR = 258 WM_CHARTOITEM = 47 WM_CHILDACTIVATE = 34 WM_CLEAR = 771 WM_CLOSE = 16 WM_COMMAND = 273 WM_COMMNOTIFY = 68 /* OBSOLETE */ WM_COMPACTING = 65 WM_COMPAREITEM = 57 WM_CONTEXTMENU = 123 WM_COPY = 769 WM_COPYDATA = 74 WM_CREATE = 1 WM_CTLCOLORBTN = 309 WM_CTLCOLORDLG = 310 WM_CTLCOLOREDIT = 307 WM_CTLCOLORLISTBOX = 308 WM_CTLCOLORMSGBOX = 306 WM_CTLCOLORSCROLLBAR = 311 WM_CTLCOLORSTATIC = 312 WM_CUT = 768 WM_DEADCHAR = 259 WM_DELETEITEM = 45 WM_DESTROY = 2 WM_DESTROYCLIPBOARD = 775 WM_DEVICECHANGE = 537 WM_DEVMODECHANGE = 27 WM_DISPLAYCHANGE = 126 WM_DRAWCLIPBOARD = 776 WM_DRAWITEM = 43 WM_DROPFILES = 563 WM_ENABLE = 10 WM_ENDSESSION = 22 WM_ENTERIDLE = 289 WM_ENTERMENULOOP = 529 WM_ENTERSIZEMOVE = 561 WM_ERASEBKGND = 20 WM_EXITMENULOOP = 530 WM_EXITSIZEMOVE = 562 WM_FONTCHANGE = 29 WM_GETDLGCODE = 135 WM_GETFONT = 49 WM_GETHOTKEY = 51 WM_GETICON = 127 WM_GETMINMAXINFO = 36 WM_GETTEXT = 13 WM_GETTEXTLENGTH = 14 WM_HANDHELDFIRST = 856 WM_HANDHELDLAST = 863 WM_HELP = 83 WM_HOTKEY = 786 WM_HSCROLL = 276 WM_HSCROLLCLIPBOARD = 782 WM_ICONERASEBKGND = 39 WM_INITDIALOG = 272 WM_INITMENU = 278 WM_INITMENUPOPUP = 279 WM_INPUT = 0x00FF WM_INPUTLANGCHANGE = 81 WM_INPUTLANGCHANGEREQUEST = 80 WM_KEYDOWN = 256 WM_KEYUP = 257 WM_KILLFOCUS = 8 WM_MDIACTIVATE = 546 WM_MDICASCADE = 551 WM_MDICREATE = 544 WM_MDIDESTROY = 545 WM_MDIGETACTIVE = 553 WM_MDIICONARRANGE = 552 WM_MDIMAXIMIZE = 549 WM_MDINEXT = 548 WM_MDIREFRESHMENU = 564 WM_MDIRESTORE = 547 WM_MDISETMENU = 560 WM_MDITILE = 550 WM_MEASUREITEM = 44 WM_GETOBJECT = 0x003D WM_CHANGEUISTATE = 0x0127 WM_UPDATEUISTATE = 0x0128 WM_QUERYUISTATE = 0x0129 WM_UNINITMENUPOPUP = 0x0125 WM_MENURBUTTONUP = 290 WM_MENUCOMMAND = 0x0126 WM_MENUGETOBJECT = 0x0124 WM_MENUDRAG = 0x0123 WM_APPCOMMAND = 0x0319 WM_MENUCHAR = 288 WM_MENUSELECT = 287 WM_MOVE = 3 WM_MOVING = 534 WM_NCACTIVATE = 134 WM_NCCALCSIZE = 131 WM_NCCREATE = 129 WM_NCDESTROY = 130 WM_NCHITTEST = 132 WM_NCLBUTTONDBLCLK = 163 WM_NCLBUTTONDOWN = 161 WM_NCLBUTTONUP = 162 WM_NCMBUTTONDBLCLK = 169 WM_NCMBUTTONDOWN = 167 WM_NCMBUTTONUP = 168 WM_NCXBUTTONDOWN = 171 WM_NCXBUTTONUP = 172 WM_NCXBUTTONDBLCLK = 173 WM_NCMOUSEHOVER = 0x02A0 WM_NCMOUSELEAVE = 0x02A2 WM_NCMOUSEMOVE = 160 WM_NCPAINT = 133 WM_NCRBUTTONDBLCLK = 166 WM_NCRBUTTONDOWN = 164 WM_NCRBUTTONUP = 165 WM_NEXTDLGCTL = 40 WM_NEXTMENU = 531 WM_NOTIFY = 78 WM_NOTIFYFORMAT = 85 WM_NULL = 0 WM_PAINT = 15 WM_PAINTCLIPBOARD = 777 WM_PAINTICON = 38 WM_PALETTECHANGED = 785 WM_PALETTEISCHANGING = 784 WM_PARENTNOTIFY = 528 WM_PASTE = 770 WM_PENWINFIRST = 896 WM_PENWINLAST = 911 WM_POWER = 72 WM_POWERBROADCAST = 536 WM_PRINT = 791 WM_PRINTCLIENT = 792 WM_QUERYDRAGICON = 55 WM_QUERYENDSESSION = 17 WM_QUERYNEWPALETTE = 783 WM_QUERYOPEN = 19 WM_QUEUESYNC = 35 WM_QUIT = 18 WM_RENDERALLFORMATS = 774 WM_RENDERFORMAT = 773 WM_SETCURSOR = 32 WM_SETFOCUS = 7 WM_SETFONT = 48 WM_SETHOTKEY = 50 WM_SETICON = 128 WM_SETREDRAW = 11 WM_SETTEXT = 12 WM_SETTINGCHANGE = 26 WM_SHOWWINDOW = 24 WM_SIZE = 5 WM_SIZECLIPBOARD = 779 WM_SIZING = 532 WM_SPOOLERSTATUS = 42 WM_STYLECHANGED = 125 WM_STYLECHANGING = 124 WM_SYSCHAR = 262 WM_SYSCOLORCHANGE = 21 WM_SYSCOMMAND = 274 WM_SYSDEADCHAR = 263 WM_SYSKEYDOWN = 260 WM_SYSKEYUP = 261 WM_TCARD = 82 WM_THEMECHANGED = 794 WM_TIMECHANGE = 30 WM_TIMER = 275 WM_UNDO = 772 WM_USER = 1024 WM_USERCHANGED = 84 WM_VKEYTOITEM = 46 WM_VSCROLL = 277 WM_VSCROLLCLIPBOARD = 778 WM_WINDOWPOSCHANGED = 71 WM_WINDOWPOSCHANGING = 70 WM_WININICHANGE = 26 WM_KEYFIRST = 256 WM_KEYLAST = 264 WM_SYNCPAINT = 136 WM_MOUSEACTIVATE = 33 WM_MOUSEMOVE = 512 WM_LBUTTONDOWN = 513 WM_LBUTTONUP = 514 WM_LBUTTONDBLCLK = 515 WM_RBUTTONDOWN = 516 WM_RBUTTONUP = 517 WM_RBUTTONDBLCLK = 518 WM_MBUTTONDOWN = 519 WM_MBUTTONUP = 520 WM_MBUTTONDBLCLK = 521 WM_MOUSEWHEEL = 522 WM_MOUSEFIRST = 512 WM_XBUTTONDOWN = 523 WM_XBUTTONUP = 524 WM_XBUTTONDBLCLK = 525 WM_MOUSELAST = 525 WM_MOUSEHOVER = 0x2A1 WM_MOUSELEAVE = 0x2A3 WM_CLIPBOARDUPDATE = 0x031D ) // WM_ACTIVATE const ( WA_INACTIVE = 0 WA_ACTIVE = 1 WA_CLICKACTIVE = 2 ) const LF_FACESIZE = 32 // Font weight constants const ( FW_DONTCARE = 0 FW_THIN = 100 FW_EXTRALIGHT = 200 FW_ULTRALIGHT = FW_EXTRALIGHT FW_LIGHT = 300 FW_NORMAL = 400 FW_REGULAR = 400 FW_MEDIUM = 500 FW_SEMIBOLD = 600 FW_DEMIBOLD = FW_SEMIBOLD FW_BOLD = 700 FW_EXTRABOLD = 800 FW_ULTRABOLD = FW_EXTRABOLD FW_HEAVY = 900 FW_BLACK = FW_HEAVY ) // Charset constants const ( ANSI_CHARSET = 0 DEFAULT_CHARSET = 1 SYMBOL_CHARSET = 2 SHIFTJIS_CHARSET = 128 HANGEUL_CHARSET = 129 HANGUL_CHARSET = 129 GB2312_CHARSET = 134 CHINESEBIG5_CHARSET = 136 GREEK_CHARSET = 161 TURKISH_CHARSET = 162 HEBREW_CHARSET = 177 ARABIC_CHARSET = 178 BALTIC_CHARSET = 186 RUSSIAN_CHARSET = 204 THAI_CHARSET = 222 EASTEUROPE_CHARSET = 238 OEM_CHARSET = 255 JOHAB_CHARSET = 130 VIETNAMESE_CHARSET = 163 MAC_CHARSET = 77 ) // Font output precision constants const ( OUT_DEFAULT_PRECIS = 0 OUT_STRING_PRECIS = 1 OUT_CHARACTER_PRECIS = 2 OUT_STROKE_PRECIS = 3 OUT_TT_PRECIS = 4 OUT_DEVICE_PRECIS = 5 OUT_RASTER_PRECIS = 6 OUT_TT_ONLY_PRECIS = 7 OUT_OUTLINE_PRECIS = 8 OUT_PS_ONLY_PRECIS = 10 ) // Font clipping precision constants const ( CLIP_DEFAULT_PRECIS = 0 CLIP_CHARACTER_PRECIS = 1 CLIP_STROKE_PRECIS = 2 CLIP_MASK = 15 CLIP_LH_ANGLES = 16 CLIP_TT_ALWAYS = 32 CLIP_EMBEDDED = 128 ) // Font output quality constants const ( DEFAULT_QUALITY = 0 DRAFT_QUALITY = 1 PROOF_QUALITY = 2 NONANTIALIASED_QUALITY = 3 ANTIALIASED_QUALITY = 4 CLEARTYPE_QUALITY = 5 ) // Font pitch constants const ( DEFAULT_PITCH = 0 FIXED_PITCH = 1 VARIABLE_PITCH = 2 ) // Font family constants const ( FF_DECORATIVE = 80 FF_DONTCARE = 0 FF_MODERN = 48 FF_ROMAN = 16 FF_SCRIPT = 64 FF_SWISS = 32 ) // DeviceCapabilities capabilities const ( DC_FIELDS = 1 DC_PAPERS = 2 DC_PAPERSIZE = 3 DC_MINEXTENT = 4 DC_MAXEXTENT = 5 DC_BINS = 6 DC_DUPLEX = 7 DC_SIZE = 8 DC_EXTRA = 9 DC_VERSION = 10 DC_DRIVER = 11 DC_BINNAMES = 12 DC_ENUMRESOLUTIONS = 13 DC_FILEDEPENDENCIES = 14 DC_TRUETYPE = 15 DC_PAPERNAMES = 16 DC_ORIENTATION = 17 DC_COPIES = 18 DC_BINADJUST = 19 DC_EMF_COMPLIANT = 20 DC_DATATYPE_PRODUCED = 21 DC_COLLATE = 22 DC_MANUFACTURER = 23 DC_MODEL = 24 DC_PERSONALITY = 25 DC_PRINTRATE = 26 DC_PRINTRATEUNIT = 27 DC_PRINTERMEM = 28 DC_MEDIAREADY = 29 DC_STAPLE = 30 DC_PRINTRATEPPM = 31 DC_COLORDEVICE = 32 DC_NUP = 33 DC_MEDIATYPENAMES = 34 DC_MEDIATYPES = 35 ) // GetDeviceCaps index constants const ( DRIVERVERSION = 0 TECHNOLOGY = 2 HORZSIZE = 4 VERTSIZE = 6 HORZRES = 8 VERTRES = 10 LOGPIXELSX = 88 LOGPIXELSY = 90 BITSPIXEL = 12 PLANES = 14 NUMBRUSHES = 16 NUMPENS = 18 NUMFONTS = 22 NUMCOLORS = 24 NUMMARKERS = 20 ASPECTX = 40 ASPECTY = 42 ASPECTXY = 44 PDEVICESIZE = 26 CLIPCAPS = 36 SIZEPALETTE = 104 NUMRESERVED = 106 COLORRES = 108 PHYSICALWIDTH = 110 PHYSICALHEIGHT = 111 PHYSICALOFFSETX = 112 PHYSICALOFFSETY = 113 SCALINGFACTORX = 114 SCALINGFACTORY = 115 VREFRESH = 116 DESKTOPHORZRES = 118 DESKTOPVERTRES = 117 BLTALIGNMENT = 119 SHADEBLENDCAPS = 120 COLORMGMTCAPS = 121 RASTERCAPS = 38 CURVECAPS = 28 LINECAPS = 30 POLYGONALCAPS = 32 TEXTCAPS = 34 ) // GetDeviceCaps TECHNOLOGY constants const ( DT_PLOTTER = 0 DT_RASDISPLAY = 1 DT_RASPRINTER = 2 DT_RASCAMERA = 3 DT_CHARSTREAM = 4 DT_METAFILE = 5 DT_DISPFILE = 6 ) // GetDeviceCaps SHADEBLENDCAPS constants const ( SB_NONE = 0x00 SB_CONST_ALPHA = 0x01 SB_PIXEL_ALPHA = 0x02 SB_PREMULT_ALPHA = 0x04 SB_GRAD_RECT = 0x10 SB_GRAD_TRI = 0x20 ) // GetDeviceCaps COLORMGMTCAPS constants const ( CM_NONE = 0x00 CM_DEVICE_ICM = 0x01 CM_GAMMA_RAMP = 0x02 CM_CMYK_COLOR = 0x04 ) // GetDeviceCaps RASTERCAPS constants const ( RC_BANDING = 2 RC_BITBLT = 1 RC_BITMAP64 = 8 RC_DI_BITMAP = 128 RC_DIBTODEV = 512 RC_FLOODFILL = 4096 RC_GDI20_OUTPUT = 16 RC_PALETTE = 256 RC_SCALING = 4 RC_STRETCHBLT = 2048 RC_STRETCHDIB = 8192 RC_DEVBITS = 0x8000 RC_OP_DX_OUTPUT = 0x4000 ) // GetDeviceCaps CURVECAPS constants const ( CC_NONE = 0 CC_CIRCLES = 1 CC_PIE = 2 CC_CHORD = 4 CC_ELLIPSES = 8 CC_WIDE = 16 CC_STYLED = 32 CC_WIDESTYLED = 64 CC_INTERIORS = 128 CC_ROUNDRECT = 256 ) // GetDeviceCaps LINECAPS constants const ( LC_NONE = 0 LC_POLYLINE = 2 LC_MARKER = 4 LC_POLYMARKER = 8 LC_WIDE = 16 LC_STYLED = 32 LC_WIDESTYLED = 64 LC_INTERIORS = 128 ) // GetDeviceCaps POLYGONALCAPS constants const ( PC_NONE = 0 PC_POLYGON = 1 PC_POLYPOLYGON = 256 PC_PATHS = 512 PC_RECTANGLE = 2 PC_WINDPOLYGON = 4 PC_SCANLINE = 8 PC_TRAPEZOID = 4 PC_WIDE = 16 PC_STYLED = 32 PC_WIDESTYLED = 64 PC_INTERIORS = 128 ) // GetDeviceCaps TEXTCAPS constants const ( TC_OP_CHARACTER = 1 TC_OP_STROKE = 2 TC_CP_STROKE = 4 TC_CR_90 = 8 TC_CR_ANY = 16 TC_SF_X_YINDEP = 32 TC_SA_DOUBLE = 64 TC_SA_INTEGER = 128 TC_SA_CONTIN = 256 TC_EA_DOUBLE = 512 TC_IA_ABLE = 1024 TC_UA_ABLE = 2048 TC_SO_ABLE = 4096 TC_RA_ABLE = 8192 TC_VA_ABLE = 16384 TC_RESERVED = 32768 TC_SCROLLBLT = 65536 ) // Static control styles const ( SS_BITMAP = 14 SS_BLACKFRAME = 7 SS_BLACKRECT = 4 SS_CENTER = 1 SS_CENTERIMAGE = 512 SS_EDITCONTROL = 0x2000 SS_ENHMETAFILE = 15 SS_ETCHEDFRAME = 18 SS_ETCHEDHORZ = 16 SS_ETCHEDVERT = 17 SS_GRAYFRAME = 8 SS_GRAYRECT = 5 SS_ICON = 3 SS_LEFT = 0 SS_LEFTNOWORDWRAP = 0xc SS_NOPREFIX = 128 SS_NOTIFY = 256 SS_OWNERDRAW = 0xd SS_REALSIZECONTROL = 0x040 SS_REALSIZEIMAGE = 0x800 SS_RIGHT = 2 SS_RIGHTJUST = 0x400 SS_SIMPLE = 11 SS_SUNKEN = 4096 SS_WHITEFRAME = 9 SS_WHITERECT = 6 SS_USERITEM = 10 SS_TYPEMASK = 0x0000001F SS_ENDELLIPSIS = 0x00004000 SS_PATHELLIPSIS = 0x00008000 SS_WORDELLIPSIS = 0x0000C000 SS_ELLIPSISMASK = 0x0000C000 ) // Edit styles const ( ES_LEFT = 0x0000 ES_CENTER = 0x0001 ES_RIGHT = 0x0002 ES_MULTILINE = 0x0004 ES_UPPERCASE = 0x0008 ES_LOWERCASE = 0x0010 ES_PASSWORD = 0x0020 ES_AUTOVSCROLL = 0x0040 ES_AUTOHSCROLL = 0x0080 ES_NOHIDESEL = 0x0100 ES_OEMCONVERT = 0x0400 ES_READONLY = 0x0800 ES_WANTRETURN = 0x1000 ES_NUMBER = 0x2000 ) // Edit notifications const ( EN_SETFOCUS = 0x0100 EN_KILLFOCUS = 0x0200 EN_CHANGE = 0x0300 EN_UPDATE = 0x0400 EN_ERRSPACE = 0x0500 EN_MAXTEXT = 0x0501 EN_HSCROLL = 0x0601 EN_VSCROLL = 0x0602 EN_ALIGN_LTR_EC = 0x0700 EN_ALIGN_RTL_EC = 0x0701 ) // Edit messages const ( EM_GETSEL = 0x00B0 EM_SETSEL = 0x00B1 EM_GETRECT = 0x00B2 EM_SETRECT = 0x00B3 EM_SETRECTNP = 0x00B4 EM_SCROLL = 0x00B5 EM_LINESCROLL = 0x00B6 EM_SCROLLCARET = 0x00B7 EM_GETMODIFY = 0x00B8 EM_SETMODIFY = 0x00B9 EM_GETLINECOUNT = 0x00BA EM_LINEINDEX = 0x00BB EM_SETHANDLE = 0x00BC EM_GETHANDLE = 0x00BD EM_GETTHUMB = 0x00BE EM_LINELENGTH = 0x00C1 EM_REPLACESEL = 0x00C2 EM_GETLINE = 0x00C4 EM_LIMITTEXT = 0x00C5 EM_CANUNDO = 0x00C6 EM_UNDO = 0x00C7 EM_FMTLINES = 0x00C8 EM_LINEFROMCHAR = 0x00C9 EM_SETTABSTOPS = 0x00CB EM_SETPASSWORDCHAR = 0x00CC EM_EMPTYUNDOBUFFER = 0x00CD EM_GETFIRSTVISIBLELINE = 0x00CE EM_SETREADONLY = 0x00CF EM_SETWORDBREAKPROC = 0x00D0 EM_GETWORDBREAKPROC = 0x00D1 EM_GETPASSWORDCHAR = 0x00D2 EM_SETMARGINS = 0x00D3 EM_GETMARGINS = 0x00D4 EM_SETLIMITTEXT = EM_LIMITTEXT EM_GETLIMITTEXT = 0x00D5 EM_POSFROMCHAR = 0x00D6 EM_CHARFROMPOS = 0x00D7 EM_SETIMESTATUS = 0x00D8 EM_GETIMESTATUS = 0x00D9 EM_SETCUEBANNER = 0x1501 EM_GETCUEBANNER = 0x1502 ) const ( CCM_FIRST = 0x2000 CCM_LAST = CCM_FIRST + 0x200 CCM_SETBKCOLOR = 8193 CCM_SETCOLORSCHEME = 8194 CCM_GETCOLORSCHEME = 8195 CCM_GETDROPTARGET = 8196 CCM_SETUNICODEFORMAT = 8197 CCM_GETUNICODEFORMAT = 8198 CCM_SETVERSION = 0x2007 CCM_GETVERSION = 0x2008 CCM_SETNOTIFYWINDOW = 0x2009 CCM_SETWINDOWTHEME = 0x200b CCM_DPISCALE = 0x200c ) // Common controls styles const ( CCS_TOP = 1 CCS_NOMOVEY = 2 CCS_BOTTOM = 3 CCS_NORESIZE = 4 CCS_NOPARENTALIGN = 8 CCS_ADJUSTABLE = 32 CCS_NODIVIDER = 64 CCS_VERT = 128 CCS_LEFT = 129 CCS_NOMOVEX = 130 CCS_RIGHT = 131 ) // ProgressBar messages const ( PROGRESS_CLASS = "msctls_progress32" PBM_SETPOS = WM_USER + 2 PBM_DELTAPOS = WM_USER + 3 PBM_SETSTEP = WM_USER + 4 PBM_STEPIT = WM_USER + 5 PBM_SETRANGE32 = 1030 PBM_GETRANGE = 1031 PBM_GETPOS = 1032 PBM_SETBARCOLOR = 1033 PBM_SETBKCOLOR = CCM_SETBKCOLOR PBS_SMOOTH = 1 PBS_VERTICAL = 4 ) // Trackbar messages and constants const ( TBS_AUTOTICKS = 1 TBS_VERT = 2 TBS_HORZ = 0 TBS_TOP = 4 TBS_BOTTOM = 0 TBS_LEFT = 4 TBS_RIGHT = 0 TBS_BOTH = 8 TBS_NOTICKS = 16 TBS_ENABLESELRANGE = 32 TBS_FIXEDLENGTH = 64 TBS_NOTHUMB = 128 TBS_TOOLTIPS = 0x0100 ) const ( TBM_GETPOS = (WM_USER) TBM_GETRANGEMIN = (WM_USER + 1) TBM_GETRANGEMAX = (WM_USER + 2) TBM_GETTIC = (WM_USER + 3) TBM_SETTIC = (WM_USER + 4) TBM_SETPOS = (WM_USER + 5) TBM_SETRANGE = (WM_USER + 6) TBM_SETRANGEMIN = (WM_USER + 7) TBM_SETRANGEMAX = (WM_USER + 8) TBM_CLEARTICS = (WM_USER + 9) TBM_SETSEL = (WM_USER + 10) TBM_SETSELSTART = (WM_USER + 11) TBM_SETSELEND = (WM_USER + 12) TBM_GETPTICS = (WM_USER + 14) TBM_GETTICPOS = (WM_USER + 15) TBM_GETNUMTICS = (WM_USER + 16) TBM_GETSELSTART = (WM_USER + 17) TBM_GETSELEND = (WM_USER + 18) TBM_CLEARSEL = (WM_USER + 19) TBM_SETTICFREQ = (WM_USER + 20) TBM_SETPAGESIZE = (WM_USER + 21) TBM_GETPAGESIZE = (WM_USER + 22) TBM_SETLINESIZE = (WM_USER + 23) TBM_GETLINESIZE = (WM_USER + 24) TBM_GETTHUMBRECT = (WM_USER + 25) TBM_GETCHANNELRECT = (WM_USER + 26) TBM_SETTHUMBLENGTH = (WM_USER + 27) TBM_GETTHUMBLENGTH = (WM_USER + 28) TBM_SETTOOLTIPS = (WM_USER + 29) TBM_GETTOOLTIPS = (WM_USER + 30) TBM_SETTIPSIDE = (WM_USER + 31) TBM_SETBUDDY = (WM_USER + 32) TBM_GETBUDDY = (WM_USER + 33) ) const ( TB_LINEUP = 0 TB_LINEDOWN = 1 TB_PAGEUP = 2 TB_PAGEDOWN = 3 TB_THUMBPOSITION = 4 TB_THUMBTRACK = 5 TB_TOP = 6 TB_BOTTOM = 7 TB_ENDTRACK = 8 ) // GetOpenFileName and GetSaveFileName extended flags const ( OFN_EX_NOPLACESBAR = 0x00000001 ) // GetOpenFileName and GetSaveFileName flags const ( OFN_ALLOWMULTISELECT = 0x00000200 OFN_CREATEPROMPT = 0x00002000 OFN_DONTADDTORECENT = 0x02000000 OFN_ENABLEHOOK = 0x00000020 OFN_ENABLEINCLUDENOTIFY = 0x00400000 OFN_ENABLESIZING = 0x00800000 OFN_ENABLETEMPLATE = 0x00000040 OFN_ENABLETEMPLATEHANDLE = 0x00000080 OFN_EXPLORER = 0x00080000 OFN_EXTENSIONDIFFERENT = 0x00000400 OFN_FILEMUSTEXIST = 0x00001000 OFN_FORCESHOWHIDDEN = 0x10000000 OFN_HIDEREADONLY = 0x00000004 OFN_LONGNAMES = 0x00200000 OFN_NOCHANGEDIR = 0x00000008 OFN_NODEREFERENCELINKS = 0x00100000 OFN_NOLONGNAMES = 0x00040000 OFN_NONETWORKBUTTON = 0x00020000 OFN_NOREADONLYRETURN = 0x00008000 OFN_NOTESTFILECREATE = 0x00010000 OFN_NOVALIDATE = 0x00000100 OFN_OVERWRITEPROMPT = 0x00000002 OFN_PATHMUSTEXIST = 0x00000800 OFN_READONLY = 0x00000001 OFN_SHAREAWARE = 0x00004000 OFN_SHOWHELP = 0x00000010 ) //SHBrowseForFolder flags const ( BIF_RETURNONLYFSDIRS = 0x00000001 BIF_DONTGOBELOWDOMAIN = 0x00000002 BIF_STATUSTEXT = 0x00000004 BIF_RETURNFSANCESTORS = 0x00000008 BIF_EDITBOX = 0x00000010 BIF_VALIDATE = 0x00000020 BIF_NEWDIALOGSTYLE = 0x00000040 BIF_BROWSEINCLUDEURLS = 0x00000080 BIF_USENEWUI = BIF_EDITBOX | BIF_NEWDIALOGSTYLE BIF_UAHINT = 0x00000100 BIF_NONEWFOLDERBUTTON = 0x00000200 BIF_NOTRANSLATETARGETS = 0x00000400 BIF_BROWSEFORCOMPUTER = 0x00001000 BIF_BROWSEFORPRINTER = 0x00002000 BIF_BROWSEINCLUDEFILES = 0x00004000 BIF_SHAREABLE = 0x00008000 BIF_BROWSEFILEJUNCTIONS = 0x00010000 ) //MessageBox flags const ( MB_OK = 0x00000000 MB_OKCANCEL = 0x00000001 MB_ABORTRETRYIGNORE = 0x00000002 MB_YESNOCANCEL = 0x00000003 MB_YESNO = 0x00000004 MB_RETRYCANCEL = 0x00000005 MB_CANCELTRYCONTINUE = 0x00000006 MB_ICONHAND = 0x00000010 MB_ICONQUESTION = 0x00000020 MB_ICONEXCLAMATION = 0x00000030 MB_ICONASTERISK = 0x00000040 MB_USERICON = 0x00000080 MB_ICONWARNING = MB_ICONEXCLAMATION MB_ICONERROR = MB_ICONHAND MB_ICONINFORMATION = MB_ICONASTERISK MB_ICONSTOP = MB_ICONHAND MB_DEFBUTTON1 = 0x00000000 MB_DEFBUTTON2 = 0x00000100 MB_DEFBUTTON3 = 0x00000200 MB_DEFBUTTON4 = 0x00000300 ) //COM const ( E_INVALIDARG = 0x80070057 E_OUTOFMEMORY = 0x8007000E E_UNEXPECTED = 0x8000FFFF ) const ( S_OK = 0 S_FALSE = 0x0001 RPC_E_CHANGED_MODE = 0x80010106 ) // GetSystemMetrics constants const ( SM_CXSCREEN = 0 SM_CYSCREEN = 1 SM_CXVSCROLL = 2 SM_CYHSCROLL = 3 SM_CYCAPTION = 4 SM_CXBORDER = 5 SM_CYBORDER = 6 SM_CXDLGFRAME = 7 SM_CYDLGFRAME = 8 SM_CYVTHUMB = 9 SM_CXHTHUMB = 10 SM_CXICON = 11 SM_CYICON = 12 SM_CXCURSOR = 13 SM_CYCURSOR = 14 SM_CYMENU = 15 SM_CXFULLSCREEN = 16 SM_CYFULLSCREEN = 17 SM_CYKANJIWINDOW = 18 SM_MOUSEPRESENT = 19 SM_CYVSCROLL = 20 SM_CXHSCROLL = 21 SM_DEBUG = 22 SM_SWAPBUTTON = 23 SM_RESERVED1 = 24 SM_RESERVED2 = 25 SM_RESERVED3 = 26 SM_RESERVED4 = 27 SM_CXMIN = 28 SM_CYMIN = 29 SM_CXSIZE = 30 SM_CYSIZE = 31 SM_CXFRAME = 32 SM_CYFRAME = 33 SM_CXMINTRACK = 34 SM_CYMINTRACK = 35 SM_CXDOUBLECLK = 36 SM_CYDOUBLECLK = 37 SM_CXICONSPACING = 38 SM_CYICONSPACING = 39 SM_MENUDROPALIGNMENT = 40 SM_PENWINDOWS = 41 SM_DBCSENABLED = 42 SM_CMOUSEBUTTONS = 43 SM_CXFIXEDFRAME = SM_CXDLGFRAME SM_CYFIXEDFRAME = SM_CYDLGFRAME SM_CXSIZEFRAME = SM_CXFRAME SM_CYSIZEFRAME = SM_CYFRAME SM_SECURE = 44 SM_CXEDGE = 45 SM_CYEDGE = 46 SM_CXMINSPACING = 47 SM_CYMINSPACING = 48 SM_CXSMICON = 49 SM_CYSMICON = 50 SM_CYSMCAPTION = 51 SM_CXSMSIZE = 52 SM_CYSMSIZE = 53 SM_CXMENUSIZE = 54 SM_CYMENUSIZE = 55 SM_ARRANGE = 56 SM_CXMINIMIZED = 57 SM_CYMINIMIZED = 58 SM_CXMAXTRACK = 59 SM_CYMAXTRACK = 60 SM_CXMAXIMIZED = 61 SM_CYMAXIMIZED = 62 SM_NETWORK = 63 SM_CLEANBOOT = 67 SM_CXDRAG = 68 SM_CYDRAG = 69 SM_SHOWSOUNDS = 70 SM_CXMENUCHECK = 71 SM_CYMENUCHECK = 72 SM_SLOWMACHINE = 73 SM_MIDEASTENABLED = 74 SM_MOUSEWHEELPRESENT = 75 SM_XVIRTUALSCREEN = 76 SM_YVIRTUALSCREEN = 77 SM_CXVIRTUALSCREEN = 78 SM_CYVIRTUALSCREEN = 79 SM_CMONITORS = 80 SM_SAMEDISPLAYFORMAT = 81 SM_IMMENABLED = 82 SM_CXFOCUSBORDER = 83 SM_CYFOCUSBORDER = 84 SM_TABLETPC = 86 SM_MEDIACENTER = 87 SM_STARTER = 88 SM_SERVERR2 = 89 SM_CMETRICS = 91 SM_REMOTESESSION = 0x1000 SM_SHUTTINGDOWN = 0x2000 SM_REMOTECONTROL = 0x2001 SM_CARETBLINKINGENABLED = 0x2002 ) const ( CLSCTX_INPROC_SERVER = 1 CLSCTX_INPROC_HANDLER = 2 CLSCTX_LOCAL_SERVER = 4 CLSCTX_INPROC_SERVER16 = 8 CLSCTX_REMOTE_SERVER = 16 CLSCTX_ALL = CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER | CLSCTX_LOCAL_SERVER CLSCTX_INPROC = CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER CLSCTX_SERVER = CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER ) const ( COINIT_APARTMENTTHREADED = 0x2 COINIT_MULTITHREADED = 0x0 COINIT_DISABLE_OLE1DDE = 0x4 COINIT_SPEED_OVER_MEMORY = 0x8 ) const ( DISPATCH_METHOD = 1 DISPATCH_PROPERTYGET = 2 DISPATCH_PROPERTYPUT = 4 DISPATCH_PROPERTYPUTREF = 8 ) const ( CC_FASTCALL = iota CC_CDECL CC_MSCPASCAL CC_PASCAL = CC_MSCPASCAL CC_MACPASCAL CC_STDCALL CC_FPFASTCALL CC_SYSCALL CC_MPWCDECL CC_MPWPASCAL CC_MAX = CC_MPWPASCAL ) const ( VT_EMPTY = 0x0 VT_NULL = 0x1 VT_I2 = 0x2 VT_I4 = 0x3 VT_R4 = 0x4 VT_R8 = 0x5 VT_CY = 0x6 VT_DATE = 0x7 VT_BSTR = 0x8 VT_DISPATCH = 0x9 VT_ERROR = 0xa VT_BOOL = 0xb VT_VARIANT = 0xc VT_UNKNOWN = 0xd VT_DECIMAL = 0xe VT_I1 = 0x10 VT_UI1 = 0x11 VT_UI2 = 0x12 VT_UI4 = 0x13 VT_I8 = 0x14 VT_UI8 = 0x15 VT_INT = 0x16 VT_UINT = 0x17 VT_VOID = 0x18 VT_HRESULT = 0x19 VT_PTR = 0x1a VT_SAFEARRAY = 0x1b VT_CARRAY = 0x1c VT_USERDEFINED = 0x1d VT_LPSTR = 0x1e VT_LPWSTR = 0x1f VT_RECORD = 0x24 VT_INT_PTR = 0x25 VT_UINT_PTR = 0x26 VT_FILETIME = 0x40 VT_BLOB = 0x41 VT_STREAM = 0x42 VT_STORAGE = 0x43 VT_STREAMED_OBJECT = 0x44 VT_STORED_OBJECT = 0x45 VT_BLOB_OBJECT = 0x46 VT_CF = 0x47 VT_CLSID = 0x48 VT_BSTR_BLOB = 0xfff VT_VECTOR = 0x1000 VT_ARRAY = 0x2000 VT_BYREF = 0x4000 VT_RESERVED = 0x8000 VT_ILLEGAL = 0xffff VT_ILLEGALMASKED = 0xfff VT_TYPEMASK = 0xfff ) const ( DISPID_UNKNOWN = -1 DISPID_VALUE = 0 DISPID_PROPERTYPUT = -3 DISPID_NEWENUM = -4 DISPID_EVALUATE = -5 DISPID_CONSTRUCTOR = -6 DISPID_DESTRUCTOR = -7 DISPID_COLLECT = -8 ) const ( MONITOR_DEFAULTTONULL = 0x00000000 MONITOR_DEFAULTTOPRIMARY = 0x00000001 MONITOR_DEFAULTTONEAREST = 0x00000002 MONITORINFOF_PRIMARY = 0x00000001 ) const ( CCHDEVICENAME = 32 CCHFORMNAME = 32 ) const ( IDOK = 1 IDCANCEL = 2 IDABORT = 3 IDRETRY = 4 IDIGNORE = 5 IDYES = 6 IDNO = 7 IDCLOSE = 8 IDHELP = 9 IDTRYAGAIN = 10 IDCONTINUE = 11 IDTIMEOUT = 32000 ) // Generic WM_NOTIFY notification codes const ( NM_FIRST = 0 NM_OUTOFMEMORY = NM_FIRST - 1 NM_CLICK = NM_FIRST - 2 NM_DBLCLK = NM_FIRST - 3 NM_RETURN = NM_FIRST - 4 NM_RCLICK = NM_FIRST - 5 NM_RDBLCLK = NM_FIRST - 6 NM_SETFOCUS = NM_FIRST - 7 NM_KILLFOCUS = NM_FIRST - 8 NM_CUSTOMDRAW = NM_FIRST - 12 NM_HOVER = NM_FIRST - 13 NM_NCHITTEST = NM_FIRST - 14 NM_KEYDOWN = NM_FIRST - 15 NM_RELEASEDCAPTURE = NM_FIRST - 16 NM_SETCURSOR = NM_FIRST - 17 NM_CHAR = NM_FIRST - 18 NM_TOOLTIPSCREATED = NM_FIRST - 19 NM_LAST = NM_FIRST - 99 ) // ListView messages const ( LVM_FIRST = 0x1000 LVM_GETITEMCOUNT = LVM_FIRST + 4 LVM_SETIMAGELIST = LVM_FIRST + 3 LVM_GETIMAGELIST = LVM_FIRST + 2 LVM_GETITEM = LVM_FIRST + 75 LVM_SETITEM = LVM_FIRST + 76 LVM_INSERTITEM = LVM_FIRST + 77 LVM_DELETEITEM = LVM_FIRST + 8 LVM_DELETEALLITEMS = LVM_FIRST + 9 LVM_GETCALLBACKMASK = LVM_FIRST + 10 LVM_SETCALLBACKMASK = LVM_FIRST + 11 LVM_SETUNICODEFORMAT = CCM_SETUNICODEFORMAT LVM_GETNEXTITEM = LVM_FIRST + 12 LVM_FINDITEM = LVM_FIRST + 83 LVM_GETITEMRECT = LVM_FIRST + 14 LVM_GETSTRINGWIDTH = LVM_FIRST + 87 LVM_HITTEST = LVM_FIRST + 18 LVM_ENSUREVISIBLE = LVM_FIRST + 19 LVM_SCROLL = LVM_FIRST + 20 LVM_REDRAWITEMS = LVM_FIRST + 21 LVM_ARRANGE = LVM_FIRST + 22 LVM_EDITLABEL = LVM_FIRST + 118 LVM_GETEDITCONTROL = LVM_FIRST + 24 LVM_GETCOLUMN = LVM_FIRST + 95 LVM_SETCOLUMN = LVM_FIRST + 96 LVM_INSERTCOLUMN = LVM_FIRST + 97 LVM_DELETECOLUMN = LVM_FIRST + 28 LVM_GETCOLUMNWIDTH = LVM_FIRST + 29 LVM_SETCOLUMNWIDTH = LVM_FIRST + 30 LVM_GETHEADER = LVM_FIRST + 31 LVM_CREATEDRAGIMAGE = LVM_FIRST + 33 LVM_GETVIEWRECT = LVM_FIRST + 34 LVM_GETTEXTCOLOR = LVM_FIRST + 35 LVM_SETTEXTCOLOR = LVM_FIRST + 36 LVM_GETTEXTBKCOLOR = LVM_FIRST + 37 LVM_SETTEXTBKCOLOR = LVM_FIRST + 38 LVM_GETTOPINDEX = LVM_FIRST + 39 LVM_GETCOUNTPERPAGE = LVM_FIRST + 40 LVM_GETORIGIN = LVM_FIRST + 41 LVM_UPDATE = LVM_FIRST + 42 LVM_SETITEMSTATE = LVM_FIRST + 43 LVM_GETITEMSTATE = LVM_FIRST + 44 LVM_GETITEMTEXT = LVM_FIRST + 115 LVM_SETITEMTEXT = LVM_FIRST + 116 LVM_SETITEMCOUNT = LVM_FIRST + 47 LVM_SORTITEMS = LVM_FIRST + 48 LVM_SETITEMPOSITION32 = LVM_FIRST + 49 LVM_GETSELECTEDCOUNT = LVM_FIRST + 50 LVM_GETITEMSPACING = LVM_FIRST + 51 LVM_GETISEARCHSTRING = LVM_FIRST + 117 LVM_SETICONSPACING = LVM_FIRST + 53 LVM_SETEXTENDEDLISTVIEWSTYLE = LVM_FIRST + 54 LVM_GETEXTENDEDLISTVIEWSTYLE = LVM_FIRST + 55 LVM_GETSUBITEMRECT = LVM_FIRST + 56 LVM_SUBITEMHITTEST = LVM_FIRST + 57 LVM_SETCOLUMNORDERARRAY = LVM_FIRST + 58 LVM_GETCOLUMNORDERARRAY = LVM_FIRST + 59 LVM_SETHOTITEM = LVM_FIRST + 60 LVM_GETHOTITEM = LVM_FIRST + 61 LVM_SETHOTCURSOR = LVM_FIRST + 62 LVM_GETHOTCURSOR = LVM_FIRST + 63 LVM_APPROXIMATEVIEWRECT = LVM_FIRST + 64 LVM_SETWORKAREAS = LVM_FIRST + 65 LVM_GETWORKAREAS = LVM_FIRST + 70 LVM_GETNUMBEROFWORKAREAS = LVM_FIRST + 73 LVM_GETSELECTIONMARK = LVM_FIRST + 66 LVM_SETSELECTIONMARK = LVM_FIRST + 67 LVM_SETHOVERTIME = LVM_FIRST + 71 LVM_GETHOVERTIME = LVM_FIRST + 72 LVM_SETTOOLTIPS = LVM_FIRST + 74 LVM_GETTOOLTIPS = LVM_FIRST + 78 LVM_SORTITEMSEX = LVM_FIRST + 81 LVM_SETBKIMAGE = LVM_FIRST + 138 LVM_GETBKIMAGE = LVM_FIRST + 139 LVM_SETSELECTEDCOLUMN = LVM_FIRST + 140 LVM_SETVIEW = LVM_FIRST + 142 LVM_GETVIEW = LVM_FIRST + 143 LVM_INSERTGROUP = LVM_FIRST + 145 LVM_SETGROUPINFO = LVM_FIRST + 147 LVM_GETGROUPINFO = LVM_FIRST + 149 LVM_REMOVEGROUP = LVM_FIRST + 150 LVM_MOVEGROUP = LVM_FIRST + 151 LVM_GETGROUPCOUNT = LVM_FIRST + 152 LVM_GETGROUPINFOBYINDEX = LVM_FIRST + 153 LVM_MOVEITEMTOGROUP = LVM_FIRST + 154 LVM_GETGROUPRECT = LVM_FIRST + 98 LVM_SETGROUPMETRICS = LVM_FIRST + 155 LVM_GETGROUPMETRICS = LVM_FIRST + 156 LVM_ENABLEGROUPVIEW = LVM_FIRST + 157 LVM_SORTGROUPS = LVM_FIRST + 158 LVM_INSERTGROUPSORTED = LVM_FIRST + 159 LVM_REMOVEALLGROUPS = LVM_FIRST + 160 LVM_HASGROUP = LVM_FIRST + 161 LVM_GETGROUPSTATE = LVM_FIRST + 92 LVM_GETFOCUSEDGROUP = LVM_FIRST + 93 LVM_SETTILEVIEWINFO = LVM_FIRST + 162 LVM_GETTILEVIEWINFO = LVM_FIRST + 163 LVM_SETTILEINFO = LVM_FIRST + 164 LVM_GETTILEINFO = LVM_FIRST + 165 LVM_SETINSERTMARK = LVM_FIRST + 166 LVM_GETINSERTMARK = LVM_FIRST + 167 LVM_INSERTMARKHITTEST = LVM_FIRST + 168 LVM_GETINSERTMARKRECT = LVM_FIRST + 169 LVM_SETINSERTMARKCOLOR = LVM_FIRST + 170 LVM_GETINSERTMARKCOLOR = LVM_FIRST + 171 LVM_SETINFOTIP = LVM_FIRST + 173 LVM_GETSELECTEDCOLUMN = LVM_FIRST + 174 LVM_ISGROUPVIEWENABLED = LVM_FIRST + 175 LVM_GETOUTLINECOLOR = LVM_FIRST + 176 LVM_SETOUTLINECOLOR = LVM_FIRST + 177 LVM_CANCELEDITLABEL = LVM_FIRST + 179 LVM_MAPINDEXTOID = LVM_FIRST + 180 LVM_MAPIDTOINDEX = LVM_FIRST + 181 LVM_ISITEMVISIBLE = LVM_FIRST + 182 LVM_GETNEXTITEMINDEX = LVM_FIRST + 211 ) // ListView notifications const ( LVN_FIRST = -100 LVN_ITEMCHANGING = LVN_FIRST - 0 LVN_ITEMCHANGED = LVN_FIRST - 1 LVN_INSERTITEM = LVN_FIRST - 2 LVN_DELETEITEM = LVN_FIRST - 3 LVN_DELETEALLITEMS = LVN_FIRST - 4 LVN_BEGINLABELEDITA = LVN_FIRST - 5 LVN_BEGINLABELEDITW = LVN_FIRST - 75 LVN_ENDLABELEDITA = LVN_FIRST - 6 LVN_ENDLABELEDITW = LVN_FIRST - 76 LVN_COLUMNCLICK = LVN_FIRST - 8 LVN_BEGINDRAG = LVN_FIRST - 9 LVN_BEGINRDRAG = LVN_FIRST - 11 LVN_ODCACHEHINT = LVN_FIRST - 13 LVN_ODFINDITEMA = LVN_FIRST - 52 LVN_ODFINDITEMW = LVN_FIRST - 79 LVN_ITEMACTIVATE = LVN_FIRST - 14 LVN_ODSTATECHANGED = LVN_FIRST - 15 LVN_HOTTRACK = LVN_FIRST - 21 LVN_GETDISPINFO = LVN_FIRST - 77 LVN_SETDISPINFO = LVN_FIRST - 78 LVN_KEYDOWN = LVN_FIRST - 55 LVN_MARQUEEBEGIN = LVN_FIRST - 56 LVN_GETINFOTIP = LVN_FIRST - 58 LVN_INCREMENTALSEARCH = LVN_FIRST - 63 LVN_BEGINSCROLL = LVN_FIRST - 80 LVN_ENDSCROLL = LVN_FIRST - 81 ) const ( LVSCW_AUTOSIZE = ^uintptr(0) LVSCW_AUTOSIZE_USEHEADER = ^uintptr(1) ) // ListView LVNI constants const ( LVNI_ALL = 0 LVNI_FOCUSED = 1 LVNI_SELECTED = 2 LVNI_CUT = 4 LVNI_DROPHILITED = 8 LVNI_ABOVE = 256 LVNI_BELOW = 512 LVNI_TOLEFT = 1024 LVNI_TORIGHT = 2048 ) // ListView styles const ( LVS_ICON = 0x0000 LVS_REPORT = 0x0001 LVS_SMALLICON = 0x0002 LVS_LIST = 0x0003 LVS_TYPEMASK = 0x0003 LVS_SINGLESEL = 0x0004 LVS_SHOWSELALWAYS = 0x0008 LVS_SORTASCENDING = 0x0010 LVS_SORTDESCENDING = 0x0020 LVS_SHAREIMAGELISTS = 0x0040 LVS_NOLABELWRAP = 0x0080 LVS_AUTOARRANGE = 0x0100 LVS_EDITLABELS = 0x0200 LVS_OWNERDATA = 0x1000 LVS_NOSCROLL = 0x2000 LVS_TYPESTYLEMASK = 0xfc00 LVS_ALIGNTOP = 0x0000 LVS_ALIGNLEFT = 0x0800 LVS_ALIGNMASK = 0x0c00 LVS_OWNERDRAWFIXED = 0x0400 LVS_NOCOLUMNHEADER = 0x4000 LVS_NOSORTHEADER = 0x8000 ) // ListView extended styles const ( LVS_EX_GRIDLINES = 0x00000001 LVS_EX_SUBITEMIMAGES = 0x00000002 LVS_EX_CHECKBOXES = 0x00000004 LVS_EX_TRACKSELECT = 0x00000008 LVS_EX_HEADERDRAGDROP = 0x00000010 LVS_EX_FULLROWSELECT = 0x00000020 LVS_EX_ONECLICKACTIVATE = 0x00000040 LVS_EX_TWOCLICKACTIVATE = 0x00000080 LVS_EX_FLATSB = 0x00000100 LVS_EX_REGIONAL = 0x00000200 LVS_EX_INFOTIP = 0x00000400 LVS_EX_UNDERLINEHOT = 0x00000800 LVS_EX_UNDERLINECOLD = 0x00001000 LVS_EX_MULTIWORKAREAS = 0x00002000 LVS_EX_LABELTIP = 0x00004000 LVS_EX_BORDERSELECT = 0x00008000 LVS_EX_DOUBLEBUFFER = 0x00010000 LVS_EX_HIDELABELS = 0x00020000 LVS_EX_SINGLEROW = 0x00040000 LVS_EX_SNAPTOGRID = 0x00080000 LVS_EX_SIMPLESELECT = 0x00100000 ) // ListView column flags const ( LVCF_FMT = 0x0001 LVCF_WIDTH = 0x0002 LVCF_TEXT = 0x0004 LVCF_SUBITEM = 0x0008 LVCF_IMAGE = 0x0010 LVCF_ORDER = 0x0020 ) // ListView column format constants const ( LVCFMT_LEFT = 0x0000 LVCFMT_RIGHT = 0x0001 LVCFMT_CENTER = 0x0002 LVCFMT_JUSTIFYMASK = 0x0003 LVCFMT_IMAGE = 0x0800 LVCFMT_BITMAP_ON_RIGHT = 0x1000 LVCFMT_COL_HAS_IMAGES = 0x8000 ) // ListView item flags const ( LVIF_TEXT = 0x00000001 LVIF_IMAGE = 0x00000002 LVIF_PARAM = 0x00000004 LVIF_STATE = 0x00000008 LVIF_INDENT = 0x00000010 LVIF_NORECOMPUTE = 0x00000800 LVIF_GROUPID = 0x00000100 LVIF_COLUMNS = 0x00000200 ) const LVFI_PARAM = 0x0001 // ListView item states const ( LVIS_FOCUSED = 1 LVIS_SELECTED = 2 LVIS_CUT = 4 LVIS_DROPHILITED = 8 LVIS_OVERLAYMASK = 0xF00 LVIS_STATEIMAGEMASK = 0xF000 ) // ListView hit test constants const ( LVHT_NOWHERE = 0x00000001 LVHT_ONITEMICON = 0x00000002 LVHT_ONITEMLABEL = 0x00000004 LVHT_ONITEMSTATEICON = 0x00000008 LVHT_ONITEM = LVHT_ONITEMICON | LVHT_ONITEMLABEL | LVHT_ONITEMSTATEICON LVHT_ABOVE = 0x00000008 LVHT_BELOW = 0x00000010 LVHT_TORIGHT = 0x00000020 LVHT_TOLEFT = 0x00000040 ) // ListView image list types const ( LVSIL_NORMAL = 0 LVSIL_SMALL = 1 LVSIL_STATE = 2 LVSIL_GROUPHEADER = 3 ) // InitCommonControlsEx flags const ( ICC_LISTVIEW_CLASSES = 1 ICC_TREEVIEW_CLASSES = 2 ICC_BAR_CLASSES = 4 ICC_TAB_CLASSES = 8 ICC_UPDOWN_CLASS = 16 ICC_PROGRESS_CLASS = 32 ICC_HOTKEY_CLASS = 64 ICC_ANIMATE_CLASS = 128 ICC_WIN95_CLASSES = 255 ICC_DATE_CLASSES = 256 ICC_USEREX_CLASSES = 512 ICC_COOL_CLASSES = 1024 ICC_INTERNET_CLASSES = 2048 ICC_PAGESCROLLER_CLASS = 4096 ICC_NATIVEFNTCTL_CLASS = 8192 INFOTIPSIZE = 1024 ICC_STANDARD_CLASSES = 0x00004000 ICC_LINK_CLASS = 0x00008000 ) // Dialog Codes const ( DLGC_WANTARROWS = 0x0001 DLGC_WANTTAB = 0x0002 DLGC_WANTALLKEYS = 0x0004 DLGC_WANTMESSAGE = 0x0004 DLGC_HASSETSEL = 0x0008 DLGC_DEFPUSHBUTTON = 0x0010 DLGC_UNDEFPUSHBUTTON = 0x0020 DLGC_RADIOBUTTON = 0x0040 DLGC_WANTCHARS = 0x0080 DLGC_STATIC = 0x0100 DLGC_BUTTON = 0x2000 ) // Get/SetWindowWord/Long offsets for use with WC_DIALOG windows const ( DWL_MSGRESULT = 0 DWL_DLGPROC = 4 DWL_USER = 8 ) // Registry predefined keys const ( HKEY_CLASSES_ROOT HKEY = 0x80000000 HKEY_CURRENT_USER HKEY = 0x80000001 HKEY_LOCAL_MACHINE HKEY = 0x80000002 HKEY_USERS HKEY = 0x80000003 HKEY_PERFORMANCE_DATA HKEY = 0x80000004 HKEY_CURRENT_CONFIG HKEY = 0x80000005 HKEY_DYN_DATA HKEY = 0x80000006 ) // Registry Key Security and Access Rights const ( KEY_ALL_ACCESS = 0xF003F KEY_CREATE_SUB_KEY = 0x0004 KEY_ENUMERATE_SUB_KEYS = 0x0008 KEY_NOTIFY = 0x0010 KEY_QUERY_VALUE = 0x0001 KEY_SET_VALUE = 0x0002 KEY_READ = 0x20019 KEY_WRITE = 0x20006 ) const ( NFR_ANSI = 1 NFR_UNICODE = 2 NF_QUERY = 3 NF_REQUERY = 4 ) // Registry value types const ( RRF_RT_REG_NONE = 0x00000001 RRF_RT_REG_SZ = 0x00000002 RRF_RT_REG_EXPAND_SZ = 0x00000004 RRF_RT_REG_BINARY = 0x00000008 RRF_RT_REG_DWORD = 0x00000010 RRF_RT_REG_MULTI_SZ = 0x00000020 RRF_RT_REG_QWORD = 0x00000040 RRF_RT_DWORD = (RRF_RT_REG_BINARY | RRF_RT_REG_DWORD) RRF_RT_QWORD = (RRF_RT_REG_BINARY | RRF_RT_REG_QWORD) RRF_RT_ANY = 0x0000ffff RRF_NOEXPAND = 0x10000000 RRF_ZEROONFAILURE = 0x20000000 REG_PROCESS_APPKEY = 0x00000001 REG_MUI_STRING_TRUNCATE = 0x00000001 ) // PeekMessage wRemoveMsg value const ( PM_NOREMOVE = 0x000 PM_REMOVE = 0x001 PM_NOYIELD = 0x002 ) // ImageList flags const ( ILC_MASK = 0x00000001 ILC_COLOR = 0x00000000 ILC_COLORDDB = 0x000000FE ILC_COLOR4 = 0x00000004 ILC_COLOR8 = 0x00000008 ILC_COLOR16 = 0x00000010 ILC_COLOR24 = 0x00000018 ILC_COLOR32 = 0x00000020 ILC_PALETTE = 0x00000800 ILC_MIRROR = 0x00002000 ILC_PERITEMMIRROR = 0x00008000 ILC_ORIGINALSIZE = 0x00010000 ILC_HIGHQUALITYSCALE = 0x00020000 ) // Keystroke Message Flags const ( KF_EXTENDED = 0x0100 KF_DLGMODE = 0x0800 KF_MENUMODE = 0x1000 KF_ALTDOWN = 0x2000 KF_REPEAT = 0x4000 KF_UP = 0x8000 ) // Virtual-Key Codes /* const ( VK_LBUTTON = 0x01 VK_RBUTTON = 0x02 VK_CANCEL = 0x03 VK_MBUTTON = 0x04 VK_XBUTTON1 = 0x05 VK_XBUTTON2 = 0x06 VK_BACK = 0x08 VK_TAB = 0x09 VK_CLEAR = 0x0C VK_RETURN = 0x0D VK_SHIFT = 0x10 VK_CONTROL = 0x11 VK_MENU = 0x12 VK_PAUSE = 0x13 VK_CAPITAL = 0x14 VK_KANA = 0x15 VK_HANGEUL = 0x15 VK_HANGUL = 0x15 VK_JUNJA = 0x17 VK_FINAL = 0x18 VK_HANJA = 0x19 VK_KANJI = 0x19 VK_ESCAPE = 0x1B VK_CONVERT = 0x1C VK_NONCONVERT = 0x1D VK_ACCEPT = 0x1E VK_MODECHANGE = 0x1F VK_SPACE = 0x20 VK_PRIOR = 0x21 VK_NEXT = 0x22 VK_END = 0x23 VK_HOME = 0x24 VK_LEFT = 0x25 VK_UP = 0x26 VK_RIGHT = 0x27 VK_DOWN = 0x28 VK_SELECT = 0x29 VK_PRINT = 0x2A VK_EXECUTE = 0x2B VK_SNAPSHOT = 0x2C VK_INSERT = 0x2D VK_DELETE = 0x2E VK_HELP = 0x2F VK_LWIN = 0x5B VK_RWIN = 0x5C VK_APPS = 0x5D VK_SLEEP = 0x5F VK_NUMPAD0 = 0x60 VK_NUMPAD1 = 0x61 VK_NUMPAD2 = 0x62 VK_NUMPAD3 = 0x63 VK_NUMPAD4 = 0x64 VK_NUMPAD5 = 0x65 VK_NUMPAD6 = 0x66 VK_NUMPAD7 = 0x67 VK_NUMPAD8 = 0x68 VK_NUMPAD9 = 0x69 VK_MULTIPLY = 0x6A VK_ADD = 0x6B VK_SEPARATOR = 0x6C VK_SUBTRACT = 0x6D VK_DECIMAL = 0x6E VK_DIVIDE = 0x6F VK_F1 = 0x70 VK_F2 = 0x71 VK_F3 = 0x72 VK_F4 = 0x73 VK_F5 = 0x74 VK_F6 = 0x75 VK_F7 = 0x76 VK_F8 = 0x77 VK_F9 = 0x78 VK_F10 = 0x79 VK_F11 = 0x7A VK_F12 = 0x7B VK_F13 = 0x7C VK_F14 = 0x7D VK_F15 = 0x7E VK_F16 = 0x7F VK_F17 = 0x80 VK_F18 = 0x81 VK_F19 = 0x82 VK_F20 = 0x83 VK_F21 = 0x84 VK_F22 = 0x85 VK_F23 = 0x86 VK_F24 = 0x87 VK_NUMLOCK = 0x90 VK_SCROLL = 0x91 VK_OEM_NEC_EQUAL = 0x92 VK_OEM_FJ_JISHO = 0x92 VK_OEM_FJ_MASSHOU = 0x93 VK_OEM_FJ_TOUROKU = 0x94 VK_OEM_FJ_LOYA = 0x95 VK_OEM_FJ_ROYA = 0x96 VK_LSHIFT = 0xA0 VK_RSHIFT = 0xA1 VK_LCONTROL = 0xA2 VK_RCONTROL = 0xA3 VK_LMENU = 0xA4 VK_RMENU = 0xA5 VK_BROWSER_BACK = 0xA6 VK_BROWSER_FORWARD = 0xA7 VK_BROWSER_REFRESH = 0xA8 VK_BROWSER_STOP = 0xA9 VK_BROWSER_SEARCH = 0xAA VK_BROWSER_FAVORITES = 0xAB VK_BROWSER_HOME = 0xAC VK_VOLUME_MUTE = 0xAD VK_VOLUME_DOWN = 0xAE VK_VOLUME_UP = 0xAF VK_MEDIA_NEXT_TRACK = 0xB0 VK_MEDIA_PREV_TRACK = 0xB1 VK_MEDIA_STOP = 0xB2 VK_MEDIA_PLAY_PAUSE = 0xB3 VK_LAUNCH_MAIL = 0xB4 VK_LAUNCH_MEDIA_SELECT = 0xB5 VK_LAUNCH_APP1 = 0xB6 VK_LAUNCH_APP2 = 0xB7 VK_OEM_1 = 0xBA VK_OEM_PLUS = 0xBB VK_OEM_COMMA = 0xBC VK_OEM_MINUS = 0xBD VK_OEM_PERIOD = 0xBE VK_OEM_2 = 0xBF VK_OEM_3 = 0xC0 VK_OEM_4 = 0xDB VK_OEM_5 = 0xDC VK_OEM_6 = 0xDD VK_OEM_7 = 0xDE VK_OEM_8 = 0xDF VK_OEM_AX = 0xE1 VK_OEM_102 = 0xE2 VK_ICO_HELP = 0xE3 VK_ICO_00 = 0xE4 VK_PROCESSKEY = 0xE5 VK_ICO_CLEAR = 0xE6 VK_OEM_RESET = 0xE9 VK_OEM_JUMP = 0xEA VK_OEM_PA1 = 0xEB VK_OEM_PA2 = 0xEC VK_OEM_PA3 = 0xED VK_OEM_WSCTRL = 0xEE VK_OEM_CUSEL = 0xEF VK_OEM_ATTN = 0xF0 VK_OEM_FINISH = 0xF1 VK_OEM_COPY = 0xF2 VK_OEM_AUTO = 0xF3 VK_OEM_ENLW = 0xF4 VK_OEM_BACKTAB = 0xF5 VK_ATTN = 0xF6 VK_CRSEL = 0xF7 VK_EXSEL = 0xF8 VK_EREOF = 0xF9 VK_PLAY = 0xFA VK_ZOOM = 0xFB VK_NONAME = 0xFC VK_PA1 = 0xFD VK_OEM_CLEAR = 0xFE )*/ // Registry Value Types const ( REG_NONE = 0 REG_SZ = 1 REG_EXPAND_SZ = 2 REG_BINARY = 3 REG_DWORD = 4 REG_DWORD_LITTLE_ENDIAN = 4 REG_DWORD_BIG_ENDIAN = 5 REG_LINK = 6 REG_MULTI_SZ = 7 REG_RESOURCE_LIST = 8 REG_FULL_RESOURCE_DESCRIPTOR = 9 REG_RESOURCE_REQUIREMENTS_LIST = 10 REG_QWORD = 11 REG_QWORD_LITTLE_ENDIAN = 11 ) // Tooltip styles const ( TTS_ALWAYSTIP = 0x01 TTS_NOPREFIX = 0x02 TTS_NOANIMATE = 0x10 TTS_NOFADE = 0x20 TTS_BALLOON = 0x40 TTS_CLOSE = 0x80 TTS_USEVISUALSTYLE = 0x100 ) // Tooltip messages const ( TTM_ACTIVATE = (WM_USER + 1) TTM_SETDELAYTIME = (WM_USER + 3) TTM_ADDTOOL = (WM_USER + 50) TTM_DELTOOL = (WM_USER + 51) TTM_NEWTOOLRECT = (WM_USER + 52) TTM_RELAYEVENT = (WM_USER + 7) TTM_GETTOOLINFO = (WM_USER + 53) TTM_SETTOOLINFO = (WM_USER + 54) TTM_HITTEST = (WM_USER + 55) TTM_GETTEXT = (WM_USER + 56) TTM_UPDATETIPTEXT = (WM_USER + 57) TTM_GETTOOLCOUNT = (WM_USER + 13) TTM_ENUMTOOLS = (WM_USER + 58) TTM_GETCURRENTTOOL = (WM_USER + 59) TTM_WINDOWFROMPOINT = (WM_USER + 16) TTM_TRACKACTIVATE = (WM_USER + 17) TTM_TRACKPOSITION = (WM_USER + 18) TTM_SETTIPBKCOLOR = (WM_USER + 19) TTM_SETTIPTEXTCOLOR = (WM_USER + 20) TTM_GETDELAYTIME = (WM_USER + 21) TTM_GETTIPBKCOLOR = (WM_USER + 22) TTM_GETTIPTEXTCOLOR = (WM_USER + 23) TTM_SETMAXTIPWIDTH = (WM_USER + 24) TTM_GETMAXTIPWIDTH = (WM_USER + 25) TTM_SETMARGIN = (WM_USER + 26) TTM_GETMARGIN = (WM_USER + 27) TTM_POP = (WM_USER + 28) TTM_UPDATE = (WM_USER + 29) TTM_GETBUBBLESIZE = (WM_USER + 30) TTM_ADJUSTRECT = (WM_USER + 31) TTM_SETTITLE = (WM_USER + 33) TTM_POPUP = (WM_USER + 34) TTM_GETTITLE = (WM_USER + 35) ) // Tooltip icons const ( TTI_NONE = 0 TTI_INFO = 1 TTI_WARNING = 2 TTI_ERROR = 3 TTI_INFO_LARGE = 4 TTI_WARNING_LARGE = 5 TTI_ERROR_LARGE = 6 ) // Tooltip notifications const ( TTN_FIRST = -520 TTN_LAST = -549 TTN_GETDISPINFO = (TTN_FIRST - 10) TTN_SHOW = (TTN_FIRST - 1) TTN_POP = (TTN_FIRST - 2) TTN_LINKCLICK = (TTN_FIRST - 3) TTN_NEEDTEXT = TTN_GETDISPINFO ) const ( TTF_IDISHWND = 0x0001 TTF_CENTERTIP = 0x0002 TTF_RTLREADING = 0x0004 TTF_SUBCLASS = 0x0010 TTF_TRACK = 0x0020 TTF_ABSOLUTE = 0x0080 TTF_TRANSPARENT = 0x0100 TTF_PARSELINKS = 0x1000 TTF_DI_SETITEM = 0x8000 ) const ( SWP_NOSIZE = 0x0001 SWP_NOMOVE = 0x0002 SWP_NOZORDER = 0x0004 SWP_NOREDRAW = 0x0008 SWP_NOACTIVATE = 0x0010 SWP_FRAMECHANGED = 0x0020 SWP_SHOWWINDOW = 0x0040 SWP_HIDEWINDOW = 0x0080 SWP_NOCOPYBITS = 0x0100 SWP_NOOWNERZORDER = 0x0200 SWP_NOSENDCHANGING = 0x0400 SWP_DRAWFRAME = SWP_FRAMECHANGED SWP_NOREPOSITION = SWP_NOOWNERZORDER SWP_DEFERERASE = 0x2000 SWP_ASYNCWINDOWPOS = 0x4000 ) // Predefined window handles const ( HWND_BROADCAST = HWND(0xFFFF) HWND_BOTTOM = HWND(1) HWND_NOTOPMOST = ^HWND(1) // -2 HWND_TOP = HWND(0) HWND_TOPMOST = ^HWND(0) // -1 HWND_DESKTOP = HWND(0) HWND_MESSAGE = ^HWND(2) // -3 ) // Pen types const ( PS_COSMETIC = 0x00000000 PS_GEOMETRIC = 0x00010000 PS_TYPE_MASK = 0x000F0000 ) // Pen styles const ( PS_SOLID = 0 PS_DASH = 1 PS_DOT = 2 PS_DASHDOT = 3 PS_DASHDOTDOT = 4 PS_NULL = 5 PS_INSIDEFRAME = 6 PS_USERSTYLE = 7 PS_ALTERNATE = 8 PS_STYLE_MASK = 0x0000000F ) // Pen cap types const ( PS_ENDCAP_ROUND = 0x00000000 PS_ENDCAP_SQUARE = 0x00000100 PS_ENDCAP_FLAT = 0x00000200 PS_ENDCAP_MASK = 0x00000F00 ) // Pen join types const ( PS_JOIN_ROUND = 0x00000000 PS_JOIN_BEVEL = 0x00001000 PS_JOIN_MITER = 0x00002000 PS_JOIN_MASK = 0x0000F000 ) // Hatch styles const ( HS_HORIZONTAL = 0 HS_VERTICAL = 1 HS_FDIAGONAL = 2 HS_BDIAGONAL = 3 HS_CROSS = 4 HS_DIAGCROSS = 5 ) // Stock Logical Objects const ( WHITE_BRUSH = 0 LTGRAY_BRUSH = 1 GRAY_BRUSH = 2 DKGRAY_BRUSH = 3 BLACK_BRUSH = 4 NULL_BRUSH = 5 HOLLOW_BRUSH = NULL_BRUSH WHITE_PEN = 6 BLACK_PEN = 7 NULL_PEN = 8 OEM_FIXED_FONT = 10 ANSI_FIXED_FONT = 11 ANSI_VAR_FONT = 12 SYSTEM_FONT = 13 DEVICE_DEFAULT_FONT = 14 DEFAULT_PALETTE = 15 SYSTEM_FIXED_FONT = 16 DEFAULT_GUI_FONT = 17 DC_BRUSH = 18 DC_PEN = 19 ) // Brush styles const ( BS_SOLID = 0 BS_NULL = 1 BS_HOLLOW = BS_NULL BS_HATCHED = 2 BS_PATTERN = 3 BS_INDEXED = 4 BS_DIBPATTERN = 5 BS_DIBPATTERNPT = 6 BS_PATTERN8X8 = 7 BS_DIBPATTERN8X8 = 8 BS_MONOPATTERN = 9 ) // TRACKMOUSEEVENT flags const ( TME_HOVER = 0x00000001 TME_LEAVE = 0x00000002 TME_NONCLIENT = 0x00000010 TME_QUERY = 0x40000000 TME_CANCEL = 0x80000000 HOVER_DEFAULT = 0xFFFFFFFF ) // WM_NCHITTEST and MOUSEHOOKSTRUCT Mouse Position Codes const ( HTERROR = (-2) HTTRANSPARENT = (-1) HTNOWHERE = 0 HTCLIENT = 1 HTCAPTION = 2 HTSYSMENU = 3 HTGROWBOX = 4 HTSIZE = HTGROWBOX HTMENU = 5 HTHSCROLL = 6 HTVSCROLL = 7 HTMINBUTTON = 8 HTMAXBUTTON = 9 HTLEFT = 10 HTRIGHT = 11 HTTOP = 12 HTTOPLEFT = 13 HTTOPRIGHT = 14 HTBOTTOM = 15 HTBOTTOMLEFT = 16 HTBOTTOMRIGHT = 17 HTBORDER = 18 HTREDUCE = HTMINBUTTON HTZOOM = HTMAXBUTTON HTSIZEFIRST = HTLEFT HTSIZELAST = HTBOTTOMRIGHT HTOBJECT = 19 HTCLOSE = 20 HTHELP = 21 ) // DrawText[Ex] format flags const ( DT_TOP = 0x00000000 DT_LEFT = 0x00000000 DT_CENTER = 0x00000001 DT_RIGHT = 0x00000002 DT_VCENTER = 0x00000004 DT_BOTTOM = 0x00000008 DT_WORDBREAK = 0x00000010 DT_SINGLELINE = 0x00000020 DT_EXPANDTABS = 0x00000040 DT_TABSTOP = 0x00000080 DT_NOCLIP = 0x00000100 DT_EXTERNALLEADING = 0x00000200 DT_CALCRECT = 0x00000400 DT_NOPREFIX = 0x00000800 DT_INTERNAL = 0x00001000 DT_EDITCONTROL = 0x00002000 DT_PATH_ELLIPSIS = 0x00004000 DT_END_ELLIPSIS = 0x00008000 DT_MODIFYSTRING = 0x00010000 DT_RTLREADING = 0x00020000 DT_WORD_ELLIPSIS = 0x00040000 DT_NOFULLWIDTHCHARBREAK = 0x00080000 DT_HIDEPREFIX = 0x00100000 DT_PREFIXONLY = 0x00200000 ) const CLR_INVALID = 0xFFFFFFFF // Background Modes const ( TRANSPARENT = 1 OPAQUE = 2 BKMODE_LAST = 2 ) // Global Memory Flags const ( GMEM_FIXED = 0x0000 GMEM_MOVEABLE = 0x0002 GMEM_NOCOMPACT = 0x0010 GMEM_NODISCARD = 0x0020 GMEM_ZEROINIT = 0x0040 GMEM_MODIFY = 0x0080 GMEM_DISCARDABLE = 0x0100 GMEM_NOT_BANKED = 0x1000 GMEM_SHARE = 0x2000 GMEM_DDESHARE = 0x2000 GMEM_NOTIFY = 0x4000 GMEM_LOWER = GMEM_NOT_BANKED GMEM_VALID_FLAGS = 0x7F72 GMEM_INVALID_HANDLE = 0x8000 GHND = (GMEM_MOVEABLE | GMEM_ZEROINIT) GPTR = (GMEM_FIXED | GMEM_ZEROINIT) ) // Ternary raster operations const ( SRCCOPY = 0x00CC0020 SRCPAINT = 0x00EE0086 SRCAND = 0x008800C6 SRCINVERT = 0x00660046 SRCERASE = 0x00440328 NOTSRCCOPY = 0x00330008 NOTSRCERASE = 0x001100A6 MERGECOPY = 0x00C000CA MERGEPAINT = 0x00BB0226 PATCOPY = 0x00F00021 PATPAINT = 0x00FB0A09 PATINVERT = 0x005A0049 DSTINVERT = 0x00550009 BLACKNESS = 0x00000042 WHITENESS = 0x00FF0062 NOMIRRORBITMAP = 0x80000000 CAPTUREBLT = 0x40000000 ) // Clipboard formats const ( CF_TEXT = 1 CF_BITMAP = 2 CF_METAFILEPICT = 3 CF_SYLK = 4 CF_DIF = 5 CF_TIFF = 6 CF_OEMTEXT = 7 CF_DIB = 8 CF_PALETTE = 9 CF_PENDATA = 10 CF_RIFF = 11 CF_WAVE = 12 CF_UNICODETEXT = 13 CF_ENHMETAFILE = 14 CF_HDROP = 15 CF_LOCALE = 16 CF_DIBV5 = 17 CF_MAX = 18 CF_OWNERDISPLAY = 0x0080 CF_DSPTEXT = 0x0081 CF_DSPBITMAP = 0x0082 CF_DSPMETAFILEPICT = 0x0083 CF_DSPENHMETAFILE = 0x008E CF_PRIVATEFIRST = 0x0200 CF_PRIVATELAST = 0x02FF CF_GDIOBJFIRST = 0x0300 CF_GDIOBJLAST = 0x03FF ) // Bitmap compression formats const ( BI_RGB = 0 BI_RLE8 = 1 BI_RLE4 = 2 BI_BITFIELDS = 3 BI_JPEG = 4 BI_PNG = 5 ) // SetDIBitsToDevice fuColorUse const ( DIB_PAL_COLORS = 1 DIB_RGB_COLORS = 0 ) const ( STANDARD_RIGHTS_REQUIRED = 0x000F ) // Service Control Manager object specific access types const ( SC_MANAGER_CONNECT = 0x0001 SC_MANAGER_CREATE_SERVICE = 0x0002 SC_MANAGER_ENUMERATE_SERVICE = 0x0004 SC_MANAGER_LOCK = 0x0008 SC_MANAGER_QUERY_LOCK_STATUS = 0x0010 SC_MANAGER_MODIFY_BOOT_CONFIG = 0x0020 SC_MANAGER_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SC_MANAGER_CONNECT | SC_MANAGER_CREATE_SERVICE | SC_MANAGER_ENUMERATE_SERVICE | SC_MANAGER_LOCK | SC_MANAGER_QUERY_LOCK_STATUS | SC_MANAGER_MODIFY_BOOT_CONFIG ) // Service Types (Bit Mask) const ( SERVICE_KERNEL_DRIVER = 0x00000001 SERVICE_FILE_SYSTEM_DRIVER = 0x00000002 SERVICE_ADAPTER = 0x00000004 SERVICE_RECOGNIZER_DRIVER = 0x00000008 SERVICE_DRIVER = SERVICE_KERNEL_DRIVER | SERVICE_FILE_SYSTEM_DRIVER | SERVICE_RECOGNIZER_DRIVER SERVICE_WIN32_OWN_PROCESS = 0x00000010 SERVICE_WIN32_SHARE_PROCESS = 0x00000020 SERVICE_WIN32 = SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS SERVICE_INTERACTIVE_PROCESS = 0x00000100 SERVICE_TYPE_ALL = SERVICE_WIN32 | SERVICE_ADAPTER | SERVICE_DRIVER | SERVICE_INTERACTIVE_PROCESS ) // Service State -- for CurrentState const ( SERVICE_STOPPED = 0x00000001 SERVICE_START_PENDING = 0x00000002 SERVICE_STOP_PENDING = 0x00000003 SERVICE_RUNNING = 0x00000004 SERVICE_CONTINUE_PENDING = 0x00000005 SERVICE_PAUSE_PENDING = 0x00000006 SERVICE_PAUSED = 0x00000007 ) // Controls Accepted (Bit Mask) const ( SERVICE_ACCEPT_STOP = 0x00000001 SERVICE_ACCEPT_PAUSE_CONTINUE = 0x00000002 SERVICE_ACCEPT_SHUTDOWN = 0x00000004 SERVICE_ACCEPT_PARAMCHANGE = 0x00000008 SERVICE_ACCEPT_NETBINDCHANGE = 0x00000010 SERVICE_ACCEPT_HARDWAREPROFILECHANGE = 0x00000020 SERVICE_ACCEPT_POWEREVENT = 0x00000040 SERVICE_ACCEPT_SESSIONCHANGE = 0x00000080 SERVICE_ACCEPT_PRESHUTDOWN = 0x00000100 SERVICE_ACCEPT_TIMECHANGE = 0x00000200 SERVICE_ACCEPT_TRIGGEREVENT = 0x00000400 ) // Service object specific access type const ( SERVICE_QUERY_CONFIG = 0x0001 SERVICE_CHANGE_CONFIG = 0x0002 SERVICE_QUERY_STATUS = 0x0004 SERVICE_ENUMERATE_DEPENDENTS = 0x0008 SERVICE_START = 0x0010 SERVICE_STOP = 0x0020 SERVICE_PAUSE_CONTINUE = 0x0040 SERVICE_INTERROGATE = 0x0080 SERVICE_USER_DEFINED_CONTROL = 0x0100 SERVICE_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG | SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_START | SERVICE_STOP | SERVICE_PAUSE_CONTINUE | SERVICE_INTERROGATE | SERVICE_USER_DEFINED_CONTROL ) // MapVirtualKey maptypes const ( MAPVK_VK_TO_CHAR = 2 MAPVK_VK_TO_VSC = 0 MAPVK_VSC_TO_VK = 1 MAPVK_VSC_TO_VK_EX = 3 ) // ReadEventLog Flags const ( EVENTLOG_SEEK_READ = 0x0002 EVENTLOG_SEQUENTIAL_READ = 0x0001 EVENTLOG_FORWARDS_READ = 0x0004 EVENTLOG_BACKWARDS_READ = 0x0008 ) // CreateToolhelp32Snapshot flags const ( TH32CS_SNAPHEAPLIST = 0x00000001 TH32CS_SNAPPROCESS = 0x00000002 TH32CS_SNAPTHREAD = 0x00000004 TH32CS_SNAPMODULE = 0x00000008 TH32CS_SNAPMODULE32 = 0x00000010 TH32CS_INHERIT = 0x80000000 TH32CS_SNAPALL = TH32CS_SNAPHEAPLIST | TH32CS_SNAPMODULE | TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD ) const ( MAX_MODULE_NAME32 = 255 MAX_PATH = 260 ) const ( FOREGROUND_BLUE = 0x0001 FOREGROUND_GREEN = 0x0002 FOREGROUND_RED = 0x0004 FOREGROUND_INTENSITY = 0x0008 BACKGROUND_BLUE = 0x0010 BACKGROUND_GREEN = 0x0020 BACKGROUND_RED = 0x0040 BACKGROUND_INTENSITY = 0x0080 COMMON_LVB_LEADING_BYTE = 0x0100 COMMON_LVB_TRAILING_BYTE = 0x0200 COMMON_LVB_GRID_HORIZONTAL = 0x0400 COMMON_LVB_GRID_LVERTICAL = 0x0800 COMMON_LVB_GRID_RVERTICAL = 0x1000 COMMON_LVB_REVERSE_VIDEO = 0x4000 COMMON_LVB_UNDERSCORE = 0x8000 ) // Flags used by the DWM_BLURBEHIND structure to indicate // which of its members contain valid information. const ( DWM_BB_ENABLE = 0x00000001 // A value for the fEnable member has been specified. DWM_BB_BLURREGION = 0x00000002 // A value for the hRgnBlur member has been specified. DWM_BB_TRANSITIONONMAXIMIZED = 0x00000004 // A value for the fTransitionOnMaximized member has been specified. ) // Flags used by the DwmEnableComposition function // to change the state of Desktop Window Manager (DWM) composition. const ( DWM_EC_DISABLECOMPOSITION = 0 // Disable composition DWM_EC_ENABLECOMPOSITION = 1 // Enable composition ) // enum-lite implementation for the following constant structure type DWM_SHOWCONTACT int32 const ( DWMSC_DOWN = 0x00000001 DWMSC_UP = 0x00000002 DWMSC_DRAG = 0x00000004 DWMSC_HOLD = 0x00000008 DWMSC_PENBARREL = 0x00000010 DWMSC_NONE = 0x00000000 DWMSC_ALL = 0xFFFFFFFF ) // enum-lite implementation for the following constant structure type DWM_SOURCE_FRAME_SAMPLING int32 // TODO: need to verify this construction // Flags used by the DwmSetPresentParameters function // to specify the frame sampling type const ( DWM_SOURCE_FRAME_SAMPLING_POINT = iota + 1 DWM_SOURCE_FRAME_SAMPLING_COVERAGE DWM_SOURCE_FRAME_SAMPLING_LAST ) // Flags used by the DWM_THUMBNAIL_PROPERTIES structure to // indicate which of its members contain valid information. const ( DWM_TNP_RECTDESTINATION = 0x00000001 // A value for the rcDestination member has been specified DWM_TNP_RECTSOURCE = 0x00000002 // A value for the rcSource member has been specified DWM_TNP_OPACITY = 0x00000004 // A value for the opacity member has been specified DWM_TNP_VISIBLE = 0x00000008 // A value for the fVisible member has been specified DWM_TNP_SOURCECLIENTAREAONLY = 0x00000010 // A value for the fSourceClientAreaOnly member has been specified ) // enum-lite implementation for the following constant structure type DWMFLIP3DWINDOWPOLICY int32 // TODO: need to verify this construction // Flags used by the DwmSetWindowAttribute function // to specify the Flip3D window policy const ( DWMFLIP3D_DEFAULT = iota + 1 DWMFLIP3D_EXCLUDEBELOW DWMFLIP3D_EXCLUDEABOVE DWMFLIP3D_LAST ) // enum-lite implementation for the following constant structure type DWMNCRENDERINGPOLICY int32 // TODO: need to verify this construction // Flags used by the DwmSetWindowAttribute function // to specify the non-client area rendering policy const ( DWMNCRP_USEWINDOWSTYLE = iota + 1 DWMNCRP_DISABLED DWMNCRP_ENABLED DWMNCRP_LAST ) // enum-lite implementation for the following constant structure type DWMTRANSITION_OWNEDWINDOW_TARGET int32 const ( DWMTRANSITION_OWNEDWINDOW_NULL = -1 DWMTRANSITION_OWNEDWINDOW_REPOSITION = 0 ) // enum-lite implementation for the following constant structure type DWMWINDOWATTRIBUTE int32 // TODO: need to verify this construction // Flags used by the DwmGetWindowAttribute and DwmSetWindowAttribute functions // to specify window attributes for non-client rendering const ( DWMWA_NCRENDERING_ENABLED = iota + 1 DWMWA_NCRENDERING_POLICY DWMWA_TRANSITIONS_FORCEDISABLED DWMWA_ALLOW_NCPAINT DWMWA_CAPTION_BUTTON_BOUNDS DWMWA_NONCLIENT_RTL_LAYOUT DWMWA_FORCE_ICONIC_REPRESENTATION DWMWA_FLIP3D_POLICY DWMWA_EXTENDED_FRAME_BOUNDS DWMWA_HAS_ICONIC_BITMAP DWMWA_DISALLOW_PEEK DWMWA_EXCLUDED_FROM_PEEK DWMWA_CLOAK DWMWA_CLOAKED DWMWA_FREEZE_REPRESENTATION DWMWA_LAST ) // enum-lite implementation for the following constant structure type GESTURE_TYPE int32 // TODO: use iota? // Identifies the gesture type const ( GT_PEN_TAP = 0 GT_PEN_DOUBLETAP = 1 GT_PEN_RIGHTTAP = 2 GT_PEN_PRESSANDHOLD = 3 GT_PEN_PRESSANDHOLDABORT = 4 GT_TOUCH_TAP = 5 GT_TOUCH_DOUBLETAP = 6 GT_TOUCH_RIGHTTAP = 7 GT_TOUCH_PRESSANDHOLD = 8 GT_TOUCH_PRESSANDHOLDABORT = 9 GT_TOUCH_PRESSANDTAP = 10 ) // Icons const ( ICON_SMALL = 0 ICON_BIG = 1 ICON_SMALL2 = 2 ) const ( SIZE_RESTORED = 0 SIZE_MINIMIZED = 1 SIZE_MAXIMIZED = 2 SIZE_MAXSHOW = 3 SIZE_MAXHIDE = 4 ) // XButton values const ( XBUTTON1 = 1 XBUTTON2 = 2 ) // Devmode const ( DM_SPECVERSION = 0x0401 DM_ORIENTATION = 0x00000001 DM_PAPERSIZE = 0x00000002 DM_PAPERLENGTH = 0x00000004 DM_PAPERWIDTH = 0x00000008 DM_SCALE = 0x00000010 DM_POSITION = 0x00000020 DM_NUP = 0x00000040 DM_DISPLAYORIENTATION = 0x00000080 DM_COPIES = 0x00000100 DM_DEFAULTSOURCE = 0x00000200 DM_PRINTQUALITY = 0x00000400 DM_COLOR = 0x00000800 DM_DUPLEX = 0x00001000 DM_YRESOLUTION = 0x00002000 DM_TTOPTION = 0x00004000 DM_COLLATE = 0x00008000 DM_FORMNAME = 0x00010000 DM_LOGPIXELS = 0x00020000 DM_BITSPERPEL = 0x00040000 DM_PELSWIDTH = 0x00080000 DM_PELSHEIGHT = 0x00100000 DM_DISPLAYFLAGS = 0x00200000 DM_DISPLAYFREQUENCY = 0x00400000 DM_ICMMETHOD = 0x00800000 DM_ICMINTENT = 0x01000000 DM_MEDIATYPE = 0x02000000 DM_DITHERTYPE = 0x04000000 DM_PANNINGWIDTH = 0x08000000 DM_PANNINGHEIGHT = 0x10000000 DM_DISPLAYFIXEDOUTPUT = 0x20000000 ) // ChangeDisplaySettings const ( CDS_UPDATEREGISTRY = 0x00000001 CDS_TEST = 0x00000002 CDS_FULLSCREEN = 0x00000004 CDS_GLOBAL = 0x00000008 CDS_SET_PRIMARY = 0x00000010 CDS_VIDEOPARAMETERS = 0x00000020 CDS_RESET = 0x40000000 CDS_NORESET = 0x10000000 DISP_CHANGE_SUCCESSFUL = 0 DISP_CHANGE_RESTART = 1 DISP_CHANGE_FAILED = -1 DISP_CHANGE_BADMODE = -2 DISP_CHANGE_NOTUPDATED = -3 DISP_CHANGE_BADFLAGS = -4 DISP_CHANGE_BADPARAM = -5 DISP_CHANGE_BADDUALVIEW = -6 ) const ( ENUM_CURRENT_SETTINGS = 0xFFFFFFFF ENUM_REGISTRY_SETTINGS = 0xFFFFFFFE ) // PIXELFORMATDESCRIPTOR const ( PFD_TYPE_RGBA = 0 PFD_TYPE_COLORINDEX = 1 PFD_MAIN_PLANE = 0 PFD_OVERLAY_PLANE = 1 PFD_UNDERLAY_PLANE = -1 PFD_DOUBLEBUFFER = 0x00000001 PFD_STEREO = 0x00000002 PFD_DRAW_TO_WINDOW = 0x00000004 PFD_DRAW_TO_BITMAP = 0x00000008 PFD_SUPPORT_GDI = 0x00000010 PFD_SUPPORT_OPENGL = 0x00000020 PFD_GENERIC_FORMAT = 0x00000040 PFD_NEED_PALETTE = 0x00000080 PFD_NEED_SYSTEM_PALETTE = 0x00000100 PFD_SWAP_EXCHANGE = 0x00000200 PFD_SWAP_COPY = 0x00000400 PFD_SWAP_LAYER_BUFFERS = 0x00000800 PFD_GENERIC_ACCELERATED = 0x00001000 PFD_SUPPORT_DIRECTDRAW = 0x00002000 PFD_DIRECT3D_ACCELERATED = 0x00004000 PFD_SUPPORT_COMPOSITION = 0x00008000 PFD_DEPTH_DONTCARE = 0x20000000 PFD_DOUBLEBUFFER_DONTCARE = 0x40000000 PFD_STEREO_DONTCARE = 0x80000000 ) const ( INPUT_MOUSE = 0 INPUT_KEYBOARD = 1 INPUT_HARDWARE = 2 ) const ( MOUSEEVENTF_ABSOLUTE = 0x8000 MOUSEEVENTF_HWHEEL = 0x01000 MOUSEEVENTF_MOVE = 0x0001 MOUSEEVENTF_MOVE_NOCOALESCE = 0x2000 MOUSEEVENTF_LEFTDOWN = 0x0002 MOUSEEVENTF_LEFTUP = 0x0004 MOUSEEVENTF_RIGHTDOWN = 0x0008 MOUSEEVENTF_RIGHTUP = 0x0010 MOUSEEVENTF_MIDDLEDOWN = 0x0020 MOUSEEVENTF_MIDDLEUP = 0x0040 MOUSEEVENTF_VIRTUALDESK = 0x4000 MOUSEEVENTF_WHEEL = 0x0800 MOUSEEVENTF_XDOWN = 0x0080 MOUSEEVENTF_XUP = 0x0100 ) // Windows Hooks (WH_*) // http://msdn.microsoft.com/en-us/library/windows/desktop/ms644990(v=vs.85).aspx const ( WH_CALLWNDPROC = 4 WH_CALLWNDPROCRET = 12 WH_CBT = 5 WH_DEBUG = 9 WH_FOREGROUNDIDLE = 11 WH_GETMESSAGE = 3 WH_JOURNALPLAYBACK = 1 WH_JOURNALRECORD = 0 WH_KEYBOARD = 2 WH_KEYBOARD_LL = 13 WH_MOUSE = 7 WH_MOUSE_LL = 14 WH_MSGFILTER = -1 WH_SHELL = 10 WH_SYSMSGFILTER = 6 ) // ComboBox return values const ( CB_OKAY = 0 CB_ERR = ^uintptr(0) // -1 CB_ERRSPACE = ^uintptr(1) // -2 ) // ComboBox notifications const ( CBN_ERRSPACE = -1 CBN_SELCHANGE = 1 CBN_DBLCLK = 2 CBN_SETFOCUS = 3 CBN_KILLFOCUS = 4 CBN_EDITCHANGE = 5 CBN_EDITUPDATE = 6 CBN_DROPDOWN = 7 CBN_CLOSEUP = 8 CBN_SELENDOK = 9 CBN_SELENDCANCEL = 10 ) // ComboBox styles const ( CBS_SIMPLE = 0x0001 CBS_DROPDOWN = 0x0002 CBS_DROPDOWNLIST = 0x0003 CBS_OWNERDRAWFIXED = 0x0010 CBS_OWNERDRAWVARIABLE = 0x0020 CBS_AUTOHSCROLL = 0x0040 CBS_OEMCONVERT = 0x0080 CBS_SORT = 0x0100 CBS_HASSTRINGS = 0x0200 CBS_NOINTEGRALHEIGHT = 0x0400 CBS_DISABLENOSCROLL = 0x0800 CBS_UPPERCASE = 0x2000 CBS_LOWERCASE = 0x4000 ) // ComboBox messages const ( CB_GETEDITSEL = 0x0140 CB_LIMITTEXT = 0x0141 CB_SETEDITSEL = 0x0142 CB_ADDSTRING = 0x0143 CB_DELETESTRING = 0x0144 CB_DIR = 0x0145 CB_GETCOUNT = 0x0146 CB_GETCURSEL = 0x0147 CB_GETLBTEXT = 0x0148 CB_GETLBTEXTLEN = 0x0149 CB_INSERTSTRING = 0x014A CB_RESETCONTENT = 0x014B CB_FINDSTRING = 0x014C CB_SELECTSTRING = 0x014D CB_SETCURSEL = 0x014E CB_SHOWDROPDOWN = 0x014F CB_GETITEMDATA = 0x0150 CB_SETITEMDATA = 0x0151 CB_GETDROPPEDCONTROLRECT = 0x0152 CB_SETITEMHEIGHT = 0x0153 CB_GETITEMHEIGHT = 0x0154 CB_SETEXTENDEDUI = 0x0155 CB_GETEXTENDEDUI = 0x0156 CB_GETDROPPEDSTATE = 0x0157 CB_FINDSTRINGEXACT = 0x0158 CB_SETLOCALE = 0x0159 CB_GETLOCALE = 0x015A CB_GETTOPINDEX = 0x015b CB_SETTOPINDEX = 0x015c CB_GETHORIZONTALEXTENT = 0x015d CB_SETHORIZONTALEXTENT = 0x015e CB_GETDROPPEDWIDTH = 0x015f CB_SETDROPPEDWIDTH = 0x0160 CB_INITSTORAGE = 0x0161 CB_MULTIPLEADDSTRING = 0x0163 CB_GETCOMBOBOXINFO = 0x0164 ) // TreeView styles const ( TVS_HASBUTTONS = 0x0001 TVS_HASLINES = 0x0002 TVS_LINESATROOT = 0x0004 TVS_EDITLABELS = 0x0008 TVS_DISABLEDRAGDROP = 0x0010 TVS_SHOWSELALWAYS = 0x0020 TVS_RTLREADING = 0x0040 TVS_NOTOOLTIPS = 0x0080 TVS_CHECKBOXES = 0x0100 TVS_TRACKSELECT = 0x0200 TVS_SINGLEEXPAND = 0x0400 TVS_INFOTIP = 0x0800 TVS_FULLROWSELECT = 0x1000 TVS_NOSCROLL = 0x2000 TVS_NONEVENHEIGHT = 0x4000 TVS_NOHSCROLL = 0x8000 ) const ( TVS_EX_NOSINGLECOLLAPSE = 0x0001 TVS_EX_MULTISELECT = 0x0002 TVS_EX_DOUBLEBUFFER = 0x0004 TVS_EX_NOINDENTSTATE = 0x0008 TVS_EX_RICHTOOLTIP = 0x0010 TVS_EX_AUTOHSCROLL = 0x0020 TVS_EX_FADEINOUTEXPANDOS = 0x0040 TVS_EX_PARTIALCHECKBOXES = 0x0080 TVS_EX_EXCLUSIONCHECKBOXES = 0x0100 TVS_EX_DIMMEDCHECKBOXES = 0x0200 TVS_EX_DRAWIMAGEASYNC = 0x0400 ) const ( TVIF_TEXT = 0x0001 TVIF_IMAGE = 0x0002 TVIF_PARAM = 0x0004 TVIF_STATE = 0x0008 TVIF_HANDLE = 0x0010 TVIF_SELECTEDIMAGE = 0x0020 TVIF_CHILDREN = 0x0040 TVIF_INTEGRAL = 0x0080 TVIF_STATEEX = 0x0100 TVIF_EXPANDEDIMAGE = 0x0200 ) const ( TVIS_SELECTED = 0x0002 TVIS_CUT = 0x0004 TVIS_DROPHILITED = 0x0008 TVIS_BOLD = 0x0010 TVIS_EXPANDED = 0x0020 TVIS_EXPANDEDONCE = 0x0040 TVIS_EXPANDPARTIAL = 0x0080 TVIS_OVERLAYMASK = 0x0F00 TVIS_STATEIMAGEMASK = 0xF000 TVIS_USERMASK = 0xF000 ) const ( TVIS_EX_FLAT = 0x0001 TVIS_EX_DISABLED = 0x0002 TVIS_EX_ALL = 0x0002 ) const ( TVI_ROOT = ^HTREEITEM(0xffff) TVI_FIRST = ^HTREEITEM(0xfffe) TVI_LAST = ^HTREEITEM(0xfffd) TVI_SORT = ^HTREEITEM(0xfffc) ) // TVM_EXPAND action flags const ( TVE_COLLAPSE = 0x0001 TVE_EXPAND = 0x0002 TVE_TOGGLE = 0x0003 TVE_EXPANDPARTIAL = 0x4000 TVE_COLLAPSERESET = 0x8000 ) const ( TVGN_CARET = 9 ) // TreeView messages const ( TV_FIRST = 0x1100 TVM_INSERTITEM = TV_FIRST + 50 TVM_DELETEITEM = TV_FIRST + 1 TVM_EXPAND = TV_FIRST + 2 TVM_GETITEMRECT = TV_FIRST + 4 TVM_GETCOUNT = TV_FIRST + 5 TVM_GETINDENT = TV_FIRST + 6 TVM_SETINDENT = TV_FIRST + 7 TVM_GETIMAGELIST = TV_FIRST + 8 TVM_SETIMAGELIST = TV_FIRST + 9 TVM_GETNEXTITEM = TV_FIRST + 10 TVM_SELECTITEM = TV_FIRST + 11 TVM_GETITEM = TV_FIRST + 62 TVM_SETITEM = TV_FIRST + 63 TVM_EDITLABEL = TV_FIRST + 65 TVM_GETEDITCONTROL = TV_FIRST + 15 TVM_GETVISIBLECOUNT = TV_FIRST + 16 TVM_HITTEST = TV_FIRST + 17 TVM_CREATEDRAGIMAGE = TV_FIRST + 18 TVM_SORTCHILDREN = TV_FIRST + 19 TVM_ENSUREVISIBLE = TV_FIRST + 20 TVM_SORTCHILDRENCB = TV_FIRST + 21 TVM_ENDEDITLABELNOW = TV_FIRST + 22 TVM_GETISEARCHSTRING = TV_FIRST + 64 TVM_SETTOOLTIPS = TV_FIRST + 24 TVM_GETTOOLTIPS = TV_FIRST + 25 TVM_SETINSERTMARK = TV_FIRST + 26 TVM_SETUNICODEFORMAT = CCM_SETUNICODEFORMAT TVM_GETUNICODEFORMAT = CCM_GETUNICODEFORMAT TVM_SETITEMHEIGHT = TV_FIRST + 27 TVM_GETITEMHEIGHT = TV_FIRST + 28 TVM_SETBKCOLOR = TV_FIRST + 29 TVM_SETTEXTCOLOR = TV_FIRST + 30 TVM_GETBKCOLOR = TV_FIRST + 31 TVM_GETTEXTCOLOR = TV_FIRST + 32 TVM_SETSCROLLTIME = TV_FIRST + 33 TVM_GETSCROLLTIME = TV_FIRST + 34 TVM_SETINSERTMARKCOLOR = TV_FIRST + 37 TVM_GETINSERTMARKCOLOR = TV_FIRST + 38 TVM_GETITEMSTATE = TV_FIRST + 39 TVM_SETLINECOLOR = TV_FIRST + 40 TVM_GETLINECOLOR = TV_FIRST + 41 TVM_MAPACCIDTOHTREEITEM = TV_FIRST + 42 TVM_MAPHTREEITEMTOACCID = TV_FIRST + 43 TVM_SETEXTENDEDSTYLE = TV_FIRST + 44 TVM_GETEXTENDEDSTYLE = TV_FIRST + 45 TVM_SETAUTOSCROLLINFO = TV_FIRST + 59 ) // TreeView notifications const ( TVN_FIRST = ^uint32(399) TVN_SELCHANGING = TVN_FIRST - 50 TVN_SELCHANGED = TVN_FIRST - 51 TVN_GETDISPINFO = TVN_FIRST - 52 TVN_ITEMEXPANDING = TVN_FIRST - 54 TVN_ITEMEXPANDED = TVN_FIRST - 55 TVN_BEGINDRAG = TVN_FIRST - 56 TVN_BEGINRDRAG = TVN_FIRST - 57 TVN_DELETEITEM = TVN_FIRST - 58 TVN_BEGINLABELEDIT = TVN_FIRST - 59 TVN_ENDLABELEDIT = TVN_FIRST - 60 TVN_KEYDOWN = TVN_FIRST - 12 TVN_GETINFOTIP = TVN_FIRST - 14 TVN_SINGLEEXPAND = TVN_FIRST - 15 TVN_ITEMCHANGING = TVN_FIRST - 17 TVN_ITEMCHANGED = TVN_FIRST - 19 TVN_ASYNCDRAW = TVN_FIRST - 20 ) // TreeView hit test constants const ( TVHT_NOWHERE = 1 TVHT_ONITEMICON = 2 TVHT_ONITEMLABEL = 4 TVHT_ONITEM = TVHT_ONITEMICON | TVHT_ONITEMLABEL | TVHT_ONITEMSTATEICON TVHT_ONITEMINDENT = 8 TVHT_ONITEMBUTTON = 16 TVHT_ONITEMRIGHT = 32 TVHT_ONITEMSTATEICON = 64 TVHT_ABOVE = 256 TVHT_BELOW = 512 TVHT_TORIGHT = 1024 TVHT_TOLEFT = 2048 ) type HTREEITEM HANDLE type TVITEM struct { Mask uint32 HItem HTREEITEM State uint32 StateMask uint32 PszText uintptr CchTextMax int32 IImage int32 ISelectedImage int32 CChildren int32 LParam uintptr } /*type TVITEMEX struct { mask UINT hItem HTREEITEM state UINT stateMask UINT pszText LPWSTR cchTextMax int iImage int iSelectedImage int cChildren int lParam LPARAM iIntegral int uStateEx UINT hwnd HWND iExpandedImage int }*/ type TVINSERTSTRUCT struct { HParent HTREEITEM HInsertAfter HTREEITEM Item TVITEM // itemex TVITEMEX } type NMTREEVIEW struct { Hdr NMHDR Action uint32 ItemOld TVITEM ItemNew TVITEM PtDrag POINT } type NMTVDISPINFO struct { Hdr NMHDR Item TVITEM } type NMTVKEYDOWN struct { Hdr NMHDR WVKey uint16 Flags uint32 } type TVHITTESTINFO struct { Pt POINT Flags uint32 HItem HTREEITEM } // TabPage support const TCM_FIRST = 0x1300 const TCN_FIRST = -550 const ( TCS_SCROLLOPPOSITE = 0x0001 TCS_BOTTOM = 0x0002 TCS_RIGHT = 0x0002 TCS_MULTISELECT = 0x0004 TCS_FLATBUTTONS = 0x0008 TCS_FORCEICONLEFT = 0x0010 TCS_FORCELABELLEFT = 0x0020 TCS_HOTTRACK = 0x0040 TCS_VERTICAL = 0x0080 TCS_TABS = 0x0000 TCS_BUTTONS = 0x0100 TCS_SINGLELINE = 0x0000 TCS_MULTILINE = 0x0200 TCS_RIGHTJUSTIFY = 0x0000 TCS_FIXEDWIDTH = 0x0400 TCS_RAGGEDRIGHT = 0x0800 TCS_FOCUSONBUTTONDOWN = 0x1000 TCS_OWNERDRAWFIXED = 0x2000 TCS_TOOLTIPS = 0x4000 TCS_FOCUSNEVER = 0x8000 ) const ( TCS_EX_FLATSEPARATORS = 0x00000001 TCS_EX_REGISTERDROP = 0x00000002 ) const ( TCM_GETIMAGELIST = TCM_FIRST + 2 TCM_SETIMAGELIST = TCM_FIRST + 3 TCM_GETITEMCOUNT = TCM_FIRST + 4 TCM_GETITEM = TCM_FIRST + 60 TCM_SETITEM = TCM_FIRST + 61 TCM_INSERTITEM = TCM_FIRST + 62 TCM_DELETEITEM = TCM_FIRST + 8 TCM_DELETEALLITEMS = TCM_FIRST + 9 TCM_GETITEMRECT = TCM_FIRST + 10 TCM_GETCURSEL = TCM_FIRST + 11 TCM_SETCURSEL = TCM_FIRST + 12 TCM_HITTEST = TCM_FIRST + 13 TCM_SETITEMEXTRA = TCM_FIRST + 14 TCM_ADJUSTRECT = TCM_FIRST + 40 TCM_SETITEMSIZE = TCM_FIRST + 41 TCM_REMOVEIMAGE = TCM_FIRST + 42 TCM_SETPADDING = TCM_FIRST + 43 TCM_GETROWCOUNT = TCM_FIRST + 44 TCM_GETTOOLTIPS = TCM_FIRST + 45 TCM_SETTOOLTIPS = TCM_FIRST + 46 TCM_GETCURFOCUS = TCM_FIRST + 47 TCM_SETCURFOCUS = TCM_FIRST + 48 TCM_SETMINTABWIDTH = TCM_FIRST + 49 TCM_DESELECTALL = TCM_FIRST + 50 TCM_HIGHLIGHTITEM = TCM_FIRST + 51 TCM_SETEXTENDEDSTYLE = TCM_FIRST + 52 TCM_GETEXTENDEDSTYLE = TCM_FIRST + 53 TCM_SETUNICODEFORMAT = CCM_SETUNICODEFORMAT TCM_GETUNICODEFORMAT = CCM_GETUNICODEFORMAT ) const ( TCIF_TEXT = 0x0001 TCIF_IMAGE = 0x0002 TCIF_RTLREADING = 0x0004 TCIF_PARAM = 0x0008 TCIF_STATE = 0x0010 ) const ( TCIS_BUTTONPRESSED = 0x0001 TCIS_HIGHLIGHTED = 0x0002 ) const ( TCHT_NOWHERE = 0x0001 TCHT_ONITEMICON = 0x0002 TCHT_ONITEMLABEL = 0x0004 TCHT_ONITEM = TCHT_ONITEMICON | TCHT_ONITEMLABEL ) const ( TCN_KEYDOWN = TCN_FIRST - 0 TCN_SELCHANGE = TCN_FIRST - 1 TCN_SELCHANGING = TCN_FIRST - 2 TCN_GETOBJECT = TCN_FIRST - 3 TCN_FOCUSCHANGE = TCN_FIRST - 4 ) type TCITEMHEADER struct { Mask uint32 LpReserved1 uint32 LpReserved2 uint32 PszText *uint16 CchTextMax int32 IImage int32 } type TCITEM struct { Mask uint32 DwState uint32 DwStateMask uint32 PszText *uint16 CchTextMax int32 IImage int32 LParam uintptr } type TCHITTESTINFO struct { Pt POINT flags uint32 } type NMTCKEYDOWN struct { Hdr NMHDR WVKey uint16 Flags uint32 } // Menu support constants // Constants for MENUITEMINFO.fMask const ( MIIM_STATE = 1 MIIM_ID = 2 MIIM_SUBMENU = 4 MIIM_CHECKMARKS = 8 MIIM_TYPE = 16 MIIM_DATA = 32 MIIM_STRING = 64 MIIM_BITMAP = 128 MIIM_FTYPE = 256 ) // Constants for MENUITEMINFO.fType const ( MFT_BITMAP = 4 MFT_MENUBARBREAK = 32 MFT_MENUBREAK = 64 MFT_OWNERDRAW = 256 MFT_RADIOCHECK = 512 MFT_RIGHTJUSTIFY = 0x4000 MFT_SEPARATOR = 0x800 MFT_RIGHTORDER = 0x2000 MFT_STRING = 0 ) // Constants for MENUITEMINFO.fState const ( MFS_CHECKED = 8 MFS_DEFAULT = 4096 MFS_DISABLED = 3 MFS_ENABLED = 0 MFS_GRAYED = 3 MFS_HILITE = 128 MFS_UNCHECKED = 0 MFS_UNHILITE = 0 ) // Constants for MENUITEMINFO.hbmp* const ( HBMMENU_CALLBACK = -1 HBMMENU_SYSTEM = 1 HBMMENU_MBAR_RESTORE = 2 HBMMENU_MBAR_MINIMIZE = 3 HBMMENU_MBAR_CLOSE = 5 HBMMENU_MBAR_CLOSE_D = 6 HBMMENU_MBAR_MINIMIZE_D = 7 HBMMENU_POPUP_CLOSE = 8 HBMMENU_POPUP_RESTORE = 9 HBMMENU_POPUP_MAXIMIZE = 10 HBMMENU_POPUP_MINIMIZE = 11 ) // MENUINFO mask constants const ( MIM_APPLYTOSUBMENUS = 0x80000000 MIM_BACKGROUND = 0x00000002 MIM_HELPID = 0x00000004 MIM_MAXHEIGHT = 0x00000001 MIM_MENUDATA = 0x00000008 MIM_STYLE = 0x00000010 ) // MENUINFO style constants const ( MNS_AUTODISMISS = 0x10000000 MNS_CHECKORBMP = 0x04000000 MNS_DRAGDROP = 0x20000000 MNS_MODELESS = 0x40000000 MNS_NOCHECK = 0x80000000 MNS_NOTIFYBYPOS = 0x08000000 ) const ( MF_BYCOMMAND = 0x00000000 MF_BYPOSITION = 0x00000400 ) type MENUITEMINFO struct { CbSize uint32 FMask uint32 FType uint32 FState uint32 WID uint32 HSubMenu HMENU HbmpChecked HBITMAP HbmpUnchecked HBITMAP DwItemData uintptr DwTypeData *uint16 Cch uint32 HbmpItem HBITMAP } type MENUINFO struct { CbSize uint32 FMask uint32 DwStyle uint32 CyMax uint32 HbrBack HBRUSH DwContextHelpID uint32 DwMenuData uintptr } // UI state constants const ( UIS_SET = 1 UIS_CLEAR = 2 UIS_INITIALIZE = 3 ) // UI state constants const ( UISF_HIDEFOCUS = 0x1 UISF_HIDEACCEL = 0x2 UISF_ACTIVE = 0x4 ) // Virtual key codes const ( VK_LBUTTON = 1 VK_RBUTTON = 2 VK_CANCEL = 3 VK_MBUTTON = 4 VK_XBUTTON1 = 5 VK_XBUTTON2 = 6 VK_BACK = 8 VK_TAB = 9 VK_CLEAR = 12 VK_RETURN = 13 VK_SHIFT = 16 VK_CONTROL = 17 VK_MENU = 18 VK_PAUSE = 19 VK_CAPITAL = 20 VK_KANA = 0x15 VK_HANGEUL = 0x15 VK_HANGUL = 0x15 VK_JUNJA = 0x17 VK_FINAL = 0x18 VK_HANJA = 0x19 VK_KANJI = 0x19 VK_ESCAPE = 0x1B VK_CONVERT = 0x1C VK_NONCONVERT = 0x1D VK_ACCEPT = 0x1E VK_MODECHANGE = 0x1F VK_SPACE = 32 VK_PRIOR = 33 VK_NEXT = 34 VK_END = 35 VK_HOME = 36 VK_LEFT = 37 VK_UP = 38 VK_RIGHT = 39 VK_DOWN = 40 VK_SELECT = 41 VK_PRINT = 42 VK_EXECUTE = 43 VK_SNAPSHOT = 44 VK_INSERT = 45 VK_DELETE = 46 VK_HELP = 47 VK_LWIN = 0x5B VK_RWIN = 0x5C VK_APPS = 0x5D VK_SLEEP = 0x5F VK_NUMPAD0 = 0x60 VK_NUMPAD1 = 0x61 VK_NUMPAD2 = 0x62 VK_NUMPAD3 = 0x63 VK_NUMPAD4 = 0x64 VK_NUMPAD5 = 0x65 VK_NUMPAD6 = 0x66 VK_NUMPAD7 = 0x67 VK_NUMPAD8 = 0x68 VK_NUMPAD9 = 0x69 VK_MULTIPLY = 0x6A VK_ADD = 0x6B VK_SEPARATOR = 0x6C VK_SUBTRACT = 0x6D VK_DECIMAL = 0x6E VK_DIVIDE = 0x6F VK_F1 = 0x70 VK_F2 = 0x71 VK_F3 = 0x72 VK_F4 = 0x73 VK_F5 = 0x74 VK_F6 = 0x75 VK_F7 = 0x76 VK_F8 = 0x77 VK_F9 = 0x78 VK_F10 = 0x79 VK_F11 = 0x7A VK_F12 = 0x7B VK_F13 = 0x7C VK_F14 = 0x7D VK_F15 = 0x7E VK_F16 = 0x7F VK_F17 = 0x80 VK_F18 = 0x81 VK_F19 = 0x82 VK_F20 = 0x83 VK_F21 = 0x84 VK_F22 = 0x85 VK_F23 = 0x86 VK_F24 = 0x87 VK_NUMLOCK = 0x90 VK_SCROLL = 0x91 VK_LSHIFT = 0xA0 VK_RSHIFT = 0xA1 VK_LCONTROL = 0xA2 VK_RCONTROL = 0xA3 VK_LMENU = 0xA4 VK_RMENU = 0xA5 VK_BROWSER_BACK = 0xA6 VK_BROWSER_FORWARD = 0xA7 VK_BROWSER_REFRESH = 0xA8 VK_BROWSER_STOP = 0xA9 VK_BROWSER_SEARCH = 0xAA VK_BROWSER_FAVORITES = 0xAB VK_BROWSER_HOME = 0xAC VK_VOLUME_MUTE = 0xAD VK_VOLUME_DOWN = 0xAE VK_VOLUME_UP = 0xAF VK_MEDIA_NEXT_TRACK = 0xB0 VK_MEDIA_PREV_TRACK = 0xB1 VK_MEDIA_STOP = 0xB2 VK_MEDIA_PLAY_PAUSE = 0xB3 VK_LAUNCH_MAIL = 0xB4 VK_LAUNCH_MEDIA_SELECT = 0xB5 VK_LAUNCH_APP1 = 0xB6 VK_LAUNCH_APP2 = 0xB7 VK_OEM_1 = 0xBA VK_OEM_PLUS = 0xBB VK_OEM_COMMA = 0xBC VK_OEM_MINUS = 0xBD VK_OEM_PERIOD = 0xBE VK_OEM_2 = 0xBF VK_OEM_3 = 0xC0 VK_OEM_4 = 0xDB VK_OEM_5 = 0xDC VK_OEM_6 = 0xDD VK_OEM_7 = 0xDE VK_OEM_8 = 0xDF VK_OEM_102 = 0xE2 VK_PROCESSKEY = 0xE5 VK_PACKET = 0xE7 VK_ATTN = 0xF6 VK_CRSEL = 0xF7 VK_EXSEL = 0xF8 VK_EREOF = 0xF9 VK_PLAY = 0xFA VK_ZOOM = 0xFB VK_NONAME = 0xFC VK_PA1 = 0xFD VK_OEM_CLEAR = 0xFE ) // ScrollBar constants const ( SB_HORZ = 0 SB_VERT = 1 SB_CTL = 2 SB_BOTH = 3 ) // ScrollBar commands const ( SB_LINEUP = 0 SB_LINELEFT = 0 SB_LINEDOWN = 1 SB_LINERIGHT = 1 SB_PAGEUP = 2 SB_PAGELEFT = 2 SB_PAGEDOWN = 3 SB_PAGERIGHT = 3 SB_THUMBPOSITION = 4 SB_THUMBTRACK = 5 SB_TOP = 6 SB_LEFT = 6 SB_BOTTOM = 7 SB_RIGHT = 7 SB_ENDSCROLL = 8 ) // [Get|Set]ScrollInfo mask constants const ( SIF_RANGE = 1 SIF_PAGE = 2 SIF_POS = 4 SIF_DISABLENOSCROLL = 8 SIF_TRACKPOS = 16 SIF_ALL = SIF_RANGE + SIF_PAGE + SIF_POS + SIF_TRACKPOS ) ================================================ FILE: w32/gdi32.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. * Copyright (C) 2010-2012 The W32 Authors. All Rights Reserved. */ package w32 import ( "syscall" "unsafe" ) var ( modgdi32 = syscall.NewLazyDLL("gdi32.dll") procGetDeviceCaps = modgdi32.NewProc("GetDeviceCaps") procDeleteObject = modgdi32.NewProc("DeleteObject") procCreateFontIndirect = modgdi32.NewProc("CreateFontIndirectW") procAbortDoc = modgdi32.NewProc("AbortDoc") procBitBlt = modgdi32.NewProc("BitBlt") procPatBlt = modgdi32.NewProc("PatBlt") procCloseEnhMetaFile = modgdi32.NewProc("CloseEnhMetaFile") procCopyEnhMetaFile = modgdi32.NewProc("CopyEnhMetaFileW") procCreateBrushIndirect = modgdi32.NewProc("CreateBrushIndirect") procCreateCompatibleDC = modgdi32.NewProc("CreateCompatibleDC") procCreateDC = modgdi32.NewProc("CreateDCW") procCreateDIBSection = modgdi32.NewProc("CreateDIBSection") procCreateEnhMetaFile = modgdi32.NewProc("CreateEnhMetaFileW") procCreateIC = modgdi32.NewProc("CreateICW") procDeleteDC = modgdi32.NewProc("DeleteDC") procDeleteEnhMetaFile = modgdi32.NewProc("DeleteEnhMetaFile") procEllipse = modgdi32.NewProc("Ellipse") procEndDoc = modgdi32.NewProc("EndDoc") procEndPage = modgdi32.NewProc("EndPage") procExtCreatePen = modgdi32.NewProc("ExtCreatePen") procGetEnhMetaFile = modgdi32.NewProc("GetEnhMetaFileW") procGetEnhMetaFileHeader = modgdi32.NewProc("GetEnhMetaFileHeader") procGetObject = modgdi32.NewProc("GetObjectW") procGetStockObject = modgdi32.NewProc("GetStockObject") procGetTextExtentExPoint = modgdi32.NewProc("GetTextExtentExPointW") procGetTextExtentPoint32 = modgdi32.NewProc("GetTextExtentPoint32W") procGetTextMetrics = modgdi32.NewProc("GetTextMetricsW") procLineTo = modgdi32.NewProc("LineTo") procMoveToEx = modgdi32.NewProc("MoveToEx") procPlayEnhMetaFile = modgdi32.NewProc("PlayEnhMetaFile") procRectangle = modgdi32.NewProc("Rectangle") procResetDC = modgdi32.NewProc("ResetDCW") procSelectObject = modgdi32.NewProc("SelectObject") procSetBkMode = modgdi32.NewProc("SetBkMode") procSetBrushOrgEx = modgdi32.NewProc("SetBrushOrgEx") procSetStretchBltMode = modgdi32.NewProc("SetStretchBltMode") procSetTextColor = modgdi32.NewProc("SetTextColor") procSetBkColor = modgdi32.NewProc("SetBkColor") procStartDoc = modgdi32.NewProc("StartDocW") procStartPage = modgdi32.NewProc("StartPage") procStretchBlt = modgdi32.NewProc("StretchBlt") procSetDIBitsToDevice = modgdi32.NewProc("SetDIBitsToDevice") procChoosePixelFormat = modgdi32.NewProc("ChoosePixelFormat") procDescribePixelFormat = modgdi32.NewProc("DescribePixelFormat") procGetEnhMetaFilePixelFormat = modgdi32.NewProc("GetEnhMetaFilePixelFormat") procGetPixelFormat = modgdi32.NewProc("GetPixelFormat") procSetPixelFormat = modgdi32.NewProc("SetPixelFormat") procSwapBuffers = modgdi32.NewProc("SwapBuffers") ) func GetDeviceCaps(hdc HDC, index int) int { ret, _, _ := procGetDeviceCaps.Call( uintptr(hdc), uintptr(index)) return int(ret) } func DeleteObject(hObject HGDIOBJ) bool { ret, _, _ := procDeleteObject.Call( uintptr(hObject)) return ret != 0 } func CreateFontIndirect(logFont *LOGFONT) HFONT { ret, _, _ := procCreateFontIndirect.Call( uintptr(unsafe.Pointer(logFont))) return HFONT(ret) } func AbortDoc(hdc HDC) int { ret, _, _ := procAbortDoc.Call( uintptr(hdc)) return int(ret) } func BitBlt(hdcDest HDC, nXDest, nYDest, nWidth, nHeight int, hdcSrc HDC, nXSrc, nYSrc int, dwRop uint) { ret, _, _ := procBitBlt.Call( uintptr(hdcDest), uintptr(nXDest), uintptr(nYDest), uintptr(nWidth), uintptr(nHeight), uintptr(hdcSrc), uintptr(nXSrc), uintptr(nYSrc), uintptr(dwRop)) if ret == 0 { panic("BitBlt failed") } } func PatBlt(hdc HDC, nXLeft, nYLeft, nWidth, nHeight int, dwRop uint) { ret, _, _ := procPatBlt.Call( uintptr(hdc), uintptr(nXLeft), uintptr(nYLeft), uintptr(nWidth), uintptr(nHeight), uintptr(dwRop)) if ret == 0 { panic("PatBlt failed") } } func CloseEnhMetaFile(hdc HDC) HENHMETAFILE { ret, _, _ := procCloseEnhMetaFile.Call( uintptr(hdc)) return HENHMETAFILE(ret) } func CopyEnhMetaFile(hemfSrc HENHMETAFILE, lpszFile *uint16) HENHMETAFILE { ret, _, _ := procCopyEnhMetaFile.Call( uintptr(hemfSrc), uintptr(unsafe.Pointer(lpszFile))) return HENHMETAFILE(ret) } func CreateBrushIndirect(lplb *LOGBRUSH) HBRUSH { ret, _, _ := procCreateBrushIndirect.Call( uintptr(unsafe.Pointer(lplb))) return HBRUSH(ret) } func CreateCompatibleDC(hdc HDC) HDC { ret, _, _ := procCreateCompatibleDC.Call( uintptr(hdc)) if ret == 0 { panic("Create compatible DC failed") } return HDC(ret) } func CreateDC(lpszDriver, lpszDevice, lpszOutput *uint16, lpInitData *DEVMODE) HDC { ret, _, _ := procCreateDC.Call( uintptr(unsafe.Pointer(lpszDriver)), uintptr(unsafe.Pointer(lpszDevice)), uintptr(unsafe.Pointer(lpszOutput)), uintptr(unsafe.Pointer(lpInitData))) return HDC(ret) } func CreateDIBSection(hdc HDC, pbmi *BITMAPINFO, iUsage uint, ppvBits *unsafe.Pointer, hSection HANDLE, dwOffset uint) HBITMAP { ret, _, _ := procCreateDIBSection.Call( uintptr(hdc), uintptr(unsafe.Pointer(pbmi)), uintptr(iUsage), uintptr(unsafe.Pointer(ppvBits)), uintptr(hSection), uintptr(dwOffset)) return HBITMAP(ret) } func CreateEnhMetaFile(hdcRef HDC, lpFilename *uint16, lpRect *RECT, lpDescription *uint16) HDC { ret, _, _ := procCreateEnhMetaFile.Call( uintptr(hdcRef), uintptr(unsafe.Pointer(lpFilename)), uintptr(unsafe.Pointer(lpRect)), uintptr(unsafe.Pointer(lpDescription))) return HDC(ret) } func CreateIC(lpszDriver, lpszDevice, lpszOutput *uint16, lpdvmInit *DEVMODE) HDC { ret, _, _ := procCreateIC.Call( uintptr(unsafe.Pointer(lpszDriver)), uintptr(unsafe.Pointer(lpszDevice)), uintptr(unsafe.Pointer(lpszOutput)), uintptr(unsafe.Pointer(lpdvmInit))) return HDC(ret) } func DeleteDC(hdc HDC) bool { ret, _, _ := procDeleteDC.Call( uintptr(hdc)) return ret != 0 } func DeleteEnhMetaFile(hemf HENHMETAFILE) bool { ret, _, _ := procDeleteEnhMetaFile.Call( uintptr(hemf)) return ret != 0 } func Ellipse(hdc HDC, nLeftRect, nTopRect, nRightRect, nBottomRect int32) bool { ret, _, _ := procEllipse.Call( uintptr(hdc), uintptr(nLeftRect), uintptr(nTopRect), uintptr(nRightRect), uintptr(nBottomRect)) return ret != 0 } func EndDoc(hdc HDC) int { ret, _, _ := procEndDoc.Call( uintptr(hdc)) return int(ret) } func EndPage(hdc HDC) int { ret, _, _ := procEndPage.Call( uintptr(hdc)) return int(ret) } func ExtCreatePen(dwPenStyle, dwWidth uint, lplb *LOGBRUSH, dwStyleCount uint, lpStyle *uint) HPEN { ret, _, _ := procExtCreatePen.Call( uintptr(dwPenStyle), uintptr(dwWidth), uintptr(unsafe.Pointer(lplb)), uintptr(dwStyleCount), uintptr(unsafe.Pointer(lpStyle))) return HPEN(ret) } func GetEnhMetaFile(lpszMetaFile *uint16) HENHMETAFILE { ret, _, _ := procGetEnhMetaFile.Call( uintptr(unsafe.Pointer(lpszMetaFile))) return HENHMETAFILE(ret) } func GetEnhMetaFileHeader(hemf HENHMETAFILE, cbBuffer uint, lpemh *ENHMETAHEADER) uint { ret, _, _ := procGetEnhMetaFileHeader.Call( uintptr(hemf), uintptr(cbBuffer), uintptr(unsafe.Pointer(lpemh))) return uint(ret) } func GetObject(hgdiobj HGDIOBJ, cbBuffer uintptr, lpvObject unsafe.Pointer) int { ret, _, _ := procGetObject.Call( uintptr(hgdiobj), uintptr(cbBuffer), uintptr(lpvObject)) return int(ret) } func GetStockObject(fnObject int) HGDIOBJ { ret, _, _ := procGetDeviceCaps.Call( uintptr(fnObject)) return HGDIOBJ(ret) } func GetTextExtentExPoint(hdc HDC, lpszStr *uint16, cchString, nMaxExtent int, lpnFit, alpDx *int, lpSize *SIZE) bool { ret, _, _ := procGetTextExtentExPoint.Call( uintptr(hdc), uintptr(unsafe.Pointer(lpszStr)), uintptr(cchString), uintptr(nMaxExtent), uintptr(unsafe.Pointer(lpnFit)), uintptr(unsafe.Pointer(alpDx)), uintptr(unsafe.Pointer(lpSize))) return ret != 0 } func GetTextExtentPoint32(hdc HDC, lpString *uint16, c int, lpSize *SIZE) bool { ret, _, _ := procGetTextExtentPoint32.Call( uintptr(hdc), uintptr(unsafe.Pointer(lpString)), uintptr(c), uintptr(unsafe.Pointer(lpSize))) return ret != 0 } func GetTextMetrics(hdc HDC, lptm *TEXTMETRIC) bool { ret, _, _ := procGetTextMetrics.Call( uintptr(hdc), uintptr(unsafe.Pointer(lptm))) return ret != 0 } func LineTo(hdc HDC, nXEnd, nYEnd int32) bool { ret, _, _ := procLineTo.Call( uintptr(hdc), uintptr(nXEnd), uintptr(nYEnd)) return ret != 0 } func MoveToEx(hdc HDC, x, y int, lpPoint *POINT) bool { ret, _, _ := procMoveToEx.Call( uintptr(hdc), uintptr(x), uintptr(y), uintptr(unsafe.Pointer(lpPoint))) return ret != 0 } func PlayEnhMetaFile(hdc HDC, hemf HENHMETAFILE, lpRect *RECT) bool { ret, _, _ := procPlayEnhMetaFile.Call( uintptr(hdc), uintptr(hemf), uintptr(unsafe.Pointer(lpRect))) return ret != 0 } func Rectangle(hdc HDC, nLeftRect, nTopRect, nRightRect, nBottomRect int32) bool { ret, _, _ := procRectangle.Call( uintptr(hdc), uintptr(nLeftRect), uintptr(nTopRect), uintptr(nRightRect), uintptr(nBottomRect)) return ret != 0 } func ResetDC(hdc HDC, lpInitData *DEVMODE) HDC { ret, _, _ := procResetDC.Call( uintptr(hdc), uintptr(unsafe.Pointer(lpInitData))) return HDC(ret) } func SelectObject(hdc HDC, hgdiobj HGDIOBJ) HGDIOBJ { ret, _, _ := procSelectObject.Call( uintptr(hdc), uintptr(hgdiobj)) if ret == 0 { panic("SelectObject failed") } return HGDIOBJ(ret) } func SetBkMode(hdc HDC, iBkMode int) int { ret, _, _ := procSetBkMode.Call( uintptr(hdc), uintptr(iBkMode)) if ret == 0 { panic("SetBkMode failed") } return int(ret) } func SetBrushOrgEx(hdc HDC, nXOrg, nYOrg int, lppt *POINT) bool { ret, _, _ := procSetBrushOrgEx.Call( uintptr(hdc), uintptr(nXOrg), uintptr(nYOrg), uintptr(unsafe.Pointer(lppt))) return ret != 0 } func SetStretchBltMode(hdc HDC, iStretchMode int) int { ret, _, _ := procSetStretchBltMode.Call( uintptr(hdc), uintptr(iStretchMode)) return int(ret) } func SetTextColor(hdc HDC, crColor COLORREF) COLORREF { ret, _, _ := procSetTextColor.Call( uintptr(hdc), uintptr(crColor)) if ret == CLR_INVALID { panic("SetTextColor failed") } return COLORREF(ret) } func SetBkColor(hdc HDC, crColor COLORREF) COLORREF { ret, _, _ := procSetBkColor.Call( uintptr(hdc), uintptr(crColor)) if ret == CLR_INVALID { panic("SetBkColor failed") } return COLORREF(ret) } func StartDoc(hdc HDC, lpdi *DOCINFO) int { ret, _, _ := procStartDoc.Call( uintptr(hdc), uintptr(unsafe.Pointer(lpdi))) return int(ret) } func StartPage(hdc HDC) int { ret, _, _ := procStartPage.Call( uintptr(hdc)) return int(ret) } func StretchBlt(hdcDest HDC, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest int, hdcSrc HDC, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc int, dwRop uint) { ret, _, _ := procStretchBlt.Call( uintptr(hdcDest), uintptr(nXOriginDest), uintptr(nYOriginDest), uintptr(nWidthDest), uintptr(nHeightDest), uintptr(hdcSrc), uintptr(nXOriginSrc), uintptr(nYOriginSrc), uintptr(nWidthSrc), uintptr(nHeightSrc), uintptr(dwRop)) if ret == 0 { panic("StretchBlt failed") } } func SetDIBitsToDevice(hdc HDC, xDest, yDest, dwWidth, dwHeight, xSrc, ySrc int, uStartScan, cScanLines uint, lpvBits []byte, lpbmi *BITMAPINFO, fuColorUse uint) int { ret, _, _ := procSetDIBitsToDevice.Call( uintptr(hdc), uintptr(xDest), uintptr(yDest), uintptr(dwWidth), uintptr(dwHeight), uintptr(xSrc), uintptr(ySrc), uintptr(uStartScan), uintptr(cScanLines), uintptr(unsafe.Pointer(&lpvBits[0])), uintptr(unsafe.Pointer(lpbmi)), uintptr(fuColorUse)) return int(ret) } func ChoosePixelFormat(hdc HDC, pfd *PIXELFORMATDESCRIPTOR) int { ret, _, _ := procChoosePixelFormat.Call( uintptr(hdc), uintptr(unsafe.Pointer(pfd)), ) return int(ret) } func DescribePixelFormat(hdc HDC, iPixelFormat int, nBytes uint, pfd *PIXELFORMATDESCRIPTOR) int { ret, _, _ := procDescribePixelFormat.Call( uintptr(hdc), uintptr(iPixelFormat), uintptr(nBytes), uintptr(unsafe.Pointer(pfd)), ) return int(ret) } func GetEnhMetaFilePixelFormat(hemf HENHMETAFILE, cbBuffer uint32, pfd *PIXELFORMATDESCRIPTOR) uint { ret, _, _ := procGetEnhMetaFilePixelFormat.Call( uintptr(hemf), uintptr(cbBuffer), uintptr(unsafe.Pointer(pfd)), ) return uint(ret) } func GetPixelFormat(hdc HDC) int { ret, _, _ := procGetPixelFormat.Call( uintptr(hdc), ) return int(ret) } func SetPixelFormat(hdc HDC, iPixelFormat int, pfd *PIXELFORMATDESCRIPTOR) bool { ret, _, _ := procSetPixelFormat.Call( uintptr(hdc), uintptr(iPixelFormat), uintptr(unsafe.Pointer(pfd)), ) return ret == TRUE } func SwapBuffers(hdc HDC) bool { ret, _, _ := procSwapBuffers.Call(uintptr(hdc)) return ret == TRUE } ================================================ FILE: w32/gdiplus.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. * Copyright (C) 2010-2012 The W32 Authors. All Rights Reserved. */ package w32 import ( "errors" "fmt" "syscall" "unsafe" ) const ( Ok = 0 GenericError = 1 InvalidParameter = 2 OutOfMemory = 3 ObjectBusy = 4 InsufficientBuffer = 5 NotImplemented = 6 Win32Error = 7 WrongState = 8 Aborted = 9 FileNotFound = 10 ValueOverflow = 11 AccessDenied = 12 UnknownImageFormat = 13 FontFamilyNotFound = 14 FontStyleNotFound = 15 NotTrueTypeFont = 16 UnsupportedGdiplusVersion = 17 GdiplusNotInitialized = 18 PropertyNotFound = 19 PropertyNotSupported = 20 ProfileNotFound = 21 ) func GetGpStatus(s int32) string { switch s { case Ok: return "Ok" case GenericError: return "GenericError" case InvalidParameter: return "InvalidParameter" case OutOfMemory: return "OutOfMemory" case ObjectBusy: return "ObjectBusy" case InsufficientBuffer: return "InsufficientBuffer" case NotImplemented: return "NotImplemented" case Win32Error: return "Win32Error" case WrongState: return "WrongState" case Aborted: return "Aborted" case FileNotFound: return "FileNotFound" case ValueOverflow: return "ValueOverflow" case AccessDenied: return "AccessDenied" case UnknownImageFormat: return "UnknownImageFormat" case FontFamilyNotFound: return "FontFamilyNotFound" case FontStyleNotFound: return "FontStyleNotFound" case NotTrueTypeFont: return "NotTrueTypeFont" case UnsupportedGdiplusVersion: return "UnsupportedGdiplusVersion" case GdiplusNotInitialized: return "GdiplusNotInitialized" case PropertyNotFound: return "PropertyNotFound" case PropertyNotSupported: return "PropertyNotSupported" case ProfileNotFound: return "ProfileNotFound" } return "Unknown Status Value" } var ( token uintptr modgdiplus = syscall.NewLazyDLL("gdiplus.dll") procGdipCreateBitmapFromFile = modgdiplus.NewProc("GdipCreateBitmapFromFile") procGdipCreateBitmapFromHBITMAP = modgdiplus.NewProc("GdipCreateBitmapFromHBITMAP") procGdipCreateHBITMAPFromBitmap = modgdiplus.NewProc("GdipCreateHBITMAPFromBitmap") procGdipCreateBitmapFromResource = modgdiplus.NewProc("GdipCreateBitmapFromResource") procGdipCreateBitmapFromStream = modgdiplus.NewProc("GdipCreateBitmapFromStream") procGdipDisposeImage = modgdiplus.NewProc("GdipDisposeImage") procGdiplusShutdown = modgdiplus.NewProc("GdiplusShutdown") procGdiplusStartup = modgdiplus.NewProc("GdiplusStartup") ) func GdipCreateBitmapFromFile(filename string) (*uintptr, error) { var bitmap *uintptr ret, _, _ := procGdipCreateBitmapFromFile.Call( uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(filename))), uintptr(unsafe.Pointer(&bitmap))) if ret != Ok { return nil, errors.New(fmt.Sprintf("GdipCreateBitmapFromFile failed with status '%s' for file '%s'", GetGpStatus(int32(ret)), filename)) } return bitmap, nil } func GdipCreateBitmapFromResource(instance HINSTANCE, resId *uint16) (*uintptr, error) { var bitmap *uintptr ret, _, _ := procGdipCreateBitmapFromResource.Call( uintptr(instance), uintptr(unsafe.Pointer(resId)), uintptr(unsafe.Pointer(&bitmap))) if ret != Ok { return nil, errors.New(fmt.Sprintf("GdiCreateBitmapFromResource failed with status '%s'", GetGpStatus(int32(ret)))) } return bitmap, nil } func GdipCreateBitmapFromStream(stream *IStream) (*uintptr, error) { var bitmap *uintptr ret, _, _ := procGdipCreateBitmapFromStream.Call( uintptr(unsafe.Pointer(stream)), uintptr(unsafe.Pointer(&bitmap))) if ret != Ok { return nil, errors.New(fmt.Sprintf("GdipCreateBitmapFromStream failed with status '%s'", GetGpStatus(int32(ret)))) } return bitmap, nil } func GdipCreateHBITMAPFromBitmap(bitmap *uintptr, background uint32) (HBITMAP, error) { var hbitmap HBITMAP ret, _, _ := procGdipCreateHBITMAPFromBitmap.Call( uintptr(unsafe.Pointer(bitmap)), uintptr(unsafe.Pointer(&hbitmap)), uintptr(background)) if ret != Ok { return 0, errors.New(fmt.Sprintf("GdipCreateHBITMAPFromBitmap failed with status '%s'", GetGpStatus(int32(ret)))) } return hbitmap, nil } func GdipDisposeImage(image *uintptr) { procGdipDisposeImage.Call(uintptr(unsafe.Pointer(image))) } func GdiplusShutdown() { procGdiplusShutdown.Call(token) } func GdiplusStartup(input *GdiplusStartupInput, output *GdiplusStartupOutput) { ret, _, _ := procGdiplusStartup.Call( uintptr(unsafe.Pointer(&token)), uintptr(unsafe.Pointer(input)), uintptr(unsafe.Pointer(output))) if ret != Ok { panic("GdiplusStartup failed with status " + GetGpStatus(int32(ret))) } } ================================================ FILE: w32/idispatch.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. * Copyright (C) 2010-2012 The W32 Authors. All Rights Reserved. */ package w32 import ( "unsafe" ) type pIDispatchVtbl struct { pQueryInterface uintptr pAddRef uintptr pRelease uintptr pGetTypeInfoCount uintptr pGetTypeInfo uintptr pGetIDsOfNames uintptr pInvoke uintptr } type IDispatch struct { lpVtbl *pIDispatchVtbl } func (this *IDispatch) QueryInterface(id *GUID) *IDispatch { return ComQueryInterface((*IUnknown)(unsafe.Pointer(this)), id) } func (this *IDispatch) AddRef() int32 { return ComAddRef((*IUnknown)(unsafe.Pointer(this))) } func (this *IDispatch) Release() int32 { return ComRelease((*IUnknown)(unsafe.Pointer(this))) } func (this *IDispatch) GetIDsOfName(names []string) []int32 { return ComGetIDsOfName(this, names) } func (this *IDispatch) Invoke(dispid int32, dispatch int16, params ...interface{}) *VARIANT { return ComInvoke(this, dispid, dispatch, params...) } ================================================ FILE: w32/istream.go ================================================ /* * Copyright (C) 2019 Tad Vizbaras. All Rights Reserved. * Copyright (C) 2010-2012 The W32 Authors. All Rights Reserved. */ package w32 import ( "unsafe" ) type pIStreamVtbl struct { pQueryInterface uintptr pAddRef uintptr pRelease uintptr } type IStream struct { lpVtbl *pIStreamVtbl } func (this *IStream) QueryInterface(id *GUID) *IDispatch { return ComQueryInterface((*IUnknown)(unsafe.Pointer(this)), id) } func (this *IStream) AddRef() int32 { return ComAddRef((*IUnknown)(unsafe.Pointer(this))) } func (this *IStream) Release() int32 { return ComRelease((*IUnknown)(unsafe.Pointer(this))) } ================================================ FILE: w32/iunknown.go ================================================ /* * Copyright (C) 2019 Tad Vizbaras. All Rights Reserved. * Copyright (C) 2010-2012 The W32 Authors. All Rights Reserved. */ package w32 type pIUnknownVtbl struct { pQueryInterface uintptr pAddRef uintptr pRelease uintptr } type IUnknown struct { lpVtbl *pIUnknownVtbl } func (this *IUnknown) QueryInterface(id *GUID) *IDispatch { return ComQueryInterface(this, id) } func (this *IUnknown) AddRef() int32 { return ComAddRef(this) } func (this *IUnknown) Release() int32 { return ComRelease(this) } ================================================ FILE: w32/kernel32.go ================================================ /* * Copyright (C) 2019 Tad Vizbaras. All Rights Reserved. * Copyright (C) 2010-2012 The W32 Authors. All Rights Reserved. */ package w32 import ( "syscall" "unsafe" ) var ( modkernel32 = syscall.NewLazyDLL("kernel32.dll") procGetModuleHandle = modkernel32.NewProc("GetModuleHandleW") procMulDiv = modkernel32.NewProc("MulDiv") procGetConsoleWindow = modkernel32.NewProc("GetConsoleWindow") procGetCurrentThread = modkernel32.NewProc("GetCurrentThread") procGetCurrentThreadId = modkernel32.NewProc("GetCurrentThreadId") procGetLogicalDrives = modkernel32.NewProc("GetLogicalDrives") procGetLogicalDriveStrings = modkernel32.NewProc("GetLogicalDriveStringsW") procGetUserDefaultLCID = modkernel32.NewProc("GetUserDefaultLCID") procLstrlen = modkernel32.NewProc("lstrlenW") procLstrcpy = modkernel32.NewProc("lstrcpyW") procGlobalAlloc = modkernel32.NewProc("GlobalAlloc") procGlobalFree = modkernel32.NewProc("GlobalFree") procGlobalLock = modkernel32.NewProc("GlobalLock") procGlobalUnlock = modkernel32.NewProc("GlobalUnlock") procMoveMemory = modkernel32.NewProc("RtlMoveMemory") procFindResource = modkernel32.NewProc("FindResourceW") procSizeofResource = modkernel32.NewProc("SizeofResource") procLockResource = modkernel32.NewProc("LockResource") procLoadResource = modkernel32.NewProc("LoadResource") procGetLastError = modkernel32.NewProc("GetLastError") procOpenProcess = modkernel32.NewProc("OpenProcess") procTerminateProcess = modkernel32.NewProc("TerminateProcess") procCloseHandle = modkernel32.NewProc("CloseHandle") procCreateToolhelp32Snapshot = modkernel32.NewProc("CreateToolhelp32Snapshot") procModule32First = modkernel32.NewProc("Module32FirstW") procModule32Next = modkernel32.NewProc("Module32NextW") procGetSystemTimes = modkernel32.NewProc("GetSystemTimes") procGetConsoleScreenBufferInfo = modkernel32.NewProc("GetConsoleScreenBufferInfo") procSetConsoleTextAttribute = modkernel32.NewProc("SetConsoleTextAttribute") procGetDiskFreeSpaceEx = modkernel32.NewProc("GetDiskFreeSpaceExW") procGetProcessTimes = modkernel32.NewProc("GetProcessTimes") procSetSystemTime = modkernel32.NewProc("SetSystemTime") procGetSystemTime = modkernel32.NewProc("GetSystemTime") ) func GetModuleHandle(modulename string) HINSTANCE { var mn uintptr if modulename == "" { mn = 0 } else { mn = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(modulename))) } ret, _, _ := procGetModuleHandle.Call(mn) return HINSTANCE(ret) } func MulDiv(number, numerator, denominator int) int { ret, _, _ := procMulDiv.Call( uintptr(number), uintptr(numerator), uintptr(denominator)) return int(ret) } func GetConsoleWindow() HWND { ret, _, _ := procGetConsoleWindow.Call() return HWND(ret) } func GetCurrentThread() HANDLE { ret, _, _ := procGetCurrentThread.Call() return HANDLE(ret) } func GetCurrentThreadId() HANDLE { ret, _, _ := procGetCurrentThreadId.Call() return HANDLE(ret) } func GetLogicalDrives() uint32 { ret, _, _ := procGetLogicalDrives.Call() return uint32(ret) } func GetUserDefaultLCID() uint32 { ret, _, _ := procGetUserDefaultLCID.Call() return uint32(ret) } func Lstrlen(lpString *uint16) int { ret, _, _ := procLstrlen.Call(uintptr(unsafe.Pointer(lpString))) return int(ret) } func Lstrcpy(buf []uint16, lpString *uint16) { procLstrcpy.Call( uintptr(unsafe.Pointer(&buf[0])), uintptr(unsafe.Pointer(lpString))) } func GlobalAlloc(uFlags uint, dwBytes uint32) HGLOBAL { ret, _, _ := procGlobalAlloc.Call( uintptr(uFlags), uintptr(dwBytes)) if ret == 0 { panic("GlobalAlloc failed") } return HGLOBAL(ret) } func GlobalFree(hMem HGLOBAL) { ret, _, _ := procGlobalFree.Call(uintptr(hMem)) if ret != 0 { panic("GlobalFree failed") } } func GlobalLock(hMem HGLOBAL) unsafe.Pointer { ret, _, _ := procGlobalLock.Call(uintptr(hMem)) if ret == 0 { panic("GlobalLock failed") } return unsafe.Pointer(ret) } func GlobalUnlock(hMem HGLOBAL) bool { ret, _, _ := procGlobalUnlock.Call(uintptr(hMem)) return ret != 0 } func MoveMemory(destination, source unsafe.Pointer, length uint32) { procMoveMemory.Call( uintptr(unsafe.Pointer(destination)), uintptr(source), uintptr(length)) } func FindResource(hModule HMODULE, lpName, lpType *uint16) (HRSRC, error) { ret, _, _ := procFindResource.Call( uintptr(hModule), uintptr(unsafe.Pointer(lpName)), uintptr(unsafe.Pointer(lpType))) if ret == 0 { return 0, syscall.GetLastError() } return HRSRC(ret), nil } func SizeofResource(hModule HMODULE, hResInfo HRSRC) uint32 { ret, _, _ := procSizeofResource.Call( uintptr(hModule), uintptr(hResInfo)) if ret == 0 { panic("SizeofResource failed") } return uint32(ret) } func LockResource(hResData HGLOBAL) unsafe.Pointer { ret, _, _ := procLockResource.Call(uintptr(hResData)) if ret == 0 { panic("LockResource failed") } return unsafe.Pointer(ret) } func LoadResource(hModule HMODULE, hResInfo HRSRC) HGLOBAL { ret, _, _ := procLoadResource.Call( uintptr(hModule), uintptr(hResInfo)) if ret == 0 { panic("LoadResource failed") } return HGLOBAL(ret) } func GetLastError() uint32 { ret, _, _ := procGetLastError.Call() return uint32(ret) } func OpenProcess(desiredAccess uint32, inheritHandle bool, processId uint32) HANDLE { inherit := 0 if inheritHandle { inherit = 1 } ret, _, _ := procOpenProcess.Call( uintptr(desiredAccess), uintptr(inherit), uintptr(processId)) return HANDLE(ret) } func TerminateProcess(hProcess HANDLE, uExitCode uint) bool { ret, _, _ := procTerminateProcess.Call( uintptr(hProcess), uintptr(uExitCode)) return ret != 0 } func CloseHandle(object HANDLE) bool { ret, _, _ := procCloseHandle.Call( uintptr(object)) return ret != 0 } func CreateToolhelp32Snapshot(flags, processId uint32) HANDLE { ret, _, _ := procCreateToolhelp32Snapshot.Call( uintptr(flags), uintptr(processId)) if ret <= 0 { return HANDLE(0) } return HANDLE(ret) } func Module32First(snapshot HANDLE, me *MODULEENTRY32) bool { ret, _, _ := procModule32First.Call( uintptr(snapshot), uintptr(unsafe.Pointer(me))) return ret != 0 } func Module32Next(snapshot HANDLE, me *MODULEENTRY32) bool { ret, _, _ := procModule32Next.Call( uintptr(snapshot), uintptr(unsafe.Pointer(me))) return ret != 0 } func GetSystemTimes(lpIdleTime, lpKernelTime, lpUserTime *FILETIME) bool { ret, _, _ := procGetSystemTimes.Call( uintptr(unsafe.Pointer(lpIdleTime)), uintptr(unsafe.Pointer(lpKernelTime)), uintptr(unsafe.Pointer(lpUserTime))) return ret != 0 } func GetProcessTimes(hProcess HANDLE, lpCreationTime, lpExitTime, lpKernelTime, lpUserTime *FILETIME) bool { ret, _, _ := procGetProcessTimes.Call( uintptr(hProcess), uintptr(unsafe.Pointer(lpCreationTime)), uintptr(unsafe.Pointer(lpExitTime)), uintptr(unsafe.Pointer(lpKernelTime)), uintptr(unsafe.Pointer(lpUserTime))) return ret != 0 } func GetConsoleScreenBufferInfo(hConsoleOutput HANDLE) *CONSOLE_SCREEN_BUFFER_INFO { var csbi CONSOLE_SCREEN_BUFFER_INFO ret, _, _ := procGetConsoleScreenBufferInfo.Call( uintptr(hConsoleOutput), uintptr(unsafe.Pointer(&csbi))) if ret == 0 { return nil } return &csbi } func SetConsoleTextAttribute(hConsoleOutput HANDLE, wAttributes uint16) bool { ret, _, _ := procSetConsoleTextAttribute.Call( uintptr(hConsoleOutput), uintptr(wAttributes)) return ret != 0 } func GetDiskFreeSpaceEx(dirName string) (r bool, freeBytesAvailable, totalNumberOfBytes, totalNumberOfFreeBytes uint64) { ret, _, _ := procGetDiskFreeSpaceEx.Call( uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(dirName))), uintptr(unsafe.Pointer(&freeBytesAvailable)), uintptr(unsafe.Pointer(&totalNumberOfBytes)), uintptr(unsafe.Pointer(&totalNumberOfFreeBytes))) return ret != 0, freeBytesAvailable, totalNumberOfBytes, totalNumberOfFreeBytes } func GetSystemTime() *SYSTEMTIME { var time SYSTEMTIME procGetSystemTime.Call( uintptr(unsafe.Pointer(&time))) return &time } func SetSystemTime(time *SYSTEMTIME) bool { ret, _, _ := procSetSystemTime.Call( uintptr(unsafe.Pointer(time))) return ret != 0 } func GetLogicalDriveStrings(nBufferLength uint32, lpBuffer *uint16) uint32 { ret, _, _ := procGetLogicalDriveStrings.Call( uintptr(nBufferLength), uintptr(unsafe.Pointer(lpBuffer)), 0) return uint32(ret) } ================================================ FILE: w32/ole32.go ================================================ /* * Copyright (C) 2019 Tad Vizbaras. All Rights Reserved. * Copyright (C) 2010-2012 The W32 Authors. All Rights Reserved. */ package w32 import ( "syscall" "unsafe" ) var ( modole32 = syscall.NewLazyDLL("ole32.dll") procCoInitializeEx = modole32.NewProc("CoInitializeEx") procCoInitialize = modole32.NewProc("CoInitialize") procCoUninitialize = modole32.NewProc("CoUninitialize") procCreateStreamOnHGlobal = modole32.NewProc("CreateStreamOnHGlobal") ) func CoInitializeEx(coInit uintptr) HRESULT { ret, _, _ := procCoInitializeEx.Call( 0, coInit) switch uint32(ret) { case E_INVALIDARG: panic("CoInitializeEx failed with E_INVALIDARG") case E_OUTOFMEMORY: panic("CoInitializeEx failed with E_OUTOFMEMORY") case E_UNEXPECTED: panic("CoInitializeEx failed with E_UNEXPECTED") } return HRESULT(ret) } func CoInitialize() { procCoInitialize.Call(0) } func CoUninitialize() { procCoUninitialize.Call() } func CreateStreamOnHGlobal(hGlobal HGLOBAL, fDeleteOnRelease bool) *IStream { stream := new(IStream) ret, _, _ := procCreateStreamOnHGlobal.Call( uintptr(hGlobal), uintptr(BoolToBOOL(fDeleteOnRelease)), uintptr(unsafe.Pointer(&stream))) switch uint32(ret) { case E_INVALIDARG: panic("CreateStreamOnHGlobal failed with E_INVALIDARG") case E_OUTOFMEMORY: panic("CreateStreamOnHGlobal failed with E_OUTOFMEMORY") case E_UNEXPECTED: panic("CreateStreamOnHGlobal failed with E_UNEXPECTED") } return stream } ================================================ FILE: w32/oleaut32.go ================================================ /* * Copyright (C) 2019 Tad Vizbaras. All Rights Reserved. * Copyright (C) 2010-2012 The W32 Authors. All Rights Reserved. */ package w32 import ( "syscall" "unsafe" ) var ( modoleaut32 = syscall.NewLazyDLL("oleaut32") procVariantInit = modoleaut32.NewProc("VariantInit") procSysAllocString = modoleaut32.NewProc("SysAllocString") procSysFreeString = modoleaut32.NewProc("SysFreeString") procSysStringLen = modoleaut32.NewProc("SysStringLen") procCreateDispTypeInfo = modoleaut32.NewProc("CreateDispTypeInfo") procCreateStdDispatch = modoleaut32.NewProc("CreateStdDispatch") ) func VariantInit(v *VARIANT) { hr, _, _ := procVariantInit.Call(uintptr(unsafe.Pointer(v))) if hr != 0 { panic("Invoke VariantInit error.") } return } func SysAllocString(v string) (ss *int16) { pss, _, _ := procSysAllocString.Call(uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(v)))) ss = (*int16)(unsafe.Pointer(pss)) return } func SysFreeString(v *int16) { hr, _, _ := procSysFreeString.Call(uintptr(unsafe.Pointer(v))) if hr != 0 { panic("Invoke SysFreeString error.") } return } func SysStringLen(v *int16) uint { l, _, _ := procSysStringLen.Call(uintptr(unsafe.Pointer(v))) return uint(l) } ================================================ FILE: w32/shcore.go ================================================ package w32 import ( "syscall" "unsafe" ) var ( modshcore = syscall.NewLazyDLL("shcore.dll") procGetDpiForMonitor = modshcore.NewProc("GetDpiForMonitor") ) func GetDPIForMonitor(hmonitor HMONITOR, dpiType MONITOR_DPI_TYPE, dpiX *UINT, dpiY *UINT) uintptr { ret, _, _ := procGetDpiForMonitor.Call( hmonitor, uintptr(dpiType), uintptr(unsafe.Pointer(dpiX)), uintptr(unsafe.Pointer(dpiY))) return ret } ================================================ FILE: w32/shell32.go ================================================ /* * Copyright (C) 2019 Tad Vizbaras. All Rights Reserved. * Copyright (C) 2010-2012 The W32 Authors. All Rights Reserved. */ package w32 import ( "errors" "fmt" "syscall" "unsafe" ) type CSIDL uint32 const ( CSIDL_DESKTOP = 0x00 CSIDL_INTERNET = 0x01 CSIDL_PROGRAMS = 0x02 CSIDL_CONTROLS = 0x03 CSIDL_PRINTERS = 0x04 CSIDL_PERSONAL = 0x05 CSIDL_FAVORITES = 0x06 CSIDL_STARTUP = 0x07 CSIDL_RECENT = 0x08 CSIDL_SENDTO = 0x09 CSIDL_BITBUCKET = 0x0A CSIDL_STARTMENU = 0x0B CSIDL_MYDOCUMENTS = 0x0C CSIDL_MYMUSIC = 0x0D CSIDL_MYVIDEO = 0x0E CSIDL_DESKTOPDIRECTORY = 0x10 CSIDL_DRIVES = 0x11 CSIDL_NETWORK = 0x12 CSIDL_NETHOOD = 0x13 CSIDL_FONTS = 0x14 CSIDL_TEMPLATES = 0x15 CSIDL_COMMON_STARTMENU = 0x16 CSIDL_COMMON_PROGRAMS = 0x17 CSIDL_COMMON_STARTUP = 0x18 CSIDL_COMMON_DESKTOPDIRECTORY = 0x19 CSIDL_APPDATA = 0x1A CSIDL_PRINTHOOD = 0x1B CSIDL_LOCAL_APPDATA = 0x1C CSIDL_ALTSTARTUP = 0x1D CSIDL_COMMON_ALTSTARTUP = 0x1E CSIDL_COMMON_FAVORITES = 0x1F CSIDL_INTERNET_CACHE = 0x20 CSIDL_COOKIES = 0x21 CSIDL_HISTORY = 0x22 CSIDL_COMMON_APPDATA = 0x23 CSIDL_WINDOWS = 0x24 CSIDL_SYSTEM = 0x25 CSIDL_PROGRAM_FILES = 0x26 CSIDL_MYPICTURES = 0x27 CSIDL_PROFILE = 0x28 CSIDL_SYSTEMX86 = 0x29 CSIDL_PROGRAM_FILESX86 = 0x2A CSIDL_PROGRAM_FILES_COMMON = 0x2B CSIDL_PROGRAM_FILES_COMMONX86 = 0x2C CSIDL_COMMON_TEMPLATES = 0x2D CSIDL_COMMON_DOCUMENTS = 0x2E CSIDL_COMMON_ADMINTOOLS = 0x2F CSIDL_ADMINTOOLS = 0x30 CSIDL_CONNECTIONS = 0x31 CSIDL_COMMON_MUSIC = 0x35 CSIDL_COMMON_PICTURES = 0x36 CSIDL_COMMON_VIDEO = 0x37 CSIDL_RESOURCES = 0x38 CSIDL_RESOURCES_LOCALIZED = 0x39 CSIDL_COMMON_OEM_LINKS = 0x3A CSIDL_CDBURN_AREA = 0x3B CSIDL_COMPUTERSNEARME = 0x3D CSIDL_FLAG_CREATE = 0x8000 CSIDL_FLAG_DONT_VERIFY = 0x4000 CSIDL_FLAG_NO_ALIAS = 0x1000 CSIDL_FLAG_PER_USER_INIT = 0x8000 CSIDL_FLAG_MASK = 0xFF00 ) var ( modshell32 = syscall.NewLazyDLL("shell32.dll") procSHBrowseForFolder = modshell32.NewProc("SHBrowseForFolderW") procSHGetPathFromIDList = modshell32.NewProc("SHGetPathFromIDListW") procDragAcceptFiles = modshell32.NewProc("DragAcceptFiles") procDragQueryFile = modshell32.NewProc("DragQueryFileW") procDragQueryPoint = modshell32.NewProc("DragQueryPoint") procDragFinish = modshell32.NewProc("DragFinish") procShellExecute = modshell32.NewProc("ShellExecuteW") procExtractIcon = modshell32.NewProc("ExtractIconW") procGetSpecialFolderPath = modshell32.NewProc("SHGetSpecialFolderPathW") ) func SHBrowseForFolder(bi *BROWSEINFO) uintptr { ret, _, _ := procSHBrowseForFolder.Call(uintptr(unsafe.Pointer(bi))) return ret } func SHGetPathFromIDList(idl uintptr) string { buf := make([]uint16, 1024) procSHGetPathFromIDList.Call( idl, uintptr(unsafe.Pointer(&buf[0]))) return syscall.UTF16ToString(buf) } func DragAcceptFiles(hwnd HWND, accept bool) { procDragAcceptFiles.Call( uintptr(hwnd), uintptr(BoolToBOOL(accept))) } func DragQueryFile(hDrop HDROP, iFile uint) (fileName string, fileCount uint) { ret, _, _ := procDragQueryFile.Call( uintptr(hDrop), uintptr(iFile), 0, 0) fileCount = uint(ret) if iFile != 0xFFFFFFFF { buf := make([]uint16, fileCount+1) ret, _, _ := procDragQueryFile.Call( uintptr(hDrop), uintptr(iFile), uintptr(unsafe.Pointer(&buf[0])), uintptr(fileCount+1)) if ret == 0 { panic("Invoke DragQueryFile error.") } fileName = syscall.UTF16ToString(buf) } return } func DragQueryPoint(hDrop HDROP) (x, y int, isClientArea bool) { var pt POINT ret, _, _ := procDragQueryPoint.Call( uintptr(hDrop), uintptr(unsafe.Pointer(&pt))) return int(pt.X), int(pt.Y), (ret == 1) } func DragFinish(hDrop HDROP) { procDragFinish.Call(uintptr(hDrop)) } func ShellExecute(hwnd HWND, lpOperation, lpFile, lpParameters, lpDirectory string, nShowCmd int) error { var op, param, directory uintptr if len(lpOperation) != 0 { op = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpOperation))) } if len(lpParameters) != 0 { param = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpParameters))) } if len(lpDirectory) != 0 { directory = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpDirectory))) } ret, _, _ := procShellExecute.Call( uintptr(hwnd), op, uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpFile))), param, directory, uintptr(nShowCmd)) errorMsg := "" if ret != 0 && ret <= 32 { switch int(ret) { case ERROR_FILE_NOT_FOUND: errorMsg = "The specified file was not found." case ERROR_PATH_NOT_FOUND: errorMsg = "The specified path was not found." case ERROR_BAD_FORMAT: errorMsg = "The .exe file is invalid (non-Win32 .exe or error in .exe image)." case SE_ERR_ACCESSDENIED: errorMsg = "The operating system denied access to the specified file." case SE_ERR_ASSOCINCOMPLETE: errorMsg = "The file name association is incomplete or invalid." case SE_ERR_DDEBUSY: errorMsg = "The DDE transaction could not be completed because other DDE transactions were being processed." case SE_ERR_DDEFAIL: errorMsg = "The DDE transaction failed." case SE_ERR_DDETIMEOUT: errorMsg = "The DDE transaction could not be completed because the request timed out." case SE_ERR_DLLNOTFOUND: errorMsg = "The specified DLL was not found." case SE_ERR_NOASSOC: errorMsg = "There is no application associated with the given file name extension. This error will also be returned if you attempt to print a file that is not printable." case SE_ERR_OOM: errorMsg = "There was not enough memory to complete the operation." case SE_ERR_SHARE: errorMsg = "A sharing violation occurred." default: errorMsg = fmt.Sprintf("Unknown error occurred with error code %v", ret) } } else { return nil } return errors.New(errorMsg) } func ExtractIcon(lpszExeFileName string, nIconIndex int) HICON { ret, _, _ := procExtractIcon.Call( 0, uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpszExeFileName))), uintptr(nIconIndex)) return HICON(ret) } func SHGetSpecialFolderPath(hwndOwner HWND, lpszPath *uint16, csidl CSIDL, fCreate bool) bool { ret, _, _ := procGetSpecialFolderPath.Call( uintptr(hwndOwner), uintptr(unsafe.Pointer(lpszPath)), uintptr(csidl), uintptr(BoolToBOOL(fCreate)), 0, 0) return ret != 0 } ================================================ FILE: w32/shlwapi.go ================================================ package w32 import ( "syscall" "unsafe" ) var ( modshlwapi = syscall.NewLazyDLL("shlwapi.dll") procSHCreateMemStream = modshlwapi.NewProc("SHCreateMemStream") ) func SHCreateMemStream(data []byte) (uintptr, error) { ret, _, err := procSHCreateMemStream.Call( uintptr(unsafe.Pointer(&data[0])), uintptr(len(data)), ) if ret == 0 { return 0, err } return ret, nil } ================================================ FILE: w32/toolbar.go ================================================ /* * Copyright (C) 2019 Tad Vizbaras. All Rights Reserved. * Copyright (C) 2010-2012 The W32 Authors. All Rights Reserved. */ package w32 // ToolBar messages const ( TB_ENABLEBUTTON = WM_USER + 1 TB_CHECKBUTTON = WM_USER + 2 TB_PRESSBUTTON = WM_USER + 3 TB_HIDEBUTTON = WM_USER + 4 TB_INDETERMINATE = WM_USER + 5 TB_MARKBUTTON = WM_USER + 6 TB_ISBUTTONENABLED = WM_USER + 9 TB_ISBUTTONCHECKED = WM_USER + 10 TB_ISBUTTONPRESSED = WM_USER + 11 TB_ISBUTTONHIDDEN = WM_USER + 12 TB_ISBUTTONINDETERMINATE = WM_USER + 13 TB_ISBUTTONHIGHLIGHTED = WM_USER + 14 TB_SETSTATE = WM_USER + 17 TB_GETSTATE = WM_USER + 18 TB_ADDBITMAP = WM_USER + 19 TB_DELETEBUTTON = WM_USER + 22 TB_GETBUTTON = WM_USER + 23 TB_BUTTONCOUNT = WM_USER + 24 TB_COMMANDTOINDEX = WM_USER + 25 TB_SAVERESTORE = WM_USER + 76 TB_CUSTOMIZE = WM_USER + 27 TB_ADDSTRING = WM_USER + 77 TB_GETITEMRECT = WM_USER + 29 TB_BUTTONSTRUCTSIZE = WM_USER + 30 TB_SETBUTTONSIZE = WM_USER + 31 TB_SETBITMAPSIZE = WM_USER + 32 TB_AUTOSIZE = WM_USER + 33 TB_GETTOOLTIPS = WM_USER + 35 TB_SETTOOLTIPS = WM_USER + 36 TB_SETPARENT = WM_USER + 37 TB_SETROWS = WM_USER + 39 TB_GETROWS = WM_USER + 40 TB_GETBITMAPFLAGS = WM_USER + 41 TB_SETCMDID = WM_USER + 42 TB_CHANGEBITMAP = WM_USER + 43 TB_GETBITMAP = WM_USER + 44 TB_GETBUTTONTEXT = WM_USER + 75 TB_REPLACEBITMAP = WM_USER + 46 TB_GETBUTTONSIZE = WM_USER + 58 TB_SETBUTTONWIDTH = WM_USER + 59 TB_SETINDENT = WM_USER + 47 TB_SETIMAGELIST = WM_USER + 48 TB_GETIMAGELIST = WM_USER + 49 TB_LOADIMAGES = WM_USER + 50 TB_GETRECT = WM_USER + 51 TB_SETHOTIMAGELIST = WM_USER + 52 TB_GETHOTIMAGELIST = WM_USER + 53 TB_SETDISABLEDIMAGELIST = WM_USER + 54 TB_GETDISABLEDIMAGELIST = WM_USER + 55 TB_SETSTYLE = WM_USER + 56 TB_GETSTYLE = WM_USER + 57 TB_SETMAXTEXTROWS = WM_USER + 60 TB_GETTEXTROWS = WM_USER + 61 TB_GETOBJECT = WM_USER + 62 TB_GETBUTTONINFO = WM_USER + 63 TB_SETBUTTONINFO = WM_USER + 64 TB_INSERTBUTTON = WM_USER + 67 TB_ADDBUTTONS = WM_USER + 68 TB_HITTEST = WM_USER + 69 TB_SETDRAWTEXTFLAGS = WM_USER + 70 TB_GETHOTITEM = WM_USER + 71 TB_SETHOTITEM = WM_USER + 72 TB_SETANCHORHIGHLIGHT = WM_USER + 73 TB_GETANCHORHIGHLIGHT = WM_USER + 74 TB_GETINSERTMARK = WM_USER + 79 TB_SETINSERTMARK = WM_USER + 80 TB_INSERTMARKHITTEST = WM_USER + 81 TB_MOVEBUTTON = WM_USER + 82 TB_GETMAXSIZE = WM_USER + 83 TB_SETEXTENDEDSTYLE = WM_USER + 84 TB_GETEXTENDEDSTYLE = WM_USER + 85 TB_GETPADDING = WM_USER + 86 TB_SETPADDING = WM_USER + 87 TB_SETINSERTMARKCOLOR = WM_USER + 88 TB_GETINSERTMARKCOLOR = WM_USER + 89 TB_MAPACCELERATOR = WM_USER + 90 TB_GETSTRING = WM_USER + 91 TB_SETCOLORSCHEME = CCM_SETCOLORSCHEME TB_GETCOLORSCHEME = CCM_GETCOLORSCHEME TB_SETUNICODEFORMAT = CCM_SETUNICODEFORMAT TB_GETUNICODEFORMAT = CCM_GETUNICODEFORMAT ) // ToolBar notifications const ( TBN_FIRST = -700 TBN_DROPDOWN = TBN_FIRST - 10 ) // TBN_DROPDOWN return codes const ( TBDDRET_DEFAULT = 0 TBDDRET_NODEFAULT = 1 TBDDRET_TREATPRESSED = 2 ) // ToolBar state constants const ( TBSTATE_CHECKED = 1 TBSTATE_PRESSED = 2 TBSTATE_ENABLED = 4 TBSTATE_HIDDEN = 8 TBSTATE_INDETERMINATE = 16 TBSTATE_WRAP = 32 TBSTATE_ELLIPSES = 0x40 TBSTATE_MARKED = 0x0080 ) // ToolBar style constants const ( TBSTYLE_BUTTON = 0 TBSTYLE_SEP = 1 TBSTYLE_CHECK = 2 TBSTYLE_GROUP = 4 TBSTYLE_CHECKGROUP = TBSTYLE_GROUP | TBSTYLE_CHECK TBSTYLE_DROPDOWN = 8 TBSTYLE_AUTOSIZE = 16 TBSTYLE_NOPREFIX = 32 TBSTYLE_TOOLTIPS = 256 TBSTYLE_WRAPABLE = 512 TBSTYLE_ALTDRAG = 1024 TBSTYLE_FLAT = 2048 TBSTYLE_LIST = 4096 TBSTYLE_CUSTOMERASE = 8192 TBSTYLE_REGISTERDROP = 0x4000 TBSTYLE_TRANSPARENT = 0x8000 ) // ToolBar extended style constants const ( TBSTYLE_EX_DRAWDDARROWS = 0x00000001 TBSTYLE_EX_MIXEDBUTTONS = 8 TBSTYLE_EX_HIDECLIPPEDBUTTONS = 16 TBSTYLE_EX_DOUBLEBUFFER = 0x80 ) // ToolBar button style constants const ( BTNS_BUTTON = TBSTYLE_BUTTON BTNS_SEP = TBSTYLE_SEP BTNS_CHECK = TBSTYLE_CHECK BTNS_GROUP = TBSTYLE_GROUP BTNS_CHECKGROUP = TBSTYLE_CHECKGROUP BTNS_DROPDOWN = TBSTYLE_DROPDOWN BTNS_AUTOSIZE = TBSTYLE_AUTOSIZE BTNS_NOPREFIX = TBSTYLE_NOPREFIX BTNS_WHOLEDROPDOWN = 0x0080 BTNS_SHOWTEXT = 0x0040 ) // TBBUTTONINFO mask flags const ( TBIF_IMAGE = 0x00000001 TBIF_TEXT = 0x00000002 TBIF_STATE = 0x00000004 TBIF_STYLE = 0x00000008 TBIF_LPARAM = 0x00000010 TBIF_COMMAND = 0x00000020 TBIF_SIZE = 0x00000040 TBIF_BYINDEX = 0x80000000 ) type NMMOUSE struct { Hdr NMHDR DwItemSpec uintptr DwItemData uintptr Pt POINT DwHitInfo uintptr } type NMTOOLBAR struct { Hdr NMHDR IItem int32 TbButton TBBUTTON CchText int32 PszText *uint16 RcButton RECT } type TBBUTTON struct { IBitmap int32 IdCommand int32 FsState byte FsStyle byte //#ifdef _WIN64 // BYTE bReserved[6] // padding for alignment //#elif defined(_WIN32) BReserved [2]byte // padding for alignment //#endif DwData uintptr IString uintptr } type TBBUTTONINFO struct { CbSize uint32 DwMask uint32 IdCommand int32 IImage int32 FsState byte FsStyle byte Cx uint16 LParam uintptr PszText uintptr CchText int32 } ================================================ FILE: w32/typedef.go ================================================ /* * Copyright (C) 2019 Tad Vizbaras. All Rights Reserved. * Copyright (C) 2010-2012 The W32 Authors. All Rights Reserved. */ package w32 import ( "fmt" "unsafe" ) // From MSDN: Windows Data Types // http://msdn.microsoft.com/en-us/library/s3f49ktz.aspx // http://msdn.microsoft.com/en-us/library/windows/desktop/aa383751.aspx // ATOM WORD // BOOL int32 // BOOLEAN byte // BYTE byte // CCHAR int8 // CHAR int8 // COLORREF DWORD // DWORD uint32 // DWORDLONG ULONGLONG // DWORD_PTR ULONG_PTR // DWORD32 uint32 // DWORD64 uint64 // FLOAT float32 // HACCEL HANDLE // HALF_PTR struct{} // ??? // HANDLE PVOID // HBITMAP HANDLE // HBRUSH HANDLE // HCOLORSPACE HANDLE // HCONV HANDLE // HCONVLIST HANDLE // HCURSOR HANDLE // HDC HANDLE // HDDEDATA HANDLE // HDESK HANDLE // HDROP HANDLE // HDWP HANDLE // HENHMETAFILE HANDLE // HFILE HANDLE // HFONT HANDLE // HGDIOBJ HANDLE // HGLOBAL HANDLE // HHOOK HANDLE // HICON HANDLE // HINSTANCE HANDLE // HKEY HANDLE // HKL HANDLE // HLOCAL HANDLE // HMENU HANDLE // HMETAFILE HANDLE // HMODULE HANDLE // HPALETTE HANDLE // HPEN HANDLE // HRESULT int32 // HRGN HANDLE // HSZ HANDLE // HWINSTA HANDLE // HWND HANDLE // INT int32 // INT_PTR uintptr // INT8 int8 // INT16 int16 // INT32 int32 // INT64 int64 // LANGID WORD // LCID DWORD // LCTYPE DWORD // LGRPID DWORD // LONG int32 // LONGLONG int64 // LONG_PTR uintptr // LONG32 int32 // LONG64 int64 // LPARAM LONG_PTR // LPBOOL *BOOL // LPBYTE *BYTE // LPCOLORREF *COLORREF // LPCSTR *int8 // LPCTSTR LPCWSTR // LPCVOID unsafe.Pointer // LPCWSTR *WCHAR // LPDWORD *DWORD // LPHANDLE *HANDLE // LPINT *INT // LPLONG *LONG // LPSTR *CHAR // LPTSTR LPWSTR // LPVOID unsafe.Pointer // LPWORD *WORD // LPWSTR *WCHAR // LRESULT LONG_PTR // PBOOL *BOOL // PBOOLEAN *BOOLEAN // PBYTE *BYTE // PCHAR *CHAR // PCSTR *CHAR // PCTSTR PCWSTR // PCWSTR *WCHAR // PDWORD *DWORD // PDWORDLONG *DWORDLONG // PDWORD_PTR *DWORD_PTR // PDWORD32 *DWORD32 // PDWORD64 *DWORD64 // PFLOAT *FLOAT // PHALF_PTR *HALF_PTR // PHANDLE *HANDLE // PHKEY *HKEY // PINT_PTR *INT_PTR // PINT8 *INT8 // PINT16 *INT16 // PINT32 *INT32 // PINT64 *INT64 // PLCID *LCID // PLONG *LONG // PLONGLONG *LONGLONG // PLONG_PTR *LONG_PTR // PLONG32 *LONG32 // PLONG64 *LONG64 // POINTER_32 struct{} // ??? // POINTER_64 struct{} // ??? // POINTER_SIGNED uintptr // POINTER_UNSIGNED uintptr // PSHORT *SHORT // PSIZE_T *SIZE_T // PSSIZE_T *SSIZE_T // PSTR *CHAR // PTBYTE *TBYTE // PTCHAR *TCHAR // PTSTR PWSTR // PUCHAR *UCHAR // PUHALF_PTR *UHALF_PTR // PUINT *UINT // PUINT_PTR *UINT_PTR // PUINT8 *UINT8 // PUINT16 *UINT16 // PUINT32 *UINT32 // PUINT64 *UINT64 // PULONG *ULONG // PULONGLONG *ULONGLONG // PULONG_PTR *ULONG_PTR // PULONG32 *ULONG32 // PULONG64 *ULONG64 // PUSHORT *USHORT // PVOID unsafe.Pointer // PWCHAR *WCHAR // PWORD *WORD // PWSTR *WCHAR // QWORD uint64 // SC_HANDLE HANDLE // SC_LOCK LPVOID // SERVICE_STATUS_HANDLE HANDLE // SHORT int16 // SIZE_T ULONG_PTR // SSIZE_T LONG_PTR // TBYTE WCHAR // TCHAR WCHAR // UCHAR uint8 // UHALF_PTR struct{} // ??? // UINT uint32 // UINT_PTR uintptr // UINT8 uint8 // UINT16 uint16 // UINT32 uint32 // UINT64 uint64 // ULONG uint32 // ULONGLONG uint64 // ULONG_PTR uintptr // ULONG32 uint32 // ULONG64 uint64 // USHORT uint16 // USN LONGLONG // WCHAR uint16 // WORD uint16 // WPARAM UINT_PTR type ( ATOM = uint16 BOOL = int32 COLORREF = uint32 DWM_FRAME_COUNT = uint64 WORD = uint16 DWORD = uint32 HACCEL = HANDLE HANDLE = uintptr HBITMAP = HANDLE HBRUSH = HANDLE HCURSOR = HANDLE HDC = HANDLE HDROP = HANDLE HDWP = HANDLE HENHMETAFILE = HANDLE HFONT = HANDLE HGDIOBJ = HANDLE HGLOBAL = HANDLE HGLRC = HANDLE HHOOK = HANDLE HICON = HANDLE HIMAGELIST = HANDLE HINSTANCE = HANDLE HKEY = HANDLE HKL = HANDLE HMENU = HANDLE HMODULE = HANDLE HMONITOR = HANDLE HPEN = HANDLE HRESULT = int32 HRGN = HANDLE HRSRC = HANDLE HTHUMBNAIL = HANDLE HWND = HANDLE LPARAM = uintptr LPCVOID = unsafe.Pointer LRESULT = uintptr PVOID = unsafe.Pointer QPC_TIME = uint64 ULONG_PTR = uintptr SIZE_T = ULONG_PTR WPARAM = uintptr UINT = uint ) // http://msdn.microsoft.com/en-us/library/windows/desktop/dd162805.aspx type POINT struct { X, Y int32 } // http://msdn.microsoft.com/en-us/library/windows/desktop/dd162897.aspx type RECT struct { Left, Top, Right, Bottom int32 } func (r *RECT) String() string { return fmt.Sprintf("RECT (%p): Left: %d, Top: %d, Right: %d, Bottom: %d", r, r.Left, r.Top, r.Right, r.Bottom) } // http://msdn.microsoft.com/en-us/library/windows/desktop/ms633577.aspx type WNDCLASSEX struct { Size uint32 Style uint32 WndProc uintptr ClsExtra int32 WndExtra int32 Instance HINSTANCE Icon HICON Cursor HCURSOR Background HBRUSH MenuName *uint16 ClassName *uint16 IconSm HICON } type TPMPARAMS struct { CbSize uint32 RcExclude RECT } // http://msdn.microsoft.com/en-us/library/windows/desktop/ms644958.aspx type MSG struct { Hwnd HWND Message uint32 WParam uintptr LParam uintptr Time uint32 Pt POINT } // https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-minmaxinfo type MINMAXINFO struct { PtReserved POINT PtMaxSize POINT PtMaxPosition POINT PtMinTrackSize POINT PtMaxTrackSize POINT } // http://msdn.microsoft.com/en-us/library/windows/desktop/dd145037.aspx type LOGFONT struct { Height int32 Width int32 Escapement int32 Orientation int32 Weight int32 Italic byte Underline byte StrikeOut byte CharSet byte OutPrecision byte ClipPrecision byte Quality byte PitchAndFamily byte FaceName [LF_FACESIZE]uint16 } // http://msdn.microsoft.com/en-us/library/windows/desktop/ms646839.aspx type OPENFILENAME struct { StructSize uint32 Owner HWND Instance HINSTANCE Filter *uint16 CustomFilter *uint16 MaxCustomFilter uint32 FilterIndex uint32 File *uint16 MaxFile uint32 FileTitle *uint16 MaxFileTitle uint32 InitialDir *uint16 Title *uint16 Flags uint32 FileOffset uint16 FileExtension uint16 DefExt *uint16 CustData uintptr FnHook uintptr TemplateName *uint16 PvReserved unsafe.Pointer DwReserved uint32 FlagsEx uint32 } // http://msdn.microsoft.com/en-us/library/windows/desktop/bb773205.aspx type BROWSEINFO struct { Owner HWND Root *uint16 DisplayName *uint16 Title *uint16 Flags uint32 CallbackFunc uintptr LParam uintptr Image int32 } // http://msdn.microsoft.com/en-us/library/windows/desktop/aa373931.aspx type GUID struct { Data1 uint32 Data2 uint16 Data3 uint16 Data4 [8]byte } // http://msdn.microsoft.com/en-us/library/windows/desktop/ms221627.aspx type VARIANT struct { VT uint16 // 2 WReserved1 uint16 // 4 WReserved2 uint16 // 6 WReserved3 uint16 // 8 Val int64 // 16 } // http://msdn.microsoft.com/en-us/library/windows/desktop/ms221416.aspx type DISPPARAMS struct { Rgvarg uintptr RgdispidNamedArgs uintptr CArgs uint32 CNamedArgs uint32 } // http://msdn.microsoft.com/en-us/library/windows/desktop/ms221133.aspx type EXCEPINFO struct { WCode uint16 WReserved uint16 BstrSource *uint16 BstrDescription *uint16 BstrHelpFile *uint16 DwHelpContext uint32 PvReserved uintptr PfnDeferredFillIn uintptr Scode int32 } // http://msdn.microsoft.com/en-us/library/windows/desktop/dd145035.aspx type LOGBRUSH struct { LbStyle uint32 LbColor COLORREF LbHatch uintptr } // http://msdn.microsoft.com/en-us/library/windows/desktop/dd183565.aspx type DEVMODE struct { DmDeviceName [CCHDEVICENAME]uint16 DmSpecVersion uint16 DmDriverVersion uint16 DmSize uint16 DmDriverExtra uint16 DmFields uint32 DmOrientation int16 DmPaperSize int16 DmPaperLength int16 DmPaperWidth int16 DmScale int16 DmCopies int16 DmDefaultSource int16 DmPrintQuality int16 DmColor int16 DmDuplex int16 DmYResolution int16 DmTTOption int16 DmCollate int16 DmFormName [CCHFORMNAME]uint16 DmLogPixels uint16 DmBitsPerPel uint32 DmPelsWidth uint32 DmPelsHeight uint32 DmDisplayFlags uint32 DmDisplayFrequency uint32 DmICMMethod uint32 DmICMIntent uint32 DmMediaType uint32 DmDitherType uint32 DmReserved1 uint32 DmReserved2 uint32 DmPanningWidth uint32 DmPanningHeight uint32 } // http://msdn.microsoft.com/en-us/library/windows/desktop/dd183376.aspx type BITMAPINFOHEADER struct { BiSize uint32 BiWidth int32 BiHeight int32 BiPlanes uint16 BiBitCount uint16 BiCompression uint32 BiSizeImage uint32 BiXPelsPerMeter int32 BiYPelsPerMeter int32 BiClrUsed uint32 BiClrImportant uint32 } // http://msdn.microsoft.com/en-us/library/windows/desktop/dd162938.aspx type RGBQUAD struct { RgbBlue byte RgbGreen byte RgbRed byte RgbReserved byte } // http://msdn.microsoft.com/en-us/library/windows/desktop/dd183375.aspx type BITMAPINFO struct { BmiHeader BITMAPINFOHEADER BmiColors *RGBQUAD } // http://msdn.microsoft.com/en-us/library/windows/desktop/dd183371.aspx type BITMAP struct { BmType int32 BmWidth int32 BmHeight int32 BmWidthBytes int32 BmPlanes uint16 BmBitsPixel uint16 BmBits unsafe.Pointer } // http://msdn.microsoft.com/en-us/library/windows/desktop/dd183567.aspx type DIBSECTION struct { DsBm BITMAP DsBmih BITMAPINFOHEADER DsBitfields [3]uint32 DshSection HANDLE DsOffset uint32 } // http://msdn.microsoft.com/en-us/library/windows/desktop/dd162607.aspx type ENHMETAHEADER struct { IType uint32 NSize uint32 RclBounds RECT RclFrame RECT DSignature uint32 NVersion uint32 NBytes uint32 NRecords uint32 NHandles uint16 SReserved uint16 NDescription uint32 OffDescription uint32 NPalEntries uint32 SzlDevice SIZE SzlMillimeters SIZE CbPixelFormat uint32 OffPixelFormat uint32 BOpenGL uint32 SzlMicrometers SIZE } // http://msdn.microsoft.com/en-us/library/windows/desktop/dd145106.aspx type SIZE struct { CX, CY int32 } // http://msdn.microsoft.com/en-us/library/windows/desktop/dd145132.aspx type TEXTMETRIC struct { TmHeight int32 TmAscent int32 TmDescent int32 TmInternalLeading int32 TmExternalLeading int32 TmAveCharWidth int32 TmMaxCharWidth int32 TmWeight int32 TmOverhang int32 TmDigitizedAspectX int32 TmDigitizedAspectY int32 TmFirstChar uint16 TmLastChar uint16 TmDefaultChar uint16 TmBreakChar uint16 TmItalic byte TmUnderlined byte TmStruckOut byte TmPitchAndFamily byte TmCharSet byte } // http://msdn.microsoft.com/en-us/library/windows/desktop/dd183574.aspx type DOCINFO struct { CbSize int32 LpszDocName *uint16 LpszOutput *uint16 LpszDatatype *uint16 FwType uint32 } // http://msdn.microsoft.com/en-us/library/windows/desktop/bb775514.aspx type NMHDR struct { HwndFrom HWND IdFrom uintptr Code uint32 } // http://msdn.microsoft.com/en-us/library/windows/desktop/bb774743.aspx type LVCOLUMN struct { Mask uint32 Fmt int32 Cx int32 PszText *uint16 CchTextMax int32 ISubItem int32 IImage int32 IOrder int32 } // http://msdn.microsoft.com/en-us/library/windows/desktop/bb774760.aspx type LVITEM struct { Mask uint32 IItem int32 ISubItem int32 State uint32 StateMask uint32 PszText *uint16 CchTextMax int32 IImage int32 LParam uintptr IIndent int32 IGroupId int32 CColumns uint32 PuColumns uint32 } type LVFINDINFO struct { Flags uint32 PszText *uint16 LParam uintptr Pt POINT VkDirection uint32 } // http://msdn.microsoft.com/en-us/library/windows/desktop/bb774754.aspx type LVHITTESTINFO struct { Pt POINT Flags uint32 IItem int32 ISubItem int32 IGroup int32 } // http://msdn.microsoft.com/en-us/library/windows/desktop/bb774771.aspx type NMITEMACTIVATE struct { Hdr NMHDR IItem int32 ISubItem int32 UNewState uint32 UOldState uint32 UChanged uint32 PtAction POINT LParam uintptr UKeyFlags uint32 } type NMLVKEYDOWN struct { Hdr NMHDR WVKey uint16 Flags uint32 } // http://msdn.microsoft.com/en-us/library/windows/desktop/bb774773.aspx type NMLISTVIEW struct { Hdr NMHDR IItem int32 ISubItem int32 UNewState uint32 UOldState uint32 UChanged uint32 PtAction POINT LParam uintptr } // http://msdn.microsoft.com/en-us/library/windows/desktop/bb774780.aspx type NMLVDISPINFO struct { Hdr NMHDR Item LVITEM } // http://msdn.microsoft.com/en-us/library/windows/desktop/bb775507.aspx type INITCOMMONCONTROLSEX struct { DwSize uint32 DwICC uint32 } // http://msdn.microsoft.com/en-us/library/windows/desktop/bb760256.aspx type TOOLINFO struct { CbSize uint32 UFlags uint32 Hwnd HWND UId uintptr Rect RECT Hinst HINSTANCE LpszText *uint16 LParam uintptr LpReserved unsafe.Pointer } // http://msdn.microsoft.com/en-us/library/windows/desktop/ms645604.aspx type TRACKMOUSEEVENT struct { CbSize uint32 DwFlags uint32 HwndTrack HWND DwHoverTime uint32 } // http://msdn.microsoft.com/en-us/library/windows/desktop/ms534067.aspx type GdiplusStartupInput struct { GdiplusVersion uint32 DebugEventCallback uintptr SuppressBackgroundThread BOOL SuppressExternalCodecs BOOL } // http://msdn.microsoft.com/en-us/library/windows/desktop/ms534068.aspx type GdiplusStartupOutput struct { NotificationHook uintptr NotificationUnhook uintptr } // http://msdn.microsoft.com/en-us/library/windows/desktop/dd162768.aspx type PAINTSTRUCT struct { Hdc HDC FErase BOOL RcPaint RECT FRestore BOOL FIncUpdate BOOL RgbReserved [32]byte } // http://msdn.microsoft.com/en-us/library/windows/desktop/aa363646.aspx type EVENTLOGRECORD struct { Length uint32 Reserved uint32 RecordNumber uint32 TimeGenerated uint32 TimeWritten uint32 EventID uint32 EventType uint16 NumStrings uint16 EventCategory uint16 ReservedFlags uint16 ClosingRecordNumber uint32 StringOffset uint32 UserSidLength uint32 UserSidOffset uint32 DataLength uint32 DataOffset uint32 } // http://msdn.microsoft.com/en-us/library/windows/desktop/ms685996.aspx type SERVICE_STATUS struct { DwServiceType uint32 DwCurrentState uint32 DwControlsAccepted uint32 DwWin32ExitCode uint32 DwServiceSpecificExitCode uint32 DwCheckPoint uint32 DwWaitHint uint32 } /* ------------------------- Undocumented API ------------------------- */ type ACCENT_STATE DWORD const ( ACCENT_DISABLED ACCENT_STATE = 0 ACCENT_ENABLE_GRADIENT ACCENT_STATE = 1 ACCENT_ENABLE_TRANSPARENTGRADIENT ACCENT_STATE = 2 ACCENT_ENABLE_BLURBEHIND ACCENT_STATE = 3 ACCENT_ENABLE_ACRYLICBLURBEHIND ACCENT_STATE = 4 // RS4 1803 ACCENT_ENABLE_HOSTBACKDROP ACCENT_STATE = 5 // RS5 1809 ACCENT_INVALID_STATE ACCENT_STATE = 6 ) type ACCENT_POLICY struct { AccentState ACCENT_STATE AccentFlags DWORD GradientColor DWORD AnimationId DWORD } type WINDOWCOMPOSITIONATTRIBDATA struct { Attrib WINDOWCOMPOSITIONATTRIB PvData PVOID CbData SIZE_T } type WINDOWCOMPOSITIONATTRIB DWORD const ( WCA_UNDEFINED WINDOWCOMPOSITIONATTRIB = 0 WCA_NCRENDERING_ENABLED WINDOWCOMPOSITIONATTRIB = 1 WCA_NCRENDERING_POLICY WINDOWCOMPOSITIONATTRIB = 2 WCA_TRANSITIONS_FORCEDISABLED WINDOWCOMPOSITIONATTRIB = 3 WCA_ALLOW_NCPAINT WINDOWCOMPOSITIONATTRIB = 4 WCA_CAPTION_BUTTON_BOUNDS WINDOWCOMPOSITIONATTRIB = 5 WCA_NONCLIENT_RTL_LAYOUT WINDOWCOMPOSITIONATTRIB = 6 WCA_FORCE_ICONIC_REPRESENTATION WINDOWCOMPOSITIONATTRIB = 7 WCA_EXTENDED_FRAME_BOUNDS WINDOWCOMPOSITIONATTRIB = 8 WCA_HAS_ICONIC_BITMAP WINDOWCOMPOSITIONATTRIB = 9 WCA_THEME_ATTRIBUTES WINDOWCOMPOSITIONATTRIB = 10 WCA_NCRENDERING_EXILED WINDOWCOMPOSITIONATTRIB = 11 WCA_NCADORNMENTINFO WINDOWCOMPOSITIONATTRIB = 12 WCA_EXCLUDED_FROM_LIVEPREVIEW WINDOWCOMPOSITIONATTRIB = 13 WCA_VIDEO_OVERLAY_ACTIVE WINDOWCOMPOSITIONATTRIB = 14 WCA_FORCE_ACTIVEWINDOW_APPEARANCE WINDOWCOMPOSITIONATTRIB = 15 WCA_DISALLOW_PEEK WINDOWCOMPOSITIONATTRIB = 16 WCA_CLOAK WINDOWCOMPOSITIONATTRIB = 17 WCA_CLOAKED WINDOWCOMPOSITIONATTRIB = 18 WCA_ACCENT_POLICY WINDOWCOMPOSITIONATTRIB = 19 WCA_FREEZE_REPRESENTATION WINDOWCOMPOSITIONATTRIB = 20 WCA_EVER_UNCLOAKED WINDOWCOMPOSITIONATTRIB = 21 WCA_VISUAL_OWNER WINDOWCOMPOSITIONATTRIB = 22 WCA_HOLOGRAPHIC WINDOWCOMPOSITIONATTRIB = 23 WCA_EXCLUDED_FROM_DDA WINDOWCOMPOSITIONATTRIB = 24 WCA_PASSIVEUPDATEMODE WINDOWCOMPOSITIONATTRIB = 25 WCA_USEDARKMODECOLORS WINDOWCOMPOSITIONATTRIB = 26 WCA_CORNER_STYLE WINDOWCOMPOSITIONATTRIB = 27 WCA_PART_COLOR WINDOWCOMPOSITIONATTRIB = 28 WCA_DISABLE_MOVESIZE_FEEDBACK WINDOWCOMPOSITIONATTRIB = 29 WCA_LAST WINDOWCOMPOSITIONATTRIB = 30 ) // ------------------------- // http://msdn.microsoft.com/en-us/library/windows/desktop/ms684225.aspx type MODULEENTRY32 struct { Size uint32 ModuleID uint32 ProcessID uint32 GlblcntUsage uint32 ProccntUsage uint32 ModBaseAddr *uint8 ModBaseSize uint32 HModule HMODULE SzModule [MAX_MODULE_NAME32 + 1]uint16 SzExePath [MAX_PATH]uint16 } // http://msdn.microsoft.com/en-us/library/windows/desktop/ms724284.aspx type FILETIME struct { DwLowDateTime uint32 DwHighDateTime uint32 } // http://msdn.microsoft.com/en-us/library/windows/desktop/ms682119.aspx type COORD struct { X, Y int16 } // http://msdn.microsoft.com/en-us/library/windows/desktop/ms686311.aspx type SMALL_RECT struct { Left, Top, Right, Bottom int16 } // http://msdn.microsoft.com/en-us/library/windows/desktop/ms682093.aspx type CONSOLE_SCREEN_BUFFER_INFO struct { DwSize COORD DwCursorPosition COORD WAttributes uint16 SrWindow SMALL_RECT DwMaximumWindowSize COORD } // http://msdn.microsoft.com/en-us/library/windows/desktop/bb773244.aspx type MARGINS struct { CxLeftWidth, CxRightWidth, CyTopHeight, CyBottomHeight int32 } // http://msdn.microsoft.com/en-us/library/windows/desktop/aa969500.aspx type DWM_BLURBEHIND struct { DwFlags uint32 fEnable BOOL hRgnBlur HRGN fTransitionOnMaximized BOOL } // http://msdn.microsoft.com/en-us/library/windows/desktop/aa969501.aspx type DWM_PRESENT_PARAMETERS struct { cbSize uint32 fQueue BOOL cRefreshStart DWM_FRAME_COUNT cBuffer uint32 fUseSourceRate BOOL rateSource UNSIGNED_RATIO cRefreshesPerFrame uint32 eSampling DWM_SOURCE_FRAME_SAMPLING } // http://msdn.microsoft.com/en-us/library/windows/desktop/aa969502.aspx type DWM_THUMBNAIL_PROPERTIES struct { dwFlags uint32 rcDestination RECT rcSource RECT opacity byte fVisible BOOL fSourceClientAreaOnly BOOL } // http://msdn.microsoft.com/en-us/library/windows/desktop/aa969503.aspx type DWM_TIMING_INFO struct { cbSize uint32 rateRefresh UNSIGNED_RATIO qpcRefreshPeriod QPC_TIME rateCompose UNSIGNED_RATIO qpcVBlank QPC_TIME cRefresh DWM_FRAME_COUNT cDXRefresh uint32 qpcCompose QPC_TIME cFrame DWM_FRAME_COUNT cDXPresent uint32 cRefreshFrame DWM_FRAME_COUNT cFrameSubmitted DWM_FRAME_COUNT cDXPresentSubmitted uint32 cFrameConfirmed DWM_FRAME_COUNT cDXPresentConfirmed uint32 cRefreshConfirmed DWM_FRAME_COUNT cDXRefreshConfirmed uint32 cFramesLate DWM_FRAME_COUNT cFramesOutstanding uint32 cFrameDisplayed DWM_FRAME_COUNT qpcFrameDisplayed QPC_TIME cRefreshFrameDisplayed DWM_FRAME_COUNT cFrameComplete DWM_FRAME_COUNT qpcFrameComplete QPC_TIME cFramePending DWM_FRAME_COUNT qpcFramePending QPC_TIME cFramesDisplayed DWM_FRAME_COUNT cFramesComplete DWM_FRAME_COUNT cFramesPending DWM_FRAME_COUNT cFramesAvailable DWM_FRAME_COUNT cFramesDropped DWM_FRAME_COUNT cFramesMissed DWM_FRAME_COUNT cRefreshNextDisplayed DWM_FRAME_COUNT cRefreshNextPresented DWM_FRAME_COUNT cRefreshesDisplayed DWM_FRAME_COUNT cRefreshesPresented DWM_FRAME_COUNT cRefreshStarted DWM_FRAME_COUNT cPixelsReceived uint64 cPixelsDrawn uint64 cBuffersEmpty DWM_FRAME_COUNT } // http://msdn.microsoft.com/en-us/library/windows/desktop/dd389402.aspx type MilMatrix3x2D struct { S_11, S_12, S_21, S_22 float64 DX, DY float64 } // http://msdn.microsoft.com/en-us/library/windows/desktop/aa969505.aspx type UNSIGNED_RATIO struct { uiNumerator uint32 uiDenominator uint32 } // http://msdn.microsoft.com/en-us/library/windows/desktop/ms632603.aspx type CREATESTRUCT struct { CreateParams uintptr Instance HINSTANCE Menu HMENU Parent HWND Cy, Cx int32 Y, X int32 Style int32 Name *uint16 Class *uint16 dwExStyle uint32 } // http://msdn.microsoft.com/en-us/library/windows/desktop/dd145065.aspx type MONITORINFO struct { CbSize uint32 RcMonitor RECT RcWork RECT DwFlags uint32 } type WINDOWINFO struct { CbSize DWORD RcWindow RECT RcClient RECT DwStyle DWORD DwExStyle DWORD DwWindowStatus DWORD CxWindowBorders UINT CyWindowBorders UINT AtomWindowType ATOM WCreatorVersion WORD } type MONITOR_DPI_TYPE int32 const ( MDT_EFFECTIVE_DPI MONITOR_DPI_TYPE = 0 MDT_ANGULAR_DPI MONITOR_DPI_TYPE = 1 MDT_RAW_DPI MONITOR_DPI_TYPE = 2 MDT_DEFAULT MONITOR_DPI_TYPE = 0 ) func (w *WINDOWINFO) isStyle(style DWORD) bool { return w.DwStyle&style == style } func (w *WINDOWINFO) IsPopup() bool { return w.isStyle(WS_POPUP) } func (m *MONITORINFO) Dump() { fmt.Printf("MONITORINFO (%p)\n", m) fmt.Printf(" CbSize : %d\n", m.CbSize) fmt.Printf(" RcMonitor: %s\n", &m.RcMonitor) fmt.Printf(" RcWork : %s\n", &m.RcWork) fmt.Printf(" DwFlags : %d\n", m.DwFlags) } // http://msdn.microsoft.com/en-us/library/windows/desktop/dd145066.aspx type MONITORINFOEX struct { MONITORINFO SzDevice [CCHDEVICENAME]uint16 } // http://msdn.microsoft.com/en-us/library/windows/desktop/dd368826.aspx type PIXELFORMATDESCRIPTOR struct { Size uint16 Version uint16 DwFlags uint32 IPixelType byte ColorBits byte RedBits, RedShift byte GreenBits, GreenShift byte BlueBits, BlueShift byte AlphaBits, AlphaShift byte AccumBits byte AccumRedBits byte AccumGreenBits byte AccumBlueBits byte AccumAlphaBits byte DepthBits, StencilBits byte AuxBuffers byte ILayerType byte Reserved byte DwLayerMask uint32 DwVisibleMask uint32 DwDamageMask uint32 } // http://msdn.microsoft.com/en-us/library/windows/desktop/ms646270(v=vs.85).aspx type INPUT struct { Type uint32 Mi MOUSEINPUT Ki KEYBDINPUT Hi HARDWAREINPUT } // http://msdn.microsoft.com/en-us/library/windows/desktop/ms646273(v=vs.85).aspx type MOUSEINPUT struct { Dx int32 Dy int32 MouseData uint32 DwFlags uint32 Time uint32 DwExtraInfo uintptr } // http://msdn.microsoft.com/en-us/library/windows/desktop/ms646271(v=vs.85).aspx type KEYBDINPUT struct { WVk uint16 WScan uint16 DwFlags uint32 Time uint32 DwExtraInfo uintptr } // http://msdn.microsoft.com/en-us/library/windows/desktop/ms646269(v=vs.85).aspx type HARDWAREINPUT struct { UMsg uint32 WParamL uint16 WParamH uint16 } type KbdInput struct { typ uint32 ki KEYBDINPUT } type MouseInput struct { typ uint32 mi MOUSEINPUT } type HardwareInput struct { typ uint32 hi HARDWAREINPUT } // http://msdn.microsoft.com/en-us/library/windows/desktop/ms724950(v=vs.85).aspx type SYSTEMTIME struct { Year uint16 Month uint16 DayOfWeek uint16 Day uint16 Hour uint16 Minute uint16 Second uint16 Milliseconds uint16 } // http://msdn.microsoft.com/en-us/library/windows/desktop/ms644967(v=vs.85).aspx type KBDLLHOOKSTRUCT struct { VkCode DWORD ScanCode DWORD Flags DWORD Time DWORD DwExtraInfo ULONG_PTR } type HOOKPROC func(int, WPARAM, LPARAM) LRESULT type WINDOWPLACEMENT struct { Length uint32 Flags uint32 ShowCmd uint32 PtMinPosition POINT PtMaxPosition POINT RcNormalPosition RECT } type SCROLLINFO struct { CbSize uint32 FMask uint32 NMin int32 NMax int32 NPage uint32 NPos int32 NTrackPos int32 } ================================================ FILE: w32/user32.go ================================================ /* * Copyright (C) 2019 Tad Vizbaras. All Rights Reserved. * Copyright (C) 2010-2012 The W32 Authors. All Rights Reserved. */ package w32 import ( "fmt" "runtime" "syscall" "unsafe" ) var ( moduser32 = syscall.NewLazyDLL("user32.dll") procRegisterClassEx = moduser32.NewProc("RegisterClassExW") procLoadIcon = moduser32.NewProc("LoadIconW") procLoadCursor = moduser32.NewProc("LoadCursorW") procShowWindow = moduser32.NewProc("ShowWindow") procShowWindowAsync = moduser32.NewProc("ShowWindowAsync") procUpdateWindow = moduser32.NewProc("UpdateWindow") procCreateWindowEx = moduser32.NewProc("CreateWindowExW") procAdjustWindowRect = moduser32.NewProc("AdjustWindowRect") procAdjustWindowRectEx = moduser32.NewProc("AdjustWindowRectEx") procDestroyWindow = moduser32.NewProc("DestroyWindow") procDefWindowProc = moduser32.NewProc("DefWindowProcW") procDefDlgProc = moduser32.NewProc("DefDlgProcW") procPostQuitMessage = moduser32.NewProc("PostQuitMessage") procGetMessage = moduser32.NewProc("GetMessageW") procTranslateMessage = moduser32.NewProc("TranslateMessage") procDispatchMessage = moduser32.NewProc("DispatchMessageW") procSendMessage = moduser32.NewProc("SendMessageW") procPostMessage = moduser32.NewProc("PostMessageW") procWaitMessage = moduser32.NewProc("WaitMessage") procSetWindowText = moduser32.NewProc("SetWindowTextW") procGetWindowTextLength = moduser32.NewProc("GetWindowTextLengthW") procGetWindowText = moduser32.NewProc("GetWindowTextW") procGetWindowRect = moduser32.NewProc("GetWindowRect") procGetWindowInfo = moduser32.NewProc("GetWindowInfo") procSetWindowCompositionAttribute = moduser32.NewProc("SetWindowCompositionAttribute") procMoveWindow = moduser32.NewProc("MoveWindow") procScreenToClient = moduser32.NewProc("ScreenToClient") procCallWindowProc = moduser32.NewProc("CallWindowProcW") procSetWindowLong = moduser32.NewProc("SetWindowLongW") procSetWindowLongPtr = moduser32.NewProc("SetWindowLongW") procGetWindowLong = moduser32.NewProc("GetWindowLongW") procGetWindowLongPtr = moduser32.NewProc("GetWindowLongW") procEnableWindow = moduser32.NewProc("EnableWindow") procIsWindowEnabled = moduser32.NewProc("IsWindowEnabled") procIsWindowVisible = moduser32.NewProc("IsWindowVisible") procSetFocus = moduser32.NewProc("SetFocus") procGetFocus = moduser32.NewProc("GetFocus") procSetActiveWindow = moduser32.NewProc("SetActiveWindow") procSetForegroundWindow = moduser32.NewProc("SetForegroundWindow") procBringWindowToTop = moduser32.NewProc("BringWindowToTop") procInvalidateRect = moduser32.NewProc("InvalidateRect") procGetClientRect = moduser32.NewProc("GetClientRect") procGetDC = moduser32.NewProc("GetDC") procReleaseDC = moduser32.NewProc("ReleaseDC") procSetCapture = moduser32.NewProc("SetCapture") procReleaseCapture = moduser32.NewProc("ReleaseCapture") procGetWindowThreadProcessId = moduser32.NewProc("GetWindowThreadProcessId") procMessageBox = moduser32.NewProc("MessageBoxW") procGetSystemMetrics = moduser32.NewProc("GetSystemMetrics") procPostThreadMessageW = moduser32.NewProc("PostThreadMessageW") //procSysColorBrush = moduser32.NewProc("GetSysColorBrush") procCopyRect = moduser32.NewProc("CopyRect") procEqualRect = moduser32.NewProc("EqualRect") procInflateRect = moduser32.NewProc("InflateRect") procIntersectRect = moduser32.NewProc("IntersectRect") procIsRectEmpty = moduser32.NewProc("IsRectEmpty") procOffsetRect = moduser32.NewProc("OffsetRect") procPtInRect = moduser32.NewProc("PtInRect") procSetRect = moduser32.NewProc("SetRect") procSetRectEmpty = moduser32.NewProc("SetRectEmpty") procSubtractRect = moduser32.NewProc("SubtractRect") procUnionRect = moduser32.NewProc("UnionRect") procCreateDialogParam = moduser32.NewProc("CreateDialogParamW") procDialogBoxParam = moduser32.NewProc("DialogBoxParamW") procGetDlgItem = moduser32.NewProc("GetDlgItem") procDrawIcon = moduser32.NewProc("DrawIcon") procCreateMenu = moduser32.NewProc("CreateMenu") //procSetMenu = moduser32.NewProc("SetMenu") procDestroyMenu = moduser32.NewProc("DestroyMenu") procCreatePopupMenu = moduser32.NewProc("CreatePopupMenu") procCheckMenuRadioItem = moduser32.NewProc("CheckMenuRadioItem") //procDrawMenuBar = moduser32.NewProc("DrawMenuBar") //procInsertMenuItem = moduser32.NewProc("InsertMenuItemW") // FIXIT: procClientToScreen = moduser32.NewProc("ClientToScreen") procIsDialogMessage = moduser32.NewProc("IsDialogMessageW") procIsWindow = moduser32.NewProc("IsWindow") procEndDialog = moduser32.NewProc("EndDialog") procPeekMessage = moduser32.NewProc("PeekMessageW") procTranslateAccelerator = moduser32.NewProc("TranslateAcceleratorW") procSetWindowPos = moduser32.NewProc("SetWindowPos") procFillRect = moduser32.NewProc("FillRect") procDrawText = moduser32.NewProc("DrawTextW") procAddClipboardFormatListener = moduser32.NewProc("AddClipboardFormatListener") procRemoveClipboardFormatListener = moduser32.NewProc("RemoveClipboardFormatListener") procOpenClipboard = moduser32.NewProc("OpenClipboard") procCloseClipboard = moduser32.NewProc("CloseClipboard") procEnumClipboardFormats = moduser32.NewProc("EnumClipboardFormats") procGetClipboardData = moduser32.NewProc("GetClipboardData") procSetClipboardData = moduser32.NewProc("SetClipboardData") procEmptyClipboard = moduser32.NewProc("EmptyClipboard") procGetClipboardFormatName = moduser32.NewProc("GetClipboardFormatNameW") procIsClipboardFormatAvailable = moduser32.NewProc("IsClipboardFormatAvailable") procBeginPaint = moduser32.NewProc("BeginPaint") procEndPaint = moduser32.NewProc("EndPaint") procGetKeyboardState = moduser32.NewProc("GetKeyboardState") procMapVirtualKey = moduser32.NewProc("MapVirtualKeyExW") procGetAsyncKeyState = moduser32.NewProc("GetAsyncKeyState") procToAscii = moduser32.NewProc("ToAscii") procSwapMouseButton = moduser32.NewProc("SwapMouseButton") procGetCursorPos = moduser32.NewProc("GetCursorPos") procSetCursorPos = moduser32.NewProc("SetCursorPos") procSetCursor = moduser32.NewProc("SetCursor") procCreateIcon = moduser32.NewProc("CreateIcon") procDestroyIcon = moduser32.NewProc("DestroyIcon") procMonitorFromPoint = moduser32.NewProc("MonitorFromPoint") procMonitorFromRect = moduser32.NewProc("MonitorFromRect") procMonitorFromWindow = moduser32.NewProc("MonitorFromWindow") procGetMonitorInfo = moduser32.NewProc("GetMonitorInfoW") procEnumDisplayMonitors = moduser32.NewProc("EnumDisplayMonitors") procEnumDisplaySettingsEx = moduser32.NewProc("EnumDisplaySettingsExW") procChangeDisplaySettingsEx = moduser32.NewProc("ChangeDisplaySettingsExW") procSendInput = moduser32.NewProc("SendInput") procSetWindowsHookEx = moduser32.NewProc("SetWindowsHookExW") procUnhookWindowsHookEx = moduser32.NewProc("UnhookWindowsHookEx") procCallNextHookEx = moduser32.NewProc("CallNextHookEx") libuser32, _ = syscall.LoadLibrary("user32.dll") insertMenuItem, _ = syscall.GetProcAddress(libuser32, "InsertMenuItemW") setMenuItemInfo, _ = syscall.GetProcAddress(libuser32, "SetMenuItemInfoW") setMenu, _ = syscall.GetProcAddress(libuser32, "SetMenu") drawMenuBar, _ = syscall.GetProcAddress(libuser32, "DrawMenuBar") trackPopupMenuEx, _ = syscall.GetProcAddress(libuser32, "TrackPopupMenuEx") getKeyState, _ = syscall.GetProcAddress(libuser32, "GetKeyState") getSysColorBrush, _ = syscall.GetProcAddress(libuser32, "GetSysColorBrush") getWindowPlacement, _ = syscall.GetProcAddress(libuser32, "GetWindowPlacement") setWindowPlacement, _ = syscall.GetProcAddress(libuser32, "SetWindowPlacement") setScrollInfo, _ = syscall.GetProcAddress(libuser32, "SetScrollInfo") getScrollInfo, _ = syscall.GetProcAddress(libuser32, "GetScrollInfo") mainThread HANDLE ) func init() { runtime.LockOSThread() mainThread = GetCurrentThreadId() } func GET_X_LPARAM(lp uintptr) int32 { return int32(int16(LOWORD(uint32(lp)))) } func GET_Y_LPARAM(lp uintptr) int32 { return int32(int16(HIWORD(uint32(lp)))) } func RegisterClassEx(wndClassEx *WNDCLASSEX) ATOM { ret, _, _ := procRegisterClassEx.Call(uintptr(unsafe.Pointer(wndClassEx))) return ATOM(ret) } func LoadIcon(instance HINSTANCE, iconName *uint16) HICON { ret, _, _ := procLoadIcon.Call( uintptr(instance), uintptr(unsafe.Pointer(iconName))) return HICON(ret) } func LoadCursor(instance HINSTANCE, cursorName *uint16) HCURSOR { ret, _, _ := procLoadCursor.Call( uintptr(instance), uintptr(unsafe.Pointer(cursorName))) return HCURSOR(ret) } func ShowWindow(hwnd HWND, cmdshow int) bool { ret, _, _ := procShowWindow.Call( uintptr(hwnd), uintptr(cmdshow)) return ret != 0 } func ShowWindowAsync(hwnd HWND, cmdshow int) bool { ret, _, _ := procShowWindowAsync.Call( uintptr(hwnd), uintptr(cmdshow)) return ret != 0 } func UpdateWindow(hwnd HWND) bool { ret, _, _ := procUpdateWindow.Call( uintptr(hwnd)) return ret != 0 } func PostThreadMessage(threadID HANDLE, msg int, wp, lp uintptr) { procPostThreadMessageW.Call(threadID, uintptr(msg), wp, lp) } func PostMainThreadMessage(msg uint32, wp, lp uintptr) bool { ret, _, _ := procPostThreadMessageW.Call(mainThread, uintptr(msg), wp, lp) return ret != 0 } func CreateWindowEx(exStyle uint, className, windowName *uint16, style uint, x, y, width, height int, parent HWND, menu HMENU, instance HINSTANCE, param unsafe.Pointer) HWND { ret, _, _ := procCreateWindowEx.Call( uintptr(exStyle), uintptr(unsafe.Pointer(className)), uintptr(unsafe.Pointer(windowName)), uintptr(style), uintptr(x), uintptr(y), uintptr(width), uintptr(height), uintptr(parent), uintptr(menu), uintptr(instance), uintptr(param)) return HWND(ret) } func AdjustWindowRectEx(rect *RECT, style uint, menu bool, exStyle uint) bool { ret, _, _ := procAdjustWindowRectEx.Call( uintptr(unsafe.Pointer(rect)), uintptr(style), uintptr(BoolToBOOL(menu)), uintptr(exStyle)) return ret != 0 } func AdjustWindowRect(rect *RECT, style uint, menu bool) bool { ret, _, _ := procAdjustWindowRect.Call( uintptr(unsafe.Pointer(rect)), uintptr(style), uintptr(BoolToBOOL(menu))) return ret != 0 } func DestroyWindow(hwnd HWND) bool { ret, _, _ := procDestroyWindow.Call(hwnd) return ret != 0 } func SetWindowCompositionAttribute(hwnd HWND, data *WINDOWCOMPOSITIONATTRIBDATA) bool { if procSetWindowCompositionAttribute != nil { ret, _, _ := procSetWindowCompositionAttribute.Call( hwnd, uintptr(unsafe.Pointer(data)), ) return ret != 0 } return false } func DefWindowProc(hwnd HWND, msg uint32, wParam, lParam uintptr) uintptr { ret, _, _ := procDefWindowProc.Call( uintptr(hwnd), uintptr(msg), wParam, lParam) return ret } func DefDlgProc(hwnd HWND, msg uint32, wParam, lParam uintptr) uintptr { ret, _, _ := procDefDlgProc.Call( uintptr(hwnd), uintptr(msg), wParam, lParam) return ret } func PostQuitMessage(exitCode int) { procPostQuitMessage.Call( uintptr(exitCode)) } func GetMessage(msg *MSG, hwnd HWND, msgFilterMin, msgFilterMax uint32) int { ret, _, _ := procGetMessage.Call( uintptr(unsafe.Pointer(msg)), uintptr(hwnd), uintptr(msgFilterMin), uintptr(msgFilterMax)) return int(ret) } func TranslateMessage(msg *MSG) bool { ret, _, _ := procTranslateMessage.Call( uintptr(unsafe.Pointer(msg))) return ret != 0 } func DispatchMessage(msg *MSG) uintptr { ret, _, _ := procDispatchMessage.Call( uintptr(unsafe.Pointer(msg))) return ret } func SendMessage(hwnd HWND, msg uint32, wParam, lParam uintptr) uintptr { ret, _, _ := procSendMessage.Call( uintptr(hwnd), uintptr(msg), wParam, lParam) return ret } func PostMessage(hwnd HWND, msg uint32, wParam, lParam uintptr) bool { ret, _, _ := procPostMessage.Call( uintptr(hwnd), uintptr(msg), wParam, lParam) return ret != 0 } func WaitMessage() bool { ret, _, _ := procWaitMessage.Call() return ret != 0 } func SetWindowText(hwnd HWND, text string) { procSetWindowText.Call( uintptr(hwnd), uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(text)))) } func GetWindowTextLength(hwnd HWND) int { ret, _, _ := procGetWindowTextLength.Call( uintptr(hwnd)) return int(ret) } func GetWindowInfo(hwnd HWND, info *WINDOWINFO) int { ret, _, _ := procGetWindowInfo.Call( hwnd, uintptr(unsafe.Pointer(info)), ) return int(ret) } func GetWindowText(hwnd HWND) string { textLen := GetWindowTextLength(hwnd) + 1 buf := make([]uint16, textLen) procGetWindowText.Call( uintptr(hwnd), uintptr(unsafe.Pointer(&buf[0])), uintptr(textLen)) return syscall.UTF16ToString(buf) } func GetWindowRect(hwnd HWND) *RECT { var rect RECT procGetWindowRect.Call( hwnd, uintptr(unsafe.Pointer(&rect))) return &rect } func MoveWindow(hwnd HWND, x, y, width, height int, repaint bool) bool { ret, _, _ := procMoveWindow.Call( uintptr(hwnd), uintptr(x), uintptr(y), uintptr(width), uintptr(height), uintptr(BoolToBOOL(repaint))) return ret != 0 } func ScreenToClient(hwnd HWND, x, y int) (X, Y int, ok bool) { pt := POINT{X: int32(x), Y: int32(y)} ret, _, _ := procScreenToClient.Call( uintptr(hwnd), uintptr(unsafe.Pointer(&pt))) return int(pt.X), int(pt.Y), ret != 0 } func CallWindowProc(preWndProc uintptr, hwnd HWND, msg uint32, wParam, lParam uintptr) uintptr { ret, _, _ := procCallWindowProc.Call( preWndProc, uintptr(hwnd), uintptr(msg), wParam, lParam) return ret } func SetWindowLong(hwnd HWND, index int, value uint32) uint32 { ret, _, _ := procSetWindowLong.Call( uintptr(hwnd), uintptr(index), uintptr(value)) return uint32(ret) } func SetWindowLongPtr(hwnd HWND, index int, value uintptr) uintptr { ret, _, _ := procSetWindowLongPtr.Call( uintptr(hwnd), uintptr(index), value) return ret } func GetWindowLong(hwnd HWND, index int) int32 { ret, _, _ := procGetWindowLong.Call( uintptr(hwnd), uintptr(index)) return int32(ret) } func GetWindowLongPtr(hwnd HWND, index int) uintptr { ret, _, _ := procGetWindowLongPtr.Call( uintptr(hwnd), uintptr(index)) return ret } func EnableWindow(hwnd HWND, b bool) bool { ret, _, _ := procEnableWindow.Call( uintptr(hwnd), uintptr(BoolToBOOL(b))) return ret != 0 } func IsWindowEnabled(hwnd HWND) bool { ret, _, _ := procIsWindowEnabled.Call( uintptr(hwnd)) return ret != 0 } func IsWindowVisible(hwnd HWND) bool { ret, _, _ := procIsWindowVisible.Call( uintptr(hwnd)) return ret != 0 } func SetFocus(hwnd HWND) HWND { ret, _, _ := procSetFocus.Call( uintptr(hwnd)) return HWND(ret) } func SetActiveWindow(hwnd HWND) HWND { ret, _, _ := procSetActiveWindow.Call( uintptr(hwnd)) return HWND(ret) } func BringWindowToTop(hwnd HWND) bool { ret, _, _ := procBringWindowToTop.Call(uintptr(hwnd)) return ret != 0 } func SetForegroundWindow(hwnd HWND) HWND { ret, _, _ := procSetForegroundWindow.Call( uintptr(hwnd)) return HWND(ret) } func GetFocus() HWND { ret, _, _ := procGetFocus.Call() return HWND(ret) } func InvalidateRect(hwnd HWND, rect *RECT, erase bool) bool { ret, _, _ := procInvalidateRect.Call( uintptr(hwnd), uintptr(unsafe.Pointer(rect)), uintptr(BoolToBOOL(erase))) return ret != 0 } func GetClientRect(hwnd HWND) *RECT { var rect RECT ret, _, _ := procGetClientRect.Call( uintptr(hwnd), uintptr(unsafe.Pointer(&rect))) if ret == 0 { panic(fmt.Sprintf("GetClientRect(%d) failed", hwnd)) } return &rect } func GetDC(hwnd HWND) HDC { ret, _, _ := procGetDC.Call( uintptr(hwnd)) return HDC(ret) } func ReleaseDC(hwnd HWND, hDC HDC) bool { ret, _, _ := procReleaseDC.Call( uintptr(hwnd), uintptr(hDC)) return ret != 0 } func SetCapture(hwnd HWND) HWND { ret, _, _ := procSetCapture.Call( uintptr(hwnd)) return HWND(ret) } func ReleaseCapture() bool { ret, _, _ := procReleaseCapture.Call() return ret != 0 } func GetWindowThreadProcessId(hwnd HWND) (HANDLE, int) { var processId int ret, _, _ := procGetWindowThreadProcessId.Call( uintptr(hwnd), uintptr(unsafe.Pointer(&processId))) return HANDLE(ret), processId } func MessageBox(hwnd HWND, title, caption string, flags uint) int { ret, _, _ := procMessageBox.Call( uintptr(hwnd), uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(title))), uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(caption))), uintptr(flags)) return int(ret) } func GetSystemMetrics(index int) int { ret, _, _ := procGetSystemMetrics.Call( uintptr(index)) return int(ret) } func GetSysColorBrush(nIndex int) HBRUSH { /* ret, _, _ := procSysColorBrush.Call(1, uintptr(nIndex), 0, 0) return HBRUSH(ret) */ ret, _, _ := syscall.Syscall(getSysColorBrush, 1, uintptr(nIndex), 0, 0) return HBRUSH(ret) } func CopyRect(dst, src *RECT) bool { ret, _, _ := procCopyRect.Call( uintptr(unsafe.Pointer(dst)), uintptr(unsafe.Pointer(src))) return ret != 0 } func EqualRect(rect1, rect2 *RECT) bool { ret, _, _ := procEqualRect.Call( uintptr(unsafe.Pointer(rect1)), uintptr(unsafe.Pointer(rect2))) return ret != 0 } func InflateRect(rect *RECT, dx, dy int) bool { ret, _, _ := procInflateRect.Call( uintptr(unsafe.Pointer(rect)), uintptr(dx), uintptr(dy)) return ret != 0 } func IntersectRect(dst, src1, src2 *RECT) bool { ret, _, _ := procIntersectRect.Call( uintptr(unsafe.Pointer(dst)), uintptr(unsafe.Pointer(src1)), uintptr(unsafe.Pointer(src2))) return ret != 0 } func IsRectEmpty(rect *RECT) bool { ret, _, _ := procIsRectEmpty.Call( uintptr(unsafe.Pointer(rect))) return ret != 0 } func OffsetRect(rect *RECT, dx, dy int) bool { ret, _, _ := procOffsetRect.Call( uintptr(unsafe.Pointer(rect)), uintptr(dx), uintptr(dy)) return ret != 0 } func PtInRect(rect *RECT, x, y int) bool { pt := POINT{X: int32(x), Y: int32(y)} ret, _, _ := procPtInRect.Call( uintptr(unsafe.Pointer(rect)), uintptr(unsafe.Pointer(&pt))) return ret != 0 } func SetRect(rect *RECT, left, top, right, bottom int) bool { ret, _, _ := procSetRect.Call( uintptr(unsafe.Pointer(rect)), uintptr(left), uintptr(top), uintptr(right), uintptr(bottom)) return ret != 0 } func SetRectEmpty(rect *RECT) bool { ret, _, _ := procSetRectEmpty.Call( uintptr(unsafe.Pointer(rect))) return ret != 0 } func SubtractRect(dst, src1, src2 *RECT) bool { ret, _, _ := procSubtractRect.Call( uintptr(unsafe.Pointer(dst)), uintptr(unsafe.Pointer(src1)), uintptr(unsafe.Pointer(src2))) return ret != 0 } func UnionRect(dst, src1, src2 *RECT) bool { ret, _, _ := procUnionRect.Call( uintptr(unsafe.Pointer(dst)), uintptr(unsafe.Pointer(src1)), uintptr(unsafe.Pointer(src2))) return ret != 0 } func CreateDialog(hInstance HINSTANCE, lpTemplate *uint16, hWndParent HWND, lpDialogProc uintptr) HWND { ret, _, _ := procCreateDialogParam.Call( uintptr(hInstance), uintptr(unsafe.Pointer(lpTemplate)), uintptr(hWndParent), lpDialogProc, 0) return HWND(ret) } func DialogBox(hInstance HINSTANCE, lpTemplateName *uint16, hWndParent HWND, lpDialogProc uintptr) int { ret, _, _ := procDialogBoxParam.Call( uintptr(hInstance), uintptr(unsafe.Pointer(lpTemplateName)), uintptr(hWndParent), lpDialogProc, 0) return int(ret) } func GetDlgItem(hDlg HWND, nIDDlgItem int) HWND { ret, _, _ := procGetDlgItem.Call( uintptr(unsafe.Pointer(hDlg)), uintptr(nIDDlgItem)) return HWND(ret) } func DrawIcon(hDC HDC, x, y int, hIcon HICON) bool { ret, _, _ := procDrawIcon.Call( uintptr(unsafe.Pointer(hDC)), uintptr(x), uintptr(y), uintptr(unsafe.Pointer(hIcon))) return ret != 0 } func CreateMenu() HMENU { ret, _, _ := procCreateMenu.Call(0, 0, 0, 0) return HMENU(ret) } func SetMenu(hWnd HWND, hMenu HMENU) bool { ret, _, _ := syscall.Syscall(setMenu, 2, uintptr(hWnd), uintptr(hMenu), 0) return ret != 0 } // https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-checkmenuradioitem func SelectRadioMenuItem(menuID uint16, startID uint16, endID uint16, hwnd HWND) bool { ret, _, _ := procCheckMenuRadioItem.Call( hwnd, uintptr(startID), uintptr(endID), uintptr(menuID), MF_BYCOMMAND) return ret != 0 } func CreatePopupMenu() HMENU { ret, _, _ := procCreatePopupMenu.Call(0, 0, 0, 0) return HMENU(ret) } func TrackPopupMenuEx(hMenu HMENU, fuFlags uint32, x, y int32, hWnd HWND, lptpm *TPMPARAMS) BOOL { ret, _, _ := syscall.Syscall6(trackPopupMenuEx, 6, uintptr(hMenu), uintptr(fuFlags), uintptr(x), uintptr(y), uintptr(hWnd), uintptr(unsafe.Pointer(lptpm))) return BOOL(ret) } func DrawMenuBar(hWnd HWND) bool { ret, _, _ := syscall.Syscall(drawMenuBar, 1, uintptr(hWnd), 0, 0) return ret != 0 } func InsertMenuItem(hMenu HMENU, uItem uint32, fByPosition bool, lpmii *MENUITEMINFO) bool { ret, _, _ := syscall.Syscall6(insertMenuItem, 4, uintptr(hMenu), uintptr(uItem), uintptr(BoolToBOOL(fByPosition)), uintptr(unsafe.Pointer(lpmii)), 0, 0) return ret != 0 } func SetMenuItemInfo(hMenu HMENU, uItem uint32, fByPosition bool, lpmii *MENUITEMINFO) bool { ret, _, _ := syscall.Syscall6(setMenuItemInfo, 4, uintptr(hMenu), uintptr(uItem), uintptr(BoolToBOOL(fByPosition)), uintptr(unsafe.Pointer(lpmii)), 0, 0) return ret != 0 } func ClientToScreen(hwnd HWND, x, y int) (int, int) { pt := POINT{X: int32(x), Y: int32(y)} procClientToScreen.Call( uintptr(hwnd), uintptr(unsafe.Pointer(&pt))) return int(pt.X), int(pt.Y) } func IsDialogMessage(hwnd HWND, msg *MSG) bool { ret, _, _ := procIsDialogMessage.Call( uintptr(hwnd), uintptr(unsafe.Pointer(msg))) return ret != 0 } func IsWindow(hwnd HWND) bool { ret, _, _ := procIsWindow.Call( uintptr(hwnd)) return ret != 0 } func EndDialog(hwnd HWND, nResult uintptr) bool { ret, _, _ := procEndDialog.Call( uintptr(hwnd), nResult) return ret != 0 } func PeekMessage(lpMsg *MSG, hwnd HWND, wMsgFilterMin, wMsgFilterMax, wRemoveMsg uint32) bool { ret, _, _ := procPeekMessage.Call( uintptr(unsafe.Pointer(lpMsg)), uintptr(hwnd), uintptr(wMsgFilterMin), uintptr(wMsgFilterMax), uintptr(wRemoveMsg)) return ret != 0 } func TranslateAccelerator(hwnd HWND, hAccTable HACCEL, lpMsg *MSG) bool { ret, _, _ := procTranslateMessage.Call( uintptr(hwnd), uintptr(hAccTable), uintptr(unsafe.Pointer(lpMsg))) return ret != 0 } func SetWindowPos(hwnd, hWndInsertAfter HWND, x, y, cx, cy int, uFlags uint) bool { ret, _, _ := procSetWindowPos.Call( uintptr(hwnd), uintptr(hWndInsertAfter), uintptr(x), uintptr(y), uintptr(cx), uintptr(cy), uintptr(uFlags)) return ret != 0 } func FillRect(hDC HDC, lprc *RECT, hbr HBRUSH) bool { ret, _, _ := procFillRect.Call( uintptr(hDC), uintptr(unsafe.Pointer(lprc)), uintptr(hbr)) return ret != 0 } func DrawText(hDC HDC, text string, uCount int, lpRect *RECT, uFormat uint) int { ret, _, _ := procDrawText.Call( uintptr(hDC), uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(text))), uintptr(uCount), uintptr(unsafe.Pointer(lpRect)), uintptr(uFormat)) return int(ret) } func AddClipboardFormatListener(hwnd HWND) bool { ret, _, _ := procAddClipboardFormatListener.Call( uintptr(hwnd)) return ret != 0 } func RemoveClipboardFormatListener(hwnd HWND) bool { ret, _, _ := procRemoveClipboardFormatListener.Call( uintptr(hwnd)) return ret != 0 } func OpenClipboard(hWndNewOwner HWND) bool { ret, _, _ := procOpenClipboard.Call( uintptr(hWndNewOwner)) return ret != 0 } func CloseClipboard() bool { ret, _, _ := procCloseClipboard.Call() return ret != 0 } func EnumClipboardFormats(format uint) uint { ret, _, _ := procEnumClipboardFormats.Call( uintptr(format)) return uint(ret) } func GetClipboardData(uFormat uint) HANDLE { ret, _, _ := procGetClipboardData.Call( uintptr(uFormat)) return HANDLE(ret) } func SetClipboardData(uFormat uint, hMem HANDLE) HANDLE { ret, _, _ := procSetClipboardData.Call( uintptr(uFormat), uintptr(hMem)) return HANDLE(ret) } func EmptyClipboard() bool { ret, _, _ := procEmptyClipboard.Call() return ret != 0 } func GetClipboardFormatName(format uint) (string, bool) { cchMaxCount := 255 buf := make([]uint16, cchMaxCount) ret, _, _ := procGetClipboardFormatName.Call( uintptr(format), uintptr(unsafe.Pointer(&buf[0])), uintptr(cchMaxCount)) if ret > 0 { return syscall.UTF16ToString(buf), true } return "Requested format does not exist or is predefined", false } func IsClipboardFormatAvailable(format uint) bool { ret, _, _ := procIsClipboardFormatAvailable.Call(uintptr(format)) return ret != 0 } func BeginPaint(hwnd HWND, paint *PAINTSTRUCT) HDC { ret, _, _ := procBeginPaint.Call( uintptr(hwnd), uintptr(unsafe.Pointer(paint))) return HDC(ret) } func EndPaint(hwnd HWND, paint *PAINTSTRUCT) { procEndPaint.Call( uintptr(hwnd), uintptr(unsafe.Pointer(paint))) } func GetKeyboardState(lpKeyState *[]byte) bool { ret, _, _ := procGetKeyboardState.Call( uintptr(unsafe.Pointer(&(*lpKeyState)[0]))) return ret != 0 } func MapVirtualKeyEx(uCode, uMapType uint, dwhkl HKL) uint { ret, _, _ := procMapVirtualKey.Call( uintptr(uCode), uintptr(uMapType), uintptr(dwhkl)) return uint(ret) } func GetAsyncKeyState(vKey int) uint16 { ret, _, _ := procGetAsyncKeyState.Call(uintptr(vKey)) return uint16(ret) } func ToAscii(uVirtKey, uScanCode uint, lpKeyState *byte, lpChar *uint16, uFlags uint) int { ret, _, _ := procToAscii.Call( uintptr(uVirtKey), uintptr(uScanCode), uintptr(unsafe.Pointer(lpKeyState)), uintptr(unsafe.Pointer(lpChar)), uintptr(uFlags)) return int(ret) } func SwapMouseButton(fSwap bool) bool { ret, _, _ := procSwapMouseButton.Call( uintptr(BoolToBOOL(fSwap))) return ret != 0 } func GetCursorPos() (x, y int, ok bool) { pt := POINT{} ret, _, _ := procGetCursorPos.Call(uintptr(unsafe.Pointer(&pt))) return int(pt.X), int(pt.Y), ret != 0 } func SetCursorPos(x, y int) bool { ret, _, _ := procSetCursorPos.Call( uintptr(x), uintptr(y), ) return ret != 0 } func SetCursor(cursor HCURSOR) HCURSOR { ret, _, _ := procSetCursor.Call( uintptr(cursor), ) return HCURSOR(ret) } func CreateIcon(instance HINSTANCE, nWidth, nHeight int, cPlanes, cBitsPerPixel byte, ANDbits, XORbits *byte) HICON { ret, _, _ := procCreateIcon.Call( uintptr(instance), uintptr(nWidth), uintptr(nHeight), uintptr(cPlanes), uintptr(cBitsPerPixel), uintptr(unsafe.Pointer(ANDbits)), uintptr(unsafe.Pointer(XORbits)), ) return HICON(ret) } func DestroyIcon(icon HICON) bool { ret, _, _ := procDestroyIcon.Call( uintptr(icon), ) return ret != 0 } func MonitorFromPoint(x, y int, dwFlags uint32) HMONITOR { ret, _, _ := procMonitorFromPoint.Call( uintptr(x), uintptr(y), uintptr(dwFlags), ) return HMONITOR(ret) } func MonitorFromRect(rc *RECT, dwFlags uint32) HMONITOR { ret, _, _ := procMonitorFromRect.Call( uintptr(unsafe.Pointer(rc)), uintptr(dwFlags), ) return HMONITOR(ret) } func MonitorFromWindow(hwnd HWND, dwFlags uint32) HMONITOR { ret, _, _ := procMonitorFromWindow.Call( uintptr(hwnd), uintptr(dwFlags), ) return HMONITOR(ret) } func GetMonitorInfo(hMonitor HMONITOR, lmpi *MONITORINFO) bool { ret, _, _ := procGetMonitorInfo.Call( uintptr(hMonitor), uintptr(unsafe.Pointer(lmpi)), ) return ret != 0 } func EnumDisplayMonitors(hdc HDC, clip *RECT, fnEnum, dwData uintptr) bool { ret, _, _ := procEnumDisplayMonitors.Call( uintptr(hdc), uintptr(unsafe.Pointer(clip)), fnEnum, dwData, ) return ret != 0 } func EnumDisplaySettingsEx(szDeviceName *uint16, iModeNum uint32, devMode *DEVMODE, dwFlags uint32) bool { ret, _, _ := procEnumDisplaySettingsEx.Call( uintptr(unsafe.Pointer(szDeviceName)), uintptr(iModeNum), uintptr(unsafe.Pointer(devMode)), uintptr(dwFlags), ) return ret != 0 } func ChangeDisplaySettingsEx(szDeviceName *uint16, devMode *DEVMODE, hwnd HWND, dwFlags uint32, lParam uintptr) int32 { ret, _, _ := procChangeDisplaySettingsEx.Call( uintptr(unsafe.Pointer(szDeviceName)), uintptr(unsafe.Pointer(devMode)), uintptr(hwnd), uintptr(dwFlags), lParam, ) return int32(ret) } /* func SendInput(inputs []INPUT) uint32 { var validInputs []C.INPUT for _, oneInput := range inputs { input := C.INPUT{_type: C.DWORD(oneInput.Type)} switch oneInput.Type { case INPUT_MOUSE: (*MouseInput)(unsafe.Pointer(&input)).mi = oneInput.Mi case INPUT_KEYBOARD: (*KbdInput)(unsafe.Pointer(&input)).ki = oneInput.Ki case INPUT_HARDWARE: (*HardwareInput)(unsafe.Pointer(&input)).hi = oneInput.Hi default: panic("unkown type") } validInputs = append(validInputs, input) } ret, _, _ := procSendInput.Call( uintptr(len(validInputs)), uintptr(unsafe.Pointer(&validInputs[0])), uintptr(unsafe.Sizeof(C.INPUT{})), ) return uint32(ret) }*/ func SetWindowsHookEx(idHook int, lpfn HOOKPROC, hMod HINSTANCE, dwThreadId DWORD) HHOOK { ret, _, _ := procSetWindowsHookEx.Call( uintptr(idHook), uintptr(syscall.NewCallback(lpfn)), uintptr(hMod), uintptr(dwThreadId), ) return HHOOK(ret) } func UnhookWindowsHookEx(hhk HHOOK) bool { ret, _, _ := procUnhookWindowsHookEx.Call( uintptr(hhk), ) return ret != 0 } func CallNextHookEx(hhk HHOOK, nCode int, wParam WPARAM, lParam LPARAM) LRESULT { ret, _, _ := procCallNextHookEx.Call( uintptr(hhk), uintptr(nCode), uintptr(wParam), uintptr(lParam), ) return LRESULT(ret) } func GetKeyState(nVirtKey int32) int16 { ret, _, _ := syscall.Syscall(getKeyState, 1, uintptr(nVirtKey), 0, 0) return int16(ret) } func DestroyMenu(hMenu HMENU) bool { ret, _, _ := procDestroyMenu.Call(1, uintptr(hMenu), 0, 0) return ret != 0 } func GetWindowPlacement(hWnd HWND, lpwndpl *WINDOWPLACEMENT) bool { ret, _, _ := syscall.Syscall(getWindowPlacement, 2, uintptr(hWnd), uintptr(unsafe.Pointer(lpwndpl)), 0) return ret != 0 } func SetWindowPlacement(hWnd HWND, lpwndpl *WINDOWPLACEMENT) bool { ret, _, _ := syscall.Syscall(setWindowPlacement, 2, uintptr(hWnd), uintptr(unsafe.Pointer(lpwndpl)), 0) return ret != 0 } func SetScrollInfo(hwnd HWND, fnBar int32, lpsi *SCROLLINFO, fRedraw bool) int32 { ret, _, _ := syscall.Syscall6(setScrollInfo, 4, hwnd, uintptr(fnBar), uintptr(unsafe.Pointer(lpsi)), uintptr(BoolToBOOL(fRedraw)), 0, 0) return int32(ret) } func GetScrollInfo(hwnd HWND, fnBar int32, lpsi *SCROLLINFO) bool { ret, _, _ := syscall.Syscall(getScrollInfo, 3, hwnd, uintptr(fnBar), uintptr(unsafe.Pointer(lpsi))) return ret != 0 } ================================================ FILE: w32/utils.go ================================================ /* * Copyright (C) 2019 Tad Vizbaras. All Rights Reserved. * Copyright (C) 2010-2012 The W32 Authors. All Rights Reserved. */ package w32 import ( "syscall" "unicode/utf16" "unsafe" ) func MustLoadLibrary(name string) uintptr { lib, err := syscall.LoadLibrary(name) if err != nil { panic(err) } return uintptr(lib) } func MustGetProcAddress(lib uintptr, name string) uintptr { addr, err := syscall.GetProcAddress(syscall.Handle(lib), name) if err != nil { panic(err) } return uintptr(addr) } func SUCCEEDED(hr HRESULT) bool { return hr >= 0 } func FAILED(hr HRESULT) bool { return hr < 0 } func MakeIntResource(id uint16) *uint16 { return (*uint16)(unsafe.Pointer(uintptr(id))) } func LOWORD(dw uint32) uint16 { return uint16(dw) } func HIWORD(dw uint32) uint16 { return uint16(dw >> 16 & 0xffff) } func MAKELONG(lo, hi uint16) uint32 { return uint32(uint32(lo) | ((uint32(hi)) << 16)) } func BoolToBOOL(value bool) BOOL { if value { return 1 } return 0 } func UTF16PtrToString(cstr *uint16) string { if cstr != nil { us := make([]uint16, 0, 256) for p := uintptr(unsafe.Pointer(cstr)); ; p += 2 { u := *(*uint16)(unsafe.Pointer(p)) if u == 0 { return string(utf16.Decode(us)) } us = append(us, u) } } return "" } func ComAddRef(unknown *IUnknown) int32 { ret, _, _ := syscall.Syscall(unknown.lpVtbl.pAddRef, 1, uintptr(unsafe.Pointer(unknown)), 0, 0) return int32(ret) } func ComRelease(unknown *IUnknown) int32 { ret, _, _ := syscall.Syscall(unknown.lpVtbl.pRelease, 1, uintptr(unsafe.Pointer(unknown)), 0, 0) return int32(ret) } func ComQueryInterface(unknown *IUnknown, id *GUID) *IDispatch { var disp *IDispatch hr, _, _ := syscall.Syscall(unknown.lpVtbl.pQueryInterface, 3, uintptr(unsafe.Pointer(unknown)), uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(&disp))) if hr != 0 { panic("Invoke QieryInterface error.") } return disp } func ComGetIDsOfName(disp *IDispatch, names []string) []int32 { wnames := make([]*uint16, len(names)) dispid := make([]int32, len(names)) for i := 0; i < len(names); i++ { wnames[i] = syscall.StringToUTF16Ptr(names[i]) } hr, _, _ := syscall.Syscall6(disp.lpVtbl.pGetIDsOfNames, 6, uintptr(unsafe.Pointer(disp)), uintptr(unsafe.Pointer(IID_NULL)), uintptr(unsafe.Pointer(&wnames[0])), uintptr(len(names)), uintptr(GetUserDefaultLCID()), uintptr(unsafe.Pointer(&dispid[0]))) if hr != 0 { panic("Invoke GetIDsOfName error.") } return dispid } func ComInvoke(disp *IDispatch, dispid int32, dispatch int16, params ...interface{}) (result *VARIANT) { var dispparams DISPPARAMS if dispatch&DISPATCH_PROPERTYPUT != 0 { dispnames := [1]int32{DISPID_PROPERTYPUT} dispparams.RgdispidNamedArgs = uintptr(unsafe.Pointer(&dispnames[0])) dispparams.CNamedArgs = 1 } var vargs []VARIANT if len(params) > 0 { vargs = make([]VARIANT, len(params)) for i, v := range params { //n := len(params)-i-1 n := len(params) - i - 1 VariantInit(&vargs[n]) switch v.(type) { case bool: if v.(bool) { vargs[n] = VARIANT{VT_BOOL, 0, 0, 0, 0xffff} } else { vargs[n] = VARIANT{VT_BOOL, 0, 0, 0, 0} } case *bool: vargs[n] = VARIANT{VT_BOOL | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*bool))))} case byte: vargs[n] = VARIANT{VT_I1, 0, 0, 0, int64(v.(byte))} case *byte: vargs[n] = VARIANT{VT_I1 | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*byte))))} case int16: vargs[n] = VARIANT{VT_I2, 0, 0, 0, int64(v.(int16))} case *int16: vargs[n] = VARIANT{VT_I2 | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*int16))))} case uint16: vargs[n] = VARIANT{VT_UI2, 0, 0, 0, int64(v.(int16))} case *uint16: vargs[n] = VARIANT{VT_UI2 | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*uint16))))} case int, int32: vargs[n] = VARIANT{VT_UI4, 0, 0, 0, int64(v.(int))} case *int, *int32: vargs[n] = VARIANT{VT_I4 | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*int))))} case uint, uint32: vargs[n] = VARIANT{VT_UI4, 0, 0, 0, int64(v.(uint))} case *uint, *uint32: vargs[n] = VARIANT{VT_UI4 | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*uint))))} case int64: vargs[n] = VARIANT{VT_I8, 0, 0, 0, v.(int64)} case *int64: vargs[n] = VARIANT{VT_I8 | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*int64))))} case uint64: vargs[n] = VARIANT{VT_UI8, 0, 0, 0, int64(v.(uint64))} case *uint64: vargs[n] = VARIANT{VT_UI8 | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*uint64))))} case float32: vargs[n] = VARIANT{VT_R4, 0, 0, 0, int64(v.(float32))} case *float32: vargs[n] = VARIANT{VT_R4 | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*float32))))} case float64: vargs[n] = VARIANT{VT_R8, 0, 0, 0, int64(v.(float64))} case *float64: vargs[n] = VARIANT{VT_R8 | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*float64))))} case string: vargs[n] = VARIANT{VT_BSTR, 0, 0, 0, int64(uintptr(unsafe.Pointer(SysAllocString(v.(string)))))} case *string: vargs[n] = VARIANT{VT_BSTR | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*string))))} case *IDispatch: vargs[n] = VARIANT{VT_DISPATCH, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*IDispatch))))} case **IDispatch: vargs[n] = VARIANT{VT_DISPATCH | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(**IDispatch))))} case nil: vargs[n] = VARIANT{VT_NULL, 0, 0, 0, 0} case *VARIANT: vargs[n] = VARIANT{VT_VARIANT | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*VARIANT))))} default: panic("unknown type") } } dispparams.Rgvarg = uintptr(unsafe.Pointer(&vargs[0])) dispparams.CArgs = uint32(len(params)) } var ret VARIANT var excepInfo EXCEPINFO VariantInit(&ret) hr, _, _ := syscall.Syscall9(disp.lpVtbl.pInvoke, 8, uintptr(unsafe.Pointer(disp)), uintptr(dispid), uintptr(unsafe.Pointer(IID_NULL)), uintptr(GetUserDefaultLCID()), uintptr(dispatch), uintptr(unsafe.Pointer(&dispparams)), uintptr(unsafe.Pointer(&ret)), uintptr(unsafe.Pointer(&excepInfo)), 0) if hr != 0 { if excepInfo.BstrDescription != nil { bs := UTF16PtrToString(excepInfo.BstrDescription) panic(bs) } } for _, varg := range vargs { if varg.VT == VT_BSTR && varg.Val != 0 { SysFreeString(((*int16)(unsafe.Pointer(uintptr(varg.Val))))) } } result = &ret return } ================================================ FILE: w32/uxtheme.go ================================================ /* * Copyright (C) 2019 Tad Vizbaras. All Rights Reserved. * Copyright (C) 2010-2012 The W32 Authors. All Rights Reserved. */ package w32 import ( "syscall" "unsafe" ) // LISTVIEW parts const ( LVP_LISTITEM = 1 LVP_LISTGROUP = 2 LVP_LISTDETAIL = 3 LVP_LISTSORTEDDETAIL = 4 LVP_EMPTYTEXT = 5 LVP_GROUPHEADER = 6 LVP_GROUPHEADERLINE = 7 LVP_EXPANDBUTTON = 8 LVP_COLLAPSEBUTTON = 9 LVP_COLUMNDETAIL = 10 ) // LVP_LISTITEM states const ( LISS_NORMAL = 1 LISS_HOT = 2 LISS_SELECTED = 3 LISS_DISABLED = 4 LISS_SELECTEDNOTFOCUS = 5 LISS_HOTSELECTED = 6 ) // TREEVIEW parts const ( TVP_TREEITEM = 1 TVP_GLYPH = 2 TVP_BRANCH = 3 TVP_HOTGLYPH = 4 ) // TVP_TREEITEM states const ( TREIS_NORMAL = 1 TREIS_HOT = 2 TREIS_SELECTED = 3 TREIS_DISABLED = 4 TREIS_SELECTEDNOTFOCUS = 5 TREIS_HOTSELECTED = 6 ) type HTHEME HANDLE var ( // Library libuxtheme uintptr // Functions closeThemeData uintptr drawThemeBackground uintptr drawThemeText uintptr getThemeTextExtent uintptr openThemeData uintptr setWindowTheme uintptr ) func init() { // Library libuxtheme = MustLoadLibrary("uxtheme.dll") // Functions closeThemeData = MustGetProcAddress(libuxtheme, "CloseThemeData") drawThemeBackground = MustGetProcAddress(libuxtheme, "DrawThemeBackground") drawThemeText = MustGetProcAddress(libuxtheme, "DrawThemeText") getThemeTextExtent = MustGetProcAddress(libuxtheme, "GetThemeTextExtent") openThemeData = MustGetProcAddress(libuxtheme, "OpenThemeData") setWindowTheme = MustGetProcAddress(libuxtheme, "SetWindowTheme") } func CloseThemeData(hTheme HTHEME) HRESULT { ret, _, _ := syscall.Syscall(closeThemeData, 1, uintptr(hTheme), 0, 0) return HRESULT(ret) } func DrawThemeBackground(hTheme HTHEME, hdc HDC, iPartId, iStateId int32, pRect, pClipRect *RECT) HRESULT { ret, _, _ := syscall.Syscall6(drawThemeBackground, 6, uintptr(hTheme), uintptr(hdc), uintptr(iPartId), uintptr(iStateId), uintptr(unsafe.Pointer(pRect)), uintptr(unsafe.Pointer(pClipRect))) return HRESULT(ret) } func DrawThemeText(hTheme HTHEME, hdc HDC, iPartId, iStateId int32, pszText *uint16, iCharCount int32, dwTextFlags, dwTextFlags2 uint32, pRect *RECT) HRESULT { ret, _, _ := syscall.Syscall9(drawThemeText, 9, uintptr(hTheme), uintptr(hdc), uintptr(iPartId), uintptr(iStateId), uintptr(unsafe.Pointer(pszText)), uintptr(iCharCount), uintptr(dwTextFlags), uintptr(dwTextFlags2), uintptr(unsafe.Pointer(pRect))) return HRESULT(ret) } func GetThemeTextExtent(hTheme HTHEME, hdc HDC, iPartId, iStateId int32, pszText *uint16, iCharCount int32, dwTextFlags uint32, pBoundingRect, pExtentRect *RECT) HRESULT { ret, _, _ := syscall.Syscall9(getThemeTextExtent, 9, uintptr(hTheme), uintptr(hdc), uintptr(iPartId), uintptr(iStateId), uintptr(unsafe.Pointer(pszText)), uintptr(iCharCount), uintptr(dwTextFlags), uintptr(unsafe.Pointer(pBoundingRect)), uintptr(unsafe.Pointer(pExtentRect))) return HRESULT(ret) } func OpenThemeData(hwnd HWND, pszClassList *uint16) HTHEME { ret, _, _ := syscall.Syscall(openThemeData, 2, uintptr(hwnd), uintptr(unsafe.Pointer(pszClassList)), 0) return HTHEME(ret) } func SetWindowTheme(hwnd HWND, pszSubAppName, pszSubIdList *uint16) HRESULT { ret, _, _ := syscall.Syscall(setWindowTheme, 3, uintptr(hwnd), uintptr(unsafe.Pointer(pszSubAppName)), uintptr(unsafe.Pointer(pszSubIdList))) return HRESULT(ret) } ================================================ FILE: w32/vars.go ================================================ /* * Copyright (C) 2019 Tad Vizbaras. All Rights Reserved. * Copyright (C) 2010-2012 The W32 Authors. All Rights Reserved. */ package w32 var ( IID_NULL = &GUID{0x00000000, 0x0000, 0x0000, [8]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}} IID_IUnknown = &GUID{0x00000000, 0x0000, 0x0000, [8]byte{0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}} IID_IDispatch = &GUID{0x00020400, 0x0000, 0x0000, [8]byte{0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}} IID_IConnectionPointContainer = &GUID{0xB196B284, 0xBAB4, 0x101A, [8]byte{0xB6, 0x9C, 0x00, 0xAA, 0x00, 0x34, 0x1D, 0x07}} IID_IConnectionPoint = &GUID{0xB196B286, 0xBAB4, 0x101A, [8]byte{0xB6, 0x9C, 0x00, 0xAA, 0x00, 0x34, 0x1D, 0x07}} ) ================================================ FILE: wndproc.go ================================================ /* * Copyright (C) 2019 The Winc Authors. All Rights Reserved. * Copyright (C) 2010-2013 Allen Dang. All Rights Reserved. */ package winc import ( "unsafe" "github.com/tadvi/winc/w32" ) func genPoint(p uintptr) (x, y int) { x = int(w32.LOWORD(uint32(p))) y = int(w32.HIWORD(uint32(p))) return } func genMouseEventArg(wparam, lparam uintptr) *MouseEventData { var data MouseEventData data.Button = int(wparam) data.X, data.Y = genPoint(lparam) return &data } func genDropFilesEventArg(wparam uintptr) *DropFilesEventData { hDrop := w32.HDROP(wparam) var data DropFilesEventData _, fileCount := w32.DragQueryFile(hDrop, 0xFFFFFFFF) data.Files = make([]string, fileCount) var i uint for i = 0; i < fileCount; i++ { data.Files[i], _ = w32.DragQueryFile(hDrop, i) } data.X, data.Y, _ = w32.DragQueryPoint(hDrop) w32.DragFinish(hDrop) return &data } func generalWndProc(hwnd w32.HWND, msg uint32, wparam, lparam uintptr) uintptr { switch msg { case w32.WM_HSCROLL: //println("case w32.WM_HSCROLL") case w32.WM_VSCROLL: //println("case w32.WM_VSCROLL") } if controller := GetMsgHandler(hwnd); controller != nil { ret := controller.WndProc(msg, wparam, lparam) switch msg { case w32.WM_NOTIFY: //Reflect notification to control nm := (*w32.NMHDR)(unsafe.Pointer(lparam)) if controller := GetMsgHandler(nm.HwndFrom); controller != nil { ret := controller.WndProc(msg, wparam, lparam) if ret != 0 { w32.SetWindowLong(hwnd, w32.DWL_MSGRESULT, uint32(ret)) return w32.TRUE } } case w32.WM_COMMAND: if lparam != 0 { //Reflect message to control h := w32.HWND(lparam) if controller := GetMsgHandler(h); controller != nil { ret := controller.WndProc(msg, wparam, lparam) if ret != 0 { w32.SetWindowLong(hwnd, w32.DWL_MSGRESULT, uint32(ret)) return w32.TRUE } } } case w32.WM_CLOSE: controller.OnClose().Fire(NewEvent(controller, nil)) case w32.WM_KILLFOCUS: controller.OnKillFocus().Fire(NewEvent(controller, nil)) case w32.WM_SETFOCUS: controller.OnSetFocus().Fire(NewEvent(controller, nil)) case w32.WM_DROPFILES: controller.OnDropFiles().Fire(NewEvent(controller, genDropFilesEventArg(wparam))) case w32.WM_CONTEXTMENU: if wparam != 0 { //Reflect message to control h := w32.HWND(wparam) if controller := GetMsgHandler(h); controller != nil { contextMenu := controller.ContextMenu() x, y := genPoint(lparam) if contextMenu != nil { id := w32.TrackPopupMenuEx( contextMenu.hMenu, w32.TPM_NOANIMATION|w32.TPM_RETURNCMD, int32(x), int32(y), controller.Handle(), nil) item := findMenuItemByID(int(id)) if item != nil { item.OnClick().Fire(NewEvent(controller, genMouseEventArg(wparam, lparam))) } return 0 } } } case w32.WM_LBUTTONDOWN: controller.OnLBDown().Fire(NewEvent(controller, genMouseEventArg(wparam, lparam))) case w32.WM_LBUTTONUP: controller.OnLBUp().Fire(NewEvent(controller, genMouseEventArg(wparam, lparam))) case w32.WM_LBUTTONDBLCLK: controller.OnLBDbl().Fire(NewEvent(controller, genMouseEventArg(wparam, lparam))) case w32.WM_MBUTTONDOWN: controller.OnMBDown().Fire(NewEvent(controller, genMouseEventArg(wparam, lparam))) case w32.WM_MBUTTONUP: controller.OnMBUp().Fire(NewEvent(controller, genMouseEventArg(wparam, lparam))) case w32.WM_RBUTTONDOWN: controller.OnRBDown().Fire(NewEvent(controller, genMouseEventArg(wparam, lparam))) case w32.WM_RBUTTONUP: controller.OnRBUp().Fire(NewEvent(controller, genMouseEventArg(wparam, lparam))) case w32.WM_RBUTTONDBLCLK: controller.OnRBDbl().Fire(NewEvent(controller, genMouseEventArg(wparam, lparam))) case w32.WM_MOUSEMOVE: controller.OnMouseMove().Fire(NewEvent(controller, genMouseEventArg(wparam, lparam))) case w32.WM_PAINT: canvas := NewCanvasFromHwnd(hwnd) defer canvas.Dispose() controller.OnPaint().Fire(NewEvent(controller, &PaintEventData{Canvas: canvas})) case w32.WM_KEYUP: controller.OnKeyUp().Fire(NewEvent(controller, &KeyUpEventData{int(wparam), int(lparam)})) case w32.WM_SIZE: x, y := genPoint(lparam) controller.OnSize().Fire(NewEvent(controller, &SizeEventData{uint(wparam), x, y})) } return ret } return w32.DefWindowProc(hwnd, uint32(msg), wparam, lparam) }