From c91aa462aa2eeffe80e23707af1011faa65b963c Mon Sep 17 00:00:00 2001 From: Travis McLane Date: Sun, 23 Apr 2023 18:34:44 -0500 Subject: [PATCH 01/28] [darwin] add getPrimaryScreen/getScreens to impl (#2618) --- v3/pkg/application/screen_darwin.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/v3/pkg/application/screen_darwin.go b/v3/pkg/application/screen_darwin.go index d45753f7b..0669d531a 100644 --- a/v3/pkg/application/screen_darwin.go +++ b/v3/pkg/application/screen_darwin.go @@ -128,12 +128,12 @@ func cScreenToScreen(screen C.Screen) *Screen { } } -func getPrimaryScreen() (*Screen, error) { +func (m *macosApp) getPrimaryScreen() (*Screen, error) { cScreen := C.GetPrimaryScreen() return cScreenToScreen(cScreen), nil } -func getScreens() ([]*Screen, error) { +func (m *macosApp) getScreens() ([]*Screen, error) { cScreens := C.getAllScreens() defer C.free(unsafe.Pointer(cScreens)) numScreens := int(C.GetNumScreens()) From cff3ee5079fc238105bdcd426bf1f00840dd8b94 Mon Sep 17 00:00:00 2001 From: stffabi Date: Thu, 20 Apr 2023 12:06:37 +0200 Subject: [PATCH 02/28] [assetServer] Improve release/close handling of webview requests (#2612) --- .../frontend/desktop/darwin/frontend.go | 1 - .../frontend/desktop/linux/frontend.go | 1 - v2/pkg/assetserver/assetserver_legacy.go | 12 +----- v2/pkg/assetserver/assetserver_webview.go | 12 +++--- v2/pkg/assetserver/webview/request.go | 3 +- v2/pkg/assetserver/webview/request_darwin.go | 24 +++++------ .../assetserver/webview/request_finalizer.go | 40 +++++++++++++++++++ v2/pkg/assetserver/webview/request_linux.go | 27 ++++++------- v2/pkg/assetserver/webview/responsewriter.go | 4 +- .../webview/responsewriter_darwin.go | 5 +-- .../webview/responsewriter_linux.go | 5 +-- v3/pkg/application/application.go | 4 -- 12 files changed, 78 insertions(+), 60 deletions(-) create mode 100644 v2/pkg/assetserver/webview/request_finalizer.go diff --git a/v2/internal/frontend/desktop/darwin/frontend.go b/v2/internal/frontend/desktop/darwin/frontend.go index a5517ffcb..5187be2c0 100644 --- a/v2/internal/frontend/desktop/darwin/frontend.go +++ b/v2/internal/frontend/desktop/darwin/frontend.go @@ -113,7 +113,6 @@ func (f *Frontend) startMessageProcessor() { func (f *Frontend) startRequestProcessor() { for request := range requestBuffer { f.assets.ServeWebViewRequest(request) - request.Release() } } func (f *Frontend) startCallbackProcessor() { diff --git a/v2/internal/frontend/desktop/linux/frontend.go b/v2/internal/frontend/desktop/linux/frontend.go index f8c83eac1..e02c6a928 100644 --- a/v2/internal/frontend/desktop/linux/frontend.go +++ b/v2/internal/frontend/desktop/linux/frontend.go @@ -466,7 +466,6 @@ var requestBuffer = make(chan webview.Request, 100) func (f *Frontend) startRequestProcessor() { for request := range requestBuffer { f.assets.ServeWebViewRequest(request) - request.Release() } } diff --git a/v2/pkg/assetserver/assetserver_legacy.go b/v2/pkg/assetserver/assetserver_legacy.go index 2d315aca3..4df671bc2 100644 --- a/v2/pkg/assetserver/assetserver_legacy.go +++ b/v2/pkg/assetserver/assetserver_legacy.go @@ -56,13 +56,7 @@ func (r legacyRequest) Response() webview.ResponseWriter { return &legacyRequestNoOpCloserResponseWriter{r.rw} } -func (r legacyRequest) AddRef() error { - return nil -} - -func (r legacyRequest) Release() error { - return nil -} +func (r legacyRequest) Close() error { return nil } func (r *legacyRequest) request() (*http.Request, error) { if r.req != nil { @@ -81,6 +75,4 @@ type legacyRequestNoOpCloserResponseWriter struct { http.ResponseWriter } -func (*legacyRequestNoOpCloserResponseWriter) Finish() error { - return nil -} +func (*legacyRequestNoOpCloserResponseWriter) Finish() {} diff --git a/v2/pkg/assetserver/assetserver_webview.go b/v2/pkg/assetserver/assetserver_webview.go index 3a7178c20..ae85f2513 100644 --- a/v2/pkg/assetserver/assetserver_webview.go +++ b/v2/pkg/assetserver/assetserver_webview.go @@ -22,6 +22,7 @@ type assetServerWebView struct { // ServeWebViewRequest processes the HTTP Request asynchronously by faking a golang HTTP Server. // The request will be finished with a StatusNotImplemented code if no handler has written to the response. +// The AssetServer takes ownership of the request and the caller mustn't close it or access it in any other way. func (d *AssetServer) ServeWebViewRequest(req webview.Request) { d.dispatchInit.Do(func() { workers := d.dispatchWorkers @@ -33,8 +34,11 @@ func (d *AssetServer) ServeWebViewRequest(req webview.Request) { for i := 0; i < workers; i++ { go func() { for req := range workerC { + uri, _ := req.URL() d.processWebViewRequest(req) - req.Release() + if err := req.Close(); err != nil { + d.logError("Unable to call close for request for uri '%s'", uri) + } } }() } @@ -45,12 +49,6 @@ func (d *AssetServer) ServeWebViewRequest(req webview.Request) { d.dispatchReqC = dispatchC }) - if err := req.AddRef(); err != nil { - uri, _ := req.URL() - d.logError("Unable to call AddRef for request '%s'", uri) - return - } - d.dispatchReqC <- req } diff --git a/v2/pkg/assetserver/webview/request.go b/v2/pkg/assetserver/webview/request.go index b0ce3d069..18ff29890 100644 --- a/v2/pkg/assetserver/webview/request.go +++ b/v2/pkg/assetserver/webview/request.go @@ -13,6 +13,5 @@ type Request interface { Response() ResponseWriter - AddRef() error - Release() error + Close() error } diff --git a/v2/pkg/assetserver/webview/request_darwin.go b/v2/pkg/assetserver/webview/request_darwin.go index 4f4919fab..653c19506 100644 --- a/v2/pkg/assetserver/webview/request_darwin.go +++ b/v2/pkg/assetserver/webview/request_darwin.go @@ -118,11 +118,9 @@ import ( ) // NewRequest creates as new WebViewRequest based on a pointer to an `id` -// -// Please make sure to call Release() when finished using the request. func NewRequest(wkURLSchemeTask unsafe.Pointer) Request { C.URLSchemeTaskRetain(wkURLSchemeTask) - return &request{task: wkURLSchemeTask} + return newRequestFinalizer(&request{task: wkURLSchemeTask}) } var _ Request = &request{} @@ -135,16 +133,6 @@ type request struct { rw *responseWriter } -func (r *request) AddRef() error { - C.URLSchemeTaskRetain(r.task) - return nil -} - -func (r *request) Release() error { - C.URLSchemeTaskRelease(r.task) - return nil -} - func (r *request) URL() (string, error) { return C.GoString(C.URLSchemeTaskRequestURL(r.task)), nil } @@ -205,6 +193,16 @@ func (r *request) Response() ResponseWriter { return r.rw } +func (r *request) Close() error { + var err error + if r.body != nil { + err = r.body.Close() + } + r.Response().Finish() + C.URLSchemeTaskRelease(r.task) + return err +} + var _ io.ReadCloser = &requestBodyStreamReader{} type requestBodyStreamReader struct { diff --git a/v2/pkg/assetserver/webview/request_finalizer.go b/v2/pkg/assetserver/webview/request_finalizer.go new file mode 100644 index 000000000..6a8c6a928 --- /dev/null +++ b/v2/pkg/assetserver/webview/request_finalizer.go @@ -0,0 +1,40 @@ +package webview + +import ( + "runtime" + "sync/atomic" +) + +var _ Request = &requestFinalizer{} + +type requestFinalizer struct { + Request + closed int32 +} + +// newRequestFinalizer returns a request with a runtime finalizer to make sure it will be closed from the finalizer +// if it has not been already closed. +// It also makes sure Close() of the wrapping request is only called once. +func newRequestFinalizer(r Request) Request { + rf := &requestFinalizer{Request: r} + // Make sure to async release since it might block the finalizer goroutine for a longer period + runtime.SetFinalizer(rf, func(obj *requestFinalizer) { rf.close(true) }) + return rf +} + +func (r *requestFinalizer) Close() error { + return r.close(false) +} + +func (r *requestFinalizer) close(asyncRelease bool) error { + if atomic.CompareAndSwapInt32(&r.closed, 0, 1) { + runtime.SetFinalizer(r, nil) + if asyncRelease { + go r.Request.Close() + return nil + } else { + return r.Request.Close() + } + } + return nil +} diff --git a/v2/pkg/assetserver/webview/request_linux.go b/v2/pkg/assetserver/webview/request_linux.go index ff758a065..101ee12fb 100644 --- a/v2/pkg/assetserver/webview/request_linux.go +++ b/v2/pkg/assetserver/webview/request_linux.go @@ -18,13 +18,12 @@ import ( ) // NewRequest creates as new WebViewRequest based on a pointer to an `WebKitURISchemeRequest` -// -// Please make sure to call Release() when finished using the request. func NewRequest(webKitURISchemeRequest unsafe.Pointer) Request { webkitReq := (*C.WebKitURISchemeRequest)(webKitURISchemeRequest) + C.g_object_ref(C.gpointer(webkitReq)) + req := &request{req: webkitReq} - req.AddRef() - return req + return newRequestFinalizer(req) } var _ Request = &request{} @@ -37,16 +36,6 @@ type request struct { rw *responseWriter } -func (r *request) AddRef() error { - C.g_object_ref(C.gpointer(r.req)) - return nil -} - -func (r *request) Release() error { - C.g_object_unref(C.gpointer(r.req)) - return nil -} - func (r *request) URL() (string, error) { return C.GoString(C.webkit_uri_scheme_request_get_uri(r.req)), nil } @@ -82,3 +71,13 @@ func (r *request) Response() ResponseWriter { r.rw = &responseWriter{req: r.req} return r.rw } + +func (r *request) Close() error { + var err error + if r.body != nil { + err = r.body.Close() + } + r.Response().Finish() + C.g_object_unref(C.gpointer(r.req)) + return err +} diff --git a/v2/pkg/assetserver/webview/responsewriter.go b/v2/pkg/assetserver/webview/responsewriter.go index 9e3c1952f..d67802a05 100644 --- a/v2/pkg/assetserver/webview/responsewriter.go +++ b/v2/pkg/assetserver/webview/responsewriter.go @@ -20,6 +20,6 @@ var ( type ResponseWriter interface { http.ResponseWriter - // Finish the response and flush all data. - Finish() error + // Finish the response and flush all data. A Finish after the request has already been finished has no effect. + Finish() } diff --git a/v2/pkg/assetserver/webview/responsewriter_darwin.go b/v2/pkg/assetserver/webview/responsewriter_darwin.go index 77de3c455..1c0cbee72 100644 --- a/v2/pkg/assetserver/webview/responsewriter_darwin.go +++ b/v2/pkg/assetserver/webview/responsewriter_darwin.go @@ -133,16 +133,15 @@ func (rw *responseWriter) WriteHeader(code int) { C.URLSchemeTaskDidReceiveResponse(rw.r.task, C.int(code), headers, C.int(headersLen)) } -func (rw *responseWriter) Finish() error { +func (rw *responseWriter) Finish() { if !rw.wroteHeader { rw.WriteHeader(http.StatusNotImplemented) } if rw.finished { - return nil + return } rw.finished = true C.URLSchemeTaskDidFinish(rw.r.task) - return nil } diff --git a/v2/pkg/assetserver/webview/responsewriter_linux.go b/v2/pkg/assetserver/webview/responsewriter_linux.go index 52e28aa5d..9b3f53a78 100644 --- a/v2/pkg/assetserver/webview/responsewriter_linux.go +++ b/v2/pkg/assetserver/webview/responsewriter_linux.go @@ -84,19 +84,18 @@ func (rw *responseWriter) WriteHeader(code int) { } } -func (rw *responseWriter) Finish() error { +func (rw *responseWriter) Finish() { if !rw.wroteHeader { rw.WriteHeader(http.StatusNotImplemented) } if rw.finished { - return nil + return } rw.finished = true if rw.w != nil { rw.w.Close() } - return nil } func (rw *responseWriter) finishWithError(code int, err error) { diff --git a/v3/pkg/application/application.go b/v3/pkg/application/application.go index b26d6a6f0..80b4d7e99 100644 --- a/v3/pkg/application/application.go +++ b/v3/pkg/application/application.go @@ -327,10 +327,6 @@ func (a *App) Run() error { for { request := <-webviewRequests a.handleWebViewRequest(request) - err := request.Release() - if err != nil { - a.error("Failed to release webview request: %s", err.Error()) - } } }() go func() { From 1222e3aa1bf87e7d271988cc10ad7d0993f84dd6 Mon Sep 17 00:00:00 2001 From: stffabi Date: Thu, 20 Apr 2023 12:37:40 +0200 Subject: [PATCH 03/28] [v2, dev] Use custom schemes for in-app dev mode (#2610) This fixes some long-standing inconsistencies between dev mode builds and production builds but is a breaking change. Dev mode uses custom scheme for Vite versions >= 3.0.0 and for older it still behaves in the old way. --- v2/cmd/wails/internal/dev/dev.go | 44 +++++++++++++---- v2/cmd/wails/internal/dev/stdout_scanner.go | 39 ++++++++++++++- .../customlayout/myfrontend/package.json | 2 +- v2/internal/app/app_dev.go | 49 +++++++++++++++++-- v2/internal/frontend/devserver/devserver.go | 42 ++-------------- .../assetserver/assethandler_external.go} | 35 ++++++------- .../templates/svelte-ts/frontend/package.json | 2 +- .../templates/svelte/frontend/package.json | 2 +- .../vanilla-ts/frontend/package.json | 2 +- .../templates/vanilla/frontend/package.json | 2 +- website/src/pages/changelog.mdx | 4 ++ 11 files changed, 145 insertions(+), 78 deletions(-) rename v2/{internal/frontend/devserver/external.go => pkg/assetserver/assethandler_external.go} (68%) diff --git a/v2/cmd/wails/internal/dev/dev.go b/v2/cmd/wails/internal/dev/dev.go index ca40f36a4..b7fc4d10d 100644 --- a/v2/cmd/wails/internal/dev/dev.go +++ b/v2/cmd/wails/internal/dev/dev.go @@ -22,6 +22,7 @@ import ( "github.com/wailsapp/wails/v2/cmd/wails/flags" "github.com/wailsapp/wails/v2/cmd/wails/internal/gomod" "github.com/wailsapp/wails/v2/cmd/wails/internal/logutils" + "golang.org/x/mod/semver" "github.com/wailsapp/wails/v2/pkg/commands/buildtags" @@ -36,6 +37,10 @@ import ( "github.com/wailsapp/wails/v2/pkg/commands/build" ) +const ( + viteMinVersion = "v3.0.0" +) + func sliceToMap(input []string) map[string]struct{} { result := map[string]struct{}{} for _, value := range input { @@ -88,10 +93,11 @@ func Application(f *flags.Dev, logger *clilogger.CLILogger) error { buildOptions.IgnoreApplication = false } + legacyUseDevServerInsteadofCustomScheme := false // frontend:dev:watcher command. frontendDevAutoDiscovery := projectConfig.IsFrontendDevServerURLAutoDiscovery() if command := projectConfig.DevWatcherCommand; command != "" { - closer, devServerURL, err := runFrontendDevWatcherCommand(projectConfig.GetFrontendDir(), command, frontendDevAutoDiscovery) + closer, devServerURL, devServerViteVersion, err := runFrontendDevWatcherCommand(projectConfig.GetFrontendDir(), command, frontendDevAutoDiscovery) if err != nil { return err } @@ -100,6 +106,12 @@ func Application(f *flags.Dev, logger *clilogger.CLILogger) error { f.FrontendDevServerURL = devServerURL } defer closer() + + if devServerViteVersion != "" && semver.Compare(devServerViteVersion, viteMinVersion) < 0 { + logutils.LogRed("Please upgrade your Vite Server to at least '%s' future Wails versions will require at least Vite '%s'", viteMinVersion, viteMinVersion) + time.Sleep(3 * time.Second) + legacyUseDevServerInsteadofCustomScheme = true + } } else if frontendDevAutoDiscovery { return fmt.Errorf("unable to auto discover frontend:dev:serverUrl without a frontend:dev:watcher command, please either set frontend:dev:watcher or remove the auto discovery from frontend:dev:serverUrl") } @@ -107,7 +119,7 @@ func Application(f *flags.Dev, logger *clilogger.CLILogger) error { // Do initial build but only for the application. logger.Println("Building application for development...") buildOptions.IgnoreFrontend = true - debugBinaryProcess, appBinary, err := restartApp(buildOptions, nil, f, exitCodeChannel) + debugBinaryProcess, appBinary, err := restartApp(buildOptions, nil, f, exitCodeChannel, legacyUseDevServerInsteadofCustomScheme) buildOptions.IgnoreFrontend = ignoreFrontend || f.FrontendDevServerURL != "" if err != nil { return err @@ -153,7 +165,7 @@ func Application(f *flags.Dev, logger *clilogger.CLILogger) error { }() // Watch for changes and trigger restartApp() - debugBinaryProcess = doWatcherLoop(buildOptions, debugBinaryProcess, f, watcher, exitCodeChannel, quitChannel, f.DevServerURL()) + debugBinaryProcess = doWatcherLoop(buildOptions, debugBinaryProcess, f, watcher, exitCodeChannel, quitChannel, f.DevServerURL(), legacyUseDevServerInsteadofCustomScheme) // Kill the current program if running and remove dev binary if err := killProcessAndCleanupBinary(debugBinaryProcess, appBinary); err != nil { @@ -202,7 +214,7 @@ func runCommand(dir string, exitOnError bool, command string, args ...string) er } // runFrontendDevWatcherCommand will run the `frontend:dev:watcher` command if it was given, ex- `npm run dev` -func runFrontendDevWatcherCommand(frontendDirectory string, devCommand string, discoverViteServerURL bool) (func(), string, error) { +func runFrontendDevWatcherCommand(frontendDirectory string, devCommand string, discoverViteServerURL bool) (func(), string, string, error) { ctx, cancel := context.WithCancel(context.Background()) scanner := NewStdoutScanner() cmdSlice := strings.Split(devCommand, " ") @@ -214,7 +226,7 @@ func runFrontendDevWatcherCommand(frontendDirectory string, devCommand string, d if err := cmd.Start(); err != nil { cancel() - return nil, "", fmt.Errorf("unable to start frontend DevWatcher: %w", err) + return nil, "", "", fmt.Errorf("unable to start frontend DevWatcher: %w", err) } var viteServerURL string @@ -224,10 +236,19 @@ func runFrontendDevWatcherCommand(frontendDirectory string, devCommand string, d viteServerURL = serverURL case <-time.After(time.Second * 10): cancel() - return nil, "", errors.New("failed to find Vite server URL") + return nil, "", "", errors.New("failed to find Vite server URL") } } + viteVersion := "" + select { + case version := <-scanner.ViteServerVersionC: + viteVersion = version + + case <-time.After(time.Second * 5): + // That's fine, then most probably it was not vite that was running + } + logutils.LogGreen("Running frontend DevWatcher command: '%s'", devCommand) var wg sync.WaitGroup wg.Add(1) @@ -255,11 +276,11 @@ func runFrontendDevWatcherCommand(frontendDirectory string, devCommand string, d } cancel() wg.Wait() - }, viteServerURL, nil + }, viteServerURL, viteVersion, nil } // restartApp does the actual rebuilding of the application when files change -func restartApp(buildOptions *build.Options, debugBinaryProcess *process.Process, f *flags.Dev, exitCodeChannel chan int) (*process.Process, string, error) { +func restartApp(buildOptions *build.Options, debugBinaryProcess *process.Process, f *flags.Dev, exitCodeChannel chan int, legacyUseDevServerInsteadofCustomScheme bool) (*process.Process, string, error) { appBinary, err := build.Build(buildOptions) println() @@ -297,6 +318,9 @@ func restartApp(buildOptions *build.Options, debugBinaryProcess *process.Process os.Setenv("assetdir", f.AssetDir) os.Setenv("devserver", f.DevServer) os.Setenv("frontenddevserverurl", f.FrontendDevServerURL) + if legacyUseDevServerInsteadofCustomScheme { + os.Setenv("legacyusedevsererinsteadofcustomscheme", "true") + } // Start up new binary with correct args newProcess := process.NewProcess(appBinary, args...) @@ -316,7 +340,7 @@ func restartApp(buildOptions *build.Options, debugBinaryProcess *process.Process } // doWatcherLoop is the main watch loop that runs while dev is active -func doWatcherLoop(buildOptions *build.Options, debugBinaryProcess *process.Process, f *flags.Dev, watcher *fsnotify.Watcher, exitCodeChannel chan int, quitChannel chan os.Signal, devServerURL *url.URL) *process.Process { +func doWatcherLoop(buildOptions *build.Options, debugBinaryProcess *process.Process, f *flags.Dev, watcher *fsnotify.Watcher, exitCodeChannel chan int, quitChannel chan os.Signal, devServerURL *url.URL, legacyUseDevServerInsteadofCustomScheme bool) *process.Process { // Main Loop var extensionsThatTriggerARebuild = sliceToMap(strings.Split(f.Extensions, ",")) var dirsThatTriggerAReload []string @@ -422,7 +446,7 @@ func doWatcherLoop(buildOptions *build.Options, debugBinaryProcess *process.Proc rebuild = false logutils.LogGreen("[Rebuild triggered] files updated") // Try and build the app - newBinaryProcess, _, err := restartApp(buildOptions, debugBinaryProcess, f, exitCodeChannel) + newBinaryProcess, _, err := restartApp(buildOptions, debugBinaryProcess, f, exitCodeChannel, legacyUseDevServerInsteadofCustomScheme) if err != nil { logutils.LogRed("Error during build: %s", err.Error()) continue diff --git a/v2/cmd/wails/internal/dev/stdout_scanner.go b/v2/cmd/wails/internal/dev/stdout_scanner.go index d84e4785e..dad4e72cf 100644 --- a/v2/cmd/wails/internal/dev/stdout_scanner.go +++ b/v2/cmd/wails/internal/dev/stdout_scanner.go @@ -2,30 +2,47 @@ package dev import ( "bufio" + "fmt" "net/url" "os" "strings" "github.com/acarl005/stripansi" "github.com/wailsapp/wails/v2/cmd/wails/internal/logutils" + "golang.org/x/mod/semver" ) // stdoutScanner acts as a stdout target that will scan the incoming // data to find out the vite server url type stdoutScanner struct { - ViteServerURLChan chan string + ViteServerURLChan chan string + ViteServerVersionC chan string + versionDetected bool } // NewStdoutScanner creates a new stdoutScanner func NewStdoutScanner() *stdoutScanner { return &stdoutScanner{ - ViteServerURLChan: make(chan string, 2), + ViteServerURLChan: make(chan string, 2), + ViteServerVersionC: make(chan string, 2), } } // Write bytes to the scanner. Will copy the bytes to stdout func (s *stdoutScanner) Write(data []byte) (n int, err error) { input := stripansi.Strip(string(data)) + if !s.versionDetected { + v, err := detectViteVersion(input) + if v != "" || err != nil { + if err != nil { + logutils.LogRed("ViteStdoutScanner: %s", err) + v = "v0.0.0" + } + s.ViteServerVersionC <- v + s.versionDetected = true + } + } + match := strings.Index(input, "Local:") if match != -1 { sc := bufio.NewScanner(strings.NewReader(input)) @@ -47,3 +64,21 @@ func (s *stdoutScanner) Write(data []byte) (n int, err error) { } return os.Stdout.Write(data) } + +func detectViteVersion(line string) (string, error) { + s := strings.Split(strings.TrimSpace(line), " ") + if strings.ToLower(s[0]) != "vite" { + return "", nil + } + + if len(line) < 2 { + return "", fmt.Errorf("unable to parse vite version") + } + + v := s[1] + if !semver.IsValid(v) { + return "", fmt.Errorf("%s is not a valid vite version string", v) + } + + return v, nil +} diff --git a/v2/examples/customlayout/myfrontend/package.json b/v2/examples/customlayout/myfrontend/package.json index 4ac881798..a1b6f8e1a 100644 --- a/v2/examples/customlayout/myfrontend/package.json +++ b/v2/examples/customlayout/myfrontend/package.json @@ -8,6 +8,6 @@ "preview": "vite preview" }, "devDependencies": { - "vite": "^2.9.9" + "vite": "^3.0.7" } } \ No newline at end of file diff --git a/v2/internal/app/app_dev.go b/v2/internal/app/app_dev.go index 32c27fa2e..8373d399f 100644 --- a/v2/internal/app/app_dev.go +++ b/v2/internal/app/app_dev.go @@ -8,9 +8,11 @@ import ( "flag" "fmt" iofs "io/fs" + "net" "net/url" "os" "path/filepath" + "time" "github.com/wailsapp/wails/v2/pkg/assetserver" @@ -104,17 +106,35 @@ func CreateApp(appoptions *options.App) (*App, error) { } if frontendDevServerURL != "" { - if devServer == "" { - return nil, fmt.Errorf("Unable to use FrontendDevServerUrl without a DevServer address") + if os.Getenv("legacyusedevsererinsteadofcustomscheme") != "" { + startURL, err := url.Parse("http://" + devServer) + if err != nil { + return nil, err + } + + ctx = context.WithValue(ctx, "starturl", startURL) } - startURL, err := url.Parse("http://" + devServer) + ctx = context.WithValue(ctx, "frontenddevserverurl", frontendDevServerURL) + + externalURL, err := url.Parse(frontendDevServerURL) if err != nil { return nil, err } - ctx = context.WithValue(ctx, "starturl", startURL) - ctx = context.WithValue(ctx, "frontenddevserverurl", frontendDevServerURL) + if externalURL.Host == "" { + return nil, fmt.Errorf("Invalid frontend:dev:serverUrl missing protocol scheme?") + } + + waitCb := func() { myLogger.Debug("Waiting for frontend DevServer '%s' to be ready", externalURL) } + if !checkPortIsOpen(externalURL.Host, time.Minute, waitCb) { + myLogger.Error("Timeout waiting for frontend DevServer") + } + + handler := assetserver.NewExternalAssetsHandler(myLogger, assetConfig, externalURL) + assetConfig.Assets = nil + assetConfig.Handler = handler + assetConfig.Middleware = nil myLogger.Info("Serving assets from frontend DevServer URL: %s", frontendDevServerURL) } else { @@ -246,3 +266,22 @@ func tryInferAssetDirFromFS(assets iofs.FS) (string, error) { return path, nil } + +func checkPortIsOpen(host string, timeout time.Duration, waitCB func()) (ret bool) { + if timeout == 0 { + timeout = time.Minute + } + + deadline := time.Now().Add(timeout) + for time.Now().Before(deadline) { + conn, _ := net.DialTimeout("tcp", host, 2*time.Second) + if conn != nil { + conn.Close() + return true + } + + waitCB() + time.Sleep(1 * time.Second) + } + return false +} diff --git a/v2/internal/frontend/devserver/devserver.go b/v2/internal/frontend/devserver/devserver.go index 47dde2953..35b67e86a 100644 --- a/v2/internal/frontend/devserver/devserver.go +++ b/v2/internal/frontend/devserver/devserver.go @@ -10,13 +10,11 @@ import ( "encoding/json" "fmt" "log" - "net" "net/http" "net/http/httputil" "net/url" "strings" "sync" - "time" "github.com/wailsapp/wails/v2/pkg/assetserver" @@ -67,7 +65,6 @@ func (d *DevWebServer) Run(ctx context.Context) error { myLogger = _logger.(*logger.Logger) } - var assetHandler http.Handler var wsHandler http.Handler _fronendDevServerURL, _ := ctx.Value("frontenddevserverurl").(string) @@ -77,33 +74,23 @@ func (d *DevWebServer) Run(ctx context.Context) error { return c.String(http.StatusOK, assetdir) }) - var err error - assetHandler, err = assetserver.NewAssetHandler(assetServerConfig, myLogger) - if err != nil { - log.Fatal(err) - } } else { externalURL, err := url.Parse(_fronendDevServerURL) if err != nil { return err } - if externalURL.Host == "" { - return fmt.Errorf("Invalid frontend:dev:serverUrl missing protocol scheme?") - } - - waitCb := func() { d.LogDebug("Waiting for frontend DevServer '%s' to be ready", externalURL) } - if !checkPortIsOpen(externalURL.Host, time.Minute, waitCb) { - d.logger.Error("Timeout waiting for frontend DevServer") - } - - assetHandler = newExternalDevServerAssetHandler(d.logger, externalURL, assetServerConfig) // WebSockets aren't currently supported in prod mode, so a WebSocket connection is the result of the // FrontendDevServer e.g. Vite to support auto reloads. // Therefore we direct WebSockets directly to the FrontendDevServer instead of returning a NotImplementedStatus. wsHandler = httputil.NewSingleHostReverseProxy(externalURL) } + assetHandler, err := assetserver.NewAssetHandler(assetServerConfig, myLogger) + if err != nil { + log.Fatal(err) + } + // Setup internal dev server bindingsJSON, err := d.appBindings.ToJSON() if err != nil { @@ -307,22 +294,3 @@ func NewFrontend(ctx context.Context, appoptions *options.App, myLogger *logger. result.server.HidePort = true return result } - -func checkPortIsOpen(host string, timeout time.Duration, waitCB func()) (ret bool) { - if timeout == 0 { - timeout = time.Minute - } - - deadline := time.Now().Add(timeout) - for time.Now().Before(deadline) { - conn, _ := net.DialTimeout("tcp", host, 2*time.Second) - if conn != nil { - conn.Close() - return true - } - - waitCB() - time.Sleep(1 * time.Second) - } - return false -} diff --git a/v2/internal/frontend/devserver/external.go b/v2/pkg/assetserver/assethandler_external.go similarity index 68% rename from v2/internal/frontend/devserver/external.go rename to v2/pkg/assetserver/assethandler_external.go index fd717e723..588b350f5 100644 --- a/v2/internal/frontend/devserver/external.go +++ b/v2/pkg/assetserver/assethandler_external.go @@ -1,7 +1,7 @@ //go:build dev // +build dev -package devserver +package assetserver import ( "errors" @@ -10,21 +10,12 @@ import ( "net/http/httputil" "net/url" - "github.com/wailsapp/wails/v2/internal/logger" "github.com/wailsapp/wails/v2/pkg/options/assetserver" ) -func newExternalDevServerAssetHandler(logger *logger.Logger, url *url.URL, options assetserver.Options) http.Handler { - handler := newExternalAssetsHandler(logger, url, options.Handler) +func NewExternalAssetsHandler(logger Logger, options assetserver.Options, url *url.URL) http.Handler { + baseHandler := options.Handler - if middleware := options.Middleware; middleware != nil { - handler = middleware(handler) - } - - return handler -} - -func newExternalAssetsHandler(logger *logger.Logger, url *url.URL, handler http.Handler) http.Handler { errSkipProxy := fmt.Errorf("skip proxying") proxy := httputil.NewSingleHostReverseProxy(url) @@ -37,7 +28,7 @@ func newExternalAssetsHandler(logger *logger.Logger, url *url.URL, handler http. } proxy.ModifyResponse = func(res *http.Response) error { - if handler == nil { + if baseHandler == nil { return nil } @@ -53,11 +44,11 @@ func newExternalAssetsHandler(logger *logger.Logger, url *url.URL, handler http. } proxy.ErrorHandler = func(rw http.ResponseWriter, r *http.Request, err error) { - if handler != nil && errors.Is(err, errSkipProxy) { + if baseHandler != nil && errors.Is(err, errSkipProxy) { if logger != nil { - logger.Debug("[ExternalAssetHandler] Loading '%s' failed, using AssetHandler", r.URL) + logger.Debug("[ExternalAssetHandler] Loading '%s' failed, using original AssetHandler", r.URL) } - handler.ServeHTTP(rw, r) + baseHandler.ServeHTTP(rw, r) } else { if logger != nil { logger.Error("[ExternalAssetHandler] Proxy error: %v", err) @@ -66,18 +57,24 @@ func newExternalAssetsHandler(logger *logger.Logger, url *url.URL, handler http. } } - return http.HandlerFunc( + var result http.Handler = http.HandlerFunc( func(rw http.ResponseWriter, req *http.Request) { if req.Method == http.MethodGet { proxy.ServeHTTP(rw, req) return } - if handler != nil { - handler.ServeHTTP(rw, req) + if baseHandler != nil { + baseHandler.ServeHTTP(rw, req) return } rw.WriteHeader(http.StatusMethodNotAllowed) }) + + if middleware := options.Middleware; middleware != nil { + result = middleware(result) + } + + return result } diff --git a/v2/pkg/templates/templates/svelte-ts/frontend/package.json b/v2/pkg/templates/templates/svelte-ts/frontend/package.json index 8bbb15b1b..2ee69eaf5 100644 --- a/v2/pkg/templates/templates/svelte-ts/frontend/package.json +++ b/v2/pkg/templates/templates/svelte-ts/frontend/package.json @@ -17,6 +17,6 @@ "svelte-preprocess": "^4.10.7", "tslib": "^2.4.0", "typescript": "^4.6.4", - "vite": "^3.0.0" + "vite": "^3.0.7" } } \ No newline at end of file diff --git a/v2/pkg/templates/templates/svelte/frontend/package.json b/v2/pkg/templates/templates/svelte/frontend/package.json index 8a9354150..8c9ae62a8 100644 --- a/v2/pkg/templates/templates/svelte/frontend/package.json +++ b/v2/pkg/templates/templates/svelte/frontend/package.json @@ -11,6 +11,6 @@ "devDependencies": { "@sveltejs/vite-plugin-svelte": "^1.0.1", "svelte": "^3.49.0", - "vite": "^3.0.0" + "vite": "^3.0.7" } } \ No newline at end of file diff --git a/v2/pkg/templates/templates/vanilla-ts/frontend/package.json b/v2/pkg/templates/templates/vanilla-ts/frontend/package.json index 37305b4c0..c57eb8610 100644 --- a/v2/pkg/templates/templates/vanilla-ts/frontend/package.json +++ b/v2/pkg/templates/templates/vanilla-ts/frontend/package.json @@ -9,6 +9,6 @@ }, "devDependencies": { "typescript": "^4.5.4", - "vite": "^2.9.9" + "vite": "^3.0.7" } } \ No newline at end of file diff --git a/v2/pkg/templates/templates/vanilla/frontend/package.json b/v2/pkg/templates/templates/vanilla/frontend/package.json index 4ac881798..a1b6f8e1a 100644 --- a/v2/pkg/templates/templates/vanilla/frontend/package.json +++ b/v2/pkg/templates/templates/vanilla/frontend/package.json @@ -8,6 +8,6 @@ "preview": "vite preview" }, "devDependencies": { - "vite": "^2.9.9" + "vite": "^3.0.7" } } \ No newline at end of file diff --git a/website/src/pages/changelog.mdx b/website/src/pages/changelog.mdx index 0a0ab8359..7b596377b 100644 --- a/website/src/pages/changelog.mdx +++ b/website/src/pages/changelog.mdx @@ -14,6 +14,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Breaking Changes + +- `wails dev` now uses the custom schemes `wails://` on macOS and Linux if Vite >= `v3.0.0` is used. This makes the dev application consistent in behaviour with the final production application and fixes some long-standing inconsistencies. Changed by @stffabi in [PR](https://github.com/wailsapp/wails/pull/2610) + ### Added - Added Nodejs version in `wails doctor`. Added by @misitebao in [PR](https://github.com/wailsapp/wails/pull/2546) From 3547b4d0101d2a33f69c2f9efbb11c3a41e76631 Mon Sep 17 00:00:00 2001 From: stffabi Date: Thu, 20 Apr 2023 12:38:32 +0200 Subject: [PATCH 04/28] [v2, darwin] Add some missing default shortcuts (#2586) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [v2, darwin] Add "Hide, Hide Others, Show All“ to appmenu This also includes shortcuts support for those commands. Arrange the menu items in the well known MacOS order. * [v2, darwin] Add Window menu with well known shortcuts Minimize, Full-Screen and Zoom. --- v2/internal/frontend/desktop/darwin/Role.h | 1 + .../frontend/desktop/darwin/WailsMenu.m | 25 ++++++++++++++++--- v2/pkg/menu/menuroles.go | 9 ++++--- v2/pkg/options/options.go | 10 +++++--- website/src/pages/changelog.mdx | 2 ++ 5 files changed, 38 insertions(+), 9 deletions(-) diff --git a/v2/internal/frontend/desktop/darwin/Role.h b/v2/internal/frontend/desktop/darwin/Role.h index 20e670689..6b8877a09 100644 --- a/v2/internal/frontend/desktop/darwin/Role.h +++ b/v2/internal/frontend/desktop/darwin/Role.h @@ -12,5 +12,6 @@ typedef int Role; static const Role AppMenu = 1; static const Role EditMenu = 2; +static const Role WindowMenu = 3; #endif /* Role_h */ diff --git a/v2/internal/frontend/desktop/darwin/WailsMenu.m b/v2/internal/frontend/desktop/darwin/WailsMenu.m index af03ca6b9..66e5dd399 100644 --- a/v2/internal/frontend/desktop/darwin/WailsMenu.m +++ b/v2/internal/frontend/desktop/darwin/WailsMenu.m @@ -68,12 +68,20 @@ appName = [[NSProcessInfo processInfo] processName]; } WailsMenu *appMenu = [[[WailsMenu new] initWithNSTitle:appName] autorelease]; + + if (ctx.aboutTitle != nil) { + [appMenu addItem:[self newMenuItemWithContext :ctx :[@"About " stringByAppendingString:appName] :@selector(About) :nil :0]]; + [appMenu addItem:[NSMenuItem separatorItem]]; + } + + [appMenu addItem:[self newMenuItem:[@"Hide " stringByAppendingString:appName] :@selector(hide:) :@"h" :NSEventModifierFlagCommand]]; + [appMenu addItem:[self newMenuItem:@"Hide Others" :@selector(hideOtherApplications:) :@"h" :(NSEventModifierFlagOption | NSEventModifierFlagCommand)]]; + [appMenu addItem:[self newMenuItem:@"Show All" :@selector(unhideAllApplications:) :@""]]; + [appMenu addItem:[NSMenuItem separatorItem]]; + id quitTitle = [@"Quit " stringByAppendingString:appName]; NSMenuItem* quitMenuItem = [self newMenuItem:quitTitle :@selector(Quit) :@"q" :NSEventModifierFlagCommand]; quitMenuItem.target = ctx; - if (ctx.aboutTitle != nil) { - [appMenu addItem:[self newMenuItemWithContext :ctx :[@"About " stringByAppendingString:appName] :@selector(About) :nil :0]]; - } [appMenu addItem:quitMenuItem]; [self appendSubmenu:appMenu]; break; @@ -100,6 +108,17 @@ [editMenu appendSubmenu:speechMenu]; [self appendSubmenu:editMenu]; + break; + } + case WindowMenu: + { + WailsMenu *windowMenu = [[[WailsMenu new] initWithNSTitle:@"Window"] autorelease]; + [windowMenu addItem:[self newMenuItem:@"Minimize" :@selector(performMiniaturize:) :@"m" :NSEventModifierFlagCommand]]; + [windowMenu addItem:[self newMenuItem:@"Zoom" :@selector(performZoom:) :@""]]; + [windowMenu addItem:[NSMenuItem separatorItem]]; + [windowMenu addItem:[self newMenuItem:@"Full Screen" :@selector(enterFullScreenMode:) :@"f" :(NSEventModifierFlagControl | NSEventModifierFlagCommand)]]; + [self appendSubmenu:windowMenu]; + break; } } diff --git a/v2/pkg/menu/menuroles.go b/v2/pkg/menu/menuroles.go index 62a193c8e..e6b15b243 100644 --- a/v2/pkg/menu/menuroles.go +++ b/v2/pkg/menu/menuroles.go @@ -8,8 +8,9 @@ type Role int // These constants need to be kept in sync with `v2/internal/frontend/desktop/darwin/Role.h` const ( - AppMenuRole Role = 1 - EditMenuRole = 2 + AppMenuRole Role = 1 + EditMenuRole = 2 + WindowMenuRole = 3 //AboutRole Role = "about" //UndoRole Role = "undo" //RedoRole Role = "redo" @@ -142,14 +143,16 @@ func ViewMenu() *MenuItem { Role: ViewMenuRole, } } +*/ // WindowMenu provides a MenuItem with the whole default "Window" menu (Minimize, Zoom, etc.). +// On MacOS currently all options in there won't work if the window is frameless. func WindowMenu() *MenuItem { return &MenuItem{ Role: WindowMenuRole, } } -*/ + // These roles are Mac only // AppMenu provides a MenuItem with the whole default "App" menu (About, Services, etc.) diff --git a/v2/pkg/options/options.go b/v2/pkg/options/options.go index 204a267c6..74b2aef72 100644 --- a/v2/pkg/options/options.go +++ b/v2/pkg/options/options.go @@ -160,10 +160,14 @@ func processMenus(appoptions *App) { switch runtime.GOOS { case "darwin": if appoptions.Menu == nil { - appoptions.Menu = menu.NewMenuFromItems( - menu.AppMenu(), + items := []*menu.MenuItem{ menu.EditMenu(), - ) + } + if !appoptions.Frameless { + items = append(items, menu.WindowMenu()) // Current options in Window Menu only work if not frameless + } + + appoptions.Menu = menu.NewMenuFromItems(menu.AppMenu(), items...) } } } diff --git a/website/src/pages/changelog.mdx b/website/src/pages/changelog.mdx index 7b596377b..eb69875ff 100644 --- a/website/src/pages/changelog.mdx +++ b/website/src/pages/changelog.mdx @@ -22,6 +22,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added Nodejs version in `wails doctor`. Added by @misitebao in [PR](https://github.com/wailsapp/wails/pull/2546) - Added support for WebKit2GTK 2.40+ on Linux. This brings additional features for the [AssetServer](/docs/reference/options#assetserver), like support for HTTP Request Bodies. The app must be compiled with the Go build tag `webkit2_40` to activate support for this features. This also bumps the minimum requirement of WebKit2GTK to 2.40 for your app. Added by @stffabi in this [PR](https://github.com/wailsapp/wails/pull/2592) +- macOS: Added Window menu role with well known shortcuts "Minimize, Full-Screen and Zoom". Added by @stffabi in [PR](https://github.com/wailsapp/wails/pull/2586) +- macOS: Added "Hide, Hide Others, Show All“ to appmenu. Added by @stffabi in [PR](https://github.com/wailsapp/wails/pull/2586) ### Changed From 9bfe3094dd89fff6f5847bad1e8c0413a16ac530 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Wed, 26 Apr 2023 21:06:41 +1000 Subject: [PATCH 05/28] [windows] WIP --- v3/go.mod | 1 + v3/go.sum | 2 + v3/internal/w32/LICENSE | 48 + v3/internal/w32/README.md | 20 + v3/internal/w32/com.go | 251 + v3/internal/w32/constants.go | 4875 ++++++++++++++++++ v3/internal/w32/functions.go | 4794 +++++++++++++++++ v3/internal/w32/functions_386.go | 29 + v3/internal/w32/functions_amd64.go | 43 + v3/internal/w32/functions_arm64.go | 43 + v3/internal/w32/types.go | 1297 +++++ v3/pkg/application/application.go | 8 +- v3/pkg/application/application_windows.go | 74 +- v3/pkg/application/menu.go | 11 - v3/pkg/application/menu_darwin.go | 11 + v3/pkg/application/menu_windows.go | 10 + v3/pkg/application/options_webview_window.go | 1 + v3/pkg/application/options_windows.go | 5 + v3/pkg/application/roles.go | 11 +- v3/pkg/application/webview_window_windows.go | 43 +- 20 files changed, 11551 insertions(+), 26 deletions(-) create mode 100644 v3/internal/w32/LICENSE create mode 100644 v3/internal/w32/README.md create mode 100644 v3/internal/w32/com.go create mode 100644 v3/internal/w32/constants.go create mode 100644 v3/internal/w32/functions.go create mode 100644 v3/internal/w32/functions_386.go create mode 100644 v3/internal/w32/functions_amd64.go create mode 100644 v3/internal/w32/functions_arm64.go create mode 100644 v3/internal/w32/types.go create mode 100644 v3/pkg/application/options_windows.go diff --git a/v3/go.mod b/v3/go.mod index 4ffb85ce6..84496cb50 100644 --- a/v3/go.mod +++ b/v3/go.mod @@ -4,6 +4,7 @@ go 1.19 require ( github.com/go-task/task/v3 v3.20.0 + github.com/gonutz/w32/v2 v2.7.0 github.com/google/go-cmp v0.5.9 github.com/jackmordaunt/icns/v2 v2.2.1 github.com/json-iterator/go v1.1.12 diff --git a/v3/go.sum b/v3/go.sum index ff474ab93..5cd5efb99 100644 --- a/v3/go.sum +++ b/v3/go.sum @@ -27,6 +27,8 @@ github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8Wd github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/task/v3 v3.20.0 h1:pTavuhP+AiEpKLzh5I6Lja9Ux7ypYO5QMsEPTbhYEDc= github.com/go-task/task/v3 v3.20.0/go.mod h1:y7rWakbLR5gFElGgo6rA2dyr6vU/zNIDVfn3S4Of6OI= +github.com/gonutz/w32/v2 v2.7.0 h1:O9lx/5tZ+WjZdxdvQFTh+/kP/7y95YCaL5MHqPrIHn4= +github.com/gonutz/w32/v2 v2.7.0/go.mod h1:MgtHx0AScDVNKyB+kjyPder4xIi3XAcHS6LDDU2DmdE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= diff --git a/v3/internal/w32/LICENSE b/v3/internal/w32/LICENSE new file mode 100644 index 000000000..2a1db3e94 --- /dev/null +++ b/v3/internal/w32/LICENSE @@ -0,0 +1,48 @@ +The MIT License (MIT) + +Copyright (c) 2021 gonutz + +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. + + +This is the license from the original fork that this library is based on: + +Copyright (c) 2010-2012 The w32 Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/v3/internal/w32/README.md b/v3/internal/w32/README.md new file mode 100644 index 000000000..b67af00ab --- /dev/null +++ b/v3/internal/w32/README.md @@ -0,0 +1,20 @@ + +This is a fork of [gonutz/w32](https://github.com/gonutz/w32). + +----------------------- + +About w32 +========== + +w32 is a wrapper for a number of Windows APIs for the [Go Programming Language](https://golang.org/). + +This library has no other dependencies and you need no C-compiler, it is written in pure Go. Some function signatures have been adapted to make them work in Go, e.g. functions that take a pointer to an array and a count of items in C will now simply accept a slice in Go. + +If you miss any Windows API functions, just write an issue or create a pull request, the Win32 API is very large and has many rarely used functions in it so this wrapper is supposed to grow as needed by the Go community. + +Installation +============ + +Get the latest version with: + + go get github.com/gonutz/w32/v2 diff --git a/v3/internal/w32/com.go b/v3/internal/w32/com.go new file mode 100644 index 000000000..8542af1b1 --- /dev/null +++ b/v3/internal/w32/com.go @@ -0,0 +1,251 @@ +package w32 + +import ( + "errors" + "syscall" + "unicode/utf16" + "unsafe" +) + +type pIUnknownVtbl struct { + queryInterface uintptr + addRef uintptr + release uintptr +} + +type IUnknown struct { + lpVtbl *pIUnknownVtbl +} + +func (u *IUnknown) QueryInterface(id *GUID) (*IDispatch, HRESULT) { + return ComQueryInterface(u, id) +} + +func (u *IUnknown) AddRef() int32 { + return ComAddRef(u) +} + +func (u *IUnknown) Release() int32 { + return ComRelease(u) +} + +type pIDispatchVtbl struct { + queryInterface uintptr + addRef uintptr + release uintptr + getTypeInfoCount uintptr + getTypeInfo uintptr + getIDsOfNames uintptr + invoke uintptr +} + +type IDispatch struct { + lpVtbl *pIDispatchVtbl +} + +func (d *IDispatch) QueryInterface(id *GUID) (*IDispatch, HRESULT) { + return ComQueryInterface((*IUnknown)(unsafe.Pointer(d)), id) +} + +func (d *IDispatch) AddRef() int32 { + return ComAddRef((*IUnknown)(unsafe.Pointer(d))) +} + +func (d *IDispatch) Release() int32 { + return ComRelease((*IUnknown)(unsafe.Pointer(d))) +} + +func (d *IDispatch) GetIDsOfName(names []string) ([]int32, HRESULT) { + return ComGetIDsOfName(d, names) +} + +func (d *IDispatch) Invoke(dispid int32, dispatch int16, params ...interface{}) (*VARIANT, error) { + return ComInvoke(d, dispid, dispatch, params...) +} + +type pIStreamVtbl struct { + qeryInterface uintptr + addRef uintptr + release uintptr +} + +type IStream struct { + lpVtbl *pIStreamVtbl +} + +func (s *IStream) QueryInterface(id *GUID) (*IDispatch, HRESULT) { + return ComQueryInterface((*IUnknown)(unsafe.Pointer(s)), id) +} + +func (s *IStream) AddRef() int32 { + return ComAddRef((*IUnknown)(unsafe.Pointer(s))) +} + +func (s *IStream) Release() int32 { + return ComRelease((*IUnknown)(unsafe.Pointer(s))) +} + +func ComAddRef(unknown *IUnknown) int32 { + ret, _, _ := syscall.Syscall(unknown.lpVtbl.addRef, 1, + uintptr(unsafe.Pointer(unknown)), + 0, + 0) + return int32(ret) +} + +func ComRelease(unknown *IUnknown) int32 { + ret, _, _ := syscall.Syscall(unknown.lpVtbl.release, 1, + uintptr(unsafe.Pointer(unknown)), + 0, + 0) + return int32(ret) +} + +func ComQueryInterface(unknown *IUnknown, id *GUID) (*IDispatch, HRESULT) { + var disp *IDispatch + hr, _, _ := syscall.Syscall(unknown.lpVtbl.queryInterface, 3, + uintptr(unsafe.Pointer(unknown)), + uintptr(unsafe.Pointer(id)), + uintptr(unsafe.Pointer(&disp)), + ) + return disp, HRESULT(hr) +} + +func ComGetIDsOfName(disp *IDispatch, names []string) ([]int32, HRESULT) { + 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.getIDsOfNames, 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])), + ) + return dispid, HRESULT(hr) +} + +func ComInvoke(disp *IDispatch, dispid int32, dispatch int16, params ...interface{}) (result *VARIANT, err error) { + 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 + 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: + return nil, errors.New("w32.ComInvoke: unknown variant 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.invoke, 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) + return nil, errors.New(bs) + } + } + for _, varg := range vargs { + if varg.VT == VT_BSTR && varg.Val != 0 { + SysFreeString(((*int16)(unsafe.Pointer(uintptr(varg.Val))))) + } + } + result = &ret + return +} + +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 "" +} diff --git a/v3/internal/w32/constants.go b/v3/internal/w32/constants.go new file mode 100644 index 000000000..3c4ba53c7 --- /dev/null +++ b/v3/internal/w32/constants.go @@ -0,0 +1,4875 @@ +package w32 + +// TODO Check that these messages are correct: +// WM_* +// TTM_* +// TBM_* + +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_ALREADY_EXISTS = 183 + 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 +) + +// 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_SHIELD = 32518 + 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 +) + +// Button state constants +const ( + BST_CHECKED = 1 + BST_INDETERMINATE = 2 + BST_UNCHECKED = 0 + BST_FOCUS = 8 + BST_PUSHED = 4 +) + +// Combo box style constants +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 +) + +// Combo box message constants +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 + CB_MSGMAX = 0x0165 +) + +// Combo box return values +const ( + CB_OKAY = 0 + CB_ERR = -1 + CB_ERRSPACE = -2 +) + +// Combo box notification codes +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 +) + +// List box message constants +const ( + LB_ADDSTRING = 384 + LB_INSERTSTRING = 385 + LB_DELETESTRING = 386 + LB_SELITEMRANGEEX = 387 + LB_RESETCONTENT = 388 + LB_SETSEL = 389 + LB_SETCURSEL = 390 + LB_GETSEL = 391 + LB_GETCURSEL = 392 + LB_GETTEXT = 393 + LB_GETTEXTLEN = 394 + LB_GETCOUNT = 395 + LB_SELECTSTRING = 396 + LB_DIR = 397 + LB_GETTOPINDEX = 398 + LB_FINDSTRING = 399 + LB_GETSELCOUNT = 400 + LB_GETSELITEMS = 401 + LB_SETTABSTOPS = 402 + LB_GETHORIZONTALEXTENT = 403 + LB_SETHORIZONTALEXTENT = 404 + LB_SETCOLUMNWIDTH = 405 + LB_ADDFILE = 406 + LB_SETTOPINDEX = 407 + LB_GETITEMRECT = 408 + LB_GETITEMDATA = 409 + LB_SETITEMDATA = 410 + LB_SELITEMRANGE = 411 + LB_SETANCHORINDEX = 412 + LB_GETANCHORINDEX = 413 + LB_SETCARETINDEX = 414 + LB_GETCARETINDEX = 415 + LB_SETITEMHEIGHT = 416 + LB_GETITEMHEIGHT = 417 + LB_FINDSTRINGEXACT = 418 + LB_SETLOCALE = 421 + LB_GETLOCALE = 422 + LB_SETCOUNT = 423 + LB_INITSTORAGE = 424 + LB_ITEMFROMPOINT = 425 + LB_SETTEXT = 426 + LB_GETCHECKMARK = 427 + LB_SETCHECKMARK = 428 + LB_GETITEMADDDATA = 429 + LB_SETITEMADDDATA = 430 +) + +// List box styles +const ( + LBS_NOTIFY = 0x0001 + LBS_SORT = 0x0002 + LBS_NOREDRAW = 0x0004 + LBS_MULTIPLESEL = 0x0008 + LBS_OWNERDRAWFIXED = 0x0010 + LBS_OWNERDRAWVARIABLE = 0x0020 + LBS_HASSTRINGS = 0x0040 + LBS_USETABSTOPS = 0x0080 + LBS_NOINTEGRALHEIGHT = 0x0100 + LBS_MULTICOLUMN = 0x0200 + LBS_WANTKEYBOARDINPUT = 0x0400 + LBS_EXTENDEDSEL = 0x0800 + LBS_STANDARD = LBS_NOTIFY | LBS_SORT | WS_VSCROLL | WS_BORDER + LBS_CHECKBOX = 0x1000 + LBS_USEICON = 0x2000 + LBS_AUTOCHECK = 0x4000 + LBS_AUTOCHECKBOX = 0x5000 + LBS_PRELOADED = 0x4000 + LBS_COMBOLBOX = 0x8000 +) + +// List box notification messages +const ( + LBN_ERRSPACE = -2 + LBN_SELCHANGE = 1 + LBN_DBLCLK = 2 + LBN_SELCANCEL = 3 + LBN_SETFOCUS = 4 + LBN_KILLFOCUS = 5 + LBN_CLICKCHECKMARK = 6 +) + +// List box return values +const ( + LB_OKAY = 0 + LB_ERR = -1 + LB_ERRSPACE = -2 +) + +// Predefined color/brush constants. +const ( + // Scroll bar gray area. + COLOR_SCROLLBAR = 0 + + // Desktop. + COLOR_BACKGROUND = 1 + + // Desktop. + COLOR_DESKTOP = 1 + + // Active window title bar. The associated foreground color is + // COLOR_CAPTIONTEXT. Specifies the left side color in the color gradient of + // an active window's title bar if the gradient effect is enabled. + COLOR_ACTIVECAPTION = 2 + + // Inactive window caption. + // The associated foreground color is COLOR_INACTIVECAPTIONTEXT. + // Specifies the left side color in the color gradient of an inactive window's title bar if the gradient effect is enabled. + COLOR_INACTIVECAPTION = 3 + + // Menu background. The associated foreground color is COLOR_MENUTEXT. + COLOR_MENU = 4 + + // Window background. The associated foreground colors are COLOR_WINDOWTEXT + // and COLOR_HOTLITE. + COLOR_WINDOW = 5 + + // Window frame. + COLOR_WINDOWFRAME = 6 + + // Text in menus. The associated background color is COLOR_MENU. + COLOR_MENUTEXT = 7 + + // Text in windows. The associated background color is COLOR_WINDOW. + COLOR_WINDOWTEXT = 8 + + // Text in caption, size box, and scroll bar arrow box. The associated + // background color is COLOR_ACTIVECAPTION. + COLOR_CAPTIONTEXT = 9 + + // Active window border. + COLOR_ACTIVEBORDER = 10 + + // Inactive window border. + COLOR_INACTIVEBORDER = 11 + + // Background color of multiple document interface (MDI) applications. + COLOR_APPWORKSPACE = 12 + + // Item(s) selected in a control. The associated foreground color is + // COLOR_HIGHLIGHTTEXT. + COLOR_HIGHLIGHT = 13 + + // Text of item(s) selected in a control. The associated background color is + // COLOR_HIGHLIGHT. + COLOR_HIGHLIGHTTEXT = 14 + + // Face color for three-dimensional display elements and for dialog box + // backgrounds. + COLOR_3DFACE = 15 + + // Face color for three-dimensional display elements and for dialog box + // backgrounds. The associated foreground color is COLOR_BTNTEXT. + COLOR_BTNFACE = 15 + + // Shadow color for three-dimensional display elements (for edges facing + // away from the light source). + COLOR_3DSHADOW = 16 + + // Shadow color for three-dimensional display elements (for edges facing + // away from the light source). + COLOR_BTNSHADOW = 16 + + // Grayed (disabled) text. This color is set to 0 if the current display + // driver does not support a solid gray color. + COLOR_GRAYTEXT = 17 + + // Text on push buttons. The associated background color is COLOR_BTNFACE. + COLOR_BTNTEXT = 18 + + // Color of text in an inactive caption. The associated background color is + // COLOR_INACTIVECAPTION. + COLOR_INACTIVECAPTIONTEXT = 19 + + // Highlight color for three-dimensional display elements (for edges facing + // the light source.) + COLOR_3DHIGHLIGHT = 20 + + // Highlight color for three-dimensional display elements (for edges facing + // the light source.) + COLOR_3DHILIGHT = 20 + + // Highlight color for three-dimensional display elements (for edges facing + // the light source.) + COLOR_BTNHIGHLIGHT = 20 + + // Highlight color for three-dimensional display elements (for edges facing + // the light source.) + COLOR_BTNHILIGHT = 20 + + // Dark shadow for three-dimensional display elements. + COLOR_3DDKSHADOW = 21 + + // Light color for three-dimensional display elements (for edges facing the + // light source.) + COLOR_3DLIGHT = 22 + + // Text color for tooltip controls. The associated background color is + // COLOR_INFOBK. + COLOR_INFOTEXT = 23 + + // Background color for tooltip controls. The associated foreground color is + // COLOR_INFOTEXT. + COLOR_INFOBK = 24 + + // Color for a hyperlink or hot-tracked item. The associated background + // color is COLOR_WINDOW. + COLOR_HOTLIGHT = 26 + + // Right side color in the color gradient of an active window's title bar. + // COLOR_ACTIVECAPTION specifies the left side color. Use + // SPI_GETGRADIENTCAPTIONS with the SystemParametersInfo function to + // determine whether the gradient effect is enabled. + COLOR_GRADIENTACTIVECAPTION = 27 + + // Right side color in the color gradient of an inactive window's title bar. + // COLOR_INACTIVECAPTION specifies the left side color. + COLOR_GRADIENTINACTIVECAPTION = 28 + + // The color used to highlight menu items when the menu appears as a flat + // menu (see SystemParametersInfo). The highlighted menu item is outlined + // with COLOR_HIGHLIGHT. Windows 2000: This value is not supported. + COLOR_MENUHILIGHT = 29 + + // The background color for the menu bar when menus appear as flat menus + // (see SystemParametersInfo). However, COLOR_MENU continues to specify the + // background color of the menu popup. Windows 2000: This value is not + // supported. + COLOR_MENUBAR = 30 +) + +// 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 +) + +// 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_LAYOUTRTL = 0x00400000 + WS_EX_COMPOSITED = 0x02000000 + 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 = 265 + 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_MOUSEHWHEEL = 526 + WM_MOUSEFIRST = 512 + WM_XBUTTONDOWN = 523 + WM_XBUTTONUP = 524 + WM_XBUTTONDBLCLK = 525 + WM_MOUSELAST = 526 + 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 + LF_FULLFACESIZE = 64 +) + +const ( + MM_MAX_NUMAXES = 16 + MM_MAX_AXES_NAMELEN = 16 +) + +// 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 + EM_AUTOURLDETECT = 0x45B + EM_CANPASTE = 0x432 + EM_CANREDO = 0x455 + EM_DISPLAYBAND = 0x433 + EM_EXGETSEL = 0x434 + EM_EXLIMITTEXT = 0x435 + EM_EXLINEFROMCHAR = 0x436 + EM_EXSETSEL = 0x437 + EM_FINDTEXT = 0x438 + EM_FINDTEXTEX = 0x44F + EM_FINDTEXTEXW = 0x47C + EM_FINDTEXTW = 0x47B + EM_FINDWORDBREAK = 0x44C + EM_FORMATRANGE = 0x439 + EM_GETAUTOURLDETECT = 0x45C + EM_GETBIDIOPTIONS = 0x4C9 + EM_GETCHARFORMAT = 0x43A + EM_GETEDITSTYLE = 0x4CD + EM_GETEVENTMASK = 0x43B + EM_GETIMECOLOR = 0x469 + EM_GETIMECOMPMODE = 0x47A + EM_GETIMEOPTIONS = 0x46B + EM_GETLANGOPTIONS = 0x479 + EM_GETOLEINTERFACE = 0x43C + EM_GETOPTIONS = 0x44E + EM_GETPARAFORMAT = 0x43D + EM_GETPUNCTUATION = 0x465 + EM_GETREDONAME = 0x457 + EM_GETSCROLLPOS = 0x4DD + EM_GETSELTEXT = 0x43E + EM_GETTEXTEX = 0x45E + EM_GETTEXTLENGTHEX = 0x45F + EM_GETTEXTMODE = 0x45A + EM_GETTEXTRANGE = 0x44B + EM_GETTYPOGRAPHYOPTIONS = 0x4CB + EM_GETUNDONAME = 0x456 + EM_GETWORDBREAKPROCEX = 0x450 + EM_GETWORDWRAPMODE = 0x467 + EM_GETZOOM = 0x4E0 + EM_HIDESELECTION = 0x43F + EM_PASTESPECIAL = 0x440 + EM_RECONVERSION = 0x47D + EM_REDO = 0x454 + EM_REQUESTRESIZE = 0x441 + EM_SELECTIONTYPE = 0x442 + EM_SETBIDIOPTIONS = 0x4C8 + EM_SETBKGNDCOLOR = 0x443 + EM_SETCHARFORMAT = 0x444 + EM_SETEDITSTYLE = 0x4CC + EM_SETEVENTMASK = 0x445 + EM_SETFONTSIZE = 0x4DF + EM_SETIMECOLOR = 0x468 + EM_SETIMEOPTIONS = 0x46A + EM_SETLANGOPTIONS = 0x478 + EM_SETOLECALLBACK = 0x446 + EM_SETOPTIONS = 0x44D + EM_SETPALETTE = 0x45D + EM_SETPARAFORMAT = 0x447 + EM_SETPUNCTUATION = 0x464 + EM_SETSCROLLPOS = 0x4DE + EM_SETTARGETDEVICE = 0x448 + EM_SETTEXTEX = 0x461 + EM_SETTEXTMODE = 0x459 + EM_SETTYPOGRAPHYOPTIONS = 0x4CA + EM_SETUNDOLIMIT = 0x452 + EM_SETWORDBREAKPROCEX = 0x451 + EM_SETWORDWRAPMODE = 0x466 + EM_SETZOOM = 0x4E1 + EM_SHOWSCROLLBAR = 0x460 + EM_STOPGROUPTYPING = 0x458 + EM_STREAMIN = 0x449 + EM_STREAMOUT = 0x44A +) + +const ( + CCM_FIRST = 0x2000 + CCM_LAST = CCM_FIRST + 0x0200 + CCM_SETBKCOLOR = CCM_FIRST + 1 + CCM_SETCOLORSCHEME = CCM_FIRST + 2 + CCM_GETCOLORSCHEME = CCM_FIRST + 3 + CCM_GETDROPTARGET = CCM_FIRST + 4 + CCM_SETUNICODEFORMAT = CCM_FIRST + 5 + CCM_GETUNICODEFORMAT = CCM_FIRST + 6 + CCM_SETVERSION = CCM_FIRST + 7 + CCM_GETVERSION = CCM_FIRST + 8 + CCM_SETNOTIFYWINDOW = CCM_FIRST + 9 + CCM_SETWINDOWTHEME = CCM_FIRST + 11 + CCM_DPISCALE = CCM_FIRST + 12 +) + +// 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_SETRANGE = WM_USER + 1 + PBM_SETPOS = WM_USER + 2 + PBM_DELTAPOS = WM_USER + 3 + PBM_SETSTEP = WM_USER + 4 + PBM_STEPIT = WM_USER + 5 + PBM_SETRANGE32 = WM_USER + 6 + PBM_GETRANGE = WM_USER + 7 + PBM_GETPOS = WM_USER + 8 + PBM_SETBARCOLOR = WM_USER + 9 + PBM_SETMARQUEE = WM_USER + 10 + PBM_SETBKCOLOR = CCM_SETBKCOLOR +) + +// Progress bar styles. +const ( + PBS_SMOOTH = 0x01 + PBS_VERTICAL = 0x04 + PBS_MARQUEE = 0x08 + PBS_SMOOTHREVERSE = 0x10 +) + +// 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 + MB_TOPMOST = 0x00040000 +) + +// 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 = 97 + 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_REMOTE_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 = 0 + CC_CDECL = 1 + CC_MSCPASCAL = 2 + CC_PASCAL = CC_MSCPASCAL + CC_MACPASCAL = 3 + CC_STDCALL = 4 + CC_FPFASTCALL = 5 + CC_SYSCALL = 6 + CC_MPWCDECL = 7 + CC_MPWPASCAL = 8 + CC_MAX = 9 +) + +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 ( + // https://wiki.winehq.org/List_Of_Windows_Messages + LVM_FIRST = 0x1000 + LVM_GETITEMCOUNT = 0x1004 + LVM_SETIMAGELIST = 0x1003 + LVM_GETIMAGELIST = 0x1002 + LVM_GETITEM = 0x104B + LVM_SETITEM = 0x104C + LVM_INSERTITEM = 0x104D + LVM_DELETEITEM = 0x1008 + LVM_DELETEALLITEMS = 0x1009 + LVM_GETCALLBACKMASK = 0x100A + LVM_SETCALLBACKMASK = 0x100B + LVM_SETUNICODEFORMAT = 0x2005 + LVM_GETNEXTITEM = 0x100C + LVM_FINDITEM = 0x1053 + LVM_GETITEMRECT = 0x100E + LVM_GETSTRINGWIDTH = 0x1057 + LVM_HITTEST = 0x1012 + LVM_ENSUREVISIBLE = 0x1013 + LVM_SCROLL = 0x1014 + LVM_REDRAWITEMS = 0x1015 + LVM_ARRANGE = 0x1016 + LVM_EDITLABEL = 0x1076 + LVM_GETEDITCONTROL = 0x1018 + LVM_GETCOLUMN = 0x105F + LVM_SETCOLUMN = 0x1060 + LVM_INSERTCOLUMN = 0x1061 + LVM_DELETECOLUMN = 0x101C + LVM_GETCOLUMNWIDTH = 0x101D + LVM_SETCOLUMNWIDTH = 0x101E + LVM_GETHEADER = 0x101F + LVM_CREATEDRAGIMAGE = 0x1021 + LVM_GETVIEWRECT = 0x1022 + LVM_GETTEXTCOLOR = 0x1023 + LVM_SETTEXTCOLOR = 0x1024 + LVM_GETTEXTBKCOLOR = 0x1025 + LVM_SETTEXTBKCOLOR = 0x1026 + LVM_GETTOPINDEX = 0x1027 + LVM_GETCOUNTPERPAGE = 0x1028 + LVM_GETORIGIN = 0x1029 + LVM_UPDATE = 0x102A + LVM_SETITEMSTATE = 0x102B + LVM_GETITEMSTATE = 0x102C + LVM_GETITEMTEXT = 0x1073 + LVM_SETITEMTEXT = 0x1074 + LVM_SETITEMCOUNT = 0x102F + LVM_SORTITEMS = 0x1030 + LVM_SETITEMPOSITION32 = 0x1031 + LVM_GETSELECTEDCOUNT = 0x1032 + LVM_GETITEMSPACING = 0x1033 + LVM_GETISEARCHSTRING = 0x1075 + LVM_SETICONSPACING = 0x1035 + LVM_SETEXTENDEDLISTVIEWSTYLE = 0x1036 + LVM_GETEXTENDEDLISTVIEWSTYLE = 0x1037 + LVM_GETSUBITEMRECT = 0x1038 + LVM_SUBITEMHITTEST = 0x1039 + LVM_SETCOLUMNORDERARRAY = 0x103A + LVM_GETCOLUMNORDERARRAY = 0x103B + LVM_SETHOTITEM = 0x103C + LVM_GETHOTITEM = 0x103D + LVM_SETHOTCURSOR = 0x103E + LVM_GETHOTCURSOR = 0x103F + LVM_APPROXIMATEVIEWRECT = 0x1040 + LVM_SETWORKAREAS = 0x1041 + LVM_GETWORKAREAS = 0x1046 + LVM_GETNUMBEROFWORKAREAS = 0x1049 + LVM_GETSELECTIONMARK = 0x1042 + LVM_SETSELECTIONMARK = 0x1043 + LVM_SETHOVERTIME = 0x1047 + LVM_GETHOVERTIME = 0x1048 + LVM_SETTOOLTIPS = 0x104A + LVM_GETTOOLTIPS = 0x104E + LVM_SORTITEMSEX = 0x1051 + LVM_SETBKIMAGE = 0x1044 + LVM_GETBKIMAGE = 0x108B + LVM_SETSELECTEDCOLUMN = 0x108C + LVM_SETVIEW = 0x108E + LVM_GETVIEW = 0x108F + LVM_INSERTGROUP = 0x1091 + LVM_SETGROUPINFO = 0x1093 + LVM_GETGROUPINFO = 0x1095 + LVM_REMOVEGROUP = 0x1096 + LVM_MOVEGROUP = 0x1097 + LVM_GETGROUPCOUNT = 0x1098 + LVM_GETGROUPINFOBYINDEX = 0x1099 + LVM_MOVEITEMTOGROUP = 0x109A + LVM_GETGROUPRECT = 0x1062 + LVM_SETGROUPMETRICS = 0x109B + LVM_GETGROUPMETRICS = 0x109C + LVM_ENABLEGROUPVIEW = 0x109D + LVM_SORTGROUPS = 0x109E + LVM_INSERTGROUPSORTED = 0x109F + LVM_REMOVEALLGROUPS = 0x10A0 + LVM_HASGROUP = 0x10A1 + LVM_GETGROUPSTATE = 0x105C + LVM_GETFOCUSEDGROUP = 0x105D + LVM_SETTILEVIEWINFO = 0x10A2 + LVM_GETTILEVIEWINFO = 0x10A3 + LVM_SETTILEINFO = 0x10A4 + LVM_GETTILEINFO = 0x10A5 + LVM_SETINSERTMARK = 0x10A6 + LVM_GETINSERTMARK = 0x10A7 + LVM_INSERTMARKHITTEST = 0x10A8 + LVM_GETINSERTMARKRECT = 0x10A9 + LVM_SETINSERTMARKCOLOR = 0x10AA + LVM_GETINSERTMARKCOLOR = 0x10AB + LVM_SETINFOTIP = 0x10AD + LVM_GETSELECTEDCOLUMN = 0x10AE + LVM_ISGROUPVIEWENABLED = 0x10AF + LVM_GETOUTLINECOLOR = 0x10B0 + LVM_SETOUTLINECOLOR = 0x10B1 + LVM_CANCELEDITLABEL = 0x10B3 + LVM_MAPINDEXTOID = 0x10B4 + LVM_MAPIDTOINDEX = 0x10B5 + LVM_ISITEMVISIBLE = 0x10B6 + LVM_GETNEXTITEMINDEX = 0x10D3 +) + +// 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 - 50 + LVN_SETDISPINFO = LVN_FIRST - 51 + LVN_KEYDOWN = LVN_FIRST - 55 + LVN_MARQUEEBEGIN = LVN_FIRST - 56 + LVN_GETINFOTIP = LVN_FIRST - 57 + LVN_INCREMENTALSEARCH = LVN_FIRST - 62 + LVN_BEGINSCROLL = LVN_FIRST - 80 + LVN_ENDSCROLL = LVN_FIRST - 81 +) + +// 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 +) + +// 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_IME_ON = 0x16 + VK_JUNJA = 0x17 + VK_FINAL = 0x18 + VK_HANJA = 0x19 + VK_KANJI = 0x19 + VK_IME_OFF = 0x1A + 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_PACKET = 0xE7 + 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 + 4 + TTM_DELTOOL = WM_USER + 5 + TTM_NEWTOOLRECT = WM_USER + 6 + TTM_RELAYEVENT = WM_USER + 7 + TTM_GETTOOLINFO = WM_USER + 8 + TTM_SETTOOLINFO = WM_USER + 9 + TTM_HITTEST = WM_USER + 10 + TTM_GETTEXT = WM_USER + 11 + TTM_UPDATETIPTEXT = WM_USER + 12 + TTM_GETTOOLCOUNT = WM_USER + 13 + TTM_ENUMTOOLS = WM_USER + 14 + TTM_GETCURRENTTOOL = WM_USER + 15 + 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 + 32 + 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 + 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 +) + +// 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 = 1023 +) + +// 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 + +// Flags used by the DwmSetPresentParameters function to specify the frame +// sampling type +const ( + DWM_SOURCE_FRAME_SAMPLING_POINT = 0 + DWM_SOURCE_FRAME_SAMPLING_COVERAGE = 1 + DWM_SOURCE_FRAME_SAMPLING_LAST = 2 +) + +// 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 + +// Flags used by the DwmSetWindowAttribute function to specify the Flip3D window +// policy +const ( + DWMFLIP3D_DEFAULT = 0 + DWMFLIP3D_EXCLUDEBELOW = 1 + DWMFLIP3D_EXCLUDEABOVE = 2 + DWMFLIP3D_LAST = 3 +) + +// enum-lite implementation for the following constant structure +type DWMNCRENDERINGPOLICY int32 + +// Flags used by the DwmSetWindowAttribute function to specify the non-client +// area rendering policy +const ( + DWMNCRP_USEWINDOWSTYLE = 0 + DWMNCRP_DISABLED = 1 + DWMNCRP_ENABLED = 2 + DWMNCRP_LAST = 3 +) + +// 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 + +// Flags used by the DwmGetWindowAttribute and DwmSetWindowAttribute functions +// to specify window attributes for non-client rendering +const ( + DWMWA_NCRENDERING_ENABLED = 1 + DWMWA_NCRENDERING_POLICY = 2 + DWMWA_TRANSITIONS_FORCEDISABLED = 3 + DWMWA_ALLOW_NCPAINT = 4 + DWMWA_CAPTION_BUTTON_BOUNDS = 5 + DWMWA_NONCLIENT_RTL_LAYOUT = 6 + DWMWA_FORCE_ICONIC_REPRESENTATION = 7 + DWMWA_FLIP3D_POLICY = 8 + DWMWA_EXTENDED_FRAME_BOUNDS = 9 + DWMWA_HAS_ICONIC_BITMAP = 10 + DWMWA_DISALLOW_PEEK = 11 + DWMWA_EXCLUDED_FROM_PEEK = 12 + DWMWA_CLOAK = 13 + DWMWA_CLOAKED = 14 + DWMWA_FREEZE_REPRESENTATION = 15 + DWMWA_LAST = 16 +) + +const ( + DWM_CLOAKED_APP = 1 + DWM_CLOAKED_SHELL = 2 + DWM_CLOAKED_INHERITED = 4 +) + +// enum-lite implementation for the following constant structure +type GESTURE_TYPE int32 + +// 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 +) + +const ( + KEYEVENTF_EXTENDEDKEY = 0x0001 + KEYEVENTF_KEYUP = 0x0002 + KEYEVENTF_SCANCODE = 0x0008 + KEYEVENTF_UNICODE = 0x0004 +) + +// 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 +) + +// Process Security and Access Rights +// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684880(v=vs.85).aspx +const ( + PROCESS_TERMINATE = 0x0001 + PROCESS_CREATE_THREAD = 0x0002 + PROCESS_SET_SESSIONID = 0x0004 + PROCESS_VM_OPERATION = 0x0008 + PROCESS_VM_READ = 0x0010 + PROCESS_VM_WRITE = 0x0020 + PROCESS_DUP_HANDLE = 0x0040 + PROCESS_CREATE_PROCESS = 0x0080 + PROCESS_SET_QUOTA = 0x0100 + PROCESS_SET_INFORMATION = 0x0200 + PROCESS_QUERY_INFORMATION = 0x0400 + PROCESS_SUSPEND_RESUME = 0x0800 + PROCESS_QUERY_LIMITED_INFORMATION = 0x1000 + PROCESS_SET_LIMITED_INFORMATION = 0x2000 +) + +const ( + IMAGE_BITMAP = 0 + IMAGE_ICON = 1 + IMAGE_CURSOR = 2 +) + +const ( + LR_DEFAULTCOLOR = 0x0000 + LR_MONOCHROME = 0x0001 + LR_COLOR = 0x0002 + LR_COPYRETURNORG = 0x0004 + LR_COPYDELETEORG = 0x0008 + LR_LOADFROMFILE = 0x0010 + LR_LOADTRANSPARENT = 0x0020 + LR_DEFAULTSIZE = 0x0040 + LR_VGACOLOR = 0x0080 + LR_LOADMAP3DCOLORS = 0x1000 + LR_CREATEDIBSECTION = 0x2000 + LR_COPYFROMRESOURCE = 0x4000 + LR_SHARED = 0x8000 +) + +const ( + MF_BITMAP = 0x0004 + MF_CHECKED = 0x0008 + MF_DISABLED = 0x0002 + MF_ENABLED = 0x0000 + MF_GRAYED = 0x0001 + MF_MENUBARBREAK = 0x0020 + MF_MENUBREAK = 0x0040 + MF_OWNERDRAW = 0x0100 + MF_POPUP = 0x0010 + MF_SEPARATOR = 0x0800 + MF_STRING = 0x0000 + MF_UNCHECKED = 0x0000 + MF_BYCOMMAND = 0x0000 + MF_BYPOSITION = 0x0400 +) + +const ( + RID_INPUT = 0x10000003 + RID_HEADER = 0x10000005 +) + +const ( + RIM_TYPEMOUSE = 0 + RIM_TYPEKEYBOARD = 1 + RIM_TYPEHID = 2 +) + +const ( + RI_KEY_MAKE = 0 // key is down + RI_KEY_BREAK = 1 // key is up + RI_KEY_E0 = 2 // scan code has e0 prefix + RI_KEY_E1 = 4 // scan code has e1 prefix + RI_KEY_TERMSRV_SET_LED = 8 + RI_KEY_TERMSRV_SHADOW = 0x10 +) + +const ( + MOUSE_MOVE_RELATIVE = 0 + MOUSE_MOVE_ABSOLUTE = 1 + MOUSE_VIRTUAL_DESKTOP = 0x02 + MOUSE_ATTRIBUTES_CHANGED = 0x04 + MOUSE_MOVE_NOCOALESCE = 0x08 +) + +const ( + RI_MOUSE_LEFT_BUTTON_DOWN = 0x0001 + RI_MOUSE_LEFT_BUTTON_UP = 0x0002 + RI_MOUSE_RIGHT_BUTTON_DOWN = 0x0004 + RI_MOUSE_RIGHT_BUTTON_UP = 0x0008 + RI_MOUSE_MIDDLE_BUTTON_DOWN = 0x0010 + RI_MOUSE_MIDDLE_BUTTON_UP = 0x0020 + RI_MOUSE_BUTTON_1_DOWN = RI_MOUSE_LEFT_BUTTON_DOWN + RI_MOUSE_BUTTON_1_UP = RI_MOUSE_LEFT_BUTTON_UP + RI_MOUSE_BUTTON_2_DOWN = RI_MOUSE_RIGHT_BUTTON_DOWN + RI_MOUSE_BUTTON_2_UP = RI_MOUSE_RIGHT_BUTTON_UP + RI_MOUSE_BUTTON_3_DOWN = RI_MOUSE_MIDDLE_BUTTON_DOWN + RI_MOUSE_BUTTON_3_UP = RI_MOUSE_MIDDLE_BUTTON_UP + RI_MOUSE_BUTTON_4_DOWN = 0x0040 // XBUTTON1 changed to down + RI_MOUSE_BUTTON_4_UP = 0x0080 // XBUTTON1 changed to up + RI_MOUSE_BUTTON_5_DOWN = 0x100 // XBUTTON2 changed to down + RI_MOUSE_BUTTON_5_UP = 0x0200 // XBUTTON2 changed to up + RI_MOUSE_WHEEL = 0x0400 +) + +const ( + RIDEV_REMOVE = 0x00000001 + RIDEV_EXCLUDE = 0x00000010 + RIDEV_PAGEONLY = 0x00000020 + RIDEV_NOLEGACY = 0x00000030 + RIDEV_INPUTSINK = 0x00000100 + RIDEV_CAPTUREMOUSE = 0x00000200 + RIDEV_NOHOTKEYS = 0x00000200 + RIDEV_APPKEYS = 0x00000400 + RIDEV_EXINPUTSINK = 0x00001000 + RIDEV_DEVNOTIFY = 0x00002000 +) + +// GDI+ constants +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 +) + +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}} +) + +const ( + VS_FF_DEBUG = 0x00000001 + VS_FF_INFOINFERRED = 0x00000010 + VS_FF_PATCHED = 0x00000004 + VS_FF_PRERELEASE = 0x00000002 + VS_FF_PRIVATEBUILD = 0x00000008 + VS_FF_SPECIALBUILD = 0x00000020 + + VOS_DOS = 0x00010000 + VOS_NT = 0x00040000 + VOS__WINDOWS16 = 0x00000001 + VOS__WINDOWS32 = 0x00000004 + VOS_OS216 = 0x00020000 + VOS_OS232 = 0x00030000 + VOS__PM16 = 0x00000002 + VOS__PM32 = 0x00000003 + VOS_UNKNOWN = 0x00000000 + + VOS_DOS_WINDOWS16 = 0x00010001 + VOS_DOS_WINDOWS32 = 0x00010004 + VOS_NT_WINDOWS32 = 0x00040004 + VOS_OS216_PM16 = 0x00020002 + VOS_OS232_PM32 = 0x00030003 + + VFT_APP = 0x00000001 + VFT_DLL = 0x00000002 + VFT_DRV = 0x00000003 + VFT_FONT = 0x00000004 + VFT_STATIC_LIB = 0x00000007 + VFT_UNKNOWN = 0x00000000 + VFT_VXD = 0x00000005 + + VFT2_DRV_COMM = 0x0000000A + VFT2_DRV_DISPLAY = 0x00000004 + VFT2_DRV_INSTALLABLE = 0x00000008 + VFT2_DRV_KEYBOARD = 0x00000002 + VFT2_DRV_LANGUAGE = 0x00000003 + VFT2_DRV_MOUSE = 0x00000005 + VFT2_DRV_NETWORK = 0x00000006 + VFT2_DRV_PRINTER = 0x00000001 + VFT2_DRV_SOUND = 0x00000009 + VFT2_DRV_SYSTEM = 0x00000007 + VFT2_DRV_VERSIONED_PRINTER = 0x0000000C + VFT2_UNKNOWN = 0x00000000 + + VFT2_FONT_RASTER = 0x00000001 + VFT2_FONT_TRUETYPE = 0x00000003 + VFT2_FONT_VECTOR = 0x00000002 +) + +const ( + SND_SYNC = 0 + SND_ASYNC = 1 + SND_NODEFAULT = 2 + SND_MEMORY = 4 + SND_LOOP = 8 + SND_NOSTOP = 16 + SND_NOWAIT = 0x2000 + SND_ALIAS = 0x10000 + SND_ALIAS_ID = 0x110000 + SND_FILENAME = 0x20000 + SND_RESOURCE = 0x40004 + SND_PURGE = 0x40 + SND_APPLICATION = 0x80 + SND_ALIAS_START = 0 +) + +const ( + BLACKONWHITE = 1 + WHITEONBLACK = 2 + COLORONCOLOR = 3 + HALFTONE = 4 + STRETCH_ANDSCANS = BLACKONWHITE + STRETCH_DELETESCANS = COLORONCOLOR + STRETCH_HALFTONE = HALFTONE + STRETCH_ORSCANS = WHITEONBLACK +) + +const ( + GW_HWNDFIRST = 0 + GW_HWNDLAST = 1 + GW_HWNDNEXT = 2 + GW_HWNDPREV = 3 + GW_OWNER = 4 + GW_CHILD = 5 + GW_ENABLEDPOPUP = 6 +) + +// ACCEL behavior flags +const ( + FVIRTKEY = 0x01 + FNOINVERT = 0x02 + FSHIFT = 0x04 + FCONTROL = 0x08 + FALT = 0x10 +) + +// Mouse key flags +const ( + MK_LBUTTON = 0x0001 + MK_RBUTTON = 0x0002 + MK_SHIFT = 0x0004 + MK_CONTROL = 0x0008 + MK_MBUTTON = 0x0010 + MK_XBUTTON1 = 0x0020 + MK_XBUTTON2 = 0x0040 +) + +const UPDOWN_CLASS = "msctls_updown32" + +const ( + UDS_WRAP = 1 + UDS_SETBUDDYINT = 2 + UDS_ALIGNRIGHT = 4 + UDS_ALIGNLEFT = 8 + UDS_AUTOBUDDY = 16 + UDS_ARROWKEYS = 32 + UDS_HORZ = 64 + UDS_NOTHOUSANDS = 128 +) + +const ( + UDN_FIRST = 4294966575 + UDN_LAST = 4294966567 + UDN_DELTAPOS = UDN_FIRST - 1 +) + +const ( + UDM_SETRANGE = WM_USER + 101 + UDM_GETRANGE = WM_USER + 102 + UDM_SETPOS = WM_USER + 103 + UDM_GETPOS = WM_USER + 104 + UDM_SETBUDDY = WM_USER + 105 + UDM_GETBUDDY = WM_USER + 106 + UDM_SETACCEL = WM_USER + 107 + UDM_GETACCEL = WM_USER + 108 + UDM_SETBASE = WM_USER + 109 + UDM_GETBASE = WM_USER + 110 + UDM_SETRANGE32 = WM_USER + 111 + UDM_GETRANGE32 = WM_USER + 112 + UDM_SETPOS32 = WM_USER + 113 + UDM_GETPOS32 = WM_USER + 114 + UDM_SETUNICODEFORMAT = 0x2005 + UDM_GETUNICODEFORMAT = 0x2006 +) + +const ( + GCL_CBCLSEXTRA = -20 + GCL_CBWNDEXTRA = -18 + GCLP_HBRBACKGROUND = -10 + GCLP_HCURSOR = -12 + GCLP_HICON = -14 + GCLP_HICONSM = -34 + GCLP_HMODULE = -16 + GCLP_MENUNAME = -8 + GCL_STYLE = -26 + GCLP_WNDPROC = -24 +) + +// system commands +const ( + SC_CLOSE = 0xF060 + SC_CONTEXTHELP = 0xF180 + SC_DEFAULT = 0xF160 + SC_HOTKEY = 0xF150 + SC_HSCROLL = 0xF080 + SCF_ISSECURE = 0x0001 + SC_KEYMENU = 0xF100 + SC_MAXIMIZE = 0xF030 + SC_MINIMIZE = 0xF020 + SC_MONITORPOWER = 0xF170 + SC_MOUSEMENU = 0xF090 + SC_MOVE = 0xF010 + SC_NEXTWINDOW = 0xF040 + SC_PREVWINDOW = 0xF050 + SC_RESTORE = 0xF120 + SC_SCREENSAVE = 0xF140 + SC_SIZE = 0xF000 + SC_TASKLIST = 0xF130 + SC_VSCROLL = 0xF070 +) + +const AC_SRC_OVER = 0 + +const AC_SRC_ALPHA = 1 + +const ( + RESOURCE_CONNECTED = 0x00000001 + RESOURCE_GLOBALNET = 0x00000002 + RESOURCE_REMEMBERED = 0x00000003 + RESOURCE_RECENT = 0x00000004 + RESOURCE_CONTEXT = 0x00000005 +) + +const ( + RESOURCETYPE_ANY = 0x00000000 + RESOURCETYPE_DISK = 0x00000001 + RESOURCETYPE_PRINT = 0x00000002 + RESOURCETYPE_RESERVED = 0x00000008 + RESOURCETYPE_UNKNOWN = 0xFFFFFFFF +) + +const ( + RESOURCEUSAGE_CONNECTABLE = 0x00000001 + RESOURCEUSAGE_CONTAINER = 0x00000002 + RESOURCEUSAGE_NOLOCALDEVICE = 0x00000004 + RESOURCEUSAGE_SIBLING = 0x00000008 + RESOURCEUSAGE_ATTACHED = 0x00000010 + RESOURCEUSAGE_ALL = RESOURCEUSAGE_CONNECTABLE | RESOURCEUSAGE_CONTAINER | RESOURCEUSAGE_ATTACHED + RESOURCEUSAGE_RESERVED = 0x80000000 +) + +const ( + RESOURCEDISPLAYTYPE_GENERIC = 0x00000000 + RESOURCEDISPLAYTYPE_DOMAIN = 0x00000001 + RESOURCEDISPLAYTYPE_SERVER = 0x00000002 + RESOURCEDISPLAYTYPE_SHARE = 0x00000003 + RESOURCEDISPLAYTYPE_FILE = 0x00000004 + RESOURCEDISPLAYTYPE_GROUP = 0x00000005 + RESOURCEDISPLAYTYPE_NETWORK = 0x00000006 + RESOURCEDISPLAYTYPE_ROOT = 0x00000007 + RESOURCEDISPLAYTYPE_SHAREADMIN = 0x00000008 + RESOURCEDISPLAYTYPE_DIRECTORY = 0x00000009 + RESOURCEDISPLAYTYPE_TREE = 0x0000000A + RESOURCEDISPLAYTYPE_NDSCONTAINER = 0x0000000B +) + +const NETPROPERTY_PERSISTENT = 1 + +const ( + CONNECT_UPDATE_PROFILE = 0x00000001 + CONNECT_UPDATE_RECENT = 0x00000002 + CONNECT_TEMPORARY = 0x00000004 + CONNECT_INTERACTIVE = 0x00000008 + CONNECT_PROMPT = 0x00000010 + CONNECT_NEED_DRIVE = 0x00000020 + CONNECT_REFCOUNT = 0x00000040 + CONNECT_REDIRECT = 0x00000080 + CONNECT_LOCALDRIVE = 0x00000100 + CONNECT_CURRENT_MEDIA = 0x00000200 + CONNECT_DEFERRED = 0x00000400 + CONNECT_RESERVED = 0xFF000000 + CONNECT_COMMANDLINE = 0x00000800 + CONNECT_CMD_SAVECRED = 0x00001000 +) + +const PW_CLIENTONLY = 1 + +const ( + SEM_FAILCRITICALERRORS = 0x0001 + SEM_NOALIGNMENTFAULTEXCEPT = 0x0004 + SEM_NOGPFAULTERRORBOX = 0x0002 + SEM_NOOPENFILEERRORBOX = 0x8000 +) + +const ( + GENERIC_ALL = 0x10000000 + GENERIC_EXECUTE = 0x20000000 + GENERIC_WRITE = 0x40000000 + GENERIC_READ = 0x80000000 +) + +const SYNCHRONIZE = 0x100000 + +const ( + STANDARD_RIGHTS_REQUIRED = 0xF0000 + STANDARD_RIGHTS_READ = 0x20000 + STANDARD_RIGHTS_WRITE = 0x20000 + STANDARD_RIGHTS_EXECUTE = 0x20000 + STANDARD_RIGHTS_ALL = 0x1F0000 + SPECIFIC_RIGHTS_ALL = 0xFFFF + ACCESS_SYSTEM_SECURITY = 0x1000000 +) + +const ( + FILE_READ_DATA = 1 + FILE_LIST_DIRECTORY = 1 + FILE_WRITE_DATA = 2 + FILE_ADD_FILE = 2 + FILE_APPEND_DATA = 4 + FILE_ADD_SUBDIRECTORY = 4 + FILE_CREATE_PIPE_INSTANCE = 4 + FILE_READ_EA = 8 + FILE_READ_PROPERTIES = 8 + FILE_WRITE_EA = 16 + FILE_WRITE_PROPERTIES = 16 + FILE_EXECUTE = 32 + FILE_TRAVERSE = 32 + FILE_DELETE_CHILD = 64 + FILE_READ_ATTRIBUTES = 128 + FILE_WRITE_ATTRIBUTES = 256 + FILE_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF + FILE_GENERIC_READ = STANDARD_RIGHTS_READ | FILE_READ_DATA | FILE_READ_ATTRIBUTES | FILE_READ_EA | SYNCHRONIZE + FILE_GENERIC_WRITE = STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_APPEND_DATA | SYNCHRONIZE + FILE_GENERIC_EXECUTE = STANDARD_RIGHTS_EXECUTE | FILE_READ_ATTRIBUTES | FILE_EXECUTE | SYNCHRONIZE + FILE_SHARE_READ = 1 + FILE_SHARE_WRITE = 2 + FILE_SHARE_DELETE = 4 + FILE_ATTRIBUTE_READONLY = 1 + FILE_ATTRIBUTE_HIDDEN = 2 + FILE_ATTRIBUTE_SYSTEM = 4 + FILE_ATTRIBUTE_DIRECTORY = 16 + FILE_ATTRIBUTE_ARCHIVE = 32 + FILE_ATTRIBUTE_ENCRYPTED = 16384 + FILE_ATTRIBUTE_NORMAL = 128 + FILE_ATTRIBUTE_TEMPORARY = 256 + FILE_ATTRIBUTE_SPARSE_FILE = 512 + FILE_ATTRIBUTE_REPARSE_POINT = 1024 + FILE_ATTRIBUTE_COMPRESSED = 2048 + FILE_ATTRIBUTE_OFFLINE = 0x1000 + FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x2000 + FILE_NOTIFY_CHANGE_FILE_NAME = 1 + FILE_NOTIFY_CHANGE_DIR_NAME = 2 + FILE_NOTIFY_CHANGE_ATTRIBUTES = 4 + FILE_NOTIFY_CHANGE_SIZE = 8 + FILE_NOTIFY_CHANGE_LAST_WRITE = 16 + FILE_NOTIFY_CHANGE_LAST_ACCESS = 32 + FILE_NOTIFY_CHANGE_CREATION = 64 + FILE_NOTIFY_CHANGE_SECURITY = 256 + FILE_CASE_SENSITIVE_SEARCH = 1 + FILE_CASE_PRESERVED_NAMES = 2 + FILE_UNICODE_ON_DISK = 4 + FILE_PERSISTENT_ACLS = 8 + FILE_FILE_COMPRESSION = 16 + FILE_VOLUME_QUOTAS = 32 + FILE_SUPPORTS_SPARSE_FILES = 64 + FILE_SUPPORTS_REPARSE_POINTS = 128 +) + +const ( + CREATE_NEW = 1 + CREATE_ALWAYS = 2 + OPEN_EXISTING = 3 + OPEN_ALWAYS = 4 + TRUNCATE_EXISTING = 5 +) + +const ( + SECURITY_CONTEXT_TRACKING = 0x00040000 + SECURITY_EFFECTIVE_ONLY = 0x00080000 + SECURITY_SQOS_PRESENT = 0x00100000 + SECURITY_VALID_SQOS_FLAGS = 0x001F0000 +) + +const INVALID_HANDLE_VALUE = ^HANDLE(0) + +// STORAGE_BUS_TYPE values +const ( + BusTypeUnknown = 0 + BusTypeScsi = 1 + BusTypeAtapi = 2 + BusTypeAta = 3 + BusType1394 = 4 + BusTypeSsa = 5 + BusTypeFibre = 6 + BusTypeUsb = 7 + BusTypeRAID = 8 + BusTypeiScsi = 9 + BusTypeSas = 10 + BusTypeSata = 11 + BusTypeSd = 12 + BusTypeMmc = 13 + BusTypeVirtual = 14 + BusTypeFileBackedVirtual = 15 + BusTypeSpaces = 16 + BusTypeNvme = 17 + BusTypeMax = 20 + BusTypeMaxReserved = 0x7F +) + +// STORAGE_QUERY_TYPE values +const ( + PropertyStandardQuery = 0 + PropertyExistsQuery = 1 + PropertyMaskQuery = 2 + PropertyQueryMaxDefined = 3 +) + +// STORAGE_PROPERTY_ID values +const ( + StorageDeviceProperty = 0 + StorageAdapterProperty = 1 + StorageDeviceIdProperty = 2 + StorageDeviceUniqueIdProperty = 3 + StorageDeviceWriteCacheProperty = 4 + StorageMiniportProperty = 5 + StorageAccessAlignmentProperty = 6 + StorageDeviceSeekPenaltyProperty = 7 + StorageDeviceTrimProperty = 8 + StorageDeviceWriteAggregationProperty = 9 + StorageDeviceDeviceTelemetryProperty = 10 + StorageDeviceLBProvisioningProperty = 11 + StorageDevicePowerProperty = 12 + StorageDeviceCopyOffloadProperty = 13 + StorageDeviceResiliencyProperty = 14 + StorageDeviceMediumProductType = 15 +) + +// STREAM_INFO_LEVELS +const ( + FindStreamInfoStandard = 0 +) + +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 +) + +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 +) + +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 +) + +const ( + // DEVICE_NOTIFY_WINDOW_HANDLE + // Notifications are sent using WM_POWERBROADCAST messages with a wParam + // parameter of PBT_POWERSETTINGCHANGE. + DEVICE_NOTIFY_WINDOW_HANDLE = 0 + + // DEVICE_NOTIFY_SERVICE_HANDLE + // Notifications are sent to the HandlerEx callback function with a + // dwControl parameter of SERVICE_CONTROL_POWEREVENT and a dwEventType of + // PBT_POWERSETTINGCHANGE. + DEVICE_NOTIFY_SERVICE_HANDLE = 1 +) + +// Power setting GUIDs identify power change events. This topic lists power +// setting GUIDs for notifications that are most useful to applications. An +// application should register for each power change event that might impact its +// behavior. Notification is sent each time a setting changes, through +// WM_POWERBROADCAST. +var ( + // GUID_ACDC_POWER_SOURCE + // + // The system power source has changed. The Data member is a uint32 with + // values from the SYSTEM_POWER_CONDITION enumeration that indicates the + // current power source. + // + // PoAc (0) - The computer is powered by an AC power source (or similar, + // such as a laptop powered by a 12V automotive adapter). + // + // PoDc (1) - The computer is powered by an onboard battery power source. + // + // PoHot (2) - The computer is powered by a short-term power source such as + // a UPS device. + GUID_ACDC_POWER_SOURCE = &GUID{0x5d3e9a59, 0xe9D5, 0x4b00, [8]byte{0xa6, 0xbd, 0xff, 0x34, 0xff, 0x51, 0x65, 0x48}} + + // GUID_BATTERY_PERCENTAGE_REMAINING + // + // The remaining battery capacity has changed. The granularity varies from + // system to system but the finest granularity is 1 percent. The Data member + // is a uint32 that indicates the current battery capacity remaining as a + // percentage from 0 through 100. + GUID_BATTERY_PERCENTAGE_REMAINING = &GUID{0xa7ad8041, 0xb45a, 0x4cae, [8]byte{0x87, 0xa3, 0xee, 0xcb, 0xb4, 0x68, 0xa9, 0xe1}} + + // GUID_CONSOLE_DISPLAY_STATE + // + // The current monitor's display state has changed. + // + // Windows 7, Windows Server 2008 R2, Windows Vista and Windows Server 2008: + // This notification is available starting with Windows 8 and Windows Server + // 2012. + // + // The Data member is a uint32 with one of the following values. + // + // 0x0 - The display is off. + // + // 0x1 - The display is on. + // + // 0x2 - The display is dimmed. + GUID_CONSOLE_DISPLAY_STATE = &GUID{0x6fe69556, 0x704a, 0x47a0, [8]byte{0x8f, 0x24, 0xc2, 0x8d, 0x93, 0x6f, 0xda, 0x47}} + + // GUID_GLOBAL_USER_PRESENCE + // + // The user status associated with any session has changed. This represents + // the combined status of user presence across all local and remote sessions + // on the system. + // + // This notification is sent only to services and other programs running in + // session 0. User-mode applications should register for + // GUID_SESSION_USER_PRESENCE instead. + // + // Windows 7, Windows Server 2008 R2, Windows Vista and Windows Server 2008: + // This notification is available starting with Windows 8 and Windows Server + // 2012. + // + // The Data member is a DWORD with one of the following values. + // + // PowerUserPresent (0) - The user is present in any local or remote session + // on the system. + // + // PowerUserInactive (2) - The user is not present in any local or remote + // session on the system. + GUID_GLOBAL_USER_PRESENCE = &GUID{0x786E8A1D, 0xB427, 0x4344, [8]byte{0x92, 0x07, 0x09, 0xE7, 0x0B, 0xDC, 0xBE, 0xA9}} + + // GUID_IDLE_BACKGROUND_TASK + // + // The system is busy. This indicates that the system will not be moving + // into an idle state in the near future and that the current time is a good + // time for components to perform background or idle tasks that would + // otherwise prevent the computer from entering an idle state. + // + // There is no notification when the system is able to move into an idle + // state. The idle background task notification does not indicate whether a + // user is present at the computer. The Data member has no information and + // can be ignored. + GUID_IDLE_BACKGROUND_TASK = &GUID{0x515c31d8, 0xf734, 0x163d, [8]byte{0xa0, 0xfd, 0x11, 0xa0, 0x8c, 0x91, 0xe8, 0xf1}} + + // GUID_MONITOR_POWER_ON + // + // The primary system monitor has been powered on or off. This notification + // is useful for components that actively render content to the display + // device, such as media visualization. These applications should register + // for this notification and stop rendering graphics content when the + // monitor is off to reduce system power consumption. The Data member is a + // DWORD that indicates the current monitor state. + // + // 0x0 - The monitor is off. + // + // 0x1 - The monitor is on. + // + // Windows 8 and Windows Server 2012: New applications should use + // GUID_CONSOLE_DISPLAY_STATE instead of this notification. + GUID_MONITOR_POWER_ON = &GUID{0x02731015, 0x4510, 0x4526, [8]byte{0x99, 0xe6, 0xe5, 0xa1, 0x7e, 0xbd, 0x1a, 0xea}} + + // GUID_POWER_SAVING_STATUS + // + // Battery saver has been turned off or on in response to changing power + // conditions. This notification is useful for components that participate + // in energy conservation. These applications should register for this + // notification and save power when battery saver is on. + // + // The Data member is a DWORD that indicates battery saver state. + // + // 0x0 - Battery saver is off. + // + // 0x1 - Battery saver is on. Save energy where possible. + // + // For general information about battery saver, see battery saver (in the + // hardware component guidelines). + GUID_POWER_SAVING_STATUS = &GUID{0xE00958C0, 0xC213, 0x4ACE, [8]byte{0xAC, 0x77, 0xFE, 0xCC, 0xED, 0x2E, 0xEE, 0xA5}} + + // GUID_POWERSCHEME_PERSONALITY + // + // The active power scheme personality has changed. All power schemes map to + // one of these personalities. The Data member is a GUID that indicates the + // new active power scheme personality (GUID_MIN_POWER_SAVINGS, + // GUID_MAX_POWER_SAVINGS or GUID_TYPICAL_POWER_SAVINGS). + GUID_POWERSCHEME_PERSONALITY = &GUID{0x245d8541, 0x3943, 0x4422, [8]byte{0xb0, 0x25, 0x13, 0xA7, 0x84, 0xF6, 0x79, 0xB7}} + + // GUID_MIN_POWER_SAVINGS + // + // High Performance - The scheme is designed to deliver maximum performance + // at the expense of power consumption savings. + GUID_MIN_POWER_SAVINGS = &GUID{0x8c5e7fda, 0xe8bf, 0x4a96, [8]byte{0x9a, 0x85, 0xa6, 0xe2, 0x3a, 0x8c, 0x63, 0x5c}} + + // GUID_MAX_POWER_SAVINGS + // + // Power Saver - The scheme is designed to deliver maximum power consumption + // savings at the expense of system performance and responsiveness. + GUID_MAX_POWER_SAVINGS = &GUID{0xa1841308, 0x3541, 0x4fab, [8]byte{0xbc, 0x81, 0xf7, 0x15, 0x56, 0xf2, 0x0b, 0x4a}} + + // GUID_TYPICAL_POWER_SAVINGS + // + // Automatic - The scheme is designed to automatically balance performance + // and power consumption savings. + GUID_TYPICAL_POWER_SAVINGS = &GUID{0x381b4222, 0xf694, 0x41f0, [8]byte{0x96, 0x85, 0xff, 0x5b, 0xb2, 0x60, 0xdf, 0x2e}} + + // GUID_SESSION_DISPLAY_STATUS + // + // The display associated with the application's session has been powered on + // or off. + // + // Windows 7, Windows Server 2008 R2, Windows Vista and Windows Server 2008: + // This notification is available starting with Windows 8 and Windows Server + // 2012. + // + // This notification is sent only to user-mode applications. Services and + // other programs running in session 0 do not receive this notification. The + // Data member is a DWORD with one of the following values. + // + // 0x0 - The display is off. + // + // 0x1 - The display is on. + // + // 0x2 - The display is dimmed. + GUID_SESSION_DISPLAY_STATUS = &GUID{0x2B84C20E, 0xAD23, 0x4ddf, [8]byte{0x93, 0xDB, 0x05, 0xFF, 0xBD, 0x7E, 0xFC, 0xA5}} + + // GUID_SESSION_USER_PRESENCE + // + // The user status associated with the application's session has changed. + // + // Windows 7, Windows Server 2008 R2, Windows Vista and Windows Server 2008: + // This notification is available starting with Windows 8 and Windows Server + // 2012. + // + // This notification is sent only to user-mode applications running in an + // interactive session. Services and other programs running in session 0 + // should register for GUID_GLOBAL_USER_PRESENCE. The Data member is a DWORD + // with one of the following values. + // + // PowerUserPresent (0) - The user is providing input to the session. + // + // PowerUserInactive (2) - The user activity timeout has elapsed with no + // interaction from the user. + // + // NOTE All applications that run in an interactive user-mode session should + // use this setting. When kernel mode applications register for monitor + // status they should use GUID_CONSOLE_DISPLAY_STATUS instead. + GUID_SESSION_USER_PRESENCE = &GUID{0x3C0F4548, 0xC03F, 0x4c4d, [8]byte{0xB9, 0xF2, 0x23, 0x7E, 0xDE, 0x68, 0x63, 0x76}} + + // GUID_SYSTEM_AWAYMODE + // + // The system is entering or exiting away mode. The Data member is a DWORD + // that indicates the current away mode state. + // + // 0x0 - The computer is exiting away mode. + // + // 0x1 - The computer is entering away mode. + GUID_SYSTEM_AWAYMODE = &GUID{0x98a7f580, 0x01f7, 0x48aa, [8]byte{0x9c, 0x0f, 0x44, 0x35, 0x2c, 0x29, 0xe5, 0xC0}} + + // GUID_DEVINTERFACE_COMPORT is defined for COM ports. + GUID_DEVINTERFACE_COMPORT = &GUID{0x86E0D1E0, 0x8089, 0x11D0, [8]byte{0x9C, 0xE4, 0x08, 0x00, 0x3E, 0x30, 0x1F, 0x73}} +) + +const ( + // Power status has changed. + PBT_APMPOWERSTATUSCHANGE = 0x000A + + // Operation is resuming automatically from a low-power state. This message + // is sent every time the system resumes. + PBT_APMRESUMEAUTOMATIC = 0x0012 + + // Operation is resuming from a low-power state. This message is sent after + // PBT_APMRESUMEAUTOMATIC if the resume is triggered by user input, such as + // pressing a key. + PBT_APMRESUMESUSPEND = 0x0007 + + // System is suspending operation. + PBT_APMSUSPEND = 0x0004 + + // A power setting change event has been received. + PBT_POWERSETTINGCHANGE = 0x8013 +) + +// SYSTEM_POWER_CONDITION enumeration +const ( + // PoAc: the computer is powered by an AC power source (or similar, such as + // a laptop powered by a 12V automotive adapter). + PoAc = 0 + // PoDc: the system is receiving power from built-in batteries. + PoDc = 1 + // PoHot: the computer is powered by a short-term power source such as a UPS + // device. + PoHot = 2 + // PoConditionMaximum: values equal to or greater than this value indicate + // an out of range value. + PoConditionMaximum = 3 +) + +const ( + CSIDL_DESKTOP = 0x0000 // + CSIDL_INTERNET = 0x0001 // Internet Explorer (icon on desktop) + CSIDL_PROGRAMS = 0x0002 // Start Menu\Programs + CSIDL_CONTROLS = 0x0003 // My Computer\Control Panel + CSIDL_PRINTERS = 0x0004 // My Computer\Printers + CSIDL_PERSONAL = 0x0005 // My Documents + CSIDL_FAVORITES = 0x0006 // \Favorites + CSIDL_STARTUP = 0x0007 // Start Menu\Programs\Startup + CSIDL_RECENT = 0x0008 // \Recent + CSIDL_SENDTO = 0x0009 // \SendTo + CSIDL_BITBUCKET = 0x000A // \Recycle Bin + CSIDL_STARTMENU = 0x000B // \Start Menu + CSIDL_MYDOCUMENTS = CSIDL_PERSONAL // Personal was just a silly name for My Documents + CSIDL_MYMUSIC = 0x000D // "My Music" folder + CSIDL_MYVIDEO = 0x000E // "My Videos" folder + CSIDL_DESKTOPDIRECTORY = 0x0010 // \Desktop + CSIDL_DRIVES = 0x0011 // My Computer + CSIDL_NETWORK = 0x0012 // Network Neighborhood (My Network Places) + CSIDL_NETHOOD = 0x0013 // \nethood + CSIDL_FONTS = 0x0014 // windows\fonts + CSIDL_TEMPLATES = 0x0015 + CSIDL_COMMON_STARTMENU = 0x0016 // All Users\Start Menu + CSIDL_COMMON_PROGRAMS = 0x0017 // All Users\Start Menu\Programs + CSIDL_COMMON_STARTUP = 0x0018 // All Users\Startup + CSIDL_COMMON_DESKTOPDIRECTORY = 0x0019 // All Users\Desktop + CSIDL_APPDATA = 0x001A // \Application Data + CSIDL_PRINTHOOD = 0x001B // \PrintHood + CSIDL_LOCAL_APPDATA = 0x001C // \Local Settings\Applicaiton Data (non roaming) + CSIDL_ALTSTARTUP = 0x001D // non localized startup + CSIDL_COMMON_ALTSTARTUP = 0x001E // non localized common startup + CSIDL_COMMON_FAVORITES = 0x001F + CSIDL_INTERNET_CACHE = 0x0020 + CSIDL_COOKIES = 0x0021 + CSIDL_HISTORY = 0x0022 + CSIDL_COMMON_APPDATA = 0x0023 // All Users\Application Data + CSIDL_WINDOWS = 0x0024 // GetWindowsDirectory() + CSIDL_SYSTEM = 0x0025 // GetSystemDirectory() + CSIDL_PROGRAM_FILES = 0x0026 // C:\Program Files + CSIDL_MYPICTURES = 0x0027 // C:\Program Files\My Pictures + CSIDL_PROFILE = 0x0028 // USERPROFILE + CSIDL_SYSTEMX86 = 0x0029 // x86 system directory on RISC + CSIDL_PROGRAM_FILESX86 = 0x002A // x86 C:\Program Files on RISC + CSIDL_PROGRAM_FILES_COMMON = 0x002B // C:\Program Files\Common + CSIDL_PROGRAM_FILES_COMMONX86 = 0x002C // x86 Program Files\Common on RISC + CSIDL_COMMON_TEMPLATES = 0x002D // All Users\Templates + CSIDL_COMMON_DOCUMENTS = 0x002E // All Users\Documents + CSIDL_COMMON_ADMINTOOLS = 0x002F // All Users\Start Menu\Programs\Administrative Tools + CSIDL_ADMINTOOLS = 0x0030 // \Start Menu\Programs\Administrative Tools + CSIDL_CONNECTIONS = 0x0031 // Network and Dial-up Connections + CSIDL_COMMON_MUSIC = 0x0035 // All Users\My Music + CSIDL_COMMON_PICTURES = 0x0036 // All Users\My Pictures + CSIDL_COMMON_VIDEO = 0x0037 // All Users\My Video + CSIDL_RESOURCES = 0x0038 // Resource Direcotry +) + +// Drive types to use with GetDriveType. +const ( + DRIVE_UNKNOWN = 0 + DRIVE_NO_ROOT_DIR = 1 + DRIVE_REMOVABLE = 2 + DRIVE_FIXED = 3 + DRIVE_REMOTE = 4 + DRIVE_CDROM = 5 + DRIVE_RAMDISK = 6 +) + +// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-osversioninfoexw +const ( + VER_PLATFORM_WIN32_NT = 2 +) + +// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-osversioninfoexw +const ( + VER_NT_SERVER = 0x0000003 + VER_NT_DOMAIN_CONTROLLER = 0x0000002 + VER_NT_WORKSTATION = 0x0000001 +) + +// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-osversioninfoexw +const ( + VER_SUITE_BACKOFFICE = 0x00000004 + VER_SUITE_BLADE = 0x00000400 + VER_SUITE_COMPUTE_SERVER = 0x00004000 + VER_SUITE_DATACENTER = 0x00000080 + VER_SUITE_ENTERPRISE = 0x00000002 + VER_SUITE_EMBEDDEDNT = 0x00000040 + VER_SUITE_PERSONAL = 0x00000200 + VER_SUITE_SINGLEUSERTS = 0x00000100 + VER_SUITE_SMALLBUSINESS = 0x00000001 + VER_SUITE_SMALLBUSINESS_RESTRICTED = 0x00000020 + VER_SUITE_STORAGE_SERVER = 0x00002000 + VER_SUITE_TERMINAL = 0x00000010 + VER_SUITE_WH_SERVER = 0x00008000 + VER_SUITE_MULTIUSERTS = 0x00020000 +) + +// https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/ns-sysinfoapi-system_info +const ( + PROCESSOR_ARCHITECTURE_AMD64 = 9 + PROCESSOR_ARCHITECTURE_ARM = 5 + PROCESSOR_ARCHITECTURE_ARM64 = 12 + PROCESSOR_ARCHITECTURE_IA64 = 6 + PROCESSOR_ARCHITECTURE_INTEL = 0 + PROCESSOR_ARCHITECTURE_UNKNOWN = 0xFFFF +) + +// Flags for SetLayeredWindowAttributes. +const ( + LWA_COLORKEY = 0x1 + LWA_ALPHA = 0x2 +) + +// Flags for RedrawWindow. +const ( + RDW_INVALIDATE = 0x0001 + RDW_INTERNALPAINT = 0x0002 + RDW_ERASE = 0x0004 + RDW_VALIDATE = 0x0008 + RDW_NOINTERNALPAINT = 0x0010 + RDW_NOERASE = 0x0020 + RDW_NOCHILDREN = 0x0040 + RDW_ALLCHILDREN = 0x0080 + RDW_UPDATENOW = 0x0100 + RDW_ERASENOW = 0x0200 + RDW_FRAME = 0x0400 + RDW_NOFRAME = 0x0800 +) + +// DrawIconEx flags. +const ( + DI_COMPAT = 0x0004 + DI_DEFAULTSIZE = 0x0008 + DI_IMAGE = 0x0002 + DI_MASK = 0x0001 + DI_NOMIRROR = 0x0010 + DI_NORMAL = DI_IMAGE | DI_MASK +) + +// Track bar messages. +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 +) + +// Track bar styles. +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 +) + +// Track bar scroll notifications. +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 +) + +// Clip region types, e.g. returned from IntersectClipRect. +const ( + ERROR = 0 + NULLREGION = 1 + SIMPLEREGION = 2 + COMPLEXREGION = 3 +) + +// Modes for CombineRgn. +const ( + RGN_AND = 1 + RGN_OR = 2 + RGN_XOR = 3 + RGN_DIFF = 4 + RGN_COPY = 5 + RGN_MIN = RGN_AND + RGN_MAX = RGN_COPY +) + +const ( + DIGCF_PRESENT = 0x0002 + DIGCF_ALLCLASSES = 0x0004 + DIGCF_PROFILE = 0x0008 + DIGCF_DEVICEINTERFACE = 0x0010 + DIGCF_INTERFACEDEVICE = DIGCF_DEVICEINTERFACE +) + +const ( + DICS_FLAG_GLOBAL = 0x00000001 + DICS_FLAG_CONFIGSPECIFIC = 0x00000002 + DICS_FLAG_CONFIGGENERAL = 0x00000004 +) + +const ( + DIREG_DEV = 0x00000001 + DIREG_DRV = 0x00000002 + DIREG_BOTH = 0x00000004 +) + +const ( + ABM_NEW = 0x0 + ABM_REMOVE = 0x1 + ABM_QUERYPOS = 0x2 + ABM_SETPOS = 0x3 + ABM_GETSTATE = 0x4 + ABM_GETTASKBARPOS = 0x5 + ABM_ACTIVATE = 0x6 + ABM_GETAUTOHIDEBAR = 0x7 + ABM_SETAUTOHIDEBAR = 0x8 + ABM_WINDOWPOSCHANGED = 0x9 + ABM_SETSTATE = 0xA +) + +const ( + ACM_OPEN = 0x464 + ACM_PLAY = 0x465 + ACM_STOP = 0x466 +) + +const ( + CBEM_GETCOMBOCONTROL = 0x406 + CBEM_GETEDITCONTROL = 0x407 + CBEM_GETEXSTYLE = 0x409 + CBEM_GETEXTENDEDSTYLE = 0x409 + CBEM_GETIMAGELIST = 0x403 + CBEM_GETITEMA = 0x404 + CBEM_GETITEMW = 0x40D + CBEM_HASEDITCHANGED = 0x40A + CBEM_INSERTITEMA = 0x401 + CBEM_INSERTITEMW = 0x40B + CBEM_SETEXSTYLE = 0x408 + CBEM_SETEXTENDEDSTYLE = 0x40E + CBEM_SETIMAGELIST = 0x402 + CBEM_SETITEMA = 0x405 + CBEM_SETITEMW = 0x40C + CBEM_GETUNICODEFORMAT = 0x2006 + CBEM_SETUNICODEFORMAT = 0x2005 +) + +const ( + CDM_GETFILEPATH = 0x465 + CDM_GETFOLDERIDLIST = 0x467 + CDM_GETFOLDERPATH = 0x466 + CDM_GETSPEC = 0x464 + CDM_HIDECONTROL = 0x469 + CDM_SETCONTROLTEXT = 0x468 + CDM_SETDEFEXT = 0x46A +) + +const ( + DL_BEGINDRAG = 0x485 + DL_CANCELDRAG = 0x488 + DL_COPYCURSOR = 0x002 + DL_CURSORSET = 0x000 + DL_DRAGGING = 0x486 + DL_DROPPED = 0x487 + DL_MOVECURSOR = 0x003 + DL_STOPCURSOR = 0x001 +) + +const ( + DM_GETDEFID = 0x400 + DM_REPOSITION = 0x402 + DM_SETDEFID = 0x401 +) + +const ( + DTM_GETMCCOLOR = 0x1007 + DTM_GETMCFONT = 0x100A + DTM_GETMONTHCAL = 0x1008 + DTM_GETRANGE = 0x1003 + DTM_GETSYSTEMTIME = 0x1001 + DTM_SETFORMATA = 0x1005 + DTM_SETFORMATW = 0x1032 + DTM_SETMCCOLOR = 0x1006 + DTM_SETMCFONT = 0x1009 + DTM_SETRANGE = 0x1004 + DTM_SETSYSTEMTIME = 0x1002 +) + +const ( + HDM_CLEARFILTER = 0x1218 + HDM_CREATEDRAGIMAGE = 0x1210 + HDM_DELETEITEM = 0x1202 + HDM_EDITFILTER = 0x1217 + HDM_GETBITMAPMARGIN = 0x1215 + HDM_GETIMAGELIST = 0x1209 + HDM_GETITEM = 0x1203 + HDM_GETITEMCOUNT = 0x1200 + HDM_GETITEMRECT = 0x1207 + HDM_GETORDERARRAY = 0x1211 + HDM_GETUNICODEFORMAT = 0x2006 + HDM_HITTEST = 0x1206 + HDM_INSERTITEM = 0x1201 + HDM_LAYOUT = 0x1205 + HDM_ORDERTOINDEX = 0x120F + HDM_SETBITMAPMARGIN = 0x1214 + HDM_SETFILTERCHANGETIMEOUT = 0x1216 + HDM_SETHOTDIVIDER = 0x1213 + HDM_SETIMAGELIST = 0x1208 + HDM_SETITEM = 0x1204 + HDM_SETORDERARRAY = 0x1212 + HDM_SETUNICODEFORMAT = 0x2005 +) + +const ( + HKM_GETHOTKEY = 0x402 + HKM_SETHOTKEY = 0x401 + HKM_SETRULES = 0x403 +) + +const ( + IPM_CLEARADDRESS = 0x464 + IPM_GETADDRESS = 0x466 + IPM_ISBLANK = 0x469 + IPM_SETADDRESS = 0x465 + IPM_SETFOCUS = 0x468 + IPM_SETRANGE = 0x467 +) + +const ( + LBCB_CARETOFF = 0x01A4 + LBCB_CARETON = 0x01A3 +) + +const ( + MCM_GETCOLOR = 0x100B + MCM_GETCURSEL = 0x1001 + MCM_GETFIRSTDAYOFWEEK = 0x1010 + MCM_GETMAXSELCOUNT = 0x1003 + MCM_GETMAXTODAYWIDTH = 0x1015 + MCM_GETMINREQRECT = 0x1009 + MCM_GETMONTHDELTA = 0x1013 + MCM_GETMONTHRANGE = 0x1007 + MCM_GETRANGE = 0x1011 + MCM_GETSELRANGE = 0x1005 + MCM_GETTODAY = 0x100D + MCM_GETUNICODEFORMAT = 0x2006 + MCM_HITTEST = 0x100E + MCM_SETCOLOR = 0x100A + MCM_SETCURSEL = 0x1002 + MCM_SETDAYSTATE = 0x1008 + MCM_SETFIRSTDAYOFWEEK = 0x100F + MCM_SETMAXSELCOUNT = 0x1004 + MCM_SETMONTHDELTA = 0x1014 + MCM_SETRANGE = 0x1012 + MCM_SETSELRANGE = 0x1006 + MCM_SETTODAY = 0x100C + MCM_SETUNICODEFORMAT = 0x2005 +) + +const ( + MN_BUTTONDOWN = 0x01ED + MN_BUTTONUP = 0x01EF + MN_CANCELMENUS = 0x01E6 + MN_CLOSEHIERARCHY = 0x01E4 + MN_DBLCLK = 0x01F1 + MN_FINDMENUWINDOWFROMPOINT = 0x01EB + MN_GETHMENU = 0x01E1 + MN_GETPPOPUPMENU = 0x01EA + MN_MOUSEMOVE = 0x01EE + MN_OPENHIERARCHY = 0x01E3 + MN_SELECTFIRSTVALIDITEM = 0x01E7 + MN_SELECTITEM = 0x01E5 + MN_SETHMENU = 0x01E0 + MN_SETTIMERTOOPENHIERARCHY = 0x01F0 + MN_SHOWPOPUPWINDOW = 0x01EC + MN_SIZEWINDOW = 0x01E2 +) + +const ( + OCM_CHARTOITEM = 0x202F + OCM_COMMAND = 0x2111 + OCM_COMPAREITEM = 0x2039 + OCM_CTLCOLORBTN = 0x2135 + OCM_CTLCOLORDLG = 0x2136 + OCM_CTLCOLOREDIT = 0x2133 + OCM_CTLCOLORLISTBOX = 0x2134 + OCM_CTLCOLORMSGBOX = 0x2132 + OCM_CTLCOLORSCROLLBAR = 0x2137 + OCM_CTLCOLORSTATIC = 0x2138 + OCM_DELETEITEM = 0x202D + OCM_DRAWITEM = 0x202B + OCM_HSCROLL = 0x2114 + OCM_MEASUREITEM = 0x202C + OCM_NOTIFY = 0x204E + OCM_PARENTNOTIFY = 0x2210 + OCM_VKEYTOITEM = 0x202E + OCM_VSCROLL = 0x2115 +) + +const ( + PGM_FORWARDMOUSE = 0x1403 + PGM_GETBKCOLOR = 0x1405 + PGM_GETBORDER = 0x1407 + PGM_GETBUTTONSIZE = 0x140B + PGM_GETBUTTONSTATE = 0x140C + PGM_GETDROPTARGET = 0x2004 + PGM_GETPOS = 0x1409 + PGM_RECALCSIZE = 0x1402 + PGM_SETBKCOLOR = 0x1404 + PGM_SETBORDER = 0x1406 + PGM_SETBUTTONSIZE = 0x140A + PGM_SETCHILD = 0x1401 + PGM_SETPOS = 0x1408 +) + +const ( + PSM_ADDPAGE = 0x467 + PSM_APPLY = 0x46E + PSM_CANCELTOCLOSE = 0x46B + PSM_CHANGED = 0x468 + PSM_GETCURRENTPAGEHWND = 0x476 + PSM_GETRESULT = 0x487 + PSM_GETTABCONTROL = 0x474 + PSM_HWNDTOINDEX = 0x481 + PSM_IDTOINDEX = 0x485 + PSM_INDEXTOHWND = 0x482 + PSM_INDEXTOID = 0x486 + PSM_INDEXTOPAGE = 0x484 + PSM_INSERTPAGE = 0x477 + PSM_ISDIALOGMESSAGE = 0x475 + PSM_PAGETOINDEX = 0x483 + PSM_PRESSBUTTON = 0x471 + PSM_QUERYSIBLINGS = 0x46C + PSM_REBOOTSYSTEM = 0x46A + PSM_RECALCPAGESIZES = 0x488 + PSM_REMOVEPAGE = 0x466 + PSM_RESTARTWINDOWS = 0x469 + PSM_SETCURSEL = 0x465 + PSM_SETCURSELID = 0x472 + PSM_SETFINISHTEXT = 0x473 + PSM_SETHEADERSUBTITLEA = 0x47F + PSM_SETHEADERSUBTITLEW = 0x480 + PSM_SETHEADERTITLEA = 0x47D + PSM_SETHEADERTITLEW = 0x47E + PSM_SETTITLE = 0x46F + PSM_SETWIZBUTTONS = 0x470 + PSM_UNCHANGED = 0x46D +) + +const ( + RB_BEGINDRAG = 0x418 + RB_DELETEBAND = 0x402 + RB_DRAGMOVE = 0x41A + RB_ENDDRAG = 0x419 + RB_GETBANDBORDERS = 0x422 + RB_GETBANDCOUNT = 0x40C + RB_GETBANDINFO = 0x41D + RB_GETBANDINFOA = 0x41D + RB_GETBANDINFOW = 0x41C + RB_GETBARHEIGHT = 0x41B + RB_GETBARINFO = 0x403 + RB_GETBKCOLOR = 0x414 + RB_GETPALETTE = 0x426 + RB_GETRECT = 0x409 + RB_GETROWCOUNT = 0x40D + RB_GETROWHEIGHT = 0x40E + RB_GETTEXTCOLOR = 0x416 + RB_GETTOOLTIPS = 0x411 + RB_HITTEST = 0x408 + RB_IDTOINDEX = 0x410 + RB_INSERTBAND = 0x401 + RB_INSERTBANDA = 0x401 + RB_INSERTBANDW = 0x40A + RB_MAXIMIZEBAND = 0x41F + RB_MINIMIZEBAND = 0x41E + RB_MOVEBAND = 0x427 + RB_PUSHCHEVRON = 0x42B + RB_SETBANDINFO = 0x406 + RB_SETBANDINFOA = 0x406 + RB_SETBANDINFOW = 0x40B + RB_SETBARINFO = 0x404 + RB_SETBKCOLOR = 0x413 + RB_SETPALETTE = 0x425 + RB_SETPARENT = 0x407 + RB_SETTEXTCOLOR = 0x415 + RB_SETTOOLTIPS = 0x412 + RB_SHOWBAND = 0x423 + RB_SIZETORECT = 0x417 + RB_SETCOLORSCHEME = 0x2002 + RB_GETCOLORSCHEME = 0x2003 + RB_GETDROPTARGET = 0x2004 + RB_SETUNICODEFORMAT = 0x2005 + RB_GETUNICODEFORMAT = 0x2006 +) + +const ( + SBM_ENABLE_ARROWS = 0xE4 + SBM_GETPOS = 0xE1 + SBM_GETRANGE = 0xE3 + SBM_GETSCROLLINFO = 0xEA + SBM_SETPOS = 0xE0 + SBM_SETRANGE = 0xE2 + SBM_SETRANGEREDRAW = 0xE6 + SBM_SETSCROLLINFO = 0xE9 +) + +const ( + SB_GETBORDERS = 0x407 + SB_GETICON = 0x414 + SB_GETPARTS = 0x406 + SB_GETRECT = 0x40A + SB_GETTEXTA = 0x402 + SB_GETTEXTLENGTHA = 0x403 + SB_GETTEXTLENGTHW = 0x40C + SB_GETTEXTW = 0x40D + SB_GETTIPTEXTA = 0x412 + SB_GETTIPTEXTW = 0x413 + SB_ISSIMPLE = 0x40E + SB_SETICON = 0x40F + SB_SETMINHEIGHT = 0x408 + SB_SETPARTS = 0x404 + SB_SETTEXTA = 0x401 + SB_SETTEXTW = 0x40B + SB_SETTIPTEXTA = 0x410 + SB_SETTIPTEXTW = 0x411 + SB_SIMPLE = 0x409 + SB_SETBKCOLOR = 0x2001 + SB_SETUNICODEFORMAT = 0x2005 + SB_GETUNICODEFORMAT = 0x2006 +) + +const ( + STM_GETICON = 0x171 + STM_GETIMAGE = 0x173 + STM_SETICON = 0x170 + STM_SETIMAGE = 0x172 +) + +const ( + TB_ADDBITMAP = 0x413 + TB_ADDBUTTONS = 0x414 + TB_ADDSTRING = 0x41C + TB_AUTOSIZE = 0x421 + TB_BUTTONCOUNT = 0x418 + TB_BUTTONSTRUCTSIZE = 0x41E + TB_CHANGEBITMAP = 0x42B + TB_CHECKBUTTON = 0x402 + TB_COMMANDTOINDEX = 0x419 + TB_CUSTOMIZE = 0x41B + TB_DELETEBUTTON = 0x416 + TB_ENABLEBUTTON = 0x401 + TB_GETANCHORHIGHLIGHT = 0x44A + TB_GETBITMAP = 0x42C + TB_GETBITMAPFLAGS = 0x429 + TB_GETBUTTON = 0x417 + TB_GETBUTTONINFOA = 0x441 + TB_GETBUTTONINFOW = 0x43F + TB_GETBUTTONSIZE = 0x43A + TB_GETBUTTONTEXT = 0x42D + TB_GETCOLORSCHEME = 0x2003 + TB_GETDISABLEDIMAGELIST = 0x437 + TB_GETEXTENDEDSTYLE = 0x455 + TB_GETHOTIMAGELIST = 0x435 + TB_GETHOTITEM = 0x447 + TB_GETIMAGELIST = 0x431 + TB_GETINSERTMARK = 0x44F + TB_GETINSERTMARKCOLOR = 0x459 + TB_GETITEMRECT = 0x41D + TB_GETMAXSIZE = 0x453 + TB_GETOBJECT = 0x43E + TB_GETPADDING = 0x456 + TB_GETRECT = 0x433 + TB_GETROWS = 0x428 + TB_GETSTATE = 0x412 + TB_GETSTRING = 0x45C + TB_GETSTYLE = 0x439 + TB_GETTEXTROWS = 0x43D + TB_GETTOOLTIPS = 0x423 + TB_GETUNICODEFORMAT = 0x2006 + TB_HIDEBUTTON = 0x404 + TB_HITTEST = 0x445 + TB_INDETERMINATE = 0x405 + TB_INSERTBUTTON = 0x415 + TB_INSERTMARKHITTEST = 0x451 + TB_ISBUTTONCHECKED = 0x40A + TB_ISBUTTONENABLED = 0x409 + TB_ISBUTTONHIDDEN = 0x40C + TB_ISBUTTONHIGHLIGHTED = 0x40E + TB_ISBUTTONINDETERMINATE = 0x40D + TB_ISBUTTONPRESSED = 0x40B + TB_LOADIMAGES = 0x432 + TB_MAPACCELERATORA = 0x44E + TB_MAPACCELERATORW = 0x45A + TB_MARKBUTTON = 0x406 + TB_MOVEBUTTON = 0x452 + TB_PRESSBUTTON = 0x403 + TB_REPLACEBITMAP = 0x42E + TB_SAVERESTORE = 0x41A + TB_SETANCHORHIGHLIGHT = 0x449 + TB_SETBITMAPSIZE = 0x420 + TB_SETBUTTONINFOA = 0x442 + TB_SETBUTTONINFOW = 0x440 + TB_SETBUTTONSIZE = 0x41F + TB_SETBUTTONWIDTH = 0x43B + TB_SETCMDID = 0x42A + TB_SETCOLORSCHEME = 0x2002 + TB_SETDISABLEDIMAGELIST = 0x436 + TB_SETDRAWTEXTFLAGS = 0x446 + TB_SETEXTENDEDSTYLE = 0x454 + TB_SETHOTIMAGELIST = 0x434 + TB_SETHOTITEM = 0x448 + TB_SETIMAGELIST = 0x430 + TB_SETINDENT = 0x42F + TB_SETINSERTMARK = 0x450 + TB_SETINSERTMARKCOLOR = 0x458 + TB_SETMAXTEXTROWS = 0x43C + TB_SETPADDING = 0x457 + TB_SETPARENT = 0x425 + TB_SETROWS = 0x427 + TB_SETSTATE = 0x411 + TB_SETSTYLE = 0x438 + TB_SETTOOLTIPS = 0x424 + TB_SETUNICODEFORMAT = 0x2005 +) + +const ( + TCM_ADJUSTRECT = 0x1328 + TCM_DELETEALLITEMS = 0x1309 + TCM_DELETEITEM = 0x1308 + TCM_DESELECTALL = 0x1332 + TCM_GETCURFOCUS = 0x132F + TCM_GETCURSEL = 0x130B + TCM_GETEXTENDEDSTYLE = 0x1335 + TCM_GETIMAGELIST = 0x1302 + TCM_GETITEM = 0x1305 + TCM_GETITEMCOUNT = 0x1304 + TCM_GETITEMRECT = 0x130A + TCM_GETROWCOUNT = 0x132C + TCM_GETTOOLTIPS = 0x132D + TCM_GETUNICODEFORMAT = 0x2006 + TCM_HIGHLIGHTITEM = 0x1333 + TCM_HITTEST = 0x130D + TCM_INSERTITEM = 0x1307 + TCM_REMOVEIMAGE = 0x132A + TCM_SETCURFOCUS = 0x1330 + TCM_SETCURSEL = 0x130C + TCM_SETEXTENDEDSTYLE = 0x1334 + TCM_SETIMAGELIST = 0x1303 + TCM_SETITEM = 0x1306 + TCM_SETITEMEXTRA = 0x130E + TCM_SETITEMSIZE = 0x1329 + TCM_SETMINTABWIDTH = 0x1331 + TCM_SETPADDING = 0x132B + TCM_SETTOOLTIPS = 0x132E + TCM_SETUNICODEFORMAT = 0x2005 +) + +const ( + TVM_CREATEDRAGIMAGE = 0x1112 + TVM_DELETEITEM = 0x1101 + TVM_EDITLABEL = 0x110E + TVM_ENDEDITLABELNOW = 0x1116 + TVM_ENSUREVISIBLE = 0x1114 + TVM_EXPAND = 0x1102 + TVM_GETBKCOLOR = 0x111F + TVM_GETCOUNT = 0x1105 + TVM_GETEDITCONTROL = 0x110F + TVM_GETIMAGELIST = 0x1108 + TVM_GETINDENT = 0x1106 + TVM_GETINSERTMARKCOLOR = 0x1126 + TVM_GETISEARCHSTRING = 0x1117 + TVM_GETITEM = 0x110C + TVM_GETITEMHEIGHT = 0x111C + TVM_GETITEMRECT = 0x1104 + TVM_GETITEMSTATE = 0x1127 + TVM_GETLINECOLOR = 0x1129 + TVM_GETNEXTITEM = 0x110A + TVM_GETSCROLLTIME = 0x1122 + TVM_GETTEXTCOLOR = 0x1120 + TVM_GETTOOLTIPS = 0x1119 + TVM_GETUNICODEFORMAT = 0x2006 + TVM_GETVISIBLECOUNT = 0x1110 + TVM_HITTEST = 0x1111 + TVM_INSERTITEM = 0x1100 + TVM_SELECTITEM = 0x110B + TVM_SETBKCOLOR = 0x111D + TVM_SETIMAGELIST = 0x1109 + TVM_SETINDENT = 0x1107 + TVM_SETINSERTMARK = 0x111A + TVM_SETINSERTMARKCOLOR = 0x1125 + TVM_SETITEM = 0x110D + TVM_SETITEMHEIGHT = 0x111B + TVM_SETLINECOLOR = 0x1128 + TVM_SETSCROLLTIME = 0x1121 + TVM_SETTEXTCOLOR = 0x111E + TVM_SETTOOLTIPS = 0x1118 + TVM_SETUNICODEFORMAT = 0x2005 + TVM_SORTCHILDREN = 0x1113 + TVM_SORTCHILDRENCB = 0x1115 +) + +// PROCESS_DPI_AWARENESS +const ( + PROCESS_DPI_UNAWARE = 0 + PROCESS_SYSTEM_DPI_AWARE = 1 + PROCESS_PER_MONITOR_DPI_AWARE = 2 +) + +// WM_DEVICECHANGE WPARAM options +const ( + DBT_DEVNODES_CHANGED = 0x0007 + DBT_QUERYCHANGECONFIG = 0x0017 + DBT_CONFIGCHANGED = 0x0018 + DBT_CONFIGCHANGECANCELED = 0x0019 + DBT_DEVICEARRIVAL = 0x8000 + DBT_DEVICEQUERYREMOVE = 0x8001 + DBT_DEVICEQUERYREMOVEFAILED = 0x8002 + DBT_DEVICEREMOVEPENDING = 0x8003 + DBT_DEVICEREMOVECOMPLETE = 0x8004 + DBT_DEVICETYPESPECIFIC = 0x8005 + DBT_CUSTOMEVENT = 0x8006 + DBT_USERDEFINED = 0xFFFF +) + +const ( + SPI_GETACCESSTIMEOUT = 0x003C + SPI_GETAUDIODESCRIPTION = 0x0074 + SPI_GETCLIENTAREAANIMATION = 0x1042 + SPI_GETDISABLEOVERLAPPEDCONTENT = 0x1040 + SPI_GETFILTERKEYS = 0x0032 + SPI_GETFOCUSBORDERHEIGHT = 0x2010 + SPI_GETFOCUSBORDERWIDTH = 0x200E + SPI_GETHIGHCONTRAST = 0x0042 + SPI_GETLOGICALDPIOVERRIDE = 0x009E + SPI_GETMESSAGEDURATION = 0x2016 + SPI_GETMOUSECLICKLOCK = 0x101E + SPI_GETMOUSECLICKLOCKTIME = 0x2008 + SPI_GETMOUSEKEYS = 0x0036 + SPI_GETMOUSESONAR = 0x101C + SPI_GETMOUSEVANISH = 0x1020 + SPI_GETSCREENREADER = 0x0046 + SPI_GETSERIALKEYS = 0x003E + SPI_GETSHOWSOUNDS = 0x0038 + SPI_GETSOUNDSENTRY = 0x0040 + SPI_GETSTICKYKEYS = 0x003A + SPI_GETTOGGLEKEYS = 0x0034 + SPI_SETACCESSTIMEOUT = 0x003D + SPI_SETAUDIODESCRIPTION = 0x0075 + SPI_SETCLIENTAREAANIMATION = 0x1043 + SPI_SETDISABLEOVERLAPPEDCONTENT = 0x1041 + SPI_SETFILTERKEYS = 0x0033 + SPI_SETFOCUSBORDERHEIGHT = 0x2011 + SPI_SETFOCUSBORDERWIDTH = 0x200F + SPI_SETHIGHCONTRAST = 0x0043 + SPI_SETLOGICALDPIOVERRIDE = 0x009F + SPI_SETMESSAGEDURATION = 0x2017 + SPI_SETMOUSECLICKLOCK = 0x101F + SPI_SETMOUSECLICKLOCKTIME = 0x2009 + SPI_SETMOUSEKEYS = 0x0037 + SPI_SETMOUSESONAR = 0x101D + SPI_SETMOUSEVANISH = 0x1021 + SPI_SETSCREENREADER = 0x0047 + SPI_SETSERIALKEYS = 0x003F + SPI_SETSHOWSOUNDS = 0x0039 + SPI_SETSOUNDSENTRY = 0x0041 + SPI_SETSTICKYKEYS = 0x003B + SPI_SETTOGGLEKEYS = 0x0035 + SPI_GETCLEARTYPE = 0x1048 + SPI_GETDESKWALLPAPER = 0x0073 + SPI_GETDROPSHADOW = 0x1024 + SPI_GETFLATMENU = 0x1022 + SPI_GETFONTSMOOTHING = 0x004A + SPI_GETFONTSMOOTHINGCONTRAST = 0x200C + SPI_GETFONTSMOOTHINGORIENTATION = 0x2012 + SPI_GETFONTSMOOTHINGTYPE = 0x200A + SPI_GETWORKAREA = 0x0030 + SPI_SETCLEARTYPE = 0x1049 + SPI_SETCURSORS = 0x0057 + SPI_SETDESKPATTERN = 0x0015 + SPI_SETDESKWALLPAPER = 0x0014 + SPI_SETDROPSHADOW = 0x1025 + SPI_SETFLATMENU = 0x1023 + SPI_SETFONTSMOOTHING = 0x004B + SPI_SETFONTSMOOTHINGCONTRAST = 0x200D + SPI_SETFONTSMOOTHINGORIENTATION = 0x2013 + SPI_SETFONTSMOOTHINGTYPE = 0x200B + SPI_SETWORKAREA = 0x002F + SPI_GETICONMETRICS = 0x002D + SPI_GETICONTITLELOGFONT = 0x001F + SPI_GETICONTITLEWRAP = 0x0019 + SPI_ICONHORIZONTALSPACING = 0x000D + SPI_ICONVERTICALSPACING = 0x0018 + SPI_SETICONMETRICS = 0x002E + SPI_SETICONS = 0x0058 + SPI_SETICONTITLELOGFONT = 0x0022 + SPI_SETICONTITLEWRAP = 0x001A + SPI_GETBEEP = 0x0001 + SPI_GETBLOCKSENDINPUTRESETS = 0x1026 + SPI_GETCONTACTVISUALIZATION = 0x2018 + SPI_GETDEFAULTINPUTLANG = 0x0059 + SPI_GETGESTUREVISUALIZATION = 0x201A + SPI_GETKEYBOARDCUES = 0x100A + SPI_GETKEYBOARDDELAY = 0x0016 + SPI_GETKEYBOARDPREF = 0x0044 + SPI_GETKEYBOARDSPEED = 0x000A + SPI_GETMOUSE = 0x0003 + SPI_GETMOUSEHOVERHEIGHT = 0x0064 + SPI_GETMOUSEHOVERTIME = 0x0066 + SPI_GETMOUSEHOVERWIDTH = 0x0062 + SPI_GETMOUSESPEED = 0x0070 + SPI_GETMOUSETRAILS = 0x005E + SPI_GETMOUSEWHEELROUTING = 0x201C + SPI_GETPENVISUALIZATION = 0x201E + SPI_GETSNAPTODEFBUTTON = 0x005F + SPI_GETSYSTEMLANGUAGEBAR = 0x1050 + SPI_GETTHREADLOCALINPUTSETTINGS = 0x104E + SPI_GETWHEELSCROLLCHARS = 0x006C + SPI_GETWHEELSCROLLLINES = 0x0068 + SPI_SETBEEP = 0x0002 + SPI_SETBLOCKSENDINPUTRESETS = 0x1027 + SPI_SETCONTACTVISUALIZATION = 0x2019 + SPI_SETDEFAULTINPUTLANG = 0x005A + SPI_SETDOUBLECLICKTIME = 0x0020 + SPI_SETDOUBLECLKHEIGHT = 0x001E + SPI_SETDOUBLECLKWIDTH = 0x001D + SPI_SETGESTUREVISUALIZATION = 0x201B + SPI_SETKEYBOARDCUES = 0x100B + SPI_SETKEYBOARDDELAY = 0x0017 + SPI_SETKEYBOARDPREF = 0x0045 + SPI_SETKEYBOARDSPEED = 0x000B + SPI_SETLANGTOGGLE = 0x005B + SPI_SETMOUSE = 0x0004 + SPI_SETMOUSEBUTTONSWAP = 0x0021 + SPI_SETMOUSEHOVERHEIGHT = 0x0065 + SPI_SETMOUSEHOVERTIME = 0x0067 + SPI_SETMOUSEHOVERWIDTH = 0x0063 + SPI_SETMOUSESPEED = 0x0071 + SPI_SETMOUSETRAILS = 0x005D + SPI_SETMOUSEWHEELROUTING = 0x201D + SPI_SETPENVISUALIZATION = 0x201F + SPI_SETSNAPTODEFBUTTON = 0x0060 + SPI_SETSYSTEMLANGUAGEBAR = 0x1051 + SPI_SETTHREADLOCALINPUTSETTINGS = 0x104F + SPI_SETWHEELSCROLLCHARS = 0x006D + SPI_SETWHEELSCROLLLINES = 0x0069 + SPI_GETMENUDROPALIGNMENT = 0x001B + SPI_GETMENUFADE = 0x1012 + SPI_GETMENUSHOWDELAY = 0x006A + SPI_SETMENUDROPALIGNMENT = 0x001C + SPI_SETMENUFADE = 0x1013 + SPI_SETMENUSHOWDELAY = 0x006B + SPI_GETLOWPOWERACTIVE = 0x0053 + SPI_GETLOWPOWERTIMEOUT = 0x004F + SPI_GETPOWEROFFACTIVE = 0x0054 + SPI_GETPOWEROFFTIMEOUT = 0x0050 + SPI_SETLOWPOWERACTIVE = 0x0055 + SPI_SETLOWPOWERTIMEOUT = 0x0051 + SPI_SETPOWEROFFACTIVE = 0x0056 + SPI_SETPOWEROFFTIMEOUT = 0x0052 + SPI_GETSCREENSAVEACTIVE = 0x0010 + SPI_GETSCREENSAVERRUNNING = 0x0072 + SPI_GETSCREENSAVESECURE = 0x0076 + SPI_GETSCREENSAVETIMEOUT = 0x000E + SPI_SETSCREENSAVEACTIVE = 0x0011 + SPI_SETSCREENSAVESECURE = 0x0077 + SPI_SETSCREENSAVETIMEOUT = 0x000F + SPI_GETHUNGAPPTIMEOUT = 0x0078 + SPI_GETWAITTOKILLTIMEOUT = 0x007A + SPI_GETWAITTOKILLSERVICETIMEOUT = 0x007C + SPI_SETHUNGAPPTIMEOUT = 0x0079 + SPI_SETWAITTOKILLTIMEOUT = 0x007B + SPI_SETWAITTOKILLSERVICETIMEOUT = 0x007D + SPI_GETCOMBOBOXANIMATION = 0x1004 + SPI_GETCURSORSHADOW = 0x101A + SPI_GETGRADIENTCAPTIONS = 0x1008 + SPI_GETHOTTRACKING = 0x100E + SPI_GETLISTBOXSMOOTHSCROLLING = 0x1006 + SPI_GETMENUANIMATION = 0x1002 + SPI_GETMENUUNDERLINES = 0x100A + SPI_GETSELECTIONFADE = 0x1014 + SPI_GETTOOLTIPANIMATION = 0x1016 + SPI_GETTOOLTIPFADE = 0x1018 + SPI_GETUIEFFECTS = 0x103E + SPI_SETCOMBOBOXANIMATION = 0x1005 + SPI_SETCURSORSHADOW = 0x101B + SPI_SETGRADIENTCAPTIONS = 0x1009 + SPI_SETHOTTRACKING = 0x100F + SPI_SETLISTBOXSMOOTHSCROLLING = 0x1007 + SPI_SETMENUANIMATION = 0x1003 + SPI_SETMENUUNDERLINES = 0x100B + SPI_SETSELECTIONFADE = 0x1015 + SPI_SETTOOLTIPANIMATION = 0x1017 + SPI_SETTOOLTIPFADE = 0x1019 + SPI_SETUIEFFECTS = 0x103F + SPI_GETACTIVEWINDOWTRACKING = 0x1000 + SPI_GETACTIVEWNDTRKZORDER = 0x100C + SPI_GETACTIVEWNDTRKTIMEOUT = 0x2002 + SPI_GETANIMATION = 0x0048 + SPI_GETBORDER = 0x0005 + SPI_GETCARETWIDTH = 0x2006 + SPI_GETDOCKMOVING = 0x0090 + SPI_GETDRAGFROMMAXIMIZE = 0x008C + SPI_GETDRAGFULLWINDOWS = 0x0026 + SPI_GETFOREGROUNDFLASHCOUNT = 0x2004 + SPI_GETFOREGROUNDLOCKTIMEOUT = 0x2000 + SPI_GETMINIMIZEDMETRICS = 0x002B + SPI_GETMOUSEDOCKTHRESHOLD = 0x007E + SPI_GETMOUSEDRAGOUTTHRESHOLD = 0x0084 + SPI_GETMOUSESIDEMOVETHRESHOLD = 0x0088 + SPI_GETNONCLIENTMETRICS = 0x0029 + SPI_GETPENDOCKTHRESHOLD = 0x0080 + SPI_GETPENDRAGOUTTHRESHOLD = 0x0086 + SPI_GETPENSIDEMOVETHRESHOLD = 0x008A + SPI_GETSHOWIMEUI = 0x006E + SPI_GETSNAPSIZING = 0x008E + SPI_GETWINARRANGING = 0x0082 + SPI_SETACTIVEWINDOWTRACKING = 0x1001 + SPI_SETACTIVEWNDTRKZORDER = 0x100D + SPI_SETACTIVEWNDTRKTIMEOUT = 0x2003 + SPI_SETANIMATION = 0x0049 + SPI_SETBORDER = 0x0006 + SPI_SETCARETWIDTH = 0x2007 + SPI_SETDOCKMOVING = 0x0091 + SPI_SETDRAGFROMMAXIMIZE = 0x008D + SPI_SETDRAGFULLWINDOWS = 0x0025 + SPI_SETDRAGHEIGHT = 0x004D + SPI_SETDRAGWIDTH = 0x004C + SPI_SETFOREGROUNDFLASHCOUNT = 0x2005 + SPI_SETFOREGROUNDLOCKTIMEOUT = 0x2001 + SPI_SETMINIMIZEDMETRICS = 0x002C + SPI_SETMOUSEDOCKTHRESHOLD = 0x007F + SPI_SETMOUSEDRAGOUTTHRESHOLD = 0x0085 + SPI_SETMOUSESIDEMOVETHRESHOLD = 0x0089 + SPI_SETNONCLIENTMETRICS = 0x002A + SPI_SETPENDOCKTHRESHOLD = 0x0081 + SPI_SETPENDRAGOUTTHRESHOLD = 0x0087 + SPI_SETPENSIDEMOVETHRESHOLD = 0x008B + SPI_SETSHOWIMEUI = 0x006F + SPI_SETSNAPSIZING = 0x008F + SPI_SETWINARRANGING = 0x0083 +) + +const ( + SPIF_UPDATEINIFILE = 0x1 + SPIF_SENDCHANGE = 0x2 + SPIF_SENDWININICHANGE = SPIF_SENDCHANGE +) diff --git a/v3/internal/w32/functions.go b/v3/internal/w32/functions.go new file mode 100644 index 000000000..d521a3397 --- /dev/null +++ b/v3/internal/w32/functions.go @@ -0,0 +1,4794 @@ +package w32 + +import ( + "errors" + "fmt" + "strconv" + "syscall" + "unsafe" +) + +var ( + user32 = syscall.NewLazyDLL("user32.dll") + advapi32 = syscall.NewLazyDLL("advapi32.dll") + comctl32 = syscall.NewLazyDLL("comctl32.dll") + comdlg32 = syscall.NewLazyDLL("comdlg32.dll") + dwmapi = syscall.NewLazyDLL("dwmapi.dll") + gdi32 = syscall.NewLazyDLL("gdi32.dll") + kernel32 = syscall.NewLazyDLL("kernel32.dll") + ole32 = syscall.NewLazyDLL("ole32.dll") + oleaut32 = syscall.NewLazyDLL("oleaut32") + opengl32 = syscall.NewLazyDLL("opengl32.dll") + psapi = syscall.NewLazyDLL("psapi.dll") + shell32 = syscall.NewLazyDLL("shell32.dll") + gdiplus = syscall.NewLazyDLL("gdiplus.dll") + version = syscall.NewLazyDLL("version.dll") + winmm = syscall.NewLazyDLL("winmm.dll") + dxva2 = syscall.NewLazyDLL("dxva2.dll") + msimg32 = syscall.NewLazyDLL("msimg32.dll") + mpr = syscall.NewLazyDLL("mpr.dll") + ntoskrnl = syscall.NewLazyDLL("ntoskrnl.exe") + ntdll = syscall.NewLazyDLL("ntdll.dll") + setupAPI = syscall.NewLazyDLL("SetupAPI.dll") + shcore = syscall.NewLazyDLL("Shcore.dll") + + registerClassEx = user32.NewProc("RegisterClassExW") + unregisterClass = user32.NewProc("UnregisterClassW") + getClassInfoEx = user32.NewProc("GetClassInfoExW") + loadIcon = user32.NewProc("LoadIconW") + loadCursor = user32.NewProc("LoadCursorW") + showWindow = user32.NewProc("ShowWindow") + showWindowAsync = user32.NewProc("ShowWindowAsync") + updateWindow = user32.NewProc("UpdateWindow") + createWindow = user32.NewProc("CreateWindowW") + createWindowEx = user32.NewProc("CreateWindowExW") + adjustWindowRect = user32.NewProc("AdjustWindowRect") + adjustWindowRectEx = user32.NewProc("AdjustWindowRectEx") + destroyWindow = user32.NewProc("DestroyWindow") + defWindowProc = user32.NewProc("DefWindowProcW") + defDlgProc = user32.NewProc("DefDlgProcW") + postQuitMessage = user32.NewProc("PostQuitMessage") + getMessage = user32.NewProc("GetMessageW") + getMessageTime = user32.NewProc("GetMessageTime") + translateMessage = user32.NewProc("TranslateMessage") + dispatchMessage = user32.NewProc("DispatchMessageW") + sendMessage = user32.NewProc("SendMessageW") + postMessage = user32.NewProc("PostMessageW") + waitMessage = user32.NewProc("WaitMessage") + setWindowText = user32.NewProc("SetWindowTextW") + getWindowTextLength = user32.NewProc("GetWindowTextLengthW") + getWindowText = user32.NewProc("GetWindowTextW") + getWindowRect = user32.NewProc("GetWindowRect") + getWindowInfo = user32.NewProc("GetWindowInfo") + moveWindow = user32.NewProc("MoveWindow") + screenToClient = user32.NewProc("ScreenToClient") + callWindowProc = user32.NewProc("CallWindowProcW") + setWindowLong = user32.NewProc("SetWindowLongW") + setWindowLongPtr = user32.NewProc("SetWindowLongPtrW") + setClassLongPtr = user32.NewProc("SetClassLongPtrW") + setClassLong = user32.NewProc("SetClassLongW") + getWindowLong = user32.NewProc("GetWindowLongW") + getWindowLongPtr = user32.NewProc("GetWindowLongPtrW") + getClassLongPtr = user32.NewProc("GetClassLongPtrW") + getClassLong = user32.NewProc("GetClassLongW") + enableWindow = user32.NewProc("EnableWindow") + isWindowEnabled = user32.NewProc("IsWindowEnabled") + isWindowVisible = user32.NewProc("IsWindowVisible") + setFocus = user32.NewProc("SetFocus") + invalidateRect = user32.NewProc("InvalidateRect") + validateRect = user32.NewProc("ValidateRect") + getClientRect = user32.NewProc("GetClientRect") + getDC = user32.NewProc("GetDC") + releaseDC = user32.NewProc("ReleaseDC") + setCapture = user32.NewProc("SetCapture") + releaseCapture = user32.NewProc("ReleaseCapture") + getWindowThreadProcessId = user32.NewProc("GetWindowThreadProcessId") + messageBox = user32.NewProc("MessageBoxW") + messageBoxIndirect = user32.NewProc("MessageBoxIndirectW") + getSystemMetrics = user32.NewProc("GetSystemMetrics") + copyRect = user32.NewProc("CopyRect") + equalRect = user32.NewProc("EqualRect") + inflateRect = user32.NewProc("InflateRect") + intersectRect = user32.NewProc("IntersectRect") + isRectEmpty = user32.NewProc("IsRectEmpty") + offsetRect = user32.NewProc("OffsetRect") + ptInRect = user32.NewProc("PtInRect") + setRect = user32.NewProc("SetRect") + setRectEmpty = user32.NewProc("SetRectEmpty") + subtractRect = user32.NewProc("SubtractRect") + unionRect = user32.NewProc("UnionRect") + createDialogParam = user32.NewProc("CreateDialogParamW") + dialogBoxParam = user32.NewProc("DialogBoxParamW") + getDlgItem = user32.NewProc("GetDlgItem") + drawIcon = user32.NewProc("DrawIcon") + drawIconEx = user32.NewProc("DrawIconEx") + clientToScreen = user32.NewProc("ClientToScreen") + isDialogMessage = user32.NewProc("IsDialogMessageW") + isWindow = user32.NewProc("IsWindow") + endDialog = user32.NewProc("EndDialog") + peekMessage = user32.NewProc("PeekMessageW") + createAcceleratorTable = user32.NewProc("CreateAcceleratorTableW") + destroyAcceleratorTable = user32.NewProc("DestroyAcceleratorTable") + translateAccelerator = user32.NewProc("TranslateAcceleratorW") + setWindowPos = user32.NewProc("SetWindowPos") + fillRect = user32.NewProc("FillRect") + drawText = user32.NewProc("DrawTextW") + addClipboardFormatListener = user32.NewProc("AddClipboardFormatListener") + removeClipboardFormatListener = user32.NewProc("RemoveClipboardFormatListener") + openClipboard = user32.NewProc("OpenClipboard") + closeClipboard = user32.NewProc("CloseClipboard") + enumClipboardFormats = user32.NewProc("EnumClipboardFormats") + getClipboardData = user32.NewProc("GetClipboardData") + setClipboardData = user32.NewProc("SetClipboardData") + emptyClipboard = user32.NewProc("EmptyClipboard") + getClipboardFormatName = user32.NewProc("GetClipboardFormatNameW") + isClipboardFormatAvailable = user32.NewProc("IsClipboardFormatAvailable") + beginPaint = user32.NewProc("BeginPaint") + endPaint = user32.NewProc("EndPaint") + getKeyboardState = user32.NewProc("GetKeyboardState") + mapVirtualKey = user32.NewProc("MapVirtualKeyW") + mapVirtualKeyEx = user32.NewProc("MapVirtualKeyExW") + getAsyncKeyState = user32.NewProc("GetAsyncKeyState") + toAscii = user32.NewProc("ToAscii") + swapMouseButton = user32.NewProc("SwapMouseButton") + getCursorPos = user32.NewProc("GetCursorPos") + setCursorPos = user32.NewProc("SetCursorPos") + setCursor = user32.NewProc("SetCursor") + createIcon = user32.NewProc("CreateIcon") + createIconFromResource = user32.NewProc("CreateIconFromResource") + createIconFromResourceEx = user32.NewProc("CreateIconFromResourceEx") + destroyIcon = user32.NewProc("DestroyIcon") + monitorFromPoint = user32.NewProc("MonitorFromPoint") + monitorFromRect = user32.NewProc("MonitorFromRect") + monitorFromWindow = user32.NewProc("MonitorFromWindow") + getMonitorInfo = user32.NewProc("GetMonitorInfoW") + enumDisplayMonitors = user32.NewProc("EnumDisplayMonitors") + enumDisplaySettingsEx = user32.NewProc("EnumDisplaySettingsExW") + changeDisplaySettingsEx = user32.NewProc("ChangeDisplaySettingsExW") + sendInput = user32.NewProc("SendInput") + setWindowsHookEx = user32.NewProc("SetWindowsHookExW") + unhookWindowsHookEx = user32.NewProc("UnhookWindowsHookEx") + callNextHookEx = user32.NewProc("CallNextHookEx") + getWindowPlacement = user32.NewProc("GetWindowPlacement") + setWindowPlacement = user32.NewProc("SetWindowPlacement") + showCursor = user32.NewProc("ShowCursor") + loadImage = user32.NewProc("LoadImageW") + getForegroundWindow = user32.NewProc("GetForegroundWindow") + findWindow = user32.NewProc("FindWindowW") + getClassName = user32.NewProc("GetClassNameW") + getDesktopWindow = user32.NewProc("GetDesktopWindow") + getRawInputData = user32.NewProc("GetRawInputData") + registerPowerSettingNotification = user32.NewProc("RegisterPowerSettingNotification") + registerRawInputDevices = user32.NewProc("RegisterRawInputDevices") + setTimer = user32.NewProc("SetTimer") + getActiveWindow = user32.NewProc("GetActiveWindow") + messageBeep = user32.NewProc("MessageBeep") + beep = kernel32.NewProc("Beep") + getCaretBlinkTime = user32.NewProc("GetCaretBlinkTime") + getWindowDC = user32.NewProc("GetWindowDC") + enumWindows = user32.NewProc("EnumWindows") + enumChildWindows = user32.NewProc("EnumChildWindows") + getTopWindow = user32.NewProc("GetTopWindow") + getWindow = user32.NewProc("GetWindow") + getKeyState = user32.NewProc("GetKeyState") + getSysColor = user32.NewProc("GetSysColor") + getSysColorBrush = user32.NewProc("GetSysColorBrush") + appendMenu = user32.NewProc("AppendMenuW") + checkMenuItem = user32.NewProc("CheckMenuItem") + checkMenuRadioItem = user32.NewProc("CheckMenuRadioItem") + createMenu = user32.NewProc("CreateMenu") + createPopupMenu = user32.NewProc("CreatePopupMenu") + deleteMenu = user32.NewProc("DeleteMenu") + destroyMenu = user32.NewProc("DestroyMenu") + drawMenuBar = user32.NewProc("DrawMenuBar") + enableMenuItem = user32.NewProc("EnableMenuItem") + endMenu = user32.NewProc("EndMenu") + getMenu = user32.NewProc("GetMenu") + getMenuBarInfo = user32.NewProc("GetMenuBarInfo") + getMenuCheckMarkDimensions = user32.NewProc("GetMenuCheckMarkDimensions") + getMenuDefaultItem = user32.NewProc("GetMenuDefaultItem") + getMenuInfo = user32.NewProc("GetMenuInfo") + getMenuItemCount = user32.NewProc("GetMenuItemCount") + getMenuItemID = user32.NewProc("GetMenuItemID") + getMenuItemInfo = user32.NewProc("GetMenuItemInfoW") + getMenuItemRect = user32.NewProc("GetMenuItemRect") + getMenuState = user32.NewProc("GetMenuState") + getMenuString = user32.NewProc("GetMenuStringW") + getSubMenu = user32.NewProc("GetSubMenu") + getSystemMenu = user32.NewProc("GetSystemMenu") + hiliteMenuItem = user32.NewProc("HiliteMenuItem") + insertMenu = user32.NewProc("InsertMenuW") + insertMenuItem = user32.NewProc("InsertMenuItemW") + isMenu = user32.NewProc("IsMenu") + loadMenu = user32.NewProc("LoadMenuW") + loadMenuIndirect = user32.NewProc("LoadMenuIndirectW") + menuItemFromPoint = user32.NewProc("MenuItemFromPoint") + modifyMenu = user32.NewProc("ModifyMenuW") + removeMenu = user32.NewProc("RemoveMenu") + setMenu = user32.NewProc("SetMenu") + setMenuDefaultItem = user32.NewProc("SetMenuDefaultItem") + setMenuInfo = user32.NewProc("SetMenuInfo") + setMenuItemBitmaps = user32.NewProc("SetMenuItemBitmaps") + setMenuItemInfo = user32.NewProc("SetMenuItemInfoW") + trackPopupMenu = user32.NewProc("TrackPopupMenu") + trackPopupMenuEx = user32.NewProc("TrackPopupMenuEx") + isDlgButtonChecked = user32.NewProc("IsDlgButtonChecked") + sendDlgItemMessage = user32.NewProc("SendDlgItemMessageW") + lookupIconIdFromDirectoryEx = user32.NewProc("LookupIconIdFromDirectoryEx") + setForegroundWindow = user32.NewProc("SetForegroundWindow") + scrollWindow = user32.NewProc("ScrollWindow") + getFocus = user32.NewProc("GetFocus") + printWindow = user32.NewProc("PrintWindow") + setLayeredWindowAttributes = user32.NewProc("SetLayeredWindowAttributes") + redrawWindow = user32.NewProc("RedrawWindow") + createCursor = user32.NewProc("CreateCursor") + destroyCursor = user32.NewProc("DestroyCursor") + getDlgCtrlID = user32.NewProc("GetDlgCtrlID") + systemParametersInfo = user32.NewProc("SystemParametersInfoW") + + regCreateKeyEx = advapi32.NewProc("RegCreateKeyExW") + regOpenKeyEx = advapi32.NewProc("RegOpenKeyExW") + regCloseKey = advapi32.NewProc("RegCloseKey") + regGetValue = advapi32.NewProc("RegGetValueW") + regEnumKeyEx = advapi32.NewProc("RegEnumKeyExW") + regEnumValue = advapi32.NewProc("RegEnumValueW") + regSetValueEx = advapi32.NewProc("RegSetValueExW") + regDeleteKeyValue = advapi32.NewProc("RegDeleteKeyValueW") + regDeleteValue = advapi32.NewProc("RegDeleteValueW") + regDeleteTree = advapi32.NewProc("RegDeleteTreeW") + openEventLog = advapi32.NewProc("OpenEventLogW") + getNumberOfEventLogRecords = advapi32.NewProc("GetNumberOfEventLogRecords") + readEventLog = advapi32.NewProc("ReadEventLogW") + closeEventLog = advapi32.NewProc("CloseEventLog") + openSCManager = advapi32.NewProc("OpenSCManagerW") + closeServiceHandle = advapi32.NewProc("CloseServiceHandle") + openService = advapi32.NewProc("OpenServiceW") + startService = advapi32.NewProc("StartServiceW") + controlService = advapi32.NewProc("ControlService") + + initCommonControlsEx = comctl32.NewProc("InitCommonControlsEx") + imageList_Create = comctl32.NewProc("ImageList_Create") + imageList_Destroy = comctl32.NewProc("ImageList_Destroy") + imageList_GetImageCount = comctl32.NewProc("ImageList_GetImageCount") + imageList_SetImageCount = comctl32.NewProc("ImageList_SetImageCount") + imageList_Add = comctl32.NewProc("ImageList_Add") + imageList_ReplaceIcon = comctl32.NewProc("ImageList_ReplaceIcon") + imageList_Remove = comctl32.NewProc("ImageList_Remove") + trackMouseEvent = comctl32.NewProc("_TrackMouseEvent") + setWindowSubclass = comctl32.NewProc("SetWindowSubclass") + defSubclassProc = comctl32.NewProc("DefSubclassProc") + + getSaveFileName = comdlg32.NewProc("GetSaveFileNameW") + getOpenFileName = comdlg32.NewProc("GetOpenFileNameW") + commDlgExtendedError = comdlg32.NewProc("CommDlgExtendedError") + + dwmDefWindowProc = dwmapi.NewProc("DwmDefWindowProc") + dwmEnableBlurBehindWindow = dwmapi.NewProc("DwmEnableBlurBehindWindow") + dwmEnableMMCSS = dwmapi.NewProc("DwmEnableMMCSS") + dwmExtendFrameIntoClientArea = dwmapi.NewProc("DwmExtendFrameIntoClientArea") + dwmFlush = dwmapi.NewProc("DwmFlush") + dwmGetColorizationColor = dwmapi.NewProc("DwmGetColorizationColor") + dwmGetCompositionTimingInfo = dwmapi.NewProc("DwmGetCompositionTimingInfo") + dwmGetTransportAttributes = dwmapi.NewProc("DwmGetTransportAttributes") + dwmGetWindowAttribute = dwmapi.NewProc("DwmGetWindowAttribute") + dwmInvalidateIconicBitmaps = dwmapi.NewProc("DwmInvalidateIconicBitmaps") + dwmIsCompositionEnabled = dwmapi.NewProc("DwmIsCompositionEnabled") + dwmModifyPreviousDxFrameDuration = dwmapi.NewProc("DwmModifyPreviousDxFrameDuration") + dwmQueryThumbnailSourceSize = dwmapi.NewProc("DwmQueryThumbnailSourceSize") + dwmRegisterThumbnail = dwmapi.NewProc("DwmRegisterThumbnail") + dwmRenderGesture = dwmapi.NewProc("DwmRenderGesture") + dwmSetDxFrameDuration = dwmapi.NewProc("DwmSetDxFrameDuration") + dwmSetIconicLivePreviewBitmap = dwmapi.NewProc("DwmSetIconicLivePreviewBitmap") + dwmSetIconicThumbnail = dwmapi.NewProc("DwmSetIconicThumbnail") + dwmSetPresentParameters = dwmapi.NewProc("DwmSetPresentParameters") + dwmSetWindowAttribute = dwmapi.NewProc("DwmSetWindowAttribute") + dwmShowContact = dwmapi.NewProc("DwmShowContact") + dwmTetherContact = dwmapi.NewProc("DwmTetherContact") + dwmTransitionOwnedWindow = dwmapi.NewProc("DwmTransitionOwnedWindow") + dwmUnregisterThumbnail = dwmapi.NewProc("DwmUnregisterThumbnail") + dwmUpdateThumbnailProperties = dwmapi.NewProc("DwmUpdateThumbnailProperties") + + getDeviceCaps = gdi32.NewProc("GetDeviceCaps") + deleteObject = gdi32.NewProc("DeleteObject") + createFontIndirect = gdi32.NewProc("CreateFontIndirectW") + abortDoc = gdi32.NewProc("AbortDoc") + bitBlt = gdi32.NewProc("BitBlt") + maskBlt = gdi32.NewProc("MaskBlt") + patBlt = gdi32.NewProc("PatBlt") + closeEnhMetaFile = gdi32.NewProc("CloseEnhMetaFile") + copyEnhMetaFile = gdi32.NewProc("CopyEnhMetaFileW") + createBrushIndirect = gdi32.NewProc("CreateBrushIndirect") + createCompatibleDC = gdi32.NewProc("CreateCompatibleDC") + createCompatibleBitmap = gdi32.NewProc("CreateCompatibleBitmap") + createBitmap = gdi32.NewProc("CreateBitmap") + createDC = gdi32.NewProc("CreateDCW") + createDIBSection = gdi32.NewProc("CreateDIBSection") + createEnhMetaFile = gdi32.NewProc("CreateEnhMetaFileW") + createIC = gdi32.NewProc("CreateICW") + deleteDC = gdi32.NewProc("DeleteDC") + deleteEnhMetaFile = gdi32.NewProc("DeleteEnhMetaFile") + ellipse = gdi32.NewProc("Ellipse") + endDoc = gdi32.NewProc("EndDoc") + endPage = gdi32.NewProc("EndPage") + extCreatePen = gdi32.NewProc("ExtCreatePen") + getEnhMetaFile = gdi32.NewProc("GetEnhMetaFileW") + getEnhMetaFileHeader = gdi32.NewProc("GetEnhMetaFileHeader") + getObject = gdi32.NewProc("GetObjectW") + getStockObject = gdi32.NewProc("GetStockObject") + getTextExtentExPoint = gdi32.NewProc("GetTextExtentExPointW") + getTextExtentPoint32 = gdi32.NewProc("GetTextExtentPoint32W") + getTextMetrics = gdi32.NewProc("GetTextMetricsW") + lineTo = gdi32.NewProc("LineTo") + moveToEx = gdi32.NewProc("MoveToEx") + playEnhMetaFile = gdi32.NewProc("PlayEnhMetaFile") + rectangle = gdi32.NewProc("Rectangle") + resetDC = gdi32.NewProc("ResetDCW") + selectObject = gdi32.NewProc("SelectObject") + setBkMode = gdi32.NewProc("SetBkMode") + setBrushOrgEx = gdi32.NewProc("SetBrushOrgEx") + setStretchBltMode = gdi32.NewProc("SetStretchBltMode") + setTextColor = gdi32.NewProc("SetTextColor") + setBkColor = gdi32.NewProc("SetBkColor") + startDoc = gdi32.NewProc("StartDocW") + startPage = gdi32.NewProc("StartPage") + stretchBlt = gdi32.NewProc("StretchBlt") + setDIBitsToDevice = gdi32.NewProc("SetDIBitsToDevice") + choosePixelFormat = gdi32.NewProc("ChoosePixelFormat") + describePixelFormat = gdi32.NewProc("DescribePixelFormat") + getEnhMetaFilePixelFormat = gdi32.NewProc("GetEnhMetaFilePixelFormat") + getPixelFormat = gdi32.NewProc("GetPixelFormat") + setPixelFormat = gdi32.NewProc("SetPixelFormat") + swapBuffers = gdi32.NewProc("SwapBuffers") + textOut = gdi32.NewProc("TextOutW") + createSolidBrush = gdi32.NewProc("CreateSolidBrush") + getDIBits = gdi32.NewProc("GetDIBits") + pie = gdi32.NewProc("Pie") + setDCPenColor = gdi32.NewProc("SetDCPenColor") + setDCBrushColor = gdi32.NewProc("SetDCBrushColor") + createPen = gdi32.NewProc("CreatePen") + arc = gdi32.NewProc("Arc") + arcTo = gdi32.NewProc("ArcTo") + angleArc = gdi32.NewProc("AngleArc") + chord = gdi32.NewProc("Chord") + polygon = gdi32.NewProc("Polygon") + polyline = gdi32.NewProc("Polyline") + polyBezier = gdi32.NewProc("PolyBezier") + intersectClipRect = gdi32.NewProc("IntersectClipRect") + selectClipRgn = gdi32.NewProc("SelectClipRgn") + createRectRgn = gdi32.NewProc("CreateRectRgn") + combineRgn = gdi32.NewProc("CombineRgn") + enumFontFamiliesEx = gdi32.NewProc("EnumFontFamiliesExW") + + getModuleHandle = kernel32.NewProc("GetModuleHandleW") + getModuleFileName = kernel32.NewProc("GetModuleFileNameW") + mulDiv = kernel32.NewProc("MulDiv") + getConsoleWindow = kernel32.NewProc("GetConsoleWindow") + getCurrentThread = kernel32.NewProc("GetCurrentThread") + getLogicalDrives = kernel32.NewProc("GetLogicalDrives") + getDriveType = kernel32.NewProc("GetDriveTypeW") + getUserDefaultLCID = kernel32.NewProc("GetUserDefaultLCID") + lstrlen = kernel32.NewProc("lstrlenW") + lstrcpy = kernel32.NewProc("lstrcpyW") + globalAlloc = kernel32.NewProc("GlobalAlloc") + globalFree = kernel32.NewProc("GlobalFree") + globalLock = kernel32.NewProc("GlobalLock") + globalUnlock = kernel32.NewProc("GlobalUnlock") + moveMemory = kernel32.NewProc("RtlMoveMemory") + findResource = kernel32.NewProc("FindResourceW") + sizeofResource = kernel32.NewProc("SizeofResource") + lockResource = kernel32.NewProc("LockResource") + loadResource = kernel32.NewProc("LoadResource") + getLastError = kernel32.NewProc("GetLastError") + openProcess = kernel32.NewProc("OpenProcess") + terminateProcess = kernel32.NewProc("TerminateProcess") + closeHandle = kernel32.NewProc("CloseHandle") + createToolhelp32Snapshot = kernel32.NewProc("CreateToolhelp32Snapshot") + module32First = kernel32.NewProc("Module32FirstW") + module32Next = kernel32.NewProc("Module32NextW") + getSystemTimes = kernel32.NewProc("GetSystemTimes") + getConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo") + setConsoleTextAttribute = kernel32.NewProc("SetConsoleTextAttribute") + getDiskFreeSpaceEx = kernel32.NewProc("GetDiskFreeSpaceExW") + getProcessTimes = kernel32.NewProc("GetProcessTimes") + setSystemTime = kernel32.NewProc("SetSystemTime") + setLocalTime = kernel32.NewProc("SetLocalTime") + getSystemTime = kernel32.NewProc("GetSystemTime") + getSystemTimeAsFileTime = kernel32.NewProc("GetSystemTimeAsFileTime") + systemTimeToFileTime = kernel32.NewProc("SystemTimeToFileTime") + fileTimeToSystemTime = kernel32.NewProc("FileTimeToSystemTime") + copyMemory = kernel32.NewProc("RtlCopyMemory") + getCurrentProcess = kernel32.NewProc("GetCurrentProcess") + getCurrentProcessId = kernel32.NewProc("GetCurrentProcessId") + getVersion = kernel32.NewProc("GetVersion") + setEnvironmentVariable = kernel32.NewProc("SetEnvironmentVariableW") + getComputerName = kernel32.NewProc("GetComputerNameW") + activateActCtx = kernel32.NewProc("ActivateActCtx") + createActCtx = kernel32.NewProc("CreateActCtxW") + getCurrentActCtx = kernel32.NewProc("GetCurrentActCtx") + setErrorMode = kernel32.NewProc("SetErrorMode") + createFile = kernel32.NewProc("CreateFileW") + deviceIoControl = kernel32.NewProc("DeviceIoControl") + findFirstStream = kernel32.NewProc("FindFirstStreamW") + findNextStream = kernel32.NewProc("FindNextStreamW") + findClose = kernel32.NewProc("FindClose") + openMutex = kernel32.NewProc("OpenMutexW") + createMutex = kernel32.NewProc("CreateMutexW") + getNativeSystemInfo = kernel32.NewProc("GetNativeSystemInfo") + + coInitializeEx = ole32.NewProc("CoInitializeEx") + coInitialize = ole32.NewProc("CoInitialize") + coUninitialize = ole32.NewProc("CoUninitialize") + createStreamOnHGlobal = ole32.NewProc("CreateStreamOnHGlobal") + + variantInit = oleaut32.NewProc("VariantInit") + sysAllocString = oleaut32.NewProc("SysAllocString") + sysFreeString = oleaut32.NewProc("SysFreeString") + sysStringLen = oleaut32.NewProc("SysStringLen") + createDispTypeInfo = oleaut32.NewProc("CreateDispTypeInfo") + createStdDispatch = oleaut32.NewProc("CreateStdDispatch") + + wglCreateContext = opengl32.NewProc("wglCreateContext") + wglCreateLayerContext = opengl32.NewProc("wglCreateLayerContext") + wglDeleteContext = opengl32.NewProc("wglDeleteContext") + wglGetProcAddress = opengl32.NewProc("wglGetProcAddress") + wglMakeCurrent = opengl32.NewProc("wglMakeCurrent") + wglShareLists = opengl32.NewProc("wglShareLists") + + enumProcesses = psapi.NewProc("EnumProcesses") + + sHBrowseForFolder = shell32.NewProc("SHBrowseForFolderW") + sHGetPathFromIDList = shell32.NewProc("SHGetPathFromIDListW") + shGetSpecialFolderPath = shell32.NewProc("SHGetSpecialFolderPathW") + dragAcceptFiles = shell32.NewProc("DragAcceptFiles") + dragQueryFile = shell32.NewProc("DragQueryFileW") + dragQueryPoint = shell32.NewProc("DragQueryPoint") + dragFinish = shell32.NewProc("DragFinish") + shellExecute = shell32.NewProc("ShellExecuteW") + extractIcon = shell32.NewProc("ExtractIconW") + + gdipCreateBitmapFromFile = gdiplus.NewProc("GdipCreateBitmapFromFile") + gdipCreateBitmapFromHBITMAP = gdiplus.NewProc("GdipCreateBitmapFromHBITMAP") + gdipCreateHBITMAPFromBitmap = gdiplus.NewProc("GdipCreateHBITMAPFromBitmap") + gdipCreateBitmapFromResource = gdiplus.NewProc("GdipCreateBitmapFromResource") + gdipCreateBitmapFromStream = gdiplus.NewProc("GdipCreateBitmapFromStream") + gdipDisposeImage = gdiplus.NewProc("GdipDisposeImage") + gdiplusShutdown = gdiplus.NewProc("GdiplusShutdown") + gdiplusStartup = gdiplus.NewProc("GdiplusStartup") + + getFileVersionInfoSize = version.NewProc("GetFileVersionInfoSizeW") + getFileVersionInfo = version.NewProc("GetFileVersionInfoW") + verQueryValue = version.NewProc("VerQueryValueW") + + playSound = winmm.NewProc("PlaySoundW") + + getMonitorBrightness = dxva2.NewProc("GetMonitorBrightness") + setMonitorBrightness = dxva2.NewProc("SetMonitorBrightness") + getNumberOfPhysicalMonitorsFromHMONITOR = dxva2.NewProc("GetNumberOfPhysicalMonitorsFromHMONITOR") + getPhysicalMonitorsFromHMONITOR = dxva2.NewProc("GetPhysicalMonitorsFromHMONITOR") + + alphaBlend = msimg32.NewProc("AlphaBlend") + + wNetAddConnection2 = mpr.NewProc("WNetAddConnection2W") + wNetAddConnection3 = mpr.NewProc("WNetAddConnection3W") + wNetCancelConnection2 = mpr.NewProc("WNetCancelConnection2W") + + rtlGetVersion = ntdll.NewProc("RtlGetVersion") + + setupDiGetClassDevs = setupAPI.NewProc("SetupDiGetClassDevsW") + setupDiDestroyDeviceInfoList = setupAPI.NewProc("SetupDiDestroyDeviceInfoList") + setupDiEnumDeviceInfo = setupAPI.NewProc("SetupDiEnumDeviceInfo") + setupDiOpenDevRegKey = setupAPI.NewProc("SetupDiOpenDevRegKey") + + setProcessDpiAwareness = shcore.NewProc("SetProcessDpiAwareness") +) + +// RegisterClassEx sets the Size of the WNDCLASSEX automatically. +func RegisterClassEx(wndClassEx *WNDCLASSEX) ATOM { + if wndClassEx != nil { + wndClassEx.Size = uint32(unsafe.Sizeof(*wndClassEx)) + } + ret, _, _ := registerClassEx.Call(uintptr(unsafe.Pointer(wndClassEx))) + return ATOM(ret) +} + +func UnregisterClass(className string, instance HINSTANCE) bool { + ret, _, _ := unregisterClass.Call( + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(className))), + uintptr(instance), + ) + return ret != 0 +} + +func UnregisterClassAtom(atom ATOM, instance HINSTANCE) bool { + ret, _, _ := unregisterClass.Call( + uintptr(atom), + uintptr(instance), + ) + return ret != 0 +} + +func GetClassInfoEx(inst HINSTANCE, className string) (c WNDCLASSEX, found bool) { + ret, _, _ := getClassInfoEx.Call( + uintptr(inst), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(className))), + uintptr(unsafe.Pointer(&c)), + ) + found = ret != 0 + return +} + +func LoadIcon(instance HINSTANCE, iconName *uint16) HICON { + ret, _, _ := loadIcon.Call( + uintptr(instance), + uintptr(unsafe.Pointer(iconName)), + ) + return HICON(ret) +} + +func LoadIconWithResourceID(instance HINSTANCE, res uint16) HICON { + ret, _, _ := loadIcon.Call( + uintptr(instance), + uintptr(res)) + + return HICON(ret) +} + +func LoadCursor(instance HINSTANCE, cursorName *uint16) HCURSOR { + ret, _, _ := loadCursor.Call( + uintptr(instance), + uintptr(unsafe.Pointer(cursorName)), + ) + return HCURSOR(ret) +} + +func LoadCursorWithResourceID(instance HINSTANCE, res uint16) HCURSOR { + ret, _, _ := loadCursor.Call( + uintptr(instance), + uintptr(res)) + + return HCURSOR(ret) +} + +func ShowWindow(hwnd HWND, cmdshow int) bool { + ret, _, _ := showWindow.Call( + uintptr(hwnd), + uintptr(cmdshow), + ) + return ret != 0 +} + +func ShowWindowAsync(hwnd HWND, cmdshow int) bool { + ret, _, _ := showWindowAsync.Call( + uintptr(hwnd), + uintptr(cmdshow), + ) + return ret != 0 +} + +func UpdateWindow(hwnd HWND) bool { + ret, _, _ := updateWindow.Call(uintptr(hwnd)) + return ret != 0 +} + +func CreateWindow(className, windowName *uint16, + style uint, x, y, width, height int, parent HWND, menu HMENU, + instance HINSTANCE, param unsafe.Pointer) HWND { + return CreateWindowEx( + 0, + className, windowName, + style, + x, y, width, height, + parent, menu, instance, param, + ) +} + +func CreateWindowStr(className, windowName string, + style uint, x, y, width, height int, parent HWND, menu HMENU, + instance HINSTANCE, param unsafe.Pointer) HWND { + return CreateWindow( + syscall.StringToUTF16Ptr(className), + syscall.StringToUTF16Ptr(windowName), + style, + x, y, width, height, + parent, menu, instance, param, + ) +} + +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, _, _ := createWindowEx.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 CreateWindowExStr(exStyle uint, className, windowName string, + style uint, x, y, width, height int, parent HWND, menu HMENU, + instance HINSTANCE, param unsafe.Pointer) HWND { + return CreateWindowEx( + exStyle, + syscall.StringToUTF16Ptr(className), + syscall.StringToUTF16Ptr(windowName), + style, + x, y, width, height, + parent, menu, instance, param, + ) +} + +func AdjustWindowRectEx(rect *RECT, style uint, menu bool, exStyle uint) bool { + ret, _, _ := adjustWindowRectEx.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, _, _ := adjustWindowRect.Call( + uintptr(unsafe.Pointer(rect)), + uintptr(style), + uintptr(BoolToBOOL(menu)), + ) + return ret != 0 +} + +func DestroyWindow(hwnd HWND) bool { + ret, _, _ := destroyWindow.Call(uintptr(hwnd)) + return ret != 0 +} + +func DefWindowProc(hwnd HWND, msg uint32, wParam, lParam uintptr) uintptr { + ret, _, _ := defWindowProc.Call( + uintptr(hwnd), + uintptr(msg), + wParam, + lParam, + ) + return ret +} + +func DefDlgProc(hwnd HWND, msg uint32, wParam, lParam uintptr) uintptr { + ret, _, _ := defDlgProc.Call( + uintptr(hwnd), + uintptr(msg), + wParam, + lParam, + ) + return ret +} + +func PostQuitMessage(exitCode int) { + postQuitMessage.Call(uintptr(exitCode)) +} + +func GetMessage(msg *MSG, hwnd HWND, msgFilterMin, msgFilterMax uint32) int { + ret, _, _ := getMessage.Call( + uintptr(unsafe.Pointer(msg)), + uintptr(hwnd), + uintptr(msgFilterMin), + uintptr(msgFilterMax), + ) + return int(ret) +} + +func GetMessageTime() int { + ret, _, _ := getMessageTime.Call() + return int(ret) +} + +func TranslateMessage(msg *MSG) bool { + ret, _, _ := translateMessage.Call(uintptr(unsafe.Pointer(msg))) + return ret != 0 + +} + +func DispatchMessage(msg *MSG) uintptr { + ret, _, _ := dispatchMessage.Call(uintptr(unsafe.Pointer(msg))) + return ret + +} + +func SendMessage(hwnd HWND, msg uint32, wParam, lParam uintptr) uintptr { + ret, _, _ := sendMessage.Call( + uintptr(hwnd), + uintptr(msg), + wParam, + lParam, + ) + return ret +} + +func PostMessage(hwnd HWND, msg uint32, wParam, lParam uintptr) bool { + ret, _, _ := postMessage.Call( + uintptr(hwnd), + uintptr(msg), + wParam, + lParam, + ) + return ret != 0 +} + +func WaitMessage() bool { + ret, _, _ := waitMessage.Call() + return ret != 0 +} + +func SetWindowText(hwnd HWND, text string) { + setWindowText.Call( + uintptr(hwnd), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(text))), + ) +} + +func GetWindowTextLength(hwnd HWND) int { + ret, _, _ := getWindowTextLength.Call(uintptr(hwnd)) + return int(ret) +} + +func GetWindowText(hwnd HWND) string { + textLen := GetWindowTextLength(hwnd) + 1 + buf := make([]uint16, textLen) + len, _, _ := getWindowText.Call( + uintptr(hwnd), + uintptr(unsafe.Pointer(&buf[0])), + uintptr(textLen), + ) + return syscall.UTF16ToString(buf[:len]) +} + +func GetWindowRect(hwnd HWND) *RECT { + var rect RECT + getWindowRect.Call( + uintptr(hwnd), + uintptr(unsafe.Pointer(&rect)), + ) + return &rect +} + +func GetWindowInfo(hwnd HWND) (WINDOWINFO, bool) { + var wi WINDOWINFO + ret, _, _ := getWindowInfo.Call( + uintptr(hwnd), + uintptr(unsafe.Pointer(&wi)), + ) + return wi, ret != 0 +} + +func MoveWindow(hwnd HWND, x, y, width, height int, repaint bool) bool { + ret, _, _ := moveWindow.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, _, _ := screenToClient.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, _, _ := callWindowProc.Call( + preWndProc, + uintptr(hwnd), + uintptr(msg), + wParam, + lParam, + ) + return ret +} + +func GetWindowLong(hwnd HWND, index int) int32 { + ret, _, _ := getWindowLong.Call( + uintptr(hwnd), + uintptr(index), + ) + return int32(ret) +} + +func SetWindowLong(hwnd HWND, index int, value int32) int32 { + ret, _, _ := setWindowLong.Call( + uintptr(hwnd), + uintptr(index), + uintptr(value), + ) + return int32(ret) +} + +func GetClassLong(hwnd HWND, index int) uint32 { + ret, _, _ := getClassLong.Call( + uintptr(hwnd), + uintptr(index), + ) + return uint32(ret) +} + +func SetClassLong(hwnd HWND, index int, value int32) uint32 { + ret, _, _ := setClassLong.Call( + uintptr(hwnd), + uintptr(index), + uintptr(value), + ) + return uint32(ret) +} + +func EnableWindow(hwnd HWND, b bool) bool { + ret, _, _ := enableWindow.Call( + uintptr(hwnd), + uintptr(BoolToBOOL(b)), + ) + return ret != 0 +} + +func IsWindowEnabled(hwnd HWND) bool { + ret, _, _ := isWindowEnabled.Call(uintptr(hwnd)) + return ret != 0 +} + +func IsWindowVisible(hwnd HWND) bool { + ret, _, _ := isWindowVisible.Call(uintptr(hwnd)) + return ret != 0 +} + +func SetFocus(hwnd HWND) HWND { + ret, _, _ := setFocus.Call(uintptr(hwnd)) + return HWND(ret) +} + +func InvalidateRect(hwnd HWND, rect *RECT, erase bool) bool { + ret, _, _ := invalidateRect.Call( + uintptr(hwnd), + uintptr(unsafe.Pointer(rect)), + uintptr(BoolToBOOL(erase)), + ) + return ret != 0 +} + +func ValidateRect(hwnd HWND, rect *RECT) bool { + ret, _, _ := validateRect.Call( + uintptr(hwnd), + uintptr(unsafe.Pointer(rect)), + ) + return ret != 0 +} + +func GetClientRect(hwnd HWND) *RECT { + var rect RECT + ret, _, _ := getClientRect.Call( + uintptr(hwnd), + uintptr(unsafe.Pointer(&rect))) + if ret == 0 { + return nil + } + return &rect +} + +func GetDC(hwnd HWND) HDC { + ret, _, _ := getDC.Call(uintptr(hwnd)) + return HDC(ret) +} + +func ReleaseDC(hwnd HWND, hDC HDC) bool { + ret, _, _ := releaseDC.Call( + uintptr(hwnd), + uintptr(hDC), + ) + return ret != 0 +} + +func SetCapture(hwnd HWND) HWND { + ret, _, _ := setCapture.Call(uintptr(hwnd)) + return HWND(ret) +} + +func ReleaseCapture() bool { + ret, _, _ := releaseCapture.Call() + return ret != 0 +} + +func GetWindowThreadProcessId(hwnd HWND) (HANDLE, DWORD) { + var processId DWORD + ret, _, _ := getWindowThreadProcessId.Call( + uintptr(hwnd), + uintptr(unsafe.Pointer(&processId)), + ) + return HANDLE(ret), processId +} + +func MessageBox(hwnd HWND, text, caption string, flags uint) int { + ret, _, _ := messageBox.Call( + uintptr(hwnd), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(text))), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(caption))), + uintptr(flags), + ) + return int(ret) +} + +func MessageBoxIndirect(params *MSGBOXPARAMS) int { + if params != nil { + params.Size = uint32(unsafe.Sizeof(*params)) + } + ret, _, _ := messageBoxIndirect.Call(uintptr(unsafe.Pointer(params))) + return int(ret) +} + +func GetSystemMetrics(index int) int { + ret, _, _ := getSystemMetrics.Call(uintptr(index)) + return int(ret) +} + +func CopyRect(dst, src *RECT) bool { + ret, _, _ := copyRect.Call( + uintptr(unsafe.Pointer(dst)), + uintptr(unsafe.Pointer(src)), + ) + return ret != 0 +} + +func EqualRect(rect1, rect2 *RECT) bool { + ret, _, _ := equalRect.Call( + uintptr(unsafe.Pointer(rect1)), + uintptr(unsafe.Pointer(rect2)), + ) + return ret != 0 +} + +func InflateRect(rect *RECT, dx, dy int) bool { + ret, _, _ := inflateRect.Call( + uintptr(unsafe.Pointer(rect)), + uintptr(dx), + uintptr(dy), + ) + return ret != 0 +} + +func IntersectRect(dst, src1, src2 *RECT) bool { + ret, _, _ := intersectRect.Call( + uintptr(unsafe.Pointer(dst)), + uintptr(unsafe.Pointer(src1)), + uintptr(unsafe.Pointer(src2)), + ) + return ret != 0 +} + +func IsRectEmpty(rect *RECT) bool { + ret, _, _ := isRectEmpty.Call(uintptr(unsafe.Pointer(rect))) + return ret != 0 +} + +func OffsetRect(rect *RECT, dx, dy int) bool { + ret, _, _ := offsetRect.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, _, _ := ptInRect.Call( + uintptr(unsafe.Pointer(rect)), + uintptr(unsafe.Pointer(&pt)), + ) + return ret != 0 +} + +func SetRect(rect *RECT, left, top, right, bottom int) bool { + ret, _, _ := setRect.Call( + uintptr(unsafe.Pointer(rect)), + uintptr(left), + uintptr(top), + uintptr(right), + uintptr(bottom), + ) + return ret != 0 +} + +func SetRectEmpty(rect *RECT) bool { + ret, _, _ := setRectEmpty.Call(uintptr(unsafe.Pointer(rect))) + return ret != 0 +} + +func SubtractRect(dst, src1, src2 *RECT) bool { + ret, _, _ := subtractRect.Call( + uintptr(unsafe.Pointer(dst)), + uintptr(unsafe.Pointer(src1)), + uintptr(unsafe.Pointer(src2)), + ) + return ret != 0 +} + +func UnionRect(dst, src1, src2 *RECT) bool { + ret, _, _ := unionRect.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, _, _ := createDialogParam.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, _, _ := dialogBoxParam.Call( + uintptr(hInstance), + uintptr(unsafe.Pointer(lpTemplateName)), + uintptr(hWndParent), + lpDialogProc, + 0, + ) + return int(ret) +} + +func GetDlgItem(hDlg HWND, nIDDlgItem int) HWND { + ret, _, _ := getDlgItem.Call( + uintptr(unsafe.Pointer(hDlg)), + uintptr(nIDDlgItem), + ) + return HWND(ret) +} + +func DrawIconEx( + hDC HDC, x, y int, hIcon HICON, width, height int, + frame uint, flickerFreeDraw HBRUSH, flags uint, +) bool { + ret, _, _ := drawIconEx.Call( + uintptr(unsafe.Pointer(hDC)), + uintptr(x), + uintptr(y), + uintptr(unsafe.Pointer(hIcon)), + uintptr(width), + uintptr(height), + uintptr(frame), + uintptr(flickerFreeDraw), + uintptr(flags), + ) + return ret != 0 +} + +func DrawIcon(hDC HDC, x, y int, hIcon HICON) bool { + ret, _, _ := drawIcon.Call( + uintptr(unsafe.Pointer(hDC)), + uintptr(x), + uintptr(y), + uintptr(unsafe.Pointer(hIcon)), + ) + return ret != 0 +} + +func ClientToScreen(hwnd HWND, x, y int) (int, int) { + pt := POINT{X: int32(x), Y: int32(y)} + clientToScreen.Call( + uintptr(hwnd), + uintptr(unsafe.Pointer(&pt)), + ) + return int(pt.X), int(pt.Y) +} + +func IsDialogMessage(hwnd HWND, msg *MSG) bool { + ret, _, _ := isDialogMessage.Call( + uintptr(hwnd), + uintptr(unsafe.Pointer(msg)), + ) + return ret != 0 +} + +func IsWindow(hwnd HWND) bool { + ret, _, _ := isWindow.Call(uintptr(hwnd)) + return ret != 0 +} + +func EndDialog(hwnd HWND, nResult uintptr) bool { + ret, _, _ := endDialog.Call( + uintptr(hwnd), + nResult, + ) + return ret != 0 +} + +func PeekMessage(lpMsg *MSG, hwnd HWND, wMsgFilterMin, wMsgFilterMax, wRemoveMsg uint32) bool { + ret, _, _ := peekMessage.Call( + uintptr(unsafe.Pointer(lpMsg)), + uintptr(hwnd), + uintptr(wMsgFilterMin), + uintptr(wMsgFilterMax), + uintptr(wRemoveMsg), + ) + return ret != 0 +} + +func CreateAcceleratorTable(acc []ACCEL) HACCEL { + if len(acc) == 0 { + return 0 + } + ret, _, _ := createAcceleratorTable.Call( + uintptr(unsafe.Pointer(&acc[0])), + uintptr(len(acc)), + ) + return HACCEL(ret) +} + +func DestroyAcceleratorTable(acc HACCEL) bool { + ret, _, _ := destroyAcceleratorTable.Call(uintptr(acc)) + return ret != 0 +} + +func TranslateAccelerator(hwnd HWND, hAccTable HACCEL, lpMsg *MSG) bool { + ret, _, _ := translateAccelerator.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, _, _ := setWindowPos.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, _, _ := fillRect.Call( + uintptr(hDC), + uintptr(unsafe.Pointer(lprc)), + uintptr(hbr), + ) + return ret != 0 +} + +// DrawText does not support DT_MODIFYSTRING in this implementation. +func DrawText(hDC HDC, text string, lpRect *RECT, uFormat uint) int { + // suppress DT_MODIFYSTRING because the given text is not a pointer and we + // do not return any text changes. + mod := uint(DT_MODIFYSTRING) + uFormat = uFormat & ^mod + count := -1 // because the text pointer is NULL terminated + ret, _, _ := drawText.Call( + uintptr(hDC), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(text))), + uintptr(count), + uintptr(unsafe.Pointer(lpRect)), + uintptr(uFormat), + ) + return int(ret) +} + +func AddClipboardFormatListener(hwnd HWND) bool { + ret, _, _ := addClipboardFormatListener.Call(uintptr(hwnd)) + return ret != 0 +} + +func RemoveClipboardFormatListener(hwnd HWND) bool { + ret, _, _ := removeClipboardFormatListener.Call(uintptr(hwnd)) + return ret != 0 +} + +func OpenClipboard(hWndNewOwner HWND) bool { + ret, _, _ := openClipboard.Call(uintptr(hWndNewOwner)) + return ret != 0 +} + +func CloseClipboard() bool { + ret, _, _ := closeClipboard.Call() + return ret != 0 +} + +func EnumClipboardFormats(format uint) uint { + ret, _, _ := enumClipboardFormats.Call(uintptr(format)) + return uint(ret) +} + +func GetClipboardData(uFormat uint) HANDLE { + ret, _, _ := getClipboardData.Call(uintptr(uFormat)) + return HANDLE(ret) +} + +func SetClipboardData(uFormat uint, hMem HANDLE) HANDLE { + ret, _, _ := setClipboardData.Call( + uintptr(uFormat), + uintptr(hMem), + ) + return HANDLE(ret) +} + +func EmptyClipboard() bool { + ret, _, _ := emptyClipboard.Call() + return ret != 0 +} + +func GetClipboardFormatName(format uint) (string, bool) { + cchMaxCount := 255 + buf := make([]uint16, cchMaxCount) + ret, _, _ := getClipboardFormatName.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, _, _ := isClipboardFormatAvailable.Call(uintptr(format)) + return ret != 0 +} + +func BeginPaint(hwnd HWND, paint *PAINTSTRUCT) HDC { + ret, _, _ := beginPaint.Call( + uintptr(hwnd), + uintptr(unsafe.Pointer(paint)), + ) + return HDC(ret) +} + +func EndPaint(hwnd HWND, paint *PAINTSTRUCT) { + endPaint.Call( + uintptr(hwnd), + uintptr(unsafe.Pointer(paint)), + ) +} + +func GetKeyboardState(keyState []byte) bool { + if len(keyState) < 256 { + return false + } + ret, _, _ := getKeyboardState.Call(uintptr(unsafe.Pointer(&keyState[0]))) + return ret != 0 +} + +func MapVirtualKey(uCode, uMapType uint) uint { + ret, _, _ := mapVirtualKey.Call( + uintptr(uCode), + uintptr(uMapType), + ) + return uint(ret) +} + +func MapVirtualKeyEx(uCode, uMapType uint, dwhkl HKL) uint { + ret, _, _ := mapVirtualKeyEx.Call( + uintptr(uCode), + uintptr(uMapType), + uintptr(dwhkl), + ) + return uint(ret) +} + +func GetAsyncKeyState(vKey int) uint16 { + ret, _, _ := getAsyncKeyState.Call(uintptr(vKey)) + return uint16(ret) +} + +func ToAscii(uVirtKey, uScanCode uint, lpKeyState *byte, lpChar *uint16, uFlags uint) int { + ret, _, _ := toAscii.Call( + uintptr(uVirtKey), + uintptr(uScanCode), + uintptr(unsafe.Pointer(lpKeyState)), + uintptr(unsafe.Pointer(lpChar)), + uintptr(uFlags), + ) + return int(ret) +} + +func SwapMouseButton(fSwap bool) bool { + ret, _, _ := swapMouseButton.Call(uintptr(BoolToBOOL(fSwap))) + return ret != 0 +} + +func GetCursorPos() (x, y int, ok bool) { + var pt POINT + ret, _, _ := getCursorPos.Call(uintptr(unsafe.Pointer(&pt))) + return int(pt.X), int(pt.Y), ret != 0 +} + +func SetCursorPos(x, y int) bool { + ret, _, _ := setCursorPos.Call( + uintptr(x), + uintptr(y), + ) + return ret != 0 +} + +func SetCursor(cursor HCURSOR) HCURSOR { + ret, _, _ := setCursor.Call(uintptr(cursor)) + return HCURSOR(ret) +} + +func CreateIcon(instance HINSTANCE, nWidth, nHeight int, cPlanes, cBitsPerPixel byte, ANDbits, XORbits *byte) HICON { + ret, _, _ := createIcon.Call( + uintptr(instance), + uintptr(nWidth), + uintptr(nHeight), + uintptr(cPlanes), + uintptr(cBitsPerPixel), + uintptr(unsafe.Pointer(ANDbits)), + uintptr(unsafe.Pointer(XORbits)), + ) + return HICON(ret) +} + +func CreateIconFromResource( + mem unsafe.Pointer, + memSize uint32, + icon bool, + version uint32, +) HICON { + ret, _, _ := createIconFromResource.Call( + uintptr(mem), + uintptr(memSize), + uintptr(BoolToBOOL(icon)), + uintptr(version), + ) + return HICON(ret) +} + +func CreateIconFromResourceEx( + mem unsafe.Pointer, + memSize uint32, + icon bool, + version uint32, + width int, + height int, + flags uint, +) HICON { + ret, _, _ := createIconFromResourceEx.Call( + uintptr(mem), + uintptr(memSize), + uintptr(BoolToBOOL(icon)), + uintptr(version), + uintptr(width), + uintptr(height), + uintptr(flags), + ) + return HICON(ret) +} + +func DestroyIcon(icon HICON) bool { + ret, _, _ := destroyIcon.Call(uintptr(icon)) + return ret != 0 +} + +func MonitorFromPoint(x, y int, dwFlags uint32) HMONITOR { + ret, _, _ := monitorFromPoint.Call( + uintptr(x), + uintptr(y), + uintptr(dwFlags), + ) + return HMONITOR(ret) +} + +func MonitorFromRect(rc *RECT, dwFlags uint32) HMONITOR { + ret, _, _ := monitorFromRect.Call( + uintptr(unsafe.Pointer(rc)), + uintptr(dwFlags), + ) + return HMONITOR(ret) +} + +func MonitorFromWindow(hwnd HWND, dwFlags uint32) HMONITOR { + ret, _, _ := monitorFromWindow.Call( + uintptr(hwnd), + uintptr(dwFlags), + ) + return HMONITOR(ret) +} + +// GetMonitorInfo automatically sets the MONITORINFO's CbSize field. +func GetMonitorInfo(hMonitor HMONITOR, lmpi *MONITORINFO) bool { + if lmpi != nil { + lmpi.CbSize = uint32(unsafe.Sizeof(*lmpi)) + } + ret, _, _ := getMonitorInfo.Call( + uintptr(hMonitor), + uintptr(unsafe.Pointer(lmpi)), + ) + return ret != 0 +} + +func EnumDisplayMonitors(hdc HDC, clip *RECT, fnEnum, dwData uintptr) bool { + ret, _, _ := enumDisplayMonitors.Call( + uintptr(hdc), + uintptr(unsafe.Pointer(clip)), + fnEnum, + dwData, + ) + return ret != 0 +} + +func EnumDisplaySettingsEx(szDeviceName *uint16, iModeNum uint32, devMode *DEVMODE, dwFlags uint32) bool { + ret, _, _ := enumDisplaySettingsEx.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, _, _ := changeDisplaySettingsEx.Call( + uintptr(unsafe.Pointer(szDeviceName)), + uintptr(unsafe.Pointer(devMode)), + uintptr(hwnd), + uintptr(dwFlags), + lParam, + ) + return int32(ret) +} + +func SendInput(inputs ...INPUT) uint32 { + if len(inputs) == 0 { + return 0 + } + ret, _, _ := sendInput.Call( + uintptr(len(inputs)), + uintptr(unsafe.Pointer(&inputs[0])), + unsafe.Sizeof(inputs[0]), + ) + return uint32(ret) +} + +func SetWindowsHookEx(idHook int, lpfn HOOKPROC, hMod HINSTANCE, dwThreadId DWORD) HHOOK { + ret, _, _ := setWindowsHookEx.Call( + uintptr(idHook), + uintptr(syscall.NewCallback(lpfn)), + uintptr(hMod), + uintptr(dwThreadId), + ) + return HHOOK(ret) +} + +func UnhookWindowsHookEx(hhk HHOOK) bool { + ret, _, _ := unhookWindowsHookEx.Call(uintptr(hhk)) + return ret != 0 +} + +func CallNextHookEx(hhk HHOOK, nCode int, wParam WPARAM, lParam LPARAM) LRESULT { + ret, _, _ := callNextHookEx.Call( + uintptr(hhk), + uintptr(nCode), + uintptr(wParam), + uintptr(lParam), + ) + return LRESULT(ret) +} + +// GetWindowPlacement automatically sets the WINDOWPLACEMENT's Length field. +func GetWindowPlacement(hwnd HWND, placement *WINDOWPLACEMENT) bool { + if placement != nil { + placement.Length = uint32(unsafe.Sizeof(*placement)) + } + ret, _, _ := getWindowPlacement.Call( + uintptr(hwnd), + uintptr(unsafe.Pointer(placement)), + ) + return ret != 0 +} + +func SetWindowPlacement(hwnd HWND, placement *WINDOWPLACEMENT) bool { + ret, _, _ := setWindowPlacement.Call( + uintptr(hwnd), + uintptr(unsafe.Pointer(placement)), + ) + return ret != 0 +} + +func ShowCursor(show bool) int { + ret, _, _ := showCursor.Call(uintptr(BoolToBOOL(show))) + return int(int32(ret)) +} + +func LoadImage( + inst HINSTANCE, + name *uint16, + typ uint, + desiredWidth, desiredHeight int, + load uint, +) HANDLE { + ret, _, _ := loadImage.Call( + uintptr(inst), + uintptr(unsafe.Pointer(name)), + uintptr(typ), + uintptr(desiredWidth), + uintptr(desiredHeight), + uintptr(load), + ) + return HANDLE(ret) +} + +func GetForegroundWindow() HWND { + ret, _, _ := getForegroundWindow.Call() + return HWND(ret) +} + +func FindWindow(className, windowName string) HWND { + var class, window uintptr + if className != "" { + class = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(className))) + } + if windowName != "" { + window = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(windowName))) + } + ret, _, _ := findWindow.Call(class, window) + return HWND(ret) +} + +func GetClassName(window HWND) (string, bool) { + var output [256]uint16 + ret, _, _ := getClassName.Call( + uintptr(window), + uintptr(unsafe.Pointer(&output[0])), + uintptr(len(output)), + ) + return syscall.UTF16ToString(output[:]), ret != 0 +} + +func GetDesktopWindow() HWND { + ret, _, _ := getDesktopWindow.Call() + return HWND(ret) +} + +func GetRawInputData(input HRAWINPUT, command uint) (raw RAWINPUT, ok bool) { + size := uint(unsafe.Sizeof(raw)) + ret, _, _ := getRawInputData.Call( + uintptr(input), + uintptr(command), + uintptr(unsafe.Pointer(&raw)), + uintptr(unsafe.Pointer(&size)), + unsafe.Sizeof(raw.Header), + ) + var fail uint32 + fail-- + ok = uint32(ret) != fail + return +} + +func RegisterPowerSettingNotification( + recipient HANDLE, + powerSettingGUID *GUID, + flags uint32, +) HANDLE { + ret, _, _ := registerPowerSettingNotification.Call( + uintptr(recipient), + uintptr(unsafe.Pointer(powerSettingGUID)), + uintptr(flags), + ) + return HANDLE(ret) +} + +func RegisterRawInputDevices(devices ...RAWINPUTDEVICE) bool { + if len(devices) == 0 { + return true + } + ret, _, _ := registerRawInputDevices.Call( + uintptr(unsafe.Pointer(&devices[0])), + uintptr(len(devices)), + unsafe.Sizeof(devices[0]), + ) + return ret != 0 +} + +func SetTimer(window HWND, idEvent uintptr, elapse uint, timerFunc uintptr) uintptr { + ret, _, _ := setTimer.Call( + uintptr(window), + idEvent, + uintptr(elapse), + timerFunc, + ) + return ret +} + +func GetActiveWindow() HWND { + ret, _, _ := getActiveWindow.Call() + return HWND(ret) +} + +func MessageBeep(typ uint) bool { + ret, _, _ := messageBeep.Call(uintptr(typ)) + return ret != 0 +} + +// Beep generates simple tones on the speaker. The function is synchronous; it +// performs an alertable wait and does not return control to its caller until +// the sound finishes. +// The frequency must be in the range 37 through 32,767 (0x25 through 0x7FFF). +func Beep(frequencyInHz, durationInMs uint32) bool { + ret, _, _ := beep.Call(uintptr(frequencyInHz), uintptr(durationInMs)) + return ret != 0 +} + +// GetCaretBlinkTime returns the time required to invert the caret's pixels, in +// milliseconds. If the number is negative, the time is infinite and thus the +// cursor does not blink. +func GetCaretBlinkTime() int { + ret, _, _ := getCaretBlinkTime.Call() + return int(int32(ret)) +} + +func GetWindowDC(window HWND) HDC { + ret, _, _ := getWindowDC.Call(uintptr(window)) + return HDC(ret) +} + +func EnumWindows(callback func(window HWND) bool) bool { + f := syscall.NewCallback(func(w, _ uintptr) uintptr { + if callback(HWND(w)) { + return 1 + } + return 0 + }) + ret, _, _ := enumWindows.Call(f, 0) + return ret != 0 +} + +func EnumChildWindows(parent HWND, callback func(window HWND) bool) bool { + f := syscall.NewCallback(func(w, _ uintptr) uintptr { + if callback(HWND(w)) { + return 1 + } + return 0 + }) + ret, _, _ := enumChildWindows.Call(uintptr(parent), f, 0) + return ret != 0 +} + +func GetTopWindow(of HWND) HWND { + ret, _, _ := getTopWindow.Call(uintptr(of)) + return HWND(ret) +} + +func GetWindow(rel HWND, cmd uint) HWND { + ret, _, _ := getWindow.Call(uintptr(rel), uintptr(cmd)) + return HWND(ret) +} + +func GetNextWindow(rel HWND, cmd uint) HWND { + return GetWindow(rel, cmd) +} + +func GetKeyState(key int) uint16 { + ret, _, _ := getKeyState.Call(uintptr(key)) + return uint16(ret) +} + +func GetSysColor(index int) uint32 { + ret, _, _ := getSysColor.Call(uintptr(index)) + return uint32(ret) +} + +func GetSysColorBrush(index int) HBRUSH { + ret, _, _ := getSysColorBrush.Call(uintptr(index)) + return HBRUSH(ret) +} + +func AppendMenu(m HMENU, flags uint, id uintptr, item string) bool { + ret, _, _ := appendMenu.Call( + uintptr(m), + uintptr(flags), + id, + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(item))), + ) + return ret != 0 +} + +func CheckMenuItem(m HMENU, item, check uint) uint32 { + ret, _, _ := checkMenuItem.Call( + uintptr(m), + uintptr(item), + uintptr(check), + ) + return uint32(ret) +} + +func CheckMenuRadioItem(m HMENU, first, last, check, flags uint) bool { + ret, _, _ := checkMenuRadioItem.Call( + uintptr(m), + uintptr(first), + uintptr(last), + uintptr(check), + uintptr(flags), + ) + return ret != 0 +} + +func CreateMenu() HMENU { + ret, _, _ := createMenu.Call() + return HMENU(ret) +} + +func CreatePopupMenu() HMENU { + ret, _, _ := createPopupMenu.Call() + return HMENU(ret) +} + +func DeleteMenu(m HMENU, pos, flags uint) bool { + ret, _, _ := deleteMenu.Call( + uintptr(m), + uintptr(pos), + uintptr(flags), + ) + return ret != 0 +} + +func DestroyMenu(m HMENU) bool { + ret, _, _ := destroyMenu.Call(uintptr(m)) + return ret != 0 +} + +func DrawMenuBar(window HWND) bool { + ret, _, _ := drawMenuBar.Call(uintptr(window)) + return ret != 0 +} + +func EnableMenuItem(m HMENU, item, enable uint) int { + ret, _, _ := enableMenuItem.Call( + uintptr(m), + uintptr(item), + uintptr(enable), + ) + return int(ret) +} + +func EndMenu() bool { + ret, _, _ := endMenu.Call() + return ret != 0 +} + +func GetMenu(window HWND) HMENU { + ret, _, _ := getMenu.Call(uintptr(window)) + return HMENU(ret) +} + +func GetMenuBarInfo(w HWND, object, item int, info *MENUBARINFO) bool { + if info != nil { + info.size = uint32(unsafe.Sizeof(*info)) + } + ret, _, _ := getMenuBarInfo.Call( + uintptr(w), + uintptr(object), + uintptr(item), + uintptr(unsafe.Pointer(info)), + ) + return ret != 0 +} + +func GetMenuCheckMarkDimensions() (w, h int) { + ret, _, _ := getMenuCheckMarkDimensions.Call() + return int(ret & 0x00FFFF), int(ret&0xFFFF0000) >> 16 +} + +func GetMenuDefaultItem(m HMENU, byPos, flags uint) int { + ret, _, _ := getMenuDefaultItem.Call( + uintptr(m), + uintptr(byPos), + uintptr(flags), + ) + return int(ret) +} + +func GetMenuInfo(m HMENU, info *MENUINFO) bool { + if info != nil { + info.size = uint32(unsafe.Sizeof(*info)) + } + ret, _, _ := getMenuInfo.Call( + uintptr(m), + uintptr(unsafe.Pointer(info)), + ) + return ret != 0 +} + +func GetMenuItemCount(m HMENU) int { + ret, _, _ := getMenuItemCount.Call(uintptr(m)) + return int(ret) +} + +func GetMenuItemID(m HMENU, pos int) int { + ret, _, _ := getMenuItemID.Call(uintptr(m), uintptr(pos)) + return int(ret) +} + +func GetMenuItemInfo(m HMENU, item uint, byPos bool, info *MENUITEMINFO) bool { + if info != nil { + info.Size = uint32(unsafe.Sizeof(*info)) + } + ret, _, _ := getMenuItemInfo.Call( + uintptr(m), + uintptr(item), + uintptr(BoolToBOOL(byPos)), + uintptr(unsafe.Pointer(info)), + ) + return ret != 0 +} + +func GetMenuItemRect(w HWND, m HMENU, item uint, r *RECT) bool { + ret, _, _ := getMenuItemRect.Call( + uintptr(w), + uintptr(m), + uintptr(item), + uintptr(unsafe.Pointer(r)), + ) + return ret != 0 +} + +func GetMenuState(m HMENU, id, flags uint) int { + ret, _, _ := getMenuState.Call( + uintptr(m), + uintptr(id), + uintptr(flags), + ) + return int(ret) +} + +func GetMenuString(m HMENU, item, flags uint) string { + length, _, _ := getMenuString.Call( + uintptr(m), + uintptr(item), + 0, + 0, + uintptr(flags), + ) + if length == 0 { + return "" + } + buf := make([]uint16, length+1) + getMenuString.Call( + uintptr(m), + uintptr(item), + uintptr(unsafe.Pointer(&buf[0])), + length+1, + uintptr(flags), + ) + buf[length] = 0 + return syscall.UTF16ToString(buf) +} + +func GetSubMenu(menu HMENU, pos int) HMENU { + ret, _, _ := getSubMenu.Call(uintptr(menu), uintptr(pos)) + return HMENU(ret) +} + +func GetSystemMenu(w HWND, revert bool) HMENU { + ret, _, _ := getSystemMenu.Call( + uintptr(w), + uintptr(BoolToBOOL(revert)), + ) + return HMENU(ret) +} + +func HiliteMenuItem(w HWND, m HMENU, item, hilite uint) bool { + ret, _, _ := hiliteMenuItem.Call( + uintptr(w), + uintptr(m), + uintptr(item), + uintptr(hilite), + ) + return ret != 0 +} + +func InsertMenu(m HMENU, pos, flags uint, id uintptr, item string) bool { + ret, _, _ := insertMenu.Call( + uintptr(m), + uintptr(pos), + uintptr(flags), + id, + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(item))), + ) + return ret != 0 +} + +func InsertMenuItem(m HMENU, item uint, byPos bool, newItem *MENUITEMINFO) bool { + ret, _, _ := insertMenuItem.Call( + uintptr(m), + uintptr(item), + uintptr(BoolToBOOL(byPos)), + uintptr(unsafe.Pointer(newItem)), + ) + return ret != 0 +} + +func IsMenu(m HMENU) bool { + ret, _, _ := isMenu.Call(uintptr(m)) + return ret != 0 +} + +func LoadMenu(inst HINSTANCE, menuName string) HMENU { + ret, _, _ := loadMenu.Call( + uintptr(inst), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(menuName))), + ) + return HMENU(ret) +} + +// TODO create nice API for this +func LoadMenuIndirect(template uintptr) HMENU { + ret, _, _ := loadMenuIndirect.Call(template) + return HMENU(ret) +} + +// ModifyMenu changes an existing menu item. This function is used to specify +// the content, appearance, and behavior of the menu item. +// +// Note The ModifyMenu function has been superseded by the SetMenuItemInfo +// function. You can still use ModifyMenu, however, if you do not need any of +// the extended features of SetMenuItemInfo. +func ModifyMenu(m HMENU, pos, flags uint, idNewItem uintptr, newItem string) bool { + ret, _, _ := modifyMenu.Call( + uintptr(m), + uintptr(pos), + uintptr(flags), + idNewItem, + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(newItem))), + ) + return ret != 0 +} + +// RemoveMenu deletes a menu item or detaches a submenu from the specified menu. +// If the menu item opens a drop-down menu or submenu, RemoveMenu does not +// destroy the menu or its handle, allowing the menu to be reused. Before this +// function is called, the GetSubMenu function should retrieve a handle to the +// drop-down menu or submenu. +func RemoveMenu(m HMENU, pos, flags uint) bool { + ret, _, _ := removeMenu.Call( + uintptr(m), + uintptr(pos), + uintptr(flags), + ) + return ret != 0 +} + +func SetMenu(w HWND, m HMENU) bool { + ret, _, _ := setMenu.Call(uintptr(w), uintptr(m)) + return ret != 0 +} + +// SetMenuDefaultItem sets the default menu item for the specified menu. +func SetMenuDefaultItem(m HMENU, item, byPos uint) bool { + ret, _, _ := setMenuDefaultItem.Call( + uintptr(m), + uintptr(item), + uintptr(byPos), + ) + return ret != 0 +} + +// SetMenuInfo sets information for a specified menu. +func SetMenuInfo(m HMENU, info *MENUINFO) bool { + ret, _, _ := setMenuInfo.Call( + uintptr(m), + uintptr(unsafe.Pointer(info)), + ) + return ret != 0 +} + +// SetMenuItemBitmaps associates the specified bitmap with a menu item. Whether +// the menu item is selected or clear, the system displays the appropriate +// bitmap next to the menu item. +func SetMenuItemBitmaps(m HMENU, pos, flags uint, unchecked, checked HBITMAP) bool { + ret, _, _ := setMenuItemBitmaps.Call( + uintptr(m), + uintptr(pos), + uintptr(flags), + uintptr(unchecked), + uintptr(checked), + ) + return ret != 0 +} + +// SetMenuItemInfo changes information about a menu item. +func SetMenuItemInfo(m HMENU, item uint, byPos bool, mii *MENUITEMINFO) bool { + if mii != nil { + mii.Size = uint32(unsafe.Sizeof(*mii)) + } + ret, _, _ := setMenuItemInfo.Call( + uintptr(m), + uintptr(item), + uintptr(BoolToBOOL(byPos)), + uintptr(unsafe.Pointer(mii)), + ) + return ret != 0 +} + +// TrackPopupMenu displays a shortcut menu at the specified location and tracks +// the selection of items on the menu. The shortcut menu can appear anywhere on +// the screen. +func TrackPopupMenu(m HMENU, flags uint, x, y int, w HWND, r *RECT) int { + ret, _, _ := trackPopupMenu.Call( + uintptr(m), + uintptr(flags), + uintptr(x), + uintptr(y), + 0, // reserved parameter + uintptr(w), + uintptr(unsafe.Pointer(r)), + ) + return int(ret) +} + +// TrackPopupMenuEx displays a shortcut menu at the specified location and +// tracks the selection of items on the shortcut menu. The shortcut menu can +// appear anywhere on the screen. +func TrackPopupMenuEx(m HMENU, flags uint, x, y int, w HWND, tpm *TPMPARAMS) int { + ret, _, _ := trackPopupMenuEx.Call( + uintptr(m), + uintptr(flags), + uintptr(x), + uintptr(y), + uintptr(w), + uintptr(unsafe.Pointer(tpm)), + ) + return int(ret) +} + +func IsDlgButtonChecked(dlg HWND, id uintptr) uint { + ret, _, _ := isDlgButtonChecked.Call(uintptr(dlg), id) + return uint(ret) +} + +func SendDlgItemMessage(dlg HWND, id int, msg uint, w, l uintptr) uintptr { + ret, _, _ := sendDlgItemMessage.Call( + uintptr(dlg), + uintptr(id), + uintptr(msg), + uintptr(w), + uintptr(l), + ) + return ret +} + +func LookupIconIdFromDirectoryEx(mem unsafe.Pointer, icon bool, width, height int, flags uint) int { + ret, _, _ := lookupIconIdFromDirectoryEx.Call( + uintptr(mem), + uintptr(BoolToBOOL(icon)), + uintptr(width), + uintptr(height), + uintptr(flags), + ) + return int(ret) +} + +func SetForegroundWindow(window HWND) bool { + ret, _, _ := setForegroundWindow.Call(uintptr(window)) + return ret != 0 +} + +func ScrollWindow(window HWND, dx, dy int, r, clip *RECT) bool { + ret, _, _ := scrollWindow.Call( + uintptr(window), + uintptr(dx), + uintptr(dy), + uintptr(unsafe.Pointer(r)), + uintptr(unsafe.Pointer(clip)), + ) + return ret != 0 +} + +func GetFocus() HWND { + ret, _, _ := getFocus.Call() + return HWND(ret) +} + +func PrintWindow(w HWND, dc HDC, flags uint) bool { + ret, _, _ := printWindow.Call( + uintptr(w), + uintptr(dc), + uintptr(flags), + ) + return ret != 0 +} + +func SetLayeredWindowAttributes(window HWND, key COLORREF, alpha uint8, flags uint32) bool { + ret, _, _ := setLayeredWindowAttributes.Call( + uintptr(window), + uintptr(key), + uintptr(alpha), + uintptr(flags), + ) + return ret != 0 +} + +func RedrawWindow(window HWND, updateRect *RECT, updateRegion HRGN, flags uint32) bool { + ret, _, _ := redrawWindow.Call( + uintptr(window), + uintptr(unsafe.Pointer(updateRect)), + uintptr(updateRegion), + uintptr(flags), + ) + return ret != 0 +} + +func CreateCursor( + instance HINSTANCE, + xHotSpot, yHotSpot, width, height int, + andPlane, xorPlane []byte, +) HCURSOR { + var and, xor uintptr + if len(andPlane) > 0 { + and = uintptr(unsafe.Pointer(&andPlane[0])) + } + if len(xorPlane) > 0 { + xor = uintptr(unsafe.Pointer(&xorPlane[0])) + } + ret, _, _ := createCursor.Call( + uintptr(instance), + uintptr(xHotSpot), + uintptr(yHotSpot), + uintptr(width), + uintptr(height), + and, + xor, + ) + return HCURSOR(ret) +} + +func DestroyCursor(c HCURSOR) bool { + ret, _, _ := destroyCursor.Call(uintptr(c)) + return ret != 0 +} + +func GetDlgCtrlID(w HWND) int { + ret, _, _ := getDlgCtrlID.Call(uintptr(w)) + return int(ret) +} + +func SystemParametersInfo(action, param uint, data uintptr, winIni uint) bool { + ret, _, _ := systemParametersInfo.Call( + uintptr(action), + uintptr(param), + data, + uintptr(winIni), + ) + return ret != 0 +} + +func SystemParametersInfoString(action, param uint, data string, winIni uint) bool { + return SystemParametersInfo( + action, + param, + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(data))), + winIni, + ) +} + +func RegCreateKey(hKey HKEY, subKey string) HKEY { + var result HKEY + ret, _, _ := regCreateKeyEx.Call( + uintptr(hKey), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))), + uintptr(0), + uintptr(0), + uintptr(0), + uintptr(KEY_ALL_ACCESS), + uintptr(0), + uintptr(unsafe.Pointer(&result)), + uintptr(0)) + _ = ret + return result +} + +func RegOpenKeyEx(hKey HKEY, subKey string, samDesired uint32) HKEY { + var result HKEY + ret, _, _ := regOpenKeyEx.Call( + uintptr(hKey), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))), + uintptr(0), + uintptr(samDesired), + uintptr(unsafe.Pointer(&result))) + if ret != ERROR_SUCCESS { + return HKEY(INVALID_HANDLE_VALUE) + } + return result +} + +func RegCloseKey(hKey HKEY) error { + var err error + ret, _, _ := regCloseKey.Call( + uintptr(hKey)) + + if ret != ERROR_SUCCESS { + err = errors.New("RegCloseKey failed") + } + return err +} + +func RegGetRaw(hKey HKEY, subKey string, value string) []byte { + var bufLen uint32 + var valptr unsafe.Pointer + if len(value) > 0 { + valptr = unsafe.Pointer(syscall.StringToUTF16Ptr(value)) + } + regGetValue.Call( + uintptr(hKey), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))), + uintptr(valptr), + uintptr(RRF_RT_ANY), + 0, + 0, + uintptr(unsafe.Pointer(&bufLen)), + ) + + if bufLen == 0 { + return nil + } + + buf := make([]byte, bufLen) + ret, _, _ := regGetValue.Call( + uintptr(hKey), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))), + uintptr(valptr), + uintptr(RRF_RT_ANY), + 0, + uintptr(unsafe.Pointer(&buf[0])), + uintptr(unsafe.Pointer(&bufLen)), + ) + + if ret != ERROR_SUCCESS { + return nil + } + + return buf +} + +func RegSetBinary(hKey HKEY, subKey string, value []byte) (errno int) { + var lptr, vptr unsafe.Pointer + if len(subKey) > 0 { + lptr = unsafe.Pointer(syscall.StringToUTF16Ptr(subKey)) + } + if len(value) > 0 { + vptr = unsafe.Pointer(&value[0]) + } + ret, _, _ := regSetValueEx.Call( + uintptr(hKey), + uintptr(lptr), + uintptr(0), + uintptr(REG_BINARY), + uintptr(vptr), + uintptr(len(value)), + ) + return int(ret) +} + +func RegSetString(hKey HKEY, subKey string, value string) (errno int) { + var lptr, vptr unsafe.Pointer + if subKey != "" { + lptr = unsafe.Pointer(syscall.StringToUTF16Ptr(subKey)) + } + var dataLength int + if value != "" { + buf, err := syscall.UTF16FromString(value) + if err != nil { + return ERROR_BAD_FORMAT + } + vptr = unsafe.Pointer(&buf[0]) + dataLength = len(buf) * 2 + } + ret, _, _ := regSetValueEx.Call( + uintptr(hKey), + uintptr(lptr), + uintptr(0), + uintptr(REG_SZ), + uintptr(vptr), + uintptr(dataLength), + ) + return int(ret) +} + +func RegSetUint32(hKey HKEY, subKey string, value uint32) (errno int) { + var lptr unsafe.Pointer + if len(subKey) > 0 { + lptr = unsafe.Pointer(syscall.StringToUTF16Ptr(subKey)) + } + vptr := unsafe.Pointer(&value) + ret, _, _ := regSetValueEx.Call( + uintptr(hKey), + uintptr(lptr), + uintptr(0), + uintptr(REG_DWORD), + uintptr(vptr), + uintptr(unsafe.Sizeof(value)), + ) + return int(ret) +} + +func RegGetString(hKey HKEY, subKey string, value string) string { + var bufLen uint32 + regGetValue.Call( + uintptr(hKey), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(value))), + uintptr(RRF_RT_REG_SZ), + 0, + 0, + uintptr(unsafe.Pointer(&bufLen)), + ) + + if bufLen == 0 { + return "" + } + + buf := make([]uint16, bufLen) + ret, _, _ := regGetValue.Call( + uintptr(hKey), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(value))), + uintptr(RRF_RT_REG_SZ), + 0, + uintptr(unsafe.Pointer(&buf[0])), + uintptr(unsafe.Pointer(&bufLen)), + ) + + if ret != ERROR_SUCCESS { + return "" + } + + return syscall.UTF16ToString(buf) +} + +func RegGetUint32(hKey HKEY, subKey string, value string) (data uint32, errno int) { + var dataLen uint32 = uint32(unsafe.Sizeof(data)) + ret, _, _ := regGetValue.Call( + uintptr(hKey), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(value))), + uintptr(RRF_RT_REG_DWORD), + 0, + uintptr(unsafe.Pointer(&data)), + uintptr(unsafe.Pointer(&dataLen)), + ) + errno = int(ret) + return +} + +func RegDeleteKeyValue(hKey HKEY, subKey string, valueName string) (errno int) { + ret, _, _ := regDeleteKeyValue.Call( + uintptr(hKey), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(valueName))), + ) + return int(ret) +} + +func RegDeleteValue(hKey HKEY, valueName string) (errno int) { + ret, _, _ := regDeleteValue.Call( + uintptr(hKey), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(valueName))), + ) + return int(ret) +} + +func RegDeleteTree(hKey HKEY, subKey string) (errno int) { + ret, _, _ := regDeleteTree.Call( + uintptr(hKey), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))), + ) + return int(ret) +} + +func RegEnumKeyEx(hKey HKEY, index uint32) string { + var bufLen uint32 = 255 + buf := make([]uint16, bufLen) + regEnumKeyEx.Call( + uintptr(hKey), + uintptr(index), + uintptr(unsafe.Pointer(&buf[0])), + uintptr(unsafe.Pointer(&bufLen)), + 0, + 0, + 0, + 0, + ) + return syscall.UTF16ToString(buf) +} + +func RegEnumValue(key HKEY, index uint32) { + var valueLen uint32 + _, _, _ = regEnumValue.Call( + uintptr(key), + uintptr(index), + 0, + uintptr(unsafe.Pointer(&valueLen)), + 0, + ) +} + +func OpenEventLog(servername string, sourcename string) HANDLE { + ret, _, _ := openEventLog.Call( + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(servername))), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(sourcename))), + ) + return HANDLE(ret) +} + +func GetNumberOfEventLogRecords(eventlog HANDLE) (n uint32, ok bool) { + ret, _, _ := getNumberOfEventLogRecords.Call( + uintptr(eventlog), + uintptr(unsafe.Pointer(&n)), + ) + ok = ret != 0 + return +} + +func ReadEventLog(eventlog HANDLE, readflags, recordoffset uint32, buffer []byte, numberofbytestoread uint32, bytesread, minnumberofbytesneeded *uint32) bool { + ret, _, _ := readEventLog.Call( + uintptr(eventlog), + uintptr(readflags), + uintptr(recordoffset), + uintptr(unsafe.Pointer(&buffer[0])), + uintptr(numberofbytestoread), + uintptr(unsafe.Pointer(bytesread)), + uintptr(unsafe.Pointer(minnumberofbytesneeded)), + ) + return ret != 0 +} + +func CloseEventLog(eventlog HANDLE) bool { + ret, _, _ := closeEventLog.Call(uintptr(eventlog)) + return ret != 0 +} + +func OpenSCManager(lpMachineName, lpDatabaseName string, dwDesiredAccess uint32) (HANDLE, error) { + var p1, p2 uintptr + if len(lpMachineName) > 0 { + p1 = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpMachineName))) + } + if len(lpDatabaseName) > 0 { + p2 = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpDatabaseName))) + } + ret, _, _ := openSCManager.Call( + p1, + p2, + uintptr(dwDesiredAccess)) + + if ret == 0 { + return 0, syscall.GetLastError() + } + return HANDLE(ret), nil +} + +func CloseServiceHandle(hSCObject HANDLE) error { + ret, _, _ := closeServiceHandle.Call(uintptr(hSCObject)) + if ret == 0 { + return syscall.GetLastError() + } + return nil +} + +func OpenService(hSCManager HANDLE, lpServiceName string, dwDesiredAccess uint32) (HANDLE, error) { + ret, _, _ := openService.Call( + uintptr(hSCManager), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpServiceName))), + uintptr(dwDesiredAccess), + ) + + if ret == 0 { + return 0, syscall.GetLastError() + } + + return HANDLE(ret), nil +} + +func StartService(hService HANDLE, lpServiceArgVectors []string) error { + l := len(lpServiceArgVectors) + var ret uintptr + if l == 0 { + ret, _, _ = startService.Call( + uintptr(hService), + 0, + 0, + ) + } else { + lpArgs := make([]uintptr, l) + for i := 0; i < l; i++ { + lpArgs[i] = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpServiceArgVectors[i]))) + } + + ret, _, _ = startService.Call( + uintptr(hService), + uintptr(l), + uintptr(unsafe.Pointer(&lpArgs[0])), + ) + } + + if ret == 0 { + return syscall.GetLastError() + } + + return nil +} + +func ControlService(service HANDLE, control uint32, serviceStatus *SERVICE_STATUS) bool { + ret, _, _ := controlService.Call( + uintptr(service), + uintptr(control), + uintptr(unsafe.Pointer(serviceStatus)), + ) + return ret != 0 +} + +func InitCommonControlsEx(lpInitCtrls *INITCOMMONCONTROLSEX) bool { + if lpInitCtrls != nil { + lpInitCtrls.size = 8 + } + ret, _, _ := initCommonControlsEx.Call(uintptr(unsafe.Pointer(lpInitCtrls))) + return ret != 0 +} + +func ImageList_Create(cx, cy int, flags uint, cInitial, cGrow int) HIMAGELIST { + ret, _, _ := imageList_Create.Call( + uintptr(cx), + uintptr(cy), + uintptr(flags), + uintptr(cInitial), + uintptr(cGrow), + ) + return HIMAGELIST(ret) +} + +func ImageList_Destroy(himl HIMAGELIST) bool { + ret, _, _ := imageList_Destroy.Call(uintptr(himl)) + return ret != 0 +} + +func ImageList_GetImageCount(himl HIMAGELIST) int { + ret, _, _ := imageList_GetImageCount.Call(uintptr(himl)) + return int(ret) +} + +func ImageList_SetImageCount(himl HIMAGELIST, uNewCount uint) bool { + ret, _, _ := imageList_SetImageCount.Call( + uintptr(himl), + uintptr(uNewCount), + ) + return ret != 0 +} + +func ImageList_Add(himl HIMAGELIST, hbmImage, hbmMask HBITMAP) int { + ret, _, _ := imageList_Add.Call( + uintptr(himl), + uintptr(hbmImage), + uintptr(hbmMask), + ) + return int(ret) +} + +func ImageList_ReplaceIcon(himl HIMAGELIST, i int, hicon HICON) int { + ret, _, _ := imageList_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, _, _ := imageList_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, _, _ := trackMouseEvent.Call(uintptr(unsafe.Pointer(tme))) + return ret != 0 +} + +func SetWindowSubclass(window HWND, proc uintptr, id uintptr, refData uintptr) bool { + ret, _, _ := setWindowSubclass.Call( + uintptr(window), + proc, + uintptr(id), + refData, + ) + return ret != 0 +} + +func DefSubclassProc(window HWND, msg uint32, w, l uintptr) uintptr { + ret, _, _ := defSubclassProc.Call( + uintptr(window), + uintptr(msg), + w, + l, + ) + return ret +} + +// GetOpenFileName automatically sets the StructSize member of the OPENFILENAME. +func GetOpenFileName(ofn *OPENFILENAME) bool { + if ofn != nil { + ofn.StructSize = uint32(unsafe.Sizeof(*ofn)) + } + ret, _, _ := getOpenFileName.Call(uintptr(unsafe.Pointer(ofn))) + return ret != 0 +} + +// GetSaveFileName automatically sets the StructSize member of the OPENFILENAME. +func GetSaveFileName(ofn *OPENFILENAME) bool { + if ofn != nil { + ofn.StructSize = uint32(unsafe.Sizeof(*ofn)) + } + ret, _, _ := getSaveFileName.Call(uintptr(unsafe.Pointer(ofn))) + return ret != 0 +} + +func CommDlgExtendedError() uint { + ret, _, _ := commDlgExtendedError.Call() + return uint(ret) +} + +func DwmDefWindowProc(hWnd HWND, msg uint, wParam, lParam uintptr) (bool, uint) { + var result uint + ret, _, _ := dwmDefWindowProc.Call( + uintptr(hWnd), + uintptr(msg), + wParam, + lParam, + uintptr(unsafe.Pointer(&result)), + ) + return ret != 0, result +} + +func DwmEnableBlurBehindWindow(hWnd HWND, pBlurBehind *DWM_BLURBEHIND) HRESULT { + ret, _, _ := dwmEnableBlurBehindWindow.Call( + uintptr(hWnd), + uintptr(unsafe.Pointer(pBlurBehind)), + ) + return HRESULT(ret) +} + +func DwmEnableMMCSS(fEnableMMCSS bool) HRESULT { + ret, _, _ := dwmEnableMMCSS.Call(uintptr(BoolToBOOL(fEnableMMCSS))) + return HRESULT(ret) +} + +func DwmExtendFrameIntoClientArea(hWnd HWND, pMarInset *MARGINS) HRESULT { + ret, _, _ := dwmExtendFrameIntoClientArea.Call( + uintptr(hWnd), + uintptr(unsafe.Pointer(pMarInset)), + ) + return HRESULT(ret) +} + +func DwmFlush() HRESULT { + ret, _, _ := dwmFlush.Call() + return HRESULT(ret) +} + +func DwmGetColorizationColor(pcrColorization *uint32, pfOpaqueBlend *BOOL) HRESULT { + ret, _, _ := dwmGetColorizationColor.Call( + uintptr(unsafe.Pointer(pcrColorization)), + uintptr(unsafe.Pointer(pfOpaqueBlend)), + ) + return HRESULT(ret) +} + +func DwmGetCompositionTimingInfo(hWnd HWND, pTimingInfo *DWM_TIMING_INFO) HRESULT { + ret, _, _ := dwmGetCompositionTimingInfo.Call( + uintptr(hWnd), + uintptr(unsafe.Pointer(pTimingInfo)), + ) + return HRESULT(ret) +} + +func DwmGetTransportAttributes(pfIsRemoting *BOOL, pfIsConnected *BOOL, pDwGeneration *uint32) HRESULT { + ret, _, _ := dwmGetTransportAttributes.Call( + uintptr(unsafe.Pointer(pfIsRemoting)), + uintptr(unsafe.Pointer(pfIsConnected)), + uintptr(unsafe.Pointer(pDwGeneration)), + ) + return HRESULT(ret) +} + +func DwmGetWindowAttributeNCRENDERING_ENABLED(window HWND) (ok, enabled bool) { + var b uint32 + ret, _, _ := dwmGetWindowAttribute.Call( + uintptr(window), + uintptr(DWMWA_NCRENDERING_ENABLED), + uintptr(unsafe.Pointer(&b)), + 4, // size of uint32 + ) + ok = ret == S_OK + enabled = b != 0 + return +} + +func DwmGetWindowAttributeCAPTION_BUTTON_BOUNDS(window HWND) (ok bool, r RECT) { + ret, _, _ := dwmGetWindowAttribute.Call( + uintptr(window), + uintptr(DWMWA_CAPTION_BUTTON_BOUNDS), + uintptr(unsafe.Pointer(&r)), + 16, // size of RECT + ) + ok = ret == S_OK + return +} + +func DwmGetWindowAttributeEXTENDED_FRAME_BOUNDS(window HWND) (ok bool, r RECT) { + ret, _, _ := dwmGetWindowAttribute.Call( + uintptr(window), + uintptr(DWMWA_EXTENDED_FRAME_BOUNDS), + uintptr(unsafe.Pointer(&r)), + 16, // size of RECT + ) + ok = ret == S_OK + return +} + +// DwmGetWindowAttributeCLOAKED returns one of the DWM_... constants. +func DwmGetWindowAttributeCLOAKED(window HWND) (ok bool, cloaked uint32) { + ret, _, _ := dwmGetWindowAttribute.Call( + uintptr(window), + uintptr(DWMWA_CLOAKED), + uintptr(unsafe.Pointer(&cloaked)), + 16, // size of uint32 + ) + ok = ret == S_OK + return +} + +func DwmInvalidateIconicBitmaps(hWnd HWND) HRESULT { + ret, _, _ := dwmInvalidateIconicBitmaps.Call(uintptr(hWnd)) + return HRESULT(ret) +} + +func DwmIsCompositionEnabled(pfEnabled *BOOL) HRESULT { + ret, _, _ := dwmIsCompositionEnabled.Call(uintptr(unsafe.Pointer(pfEnabled))) + return HRESULT(ret) +} + +func DwmModifyPreviousDxFrameDuration(hWnd HWND, cRefreshes int, fRelative bool) HRESULT { + ret, _, _ := dwmModifyPreviousDxFrameDuration.Call( + uintptr(hWnd), + uintptr(cRefreshes), + uintptr(BoolToBOOL(fRelative)), + ) + return HRESULT(ret) +} + +func DwmQueryThumbnailSourceSize(hThumbnail HTHUMBNAIL, pSize *SIZE) HRESULT { + ret, _, _ := dwmQueryThumbnailSourceSize.Call( + uintptr(hThumbnail), + uintptr(unsafe.Pointer(pSize)), + ) + return HRESULT(ret) +} + +func DwmRegisterThumbnail(hWndDestination HWND, hWndSource HWND, phThumbnailId *HTHUMBNAIL) HRESULT { + ret, _, _ := dwmRegisterThumbnail.Call( + uintptr(hWndDestination), + uintptr(hWndSource), + uintptr(unsafe.Pointer(phThumbnailId)), + ) + return HRESULT(ret) +} + +func DwmRenderGesture(gt GESTURE_TYPE, cContacts uint, pdwPointerID *uint32, pPoints *POINT) { + dwmRenderGesture.Call( + uintptr(gt), + uintptr(cContacts), + uintptr(unsafe.Pointer(pdwPointerID)), + uintptr(unsafe.Pointer(pPoints)), + ) + return +} + +func DwmSetDxFrameDuration(hWnd HWND, cRefreshes int) HRESULT { + ret, _, _ := dwmSetDxFrameDuration.Call( + uintptr(hWnd), + uintptr(cRefreshes), + ) + return HRESULT(ret) +} + +func DwmSetIconicLivePreviewBitmap(hWnd HWND, hbmp HBITMAP, pptClient *POINT, dwSITFlags uint32) HRESULT { + ret, _, _ := dwmSetIconicLivePreviewBitmap.Call( + uintptr(hWnd), + uintptr(hbmp), + uintptr(unsafe.Pointer(pptClient)), + uintptr(dwSITFlags), + ) + return HRESULT(ret) +} + +func DwmSetIconicThumbnail(hWnd HWND, hbmp HBITMAP, dwSITFlags uint32) HRESULT { + ret, _, _ := dwmSetIconicThumbnail.Call( + uintptr(hWnd), + uintptr(hbmp), + uintptr(dwSITFlags), + ) + return HRESULT(ret) +} + +func DwmSetPresentParameters(hWnd HWND, pPresentParams *DWM_PRESENT_PARAMETERS) HRESULT { + ret, _, _ := dwmSetPresentParameters.Call( + uintptr(hWnd), + uintptr(unsafe.Pointer(pPresentParams)), + ) + return HRESULT(ret) +} + +func DwmSetWindowAttribute(hWnd HWND, dwAttribute uint32, pvAttribute LPCVOID, cbAttribute uint32) HRESULT { + ret, _, _ := dwmSetWindowAttribute.Call( + uintptr(hWnd), + uintptr(dwAttribute), + uintptr(pvAttribute), + uintptr(cbAttribute), + ) + return HRESULT(ret) +} + +func DwmShowContact(dwPointerID uint32, eShowContact DWM_SHOWCONTACT) { + dwmShowContact.Call( + uintptr(dwPointerID), + uintptr(eShowContact), + ) + return +} + +func DwmTetherContact(dwPointerID uint32, fEnable bool, ptTether POINT) { + dwmTetherContact.Call( + uintptr(dwPointerID), + uintptr(BoolToBOOL(fEnable)), + uintptr(unsafe.Pointer(&ptTether)), + ) + return +} + +func DwmTransitionOwnedWindow(hWnd HWND, target DWMTRANSITION_OWNEDWINDOW_TARGET) { + dwmTransitionOwnedWindow.Call( + uintptr(hWnd), + uintptr(target), + ) + return +} + +func DwmUnregisterThumbnail(hThumbnailId HTHUMBNAIL) HRESULT { + ret, _, _ := dwmUnregisterThumbnail.Call(uintptr(hThumbnailId)) + return HRESULT(ret) +} + +func DwmUpdateThumbnailProperties(hThumbnailId HTHUMBNAIL, ptnProperties *DWM_THUMBNAIL_PROPERTIES) HRESULT { + ret, _, _ := dwmUpdateThumbnailProperties.Call( + uintptr(hThumbnailId), + uintptr(unsafe.Pointer(ptnProperties)), + ) + return HRESULT(ret) +} + +func GetDeviceCaps(hdc HDC, index int) int { + ret, _, _ := getDeviceCaps.Call( + uintptr(hdc), + uintptr(index), + ) + return int(ret) +} + +func DeleteObject(hObject HGDIOBJ) bool { + ret, _, _ := deleteObject.Call(uintptr(hObject)) + return ret != 0 +} + +func CreateFontIndirect(logFont *LOGFONT) HFONT { + ret, _, _ := createFontIndirect.Call(uintptr(unsafe.Pointer(logFont))) + return HFONT(ret) +} + +func AbortDoc(hdc HDC) int { + ret, _, _ := abortDoc.Call(uintptr(hdc)) + return int(ret) +} + +func BitBlt(hdcDest HDC, nXDest, nYDest, nWidth, nHeight int, hdcSrc HDC, nXSrc, nYSrc int, dwRop uint) bool { + ret, _, _ := bitBlt.Call( + uintptr(hdcDest), + uintptr(nXDest), + uintptr(nYDest), + uintptr(nWidth), + uintptr(nHeight), + uintptr(hdcSrc), + uintptr(nXSrc), + uintptr(nYSrc), + uintptr(dwRop), + ) + return ret != 0 +} + +func MaskBlt( + dest HDC, destX, destY, destWidth, destHeight int, + source HDC, sourceX, sourceY int, + mask HBITMAP, maskX, maskY int, + operation uint, +) bool { + ret, _, _ := maskBlt.Call( + uintptr(dest), + uintptr(destX), + uintptr(destY), + uintptr(destWidth), + uintptr(destHeight), + uintptr(source), + uintptr(sourceX), + uintptr(sourceY), + uintptr(mask), + uintptr(maskX), + uintptr(maskX), + uintptr(operation), + ) + return ret != 0 +} + +func PatBlt(hdc HDC, nXLeft, nYLeft, nWidth, nHeight int, dwRop uint) bool { + ret, _, _ := patBlt.Call( + uintptr(hdc), + uintptr(nXLeft), + uintptr(nYLeft), + uintptr(nWidth), + uintptr(nHeight), + uintptr(dwRop), + ) + return ret != 0 +} + +func CloseEnhMetaFile(hdc HDC) HENHMETAFILE { + ret, _, _ := closeEnhMetaFile.Call(uintptr(hdc)) + return HENHMETAFILE(ret) +} + +func CopyEnhMetaFile(hemfSrc HENHMETAFILE, lpszFile *uint16) HENHMETAFILE { + ret, _, _ := copyEnhMetaFile.Call( + uintptr(hemfSrc), + uintptr(unsafe.Pointer(lpszFile)), + ) + return HENHMETAFILE(ret) +} + +func CreateBrushIndirect(lplb *LOGBRUSH) HBRUSH { + ret, _, _ := createBrushIndirect.Call(uintptr(unsafe.Pointer(lplb))) + return HBRUSH(ret) +} + +func CreateCompatibleDC(hdc HDC) HDC { + ret, _, _ := createCompatibleDC.Call(uintptr(hdc)) + return HDC(ret) +} + +func CreateCompatibleBitmap(hdc HDC, width, height int) HBITMAP { + ret, _, _ := createCompatibleBitmap.Call( + uintptr(hdc), + uintptr(width), + uintptr(height), + ) + return HBITMAP(ret) +} + +func CreateBitmap(width, height int, planes, bitCount uint, bits unsafe.Pointer) HBITMAP { + ret, _, _ := createBitmap.Call( + uintptr(width), + uintptr(height), + uintptr(planes), + uintptr(bitCount), + uintptr(bits), + ) + return HBITMAP(ret) +} + +func CreateDC(lpszDriver, lpszDevice, lpszOutput *uint16, lpInitData *DEVMODE) HDC { + ret, _, _ := createDC.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, _, _ := createDIBSection.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, _, _ := createEnhMetaFile.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, _, _ := createIC.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, _, _ := deleteDC.Call(uintptr(hdc)) + return ret != 0 +} + +func DeleteEnhMetaFile(hemf HENHMETAFILE) bool { + ret, _, _ := deleteEnhMetaFile.Call(uintptr(hemf)) + return ret != 0 +} + +func Ellipse(hdc HDC, nLeftRect, nTopRect, nRightRect, nBottomRect int) bool { + ret, _, _ := ellipse.Call( + uintptr(hdc), + uintptr(nLeftRect), + uintptr(nTopRect), + uintptr(nRightRect), + uintptr(nBottomRect), + ) + return ret != 0 +} + +func EndDoc(hdc HDC) int { + ret, _, _ := endDoc.Call(uintptr(hdc)) + return int(ret) +} + +func EndPage(hdc HDC) int { + ret, _, _ := endPage.Call(uintptr(hdc)) + return int(ret) +} + +func ExtCreatePen(dwPenStyle, dwWidth uint, lplb *LOGBRUSH, dwStyleCount uint, lpStyle *uint) HPEN { + ret, _, _ := extCreatePen.Call( + uintptr(dwPenStyle), + uintptr(dwWidth), + uintptr(unsafe.Pointer(lplb)), + uintptr(dwStyleCount), + uintptr(unsafe.Pointer(lpStyle)), + ) + return HPEN(ret) +} + +func GetEnhMetaFile(lpszMetaFile *uint16) HENHMETAFILE { + ret, _, _ := getEnhMetaFile.Call(uintptr(unsafe.Pointer(lpszMetaFile))) + return HENHMETAFILE(ret) +} + +func GetEnhMetaFileHeader(hemf HENHMETAFILE, cbBuffer uint, lpemh *ENHMETAHEADER) uint { + ret, _, _ := getEnhMetaFileHeader.Call( + uintptr(hemf), + uintptr(cbBuffer), + uintptr(unsafe.Pointer(lpemh)), + ) + return uint(ret) +} + +func GetObject(hgdiobj HGDIOBJ, cbBuffer uintptr, lpvObject unsafe.Pointer) int { + ret, _, _ := getObject.Call( + uintptr(hgdiobj), + uintptr(cbBuffer), + uintptr(lpvObject), + ) + return int(ret) +} + +func GetStockObject(fnObject int) HGDIOBJ { + ret, _, _ := getStockObject.Call(uintptr(fnObject)) + return HGDIOBJ(ret) +} + +func GetTextExtentExPoint(hdc HDC, lpszStr *uint16, cchString, nMaxExtent int, lpnFit, alpDx *int, lpSize *SIZE) bool { + ret, _, _ := getTextExtentExPoint.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, text string) (SIZE, bool) { + var s SIZE + str, err := syscall.UTF16FromString(text) + if err != nil { + return s, false + } + ret, _, _ := getTextExtentPoint32.Call( + uintptr(hdc), + uintptr(unsafe.Pointer(&str[0])), + uintptr(len(str)-1), // -1 for the trailing '\0' + uintptr(unsafe.Pointer(&s)), + ) + return s, ret != 0 +} + +func GetTextMetrics(hdc HDC, lptm *TEXTMETRIC) bool { + ret, _, _ := getTextMetrics.Call( + uintptr(hdc), + uintptr(unsafe.Pointer(lptm)), + ) + return ret != 0 +} + +func LineTo(hdc HDC, nXEnd, nYEnd int) bool { + ret, _, _ := lineTo.Call( + uintptr(hdc), + uintptr(nXEnd), + uintptr(nYEnd), + ) + return ret != 0 +} + +func MoveToEx(hdc HDC, x, y int, lpPoint *POINT) bool { + ret, _, _ := moveToEx.Call( + uintptr(hdc), + uintptr(x), + uintptr(y), + uintptr(unsafe.Pointer(lpPoint)), + ) + return ret != 0 +} + +func PlayEnhMetaFile(hdc HDC, hemf HENHMETAFILE, lpRect *RECT) bool { + ret, _, _ := playEnhMetaFile.Call( + uintptr(hdc), + uintptr(hemf), + uintptr(unsafe.Pointer(lpRect)), + ) + return ret != 0 +} + +func Rectangle(hdc HDC, nLeftRect, nTopRect, nRightRect, nBottomRect int) bool { + ret, _, _ := rectangle.Call( + uintptr(hdc), + uintptr(nLeftRect), + uintptr(nTopRect), + uintptr(nRightRect), + uintptr(nBottomRect), + ) + return ret != 0 +} + +func ResetDC(hdc HDC, lpInitData *DEVMODE) HDC { + ret, _, _ := resetDC.Call( + uintptr(hdc), + uintptr(unsafe.Pointer(lpInitData)), + ) + return HDC(ret) +} + +func SelectObject(hdc HDC, hgdiobj HGDIOBJ) HGDIOBJ { + ret, _, _ := selectObject.Call( + uintptr(hdc), + uintptr(hgdiobj), + ) + return HGDIOBJ(ret) +} + +func SetBkMode(hdc HDC, iBkMode int) int { + ret, _, _ := setBkMode.Call( + uintptr(hdc), + uintptr(iBkMode), + ) + return int(ret) +} + +func SetBrushOrgEx(hdc HDC, nXOrg, nYOrg int, lppt *POINT) bool { + ret, _, _ := setBrushOrgEx.Call( + uintptr(hdc), + uintptr(nXOrg), + uintptr(nYOrg), + uintptr(unsafe.Pointer(lppt)), + ) + return ret != 0 +} + +func SetStretchBltMode(hdc HDC, iStretchMode int) int { + ret, _, _ := setStretchBltMode.Call( + uintptr(hdc), + uintptr(iStretchMode), + ) + return int(ret) +} + +func SetTextColor(hdc HDC, crColor COLORREF) COLORREF { + ret, _, _ := setTextColor.Call( + uintptr(hdc), + uintptr(crColor), + ) + return COLORREF(ret) +} + +func SetBkColor(hdc HDC, crColor COLORREF) COLORREF { + ret, _, _ := setBkColor.Call( + uintptr(hdc), + uintptr(crColor), + ) + return COLORREF(ret) +} + +func StartDoc(hdc HDC, lpdi *DOCINFO) int { + ret, _, _ := startDoc.Call( + uintptr(hdc), + uintptr(unsafe.Pointer(lpdi)), + ) + return int(ret) +} + +func StartPage(hdc HDC) int { + ret, _, _ := startPage.Call(uintptr(hdc)) + return int(ret) +} + +func StretchBlt(hdcDest HDC, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest int, hdcSrc HDC, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc int, dwRop uint) bool { + ret, _, _ := stretchBlt.Call( + uintptr(hdcDest), + uintptr(nXOriginDest), + uintptr(nYOriginDest), + uintptr(nWidthDest), + uintptr(nHeightDest), + uintptr(hdcSrc), + uintptr(nXOriginSrc), + uintptr(nYOriginSrc), + uintptr(nWidthSrc), + uintptr(nHeightSrc), + uintptr(dwRop), + ) + return ret != 0 +} + +func SetDIBitsToDevice(hdc HDC, xDest, yDest, dwWidth, dwHeight, xSrc, ySrc int, uStartScan, cScanLines uint, lpvBits []byte, lpbmi *BITMAPINFO, fuColorUse uint) int { + ret, _, _ := setDIBitsToDevice.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, _, _ := choosePixelFormat.Call( + uintptr(hdc), + uintptr(unsafe.Pointer(pfd)), + ) + return int(ret) +} + +func DescribePixelFormat(hdc HDC, iPixelFormat int, nBytes uint, pfd *PIXELFORMATDESCRIPTOR) int { + ret, _, _ := describePixelFormat.Call( + uintptr(hdc), + uintptr(iPixelFormat), + uintptr(nBytes), + uintptr(unsafe.Pointer(pfd)), + ) + return int(ret) +} + +func GetEnhMetaFilePixelFormat(hemf HENHMETAFILE, cbBuffer uint32, pfd *PIXELFORMATDESCRIPTOR) uint { + ret, _, _ := getEnhMetaFilePixelFormat.Call( + uintptr(hemf), + uintptr(cbBuffer), + uintptr(unsafe.Pointer(pfd)), + ) + return uint(ret) +} + +func GetPixelFormat(hdc HDC) int { + ret, _, _ := getPixelFormat.Call(uintptr(hdc)) + return int(ret) +} + +func SetPixelFormat(hdc HDC, iPixelFormat int, pfd *PIXELFORMATDESCRIPTOR) bool { + ret, _, _ := setPixelFormat.Call( + uintptr(hdc), + uintptr(iPixelFormat), + uintptr(unsafe.Pointer(pfd)), + ) + return ret == TRUE +} + +func SwapBuffers(hdc HDC) bool { + ret, _, _ := swapBuffers.Call(uintptr(hdc)) + return ret == TRUE +} + +func TextOut(hdc HDC, x, y int, s string) bool { + str, err := syscall.UTF16FromString(s) + if err != nil { + return false + } + ret, _, _ := textOut.Call( + uintptr(hdc), + uintptr(x), + uintptr(y), + uintptr(unsafe.Pointer(&str[0])), + uintptr(len(str)-1), // -1 for the trailing '\0' + ) + return ret != 0 +} + +func CreateSolidBrush(color uint32) HBRUSH { + ret, _, _ := createSolidBrush.Call(uintptr(color)) + return HBRUSH(ret) +} + +func GetDIBits( + dc HDC, + bmp HBITMAP, + startScan, scanLines uint, + bits unsafe.Pointer, + info *BITMAPINFO, + usage uint, +) int { + ret, _, _ := getDIBits.Call( + uintptr(dc), + uintptr(bmp), + uintptr(startScan), + uintptr(scanLines), + uintptr(bits), + uintptr(unsafe.Pointer(info)), + uintptr(usage), + ) + return int(ret) +} + +func Pie(hdc HDC, left, top, right, bottom, xr1, yr1, xr2, yr2 int) bool { + ret, _, _ := pie.Call( + uintptr(hdc), + uintptr(left), + uintptr(top), + uintptr(right), + uintptr(bottom), + uintptr(xr1), + uintptr(yr1), + uintptr(xr2), + uintptr(yr2), + ) + return ret != 0 +} + +func SetDCPenColor(hdc HDC, color COLORREF) COLORREF { + ret, _, _ := setDCPenColor.Call(uintptr(hdc), uintptr(color)) + return COLORREF(ret) +} + +func SetDCBrushColor(hdc HDC, color COLORREF) COLORREF { + ret, _, _ := setDCBrushColor.Call(uintptr(hdc), uintptr(color)) + return COLORREF(ret) +} + +func CreatePen(style int, width int, color COLORREF) HPEN { + ret, _, _ := createPen.Call( + uintptr(style), + uintptr(width), + uintptr(color), + ) + return HPEN(ret) +} + +func Arc(hdc HDC, x1, y1, x2, y2, x3, y3, x4, y4 int) bool { + ret, _, _ := arc.Call( + uintptr(hdc), + uintptr(x1), + uintptr(y1), + uintptr(x2), + uintptr(y2), + uintptr(x3), + uintptr(y3), + uintptr(x4), + uintptr(y4), + ) + return ret != 0 +} + +func ArcTo(hdc HDC, left, top, right, bottom, xr1, yr1, xr2, yr2 int) bool { + ret, _, _ := arcTo.Call( + uintptr(hdc), + uintptr(left), + uintptr(top), + uintptr(right), + uintptr(bottom), + uintptr(xr1), + uintptr(yr1), + uintptr(xr2), + uintptr(yr2), + ) + return ret != 0 +} + +func AngleArc(hdc HDC, x, y, r int, startAngle, sweepAngle float32) bool { + ret, _, _ := angleArc.Call( + uintptr(hdc), + uintptr(x), + uintptr(y), + uintptr(r), + uintptr(startAngle), + uintptr(sweepAngle), + ) + return ret != 0 +} + +func Chord(hdc HDC, x1, y1, x2, y2, x3, y3, x4, y4 int) bool { + ret, _, _ := chord.Call( + uintptr(hdc), + uintptr(x1), + uintptr(y1), + uintptr(x2), + uintptr(y2), + uintptr(x3), + uintptr(y3), + uintptr(x4), + uintptr(y4), + ) + return ret != 0 +} + +func Polygon(hdc HDC, p []POINT) bool { + if len(p) == 0 { + return true + } + ret, _, _ := polygon.Call( + uintptr(hdc), + uintptr(unsafe.Pointer(&p[0])), + uintptr(len(p)), + ) + return ret != 0 +} + +func PolygonMem(hdc HDC, start unsafe.Pointer, pointCount int) bool { + ret, _, _ := polygon.Call( + uintptr(hdc), + uintptr(start), + uintptr(pointCount), + ) + return ret != 0 +} + +func Polyline(hdc HDC, p []POINT) bool { + if len(p) == 0 { + return true + } + ret, _, _ := polyline.Call( + uintptr(hdc), + uintptr(unsafe.Pointer(&p[0])), + uintptr(len(p)), + ) + return ret != 0 +} + +func PolylineMem(hdc HDC, start unsafe.Pointer, pointCount int) bool { + ret, _, _ := polyline.Call( + uintptr(hdc), + uintptr(start), + uintptr(pointCount), + ) + return ret != 0 +} + +func PolyBezier(hdc HDC, p []POINT) bool { + if len(p) == 0 { + return true + } + ret, _, _ := polyBezier.Call( + uintptr(hdc), + uintptr(unsafe.Pointer(&p[0])), + uintptr(len(p)), + ) + return ret != 0 +} + +func PolyBezierMem(hdc HDC, start unsafe.Pointer, pointCount int) bool { + ret, _, _ := polyline.Call( + uintptr(hdc), + uintptr(start), + uintptr(pointCount), + ) + return ret != 0 +} + +func IntersectClipRect(hdc HDC, left, top, right, bottom int) int { + ret, _, _ := intersectClipRect.Call( + uintptr(hdc), + uintptr(left), + uintptr(top), + uintptr(right), + uintptr(bottom), + ) + return int(ret) +} + +func SelectClipRgn(hdc HDC, region HRGN) int { + ret, _, _ := selectClipRgn.Call(uintptr(hdc), uintptr(region)) + return int(ret) +} + +func CreateRectRgn(x1, y1, x2, y2 int) HRGN { + ret, _, _ := createRectRgn.Call( + uintptr(x1), + uintptr(y1), + uintptr(x2), + uintptr(y2), + ) + return HRGN(ret) +} + +func CombineRgn(dest, src1, src2 HRGN, mode int) int { + ret, _, _ := combineRgn.Call( + uintptr(dest), + uintptr(src1), + uintptr(src2), + uintptr(mode), + ) + return int(ret) +} + +type FontType int + +const ( + RASTER_FONTTYPE FontType = 1 + DEVICE_FONTTYPE FontType = 2 + TRUETYPE_FONTTYPE FontType = 4 +) + +func (t FontType) String() string { + switch t { + case RASTER_FONTTYPE: + return "RASTER_FONTTYPE" + case DEVICE_FONTTYPE: + return "DEVICE_FONTTYPE" + case TRUETYPE_FONTTYPE: + return "TRUETYPE_FONTTYPE" + } + return strconv.Itoa(int(t)) +} + +func EnumFontFamiliesEx(hdc HDC, font LOGFONT, f func(font *ENUMLOGFONTEX, metric *ENUMTEXTMETRIC, fontType FontType) bool) { + callback := syscall.NewCallback(func(font, metric uintptr, typ uint32, _ uintptr) uintptr { + if f( + (*ENUMLOGFONTEX)(unsafe.Pointer(font)), + (*ENUMTEXTMETRIC)(unsafe.Pointer(metric)), + FontType(typ), + ) { + return 1 + } + return 0 + }) + enumFontFamiliesEx.Call( + uintptr(hdc), + uintptr(unsafe.Pointer(&font)), + callback, + 0, + 0, + ) +} + +func GetModuleHandle(modulename string) HINSTANCE { + var mn uintptr + if modulename == "" { + mn = 0 + } else { + mn = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(modulename))) + } + ret, _, _ := getModuleHandle.Call(mn) + return HINSTANCE(ret) +} + +func GetModuleFileName(mod HMODULE) string { + var path [32768]uint16 + ret, _, _ := getModuleFileName.Call( + uintptr(mod), + uintptr(unsafe.Pointer(&path[0])), + uintptr(len(path)), + ) + if ret == 0 { + return "" + } + return syscall.UTF16ToString(path[:]) +} + +func MulDiv(number, numerator, denominator int) int { + ret, _, _ := mulDiv.Call( + uintptr(number), + uintptr(numerator), + uintptr(denominator), + ) + return int(ret) +} + +func GetConsoleWindow() HWND { + ret, _, _ := getConsoleWindow.Call() + return HWND(ret) +} + +func GetCurrentThread() HANDLE { + ret, _, _ := getCurrentThread.Call() + return HANDLE(ret) +} + +func GetLogicalDrives() uint32 { + ret, _, _ := getLogicalDrives.Call() + return uint32(ret) +} + +func GetDriveType(drive string) uint { + ret, _, _ := getDriveType.Call(uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(drive)))) + return uint(ret) +} + +func GetUserDefaultLCID() uint32 { + ret, _, _ := getUserDefaultLCID.Call() + return uint32(ret) +} + +func Lstrlen(lpString *uint16) int { + ret, _, _ := lstrlen.Call(uintptr(unsafe.Pointer(lpString))) + return int(ret) +} + +func Lstrcpy(buf []uint16, lpString *uint16) { + lstrcpy.Call( + uintptr(unsafe.Pointer(&buf[0])), + uintptr(unsafe.Pointer(lpString)), + ) +} + +func GlobalAlloc(uFlags uint, dwBytes uint32) HGLOBAL { + ret, _, _ := globalAlloc.Call( + uintptr(uFlags), + uintptr(dwBytes)) + return HGLOBAL(ret) +} + +func GlobalFree(hMem HGLOBAL) { + globalFree.Call(uintptr(hMem)) +} + +func GlobalLock(hMem HGLOBAL) unsafe.Pointer { + ret, _, _ := globalLock.Call(uintptr(hMem)) + return unsafe.Pointer(ret) +} + +func GlobalUnlock(hMem HGLOBAL) bool { + ret, _, _ := globalUnlock.Call(uintptr(hMem)) + return ret != 0 +} + +func MoveMemory(destination, source unsafe.Pointer, length uint32) { + moveMemory.Call( + uintptr(unsafe.Pointer(destination)), + uintptr(source), + uintptr(length), + ) +} + +func FindResource(hModule HMODULE, lpName, lpType *uint16) (HRSRC, error) { + ret, _, _ := findResource.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, _, _ := sizeofResource.Call( + uintptr(hModule), + uintptr(hResInfo)) + return uint32(ret) +} + +func LockResource(hResData HGLOBAL) unsafe.Pointer { + ret, _, _ := lockResource.Call(uintptr(hResData)) + return unsafe.Pointer(ret) +} + +func LoadResource(hModule HMODULE, hResInfo HRSRC) HGLOBAL { + ret, _, _ := loadResource.Call( + uintptr(hModule), + uintptr(hResInfo), + ) + return HGLOBAL(ret) +} + +func GetLastError() uint32 { + ret, _, _ := getLastError.Call() + return uint32(ret) +} + +func OpenProcess(desiredAccess uint32, inheritHandle bool, processId uint32) HANDLE { + inherit := 0 + if inheritHandle { + inherit = 1 + } + ret, _, _ := openProcess.Call( + uintptr(desiredAccess), + uintptr(inherit), + uintptr(processId), + ) + return HANDLE(ret) +} + +func TerminateProcess(hProcess HANDLE, uExitCode uint) bool { + ret, _, _ := terminateProcess.Call( + uintptr(hProcess), + uintptr(uExitCode), + ) + return ret != 0 +} + +func CloseHandle(object HANDLE) bool { + ret, _, _ := closeHandle.Call(uintptr(object)) + return ret != 0 +} + +func CreateToolhelp32Snapshot(flags, processId uint32) HANDLE { + ret, _, _ := createToolhelp32Snapshot.Call( + uintptr(flags), + uintptr(processId), + ) + if ret <= 0 { + return HANDLE(0) + } + return HANDLE(ret) +} + +func Module32First(snapshot HANDLE, me *MODULEENTRY32) bool { + ret, _, _ := module32First.Call( + uintptr(snapshot), + uintptr(unsafe.Pointer(me)), + ) + return ret != 0 +} + +func Module32Next(snapshot HANDLE, me *MODULEENTRY32) bool { + ret, _, _ := module32Next.Call( + uintptr(snapshot), + uintptr(unsafe.Pointer(me)), + ) + return ret != 0 +} + +func GetSystemTimes(lpIdleTime, lpKernelTime, lpUserTime *FILETIME) bool { + ret, _, _ := getSystemTimes.Call( + uintptr(unsafe.Pointer(lpIdleTime)), + uintptr(unsafe.Pointer(lpKernelTime)), + uintptr(unsafe.Pointer(lpUserTime)), + ) + return ret != 0 +} + +func GetProcessTimes(hProcess HANDLE) (creationTime, exitTime, kernelTime, userTime FILETIME, ok bool) { + ret, _, _ := getProcessTimes.Call( + uintptr(hProcess), + uintptr(unsafe.Pointer(&creationTime)), + uintptr(unsafe.Pointer(&exitTime)), + uintptr(unsafe.Pointer(&kernelTime)), + uintptr(unsafe.Pointer(&userTime)), + ) + ok = ret != 0 + return +} + +func GetConsoleScreenBufferInfo(hConsoleOutput HANDLE) *CONSOLE_SCREEN_BUFFER_INFO { + var csbi CONSOLE_SCREEN_BUFFER_INFO + ret, _, _ := getConsoleScreenBufferInfo.Call( + uintptr(hConsoleOutput), + uintptr(unsafe.Pointer(&csbi)), + ) + if ret == 0 { + return nil + } + return &csbi +} + +func SetConsoleTextAttribute(hConsoleOutput HANDLE, wAttributes uint16) bool { + ret, _, _ := setConsoleTextAttribute.Call( + uintptr(hConsoleOutput), + uintptr(wAttributes), + ) + return ret != 0 +} + +func GetDiskFreeSpaceEx(dirName string) (r bool, + freeBytesAvailable, totalNumberOfBytes, totalNumberOfFreeBytes uint64) { + ret, _, _ := getDiskFreeSpaceEx.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() (time SYSTEMTIME) { + getSystemTime.Call(uintptr(unsafe.Pointer(&time))) + return +} + +func GetSystemTimeAsFileTime() (time FILETIME) { + getSystemTimeAsFileTime.Call(uintptr(unsafe.Pointer(&time))) + return +} + +func SystemTimeToFileTime(sysTime SYSTEMTIME) (fileTime FILETIME, ok bool) { + ret, _, _ := systemTimeToFileTime.Call( + uintptr(unsafe.Pointer(&sysTime)), + uintptr(unsafe.Pointer(&fileTime)), + ) + ok = ret != 0 + return +} + +func FileTimeToSystemTime(fileTime FILETIME) (sysTime SYSTEMTIME, ok bool) { + ret, _, _ := fileTimeToSystemTime.Call( + uintptr(unsafe.Pointer(&fileTime)), + uintptr(unsafe.Pointer(&sysTime)), + ) + ok = ret != 0 + return +} + +func SetSystemTime(time SYSTEMTIME) bool { + ret, _, _ := setSystemTime.Call(uintptr(unsafe.Pointer(&time))) + return ret != 0 +} + +func SetLocalTime(time SYSTEMTIME) bool { + ret, _, _ := setLocalTime.Call(uintptr(unsafe.Pointer(&time))) + return ret != 0 +} + +func CopyMemory(dest, source unsafe.Pointer, sizeInBytes int) { + copyMemory.Call( + uintptr(dest), + uintptr(source), + uintptr(sizeInBytes), + ) +} + +func GetCurrentProcess() HANDLE { + id, _, _ := getCurrentProcess.Call() + return HANDLE(id) +} + +func GetCurrentProcessId() DWORD { + id, _, _ := getCurrentProcessId.Call() + return DWORD(id) +} + +func GetVersion() uint32 { + ret, _, _ := getVersion.Call() + return uint32(ret) +} + +func SetEnvironmentVariable(name, value string) bool { + ret, _, _ := setEnvironmentVariable.Call( + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(name))), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(value))), + ) + return ret != 0 +} + +func GetComputerName() string { + const maxLen = 128 + var buf [maxLen]uint16 + var size uint32 = maxLen + ret, _, _ := getComputerName.Call( + uintptr(unsafe.Pointer(&buf[0])), + uintptr(unsafe.Pointer(&size)), + ) + if ret != 0 { + return syscall.UTF16ToString(buf[:]) + } + return "" +} + +func ActivateActCtx(ctx HANDLE) (uintptr, bool) { + var cookie uintptr + ret, _, _ := activateActCtx.Call( + uintptr(ctx), + uintptr(unsafe.Pointer(&cookie)), + ) + return cookie, ret != 0 +} + +func CreateActCtx(ctx *ACTCTX) HANDLE { + if ctx != nil { + ctx.size = uint32(unsafe.Sizeof(*ctx)) + } + ret, _, _ := createActCtx.Call(uintptr(unsafe.Pointer(ctx))) + return HANDLE(ret) +} + +func GetCurrentActCtx() (HANDLE, bool) { + var h HANDLE + ret, _, _ := getCurrentActCtx.Call(uintptr(unsafe.Pointer(&h))) + return h, ret != 0 +} + +func SetErrorMode(mode uint) uint { + ret, _, _ := setErrorMode.Call(uintptr(mode)) + return uint(ret) +} + +func CreateFile( + filename string, + access uint32, + shareMode uint32, + security *SECURITY_ATTRIBUTES, + disposition uint32, + flags uint32, + templateFile HANDLE, +) HANDLE { + ret, _, _ := createFile.Call( + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(filename))), + uintptr(access), + uintptr(shareMode), + uintptr(unsafe.Pointer(security)), + uintptr(disposition), + uintptr(flags), + uintptr(templateFile), + ) + return HANDLE(ret) +} + +func DeviceIoControl( + dev HANDLE, + controlCode uint32, + inBuffer unsafe.Pointer, + inBufferSize uint32, + outBuffer unsafe.Pointer, + outBufferSize uint32, + overlapped *OVERLAPPED, +) (outBufWrittenBytes uint32, ok bool) { + ret, _, _ := deviceIoControl.Call( + uintptr(dev), + uintptr(controlCode), + uintptr(inBuffer), + uintptr(inBufferSize), + uintptr(outBuffer), + uintptr(outBufferSize), + uintptr(unsafe.Pointer(&outBufWrittenBytes)), + uintptr(unsafe.Pointer(overlapped)), + ) + ok = ret != 0 + return +} + +func FindFirstStream(filename string, data *WIN32_FIND_STREAM_DATA) (HANDLE, bool) { + ret, _, _ := findFirstStream.Call( + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(filename))), + FindStreamInfoStandard, + uintptr(unsafe.Pointer(data)), + 0, + ) + h := HANDLE(ret) + return h, h != INVALID_HANDLE_VALUE +} + +func FindNextStream(finder HANDLE, data *WIN32_FIND_STREAM_DATA) bool { + ret, _, _ := findNextStream.Call( + uintptr(finder), + uintptr(unsafe.Pointer(data)), + ) + return ret != 0 +} + +func FindClose(finder HANDLE) bool { + ret, _, _ := findClose.Call( + uintptr(finder), + ) + return ret != 0 +} + +func OpenMutex(desiredAccess uint32, inheritHandle bool, name string) HANDLE { + ret, _, _ := openMutex.Call( + uintptr(desiredAccess), + uintptr(BoolToBOOL(inheritHandle)), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(name))), + ) + return HANDLE(ret) +} + +func CreateMutex(attributes *SECURITY_ATTRIBUTES, initialOwner bool, name string) HANDLE { + ret, _, _ := createMutex.Call( + uintptr(unsafe.Pointer(attributes)), + uintptr(BoolToBOOL(initialOwner)), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(name))), + ) + return HANDLE(ret) +} + +func CoInitializeEx(coInit uint32) HRESULT { + ret, _, _ := coInitializeEx.Call(0, uintptr(coInit)) + return HRESULT(ret) +} + +func CoInitialize() { + coInitialize.Call(0) +} + +func CoUninitialize() { + coUninitialize.Call() +} + +func CreateStreamOnHGlobal(global HGLOBAL, deleteOnRelease bool) (*IStream, HRESULT) { + stream := new(IStream) + ret, _, _ := createStreamOnHGlobal.Call( + uintptr(global), + uintptr(BoolToBOOL(deleteOnRelease)), + uintptr(unsafe.Pointer(&stream)), + ) + + return stream, HRESULT(ret) +} + +func VariantInit(v *VARIANT) { + variantInit.Call(uintptr(unsafe.Pointer(v))) +} + +func SysAllocString(v string) (ss *int16) { + pss, _, _ := sysAllocString.Call( + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(v))), + ) + ss = (*int16)(unsafe.Pointer(pss)) + return +} + +func SysFreeString(v *int16) { + sysFreeString.Call(uintptr(unsafe.Pointer(v))) +} + +func SysStringLen(v *int16) uint { + l, _, _ := sysStringLen.Call(uintptr(unsafe.Pointer(v))) + return uint(l) +} + +func WglCreateContext(hdc HDC) HGLRC { + ret, _, _ := wglCreateContext.Call( + uintptr(hdc), + ) + return HGLRC(ret) +} + +func WglCreateLayerContext(hdc HDC, iLayerPlane int) HGLRC { + ret, _, _ := wglCreateLayerContext.Call( + uintptr(hdc), + uintptr(iLayerPlane), + ) + return HGLRC(ret) +} + +func WglDeleteContext(hglrc HGLRC) bool { + ret, _, _ := wglDeleteContext.Call( + uintptr(hglrc), + ) + return ret == TRUE +} + +func WglGetProcAddress(szProc string) uintptr { + ret, _, _ := wglGetProcAddress.Call( + uintptr(unsafe.Pointer(syscall.StringBytePtr(szProc))), + ) + return ret +} + +func WglMakeCurrent(hdc HDC, hglrc HGLRC) bool { + ret, _, _ := wglMakeCurrent.Call( + uintptr(hdc), + uintptr(hglrc), + ) + return ret == TRUE +} + +func WglShareLists(hglrc1, hglrc2 HGLRC) bool { + ret, _, _ := wglShareLists.Call( + uintptr(hglrc1), + uintptr(hglrc2), + ) + return ret == TRUE +} + +// EnumAllProcesses retrieves the process identifier for each process object in +// the system. It returns ok = true on success. If ok = false call GetLastError +// to see why it failed. +func EnumAllProcesses() (processIDs []uint32, ok bool) { + n := 128 + for { + processIDs, ok = EnumProcesses(make([]uint32, n)) + if !ok || len(processIDs) < n { + return + } + n *= 2 + } +} + +// EnumProcesses retrieves the process identifier for each process object in the +// system. It takes a pre-sized slice to fill and returns the filled sub-slice +// and an OK status to report success. If ok is false, call GetLastError to see +// what the problem was. +// If the given slice is filled completely, there might be more unenumerated +// process IDs. In that case increase the buffer size and call EnumProcesses +// again. You can also call EnumAllProcesses which does this automatically. +func EnumProcesses(into []uint32) (processIDs []uint32, ok bool) { + if len(into) == 0 { + return nil, true + } + var writtenBytes uint32 + ret, _, _ := enumProcesses.Call( + uintptr(unsafe.Pointer(&into[0])), + uintptr(len(into)*4), + uintptr(unsafe.Pointer(&writtenBytes)), + ) + writtenIDs := writtenBytes / 4 + return into[:writtenIDs], ret != 0 +} + +func SHBrowseForFolder(bi *BROWSEINFO) uintptr { + ret, _, _ := sHBrowseForFolder.Call(uintptr(unsafe.Pointer(bi))) + return ret +} + +func SHGetPathFromIDList(idl uintptr) string { + buf := make([]uint16, 1024) + sHGetPathFromIDList.Call( + idl, + uintptr(unsafe.Pointer(&buf[0])), + ) + return syscall.UTF16ToString(buf) +} + +func SHGetSpecialFolderPath(window HWND, id int, create bool) (string, bool) { + var buf [MAX_PATH]uint16 + ret, _, _ := shGetSpecialFolderPath.Call( + uintptr(window), + uintptr(unsafe.Pointer(&buf[0])), + uintptr(id), + uintptr(BoolToBOOL(create)), + ) + return syscall.UTF16ToString(buf[:]), ret != 0 +} + +func DragAcceptFiles(hwnd HWND, accept bool) { + dragAcceptFiles.Call( + uintptr(hwnd), + uintptr(BoolToBOOL(accept)), + ) +} + +func DragQueryFile(drop HDROP, file uint) string { + ret, _, _ := dragQueryFile.Call( + uintptr(drop), + uintptr(file), + 0, + 0, + ) + + stringSize := uint(ret) + var fileName string + + if file != 0xFFFFFFFF { + buf := make([]uint16, stringSize+1) + + ret, _, _ := dragQueryFile.Call( + uintptr(drop), + uintptr(file), + uintptr(unsafe.Pointer(&buf[0])), + uintptr(len(buf)), + ) + if ret != 0 { + fileName = syscall.UTF16ToString(buf) + } + } + + return fileName +} + +func DragQueryPoint(hDrop HDROP) (x, y int, isClientArea bool) { + var pt POINT + ret, _, _ := dragQueryPoint.Call( + uintptr(hDrop), + uintptr(unsafe.Pointer(&pt)), + ) + return int(pt.X), int(pt.Y), (ret == 1) +} + +func DragFinish(hDrop HDROP) { + dragFinish.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, _, _ := shellExecute.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, _, _ := extractIcon.Call( + 0, + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpszExeFileName))), + uintptr(nIconIndex), + ) + return HICON(ret) +} + +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" +} + +func GdipCreateBitmapFromFile(filename string) (*uintptr, error) { + var bitmap *uintptr + ret, _, _ := gdipCreateBitmapFromFile.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, _, _ := gdipCreateBitmapFromResource.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, _, _ := gdipCreateBitmapFromStream.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, _, _ := gdipCreateHBITMAPFromBitmap.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) { + gdipDisposeImage.Call(uintptr(unsafe.Pointer(image))) +} + +func GdiplusShutdown(token uintptr) { + gdiplusShutdown.Call(token) +} + +func GdiplusStartup(input *GdiplusStartupInput, output *GdiplusStartupOutput) (token uintptr, status uint32) { + ret, _, _ := gdiplusStartup.Call( + uintptr(unsafe.Pointer(&token)), + uintptr(unsafe.Pointer(input)), + uintptr(unsafe.Pointer(output)), + ) + status = uint32(ret) + return +} + +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 BoolToBOOL(value bool) BOOL { + if value { + return 1 + } + return 0 +} + +func GetFileVersionInfoSize(path string) uint32 { + ret, _, _ := getFileVersionInfoSize.Call( + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(path))), + 0, + ) + return uint32(ret) +} + +func GetFileVersionInfo(path string, data []byte) bool { + ret, _, _ := getFileVersionInfo.Call( + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(path))), + 0, + uintptr(len(data)), + uintptr(unsafe.Pointer(&data[0])), + ) + return ret != 0 +} + +// VerQueryValueRoot calls VerQueryValue +// (https://msdn.microsoft.com/en-us/library/windows/desktop/ms647464(v=vs.85).aspx) +// with `\` (root) to retieve the VS_FIXEDFILEINFO. +func VerQueryValueRoot(block []byte) (VS_FIXEDFILEINFO, bool) { + var offset uintptr + var length uint + blockStart := uintptr(unsafe.Pointer(&block[0])) + ret, _, _ := verQueryValue.Call( + blockStart, + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(`\`))), + uintptr(unsafe.Pointer(&offset)), + uintptr(unsafe.Pointer(&length)), + ) + if ret == 0 { + return VS_FIXEDFILEINFO{}, false + } + start := int(offset) - int(blockStart) + end := start + int(length) + if start < 0 || start >= len(block) || end < start || end > len(block) { + return VS_FIXEDFILEINFO{}, false + } + data := block[start:end] + info := *((*VS_FIXEDFILEINFO)(unsafe.Pointer(&data[0]))) + return info, true +} + +// VerQueryValueTranslations calls VerQueryValue +// (https://msdn.microsoft.com/en-us/library/windows/desktop/ms647464(v=vs.85).aspx) +// with `\VarFileInfo\Translation` to retrieve a list of 4-character translation +// strings as required by VerQueryValueString. +func VerQueryValueTranslations(block []byte) ([]string, bool) { + var offset uintptr + var length uint + blockStart := uintptr(unsafe.Pointer(&block[0])) + ret, _, _ := verQueryValue.Call( + blockStart, + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(`\VarFileInfo\Translation`))), + uintptr(unsafe.Pointer(&offset)), + uintptr(unsafe.Pointer(&length)), + ) + if ret == 0 { + return nil, false + } + start := int(offset) - int(blockStart) + end := start + int(length) + if start < 0 || start >= len(block) || end < start || end > len(block) { + return nil, false + } + data := block[start:end] + // each translation consists of a 16-bit language ID and a 16-bit code page + // ID, so each entry has 4 bytes + if len(data)%4 != 0 { + return nil, false + } + trans := make([]string, len(data)/4) + for i := range trans { + t := data[i*4 : (i+1)*4] + // handle endianness of the 16-bit values + t[0], t[1] = t[1], t[0] + t[2], t[3] = t[3], t[2] + trans[i] = fmt.Sprintf("%x", t) + } + return trans, true +} + +// these constants can be passed to VerQueryValueString as the item +const ( + CompanyName = "CompanyName" + FileDescription = "FileDescription" + FileVersion = "FileVersion" + LegalCopyright = "LegalCopyright" + LegalTrademarks = "LegalTrademarks" + OriginalFilename = "OriginalFilename" + ProductVersion = "ProductVersion" + PrivateBuild = "PrivateBuild" + SpecialBuild = "SpecialBuild" +) + +// VerQueryValueString calls VerQueryValue +// (https://msdn.microsoft.com/en-us/library/windows/desktop/ms647464(v=vs.85).aspx) +// with `\StringFileInfo\...` to retrieve a specific piece of information as +// string in a specific translation. +func VerQueryValueString(block []byte, translation, item string) (string, bool) { + var offset uintptr + var utf16Length uint + blockStart := uintptr(unsafe.Pointer(&block[0])) + id := `\StringFileInfo\` + translation + `\` + item + ret, _, _ := verQueryValue.Call( + blockStart, + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(id))), + uintptr(unsafe.Pointer(&offset)), + uintptr(unsafe.Pointer(&utf16Length)), + ) + if ret == 0 { + return "", false + } + start := int(offset) - int(blockStart) + end := start + int(2*utf16Length) + if start < 0 || start >= len(block) || end < start || end > len(block) { + return "", false + } + data := block[start:end] + u16 := make([]uint16, utf16Length) + for i := range u16 { + u16[i] = uint16(data[i*2+1])<<8 | uint16(data[i*2+0]) + } + return syscall.UTF16ToString(u16), true +} + +func PlaySound(sound string, mod HMODULE, flags uint32) bool { + return PlaySoundPointer(syscall.StringToUTF16Ptr(sound), mod, flags) +} + +func PlaySoundPointer(sound *uint16, mod HMODULE, flags uint32) bool { + ret, _, _ := playSound.Call( + uintptr(unsafe.Pointer(sound)), + uintptr(mod), + uintptr(flags), + ) + return ret != 0 +} + +func GetMonitorBrightness(monitor HANDLE) (ok bool, min, cur, max DWORD) { + ret, _, _ := getMonitorBrightness.Call( + uintptr(monitor), + uintptr(unsafe.Pointer(&min)), + uintptr(unsafe.Pointer(&cur)), + uintptr(unsafe.Pointer(&max)), + ) + ok = ret != 0 + return +} + +func SetMonitorBrightness(monitor HANDLE, value DWORD) bool { + ret, _, _ := setMonitorBrightness.Call( + uintptr(monitor), + uintptr(value), + ) + return ret != 0 +} + +func GetNumberOfPhysicalMonitorsFromHMONITOR(monitor HMONITOR) (bool, DWORD) { + var n DWORD + ret, _, _ := getNumberOfPhysicalMonitorsFromHMONITOR.Call( + uintptr(monitor), + uintptr(unsafe.Pointer(&n)), + ) + return ret != 0, n +} + +// len(buf) must not be 0. +func GetPhysicalMonitorsFromHMONITOR(monitor HMONITOR, buf []PHYSICAL_MONITOR) bool { + ret, _, _ := getPhysicalMonitorsFromHMONITOR.Call( + uintptr(monitor), + uintptr(len(buf)), + uintptr(unsafe.Pointer(&buf[0])), + ) + return ret != 0 +} + +func MAKEWPARAM(low, high uint16) uintptr { + return uintptr(low) | uintptr(high)<<16 +} + +func MAKELPARAM(low, high uint16) uintptr { + return MAKEWPARAM(low, high) +} + +func AlphaBlend( + dest HDC, destX, destY, destW, destH int, + src HDC, srcX, srcY, srcW, srcH int, + f BLENDFUNC, +) bool { + ret, _, _ := alphaBlend.Call( + uintptr(dest), + uintptr(destX), + uintptr(destY), + uintptr(destW), + uintptr(destH), + uintptr(src), + uintptr(srcX), + uintptr(srcY), + uintptr(srcW), + uintptr(srcH), + uintptr(*((*uintptr)(unsafe.Pointer(&f)))), + ) + return ret != 0 +} + +func WNetAddConnection2(rsc *NETRESOURCE, pass, user string, flags uint32) uint32 { + var resource *netresource + if rsc != nil { + resource = rsc.toInternal() + } + ret, _, _ := wNetAddConnection2.Call( + uintptr(unsafe.Pointer(resource)), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(pass))), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(user))), + uintptr(flags), + ) + return uint32(ret) +} + +func WNetAddConnection3(owner HWND, rsc *NETRESOURCE, pass, user string, flags uint32) uint32 { + var resource *netresource + if rsc != nil { + resource = rsc.toInternal() + } + ret, _, _ := wNetAddConnection3.Call( + uintptr(owner), + uintptr(unsafe.Pointer(resource)), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(pass))), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(user))), + uintptr(flags), + ) + return uint32(ret) +} + +func WNetCancelConnection2(name string, flags uint32, force bool) uint32 { + ret, _, _ := wNetCancelConnection2.Call( + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(name))), + uintptr(flags), + uintptr(BoolToBOOL(force)), + ) + return uint32(ret) +} + +// https://docs.microsoft.com/en-us/windows/win32/devnotes/rtlgetversion +func RtlGetVersion() RTL_OSVERSIONINFOEXW { + var info RTL_OSVERSIONINFOEXW + info.OSVersionInfoSize = 5*4 + 128*2 + 3*2 + 2*1 + rtlGetVersion.Call(uintptr(unsafe.Pointer(&info))) + return info +} + +// https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getnativesysteminfo +func GetNativeSystemInfo() SYSTEM_INFO { + var info SYSTEM_INFO + getNativeSystemInfo.Call(uintptr(unsafe.Pointer(&info))) + return info +} + +// https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdigetclassdevsw +func SetupDiGetClassDevs(classGUID *GUID, flags uint32) HANDLE { + ret, _, _ := setupDiGetClassDevs.Call( + uintptr(unsafe.Pointer(classGUID)), + 0, + 0, + uintptr(flags), + ) + return HANDLE(ret) +} + +func SetupDiDestroyDeviceInfoList(list HANDLE) bool { + ret, _, _ := setupDiDestroyDeviceInfoList.Call(uintptr(list)) + return ret != 0 +} + +func SetupDiEnumDeviceInfo(deviceInfoList HANDLE, index uint32) (SP_DEVINFO_DATA, bool) { + var data SP_DEVINFO_DATA + data.Size = uint32(unsafe.Sizeof(data)) + ret, _, _ := setupDiEnumDeviceInfo.Call( + uintptr(deviceInfoList), + uintptr(index), + uintptr(unsafe.Pointer(&data)), + ) + return data, ret != 0 +} + +func SetupDiOpenDevRegKey( + DeviceInfoList HANDLE, + data *SP_DEVINFO_DATA, + scope, hwProfile, keyType, access uint32, +) HKEY { + ret, _, _ := setupDiOpenDevRegKey.Call( + uintptr(DeviceInfoList), + uintptr(unsafe.Pointer(data)), + uintptr(scope), + uintptr(hwProfile), + uintptr(keyType), + uintptr(access), + ) + return HKEY(ret) +} + +func SetProcessDpiAwareness(value int) HRESULT { + ret, _, _ := setProcessDpiAwareness.Call(uintptr(value)) + return HRESULT(ret) +} diff --git a/v3/internal/w32/functions_386.go b/v3/internal/w32/functions_386.go new file mode 100644 index 000000000..968cafec6 --- /dev/null +++ b/v3/internal/w32/functions_386.go @@ -0,0 +1,29 @@ +package w32 + +// MenuItemFromPoint determines which menu item, if any, is at the specified +// location. +func MenuItemFromPoint(w HWND, m HMENU, screen POINT) int { + ret, _, _ := menuItemFromPoint.Call( + uintptr(w), + uintptr(m), + uintptr(screen.X), + uintptr(screen.Y), + ) + return int(ret) +} + +func GetClassLongPtr(w HWND, index int) uintptr { + return uintptr(GetClassLong(w, index)) +} + +func SetClassLongPtr(w HWND, index int, value uintptr) uintptr { + return uintptr(SetClassLong(w, index, int32(value))) +} + +func GetWindowLongPtr(hwnd HWND, index int) uintptr { + return uintptr(GetWindowLong(hwnd, index)) +} + +func SetWindowLongPtr(hwnd HWND, index int, value uintptr) uintptr { + return uintptr(SetWindowLong(hwnd, index, int32(value))) +} diff --git a/v3/internal/w32/functions_amd64.go b/v3/internal/w32/functions_amd64.go new file mode 100644 index 000000000..0e12a6210 --- /dev/null +++ b/v3/internal/w32/functions_amd64.go @@ -0,0 +1,43 @@ +package w32 + +// MenuItemFromPoint determines which menu item, if any, is at the specified +// location. +func MenuItemFromPoint(w HWND, m HMENU, screen POINT) int { + ret, _, _ := menuItemFromPoint.Call( + uintptr(w), + uintptr(m), + uintptr(uint64(screen.X)<<32|uint64(screen.Y)), + ) + return int(ret) +} + +func GetClassLongPtr(w HWND, index int) uintptr { + ret, _, _ := getClassLongPtr.Call(uintptr(w), uintptr(index)) + return ret +} + +func SetClassLongPtr(w HWND, index int, value uintptr) uintptr { + ret, _, _ := setClassLongPtr.Call( + uintptr(w), + uintptr(index), + value, + ) + return ret +} + +func GetWindowLongPtr(hwnd HWND, index int) uintptr { + ret, _, _ := getWindowLongPtr.Call( + uintptr(hwnd), + uintptr(index), + ) + return ret +} + +func SetWindowLongPtr(hwnd HWND, index int, value uintptr) uintptr { + ret, _, _ := setWindowLongPtr.Call( + uintptr(hwnd), + uintptr(index), + value, + ) + return ret +} diff --git a/v3/internal/w32/functions_arm64.go b/v3/internal/w32/functions_arm64.go new file mode 100644 index 000000000..0e12a6210 --- /dev/null +++ b/v3/internal/w32/functions_arm64.go @@ -0,0 +1,43 @@ +package w32 + +// MenuItemFromPoint determines which menu item, if any, is at the specified +// location. +func MenuItemFromPoint(w HWND, m HMENU, screen POINT) int { + ret, _, _ := menuItemFromPoint.Call( + uintptr(w), + uintptr(m), + uintptr(uint64(screen.X)<<32|uint64(screen.Y)), + ) + return int(ret) +} + +func GetClassLongPtr(w HWND, index int) uintptr { + ret, _, _ := getClassLongPtr.Call(uintptr(w), uintptr(index)) + return ret +} + +func SetClassLongPtr(w HWND, index int, value uintptr) uintptr { + ret, _, _ := setClassLongPtr.Call( + uintptr(w), + uintptr(index), + value, + ) + return ret +} + +func GetWindowLongPtr(hwnd HWND, index int) uintptr { + ret, _, _ := getWindowLongPtr.Call( + uintptr(hwnd), + uintptr(index), + ) + return ret +} + +func SetWindowLongPtr(hwnd HWND, index int, value uintptr) uintptr { + ret, _, _ := setWindowLongPtr.Call( + uintptr(hwnd), + uintptr(index), + value, + ) + return ret +} diff --git a/v3/internal/w32/types.go b/v3/internal/w32/types.go new file mode 100644 index 000000000..7f27bc9b4 --- /dev/null +++ b/v3/internal/w32/types.go @@ -0,0 +1,1297 @@ +// Copyright 2010-2012 The W32 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package w32 + +import ( + "syscall" + "time" + "unicode/utf16" + "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 +type ( + ATOM uint16 + BOOL int32 + COLORREF uint32 + DWM_FRAME_COUNT uint64 + 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 + WPARAM uintptr + HRAWINPUT HANDLE +) + +// 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) Width() int32 { + return r.Right - r.Left +} + +func (r *RECT) Height() int32 { + return r.Bottom - r.Top +} + +// 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 +} + +// 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 +} + +// 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 +} + +func toString(s []uint16) string { + for i, c := range s { + if c == 0 { + return string(utf16.Decode(s[:i])) + } + } + return string(utf16.Decode(s)) +} + +func (f *LOGFONT) GetFaceName() string { + return toString(f.FaceName[:]) +} + +func (f *LOGFONT) SetFaceName(name string) { + s := utf16.Encode([]rune(name)) + max := len(f.FaceName) - 1 + if len(s) > max { + s = s[:max] + } + copy(f.FaceName[:], s) + f.FaceName[len(s)] = 0 +} + +type ENUMLOGFONTEX struct { + LOGFONT + FullName [LF_FULLFACESIZE]uint16 + Style [LF_FACESIZE]uint16 + Script [LF_FACESIZE]uint16 +} + +func (f *ENUMLOGFONTEX) GetFullName() string { + return toString(f.FullName[:]) +} + +func (f *ENUMLOGFONTEX) GetStyle() string { + return toString(f.Style[:]) +} + +func (f *ENUMLOGFONTEX) GetScript() string { + return toString(f.Script[:]) +} + +type ENUMTEXTMETRIC struct { + NEWTEXTMETRICEX + AXESLIST +} + +type NEWTEXTMETRICEX struct { + NEWTEXTMETRIC + FONTSIGNATURE +} + +type NEWTEXTMETRIC struct { + Height int32 + Ascent int32 + Descent int32 + InternalLeading int32 + ExternalLeading int32 + AveCharWidth int32 + MaxCharWidth int32 + Weight int32 + Overhang int32 + DigitizedAspectX int32 + DigitizedAspectY int32 + FirstChar uint16 + LastChar uint16 + DefaultChar uint16 + BreakChar uint16 + Italic byte + Underlined byte + StruckOut byte + PitchAndFamily byte + CharSet byte + Flags uint32 + SizeEM uint32 + CellHeight uint32 + AvgWidth uint32 +} + +type FONTSIGNATURE struct { + Usb [4]uint32 + Csb [2]uint32 +} + +type AXESLIST struct { + Reserved uint32 + NumAxes uint32 + AxisInfo [MM_MAX_NUMAXES]AXISINFO +} + +type AXISINFO struct { + MinValue int32 + MaxValue int32 + AxisName [MM_MAX_AXES_NAMELEN]uint16 +} + +func (i *AXISINFO) GetAxisName() string { + return toString(i.AxisName[:]) +} + +// 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 +} + +// https://msdn.microsoft.com/en-us/library/windows/desktop/dd183374(v=vs.85).aspx +type BITMAPFILEHEADER struct { + BfType uint16 + BfSize uint32 + BfReserved1 uint16 + BfReserved2 uint16 + BfOffBits uint32 +} + +// 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 +} + +type NMUPDOWN struct { + Hdr NMHDR + Pos int32 + Delta int32 +} + +// 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 + CxMin int32 + CxDefault int32 + CxIdeal 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 + PiColFmt *int32 + IGroup int32 +} + +// 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 +} + +// 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 { + size uint32 + ICC 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 +} + +// 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 +} + +func (t FILETIME) Uint64() uint64 { + return uint64(t.DwHighDateTime)<<32 | uint64(t.DwLowDateTime) +} + +func (t FILETIME) Time() time.Time { + // https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime + ref := time.Date(1601, time.January, 1, 0, 0, 0, 0, time.UTC) + const tick = 100 * time.Nanosecond + // The FILETIME is a uint64 of 100-nanosecond intervals since 1601. + // Unfortunately time.Duration is really an int64 so if we cast our uint64 + // to a time.Duration it becomes negative. Thus we do it in 2 steps, adding + // half the time each step to avoid overflow. + return ref. + Add(time.Duration(t.Uint64()) * (tick / 2)). + Add(time.Duration(t.Uint64()) * (tick / 2)) +} + +// 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 +} + +// 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/ms724950(v=vs.85).aspx +type SYSTEMTIME struct { + Year uint16 + Month uint16 + DayOfWeek uint16 + Day uint16 + Hour uint16 + Minute uint16 + Second uint16 + Milliseconds uint16 +} + +func (t SYSTEMTIME) Time() time.Time { + return time.Date( + int(t.Year), + time.Month(t.Month), + int(t.Day), + int(t.Hour), + int(t.Minute), + int(t.Second), + int(t.Milliseconds)*int(time.Millisecond/time.Nanosecond), + time.UTC, + ) +} + +// 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 MINMAXINFO struct { + PtReserved POINT + PtMaxSize POINT + PtMaxPosition POINT + PtMinTrackSize POINT + PtMaxTrackSize POINT +} + +type RAWINPUTHEADER struct { + Type uint32 + Size uint32 + Device HANDLE + WParam WPARAM +} + +type RAWINPUT struct { + Header RAWINPUTHEADER + // NOTE that there is no support for C unions in Go, this would actually be + // a union of RAWMOUSE, RAWKEYBOARD and RAWHID. Since RAWMOUSE is the + // largest of those three, use it here and cast unsafely to get the other + // types. + mouse RAWMOUSE +} + +// GetMouse returns the raw input as a RAWMOUSE. Make sure to check the Header's +// Type flag so this is valid. +func (i *RAWINPUT) GetMouse() RAWMOUSE { + return i.mouse +} + +// GetKeyboard returns the raw input as a RAWKEYBOARD. Make sure to check the +// Header's Type flag so this is valid. +func (i *RAWINPUT) GetKeyboard() RAWKEYBOARD { + return *((*RAWKEYBOARD)(unsafe.Pointer(&i.mouse))) +} + +// GetHid returns the raw input as a RAWHID. Make sure to check the Header's +// Type flag so this is valid. +func (i *RAWINPUT) GetHid() RAWHID { + return *((*RAWHID)(unsafe.Pointer(&i.mouse))) +} + +type RAWKEYBOARD struct { + MakeCode uint16 + Flags uint16 + Reserved uint16 + VKey uint16 + Message uint32 + ExtraInformation uint32 +} + +type RAWHID struct { + SizeHid uint32 + Count uint32 + RawData [1]byte +} + +type RAWMOUSE struct { + Flags uint16 + Buttons uint32 + RawButtons uint32 + LastX int32 + LastY int32 + ExtraInformation uint32 +} + +func (m *RAWMOUSE) ButtonFlags() uint16 { + return uint16(m.Buttons & 0xFFFF) +} + +func (m *RAWMOUSE) ButtonData() uint16 { + return uint16((m.Buttons & 0xFFFF0000) >> 16) +} + +type RAWINPUTDEVICE struct { + UsagePage uint16 + Usage uint16 + Flags uint32 + Target HWND +} + +// INPUT is used in SendInput. To create a concrete INPUT type, use the helper +// functions MouseInput, KeyboardInput and HardwareInput. These are necessary +// because the C API uses a union here, which Go does not provide. +type INPUT struct { + Type uint32 + // use MOUSEINPUT for the union because it is the largest of all allowed + // structures + mouse MOUSEINPUT +} + +type MOUSEINPUT struct { + Dx int32 + Dy int32 + MouseData uint32 + Flags uint32 + Time uint32 + ExtraInfo uintptr +} + +type KEYBDINPUT struct { + Vk uint16 + Scan uint16 + Flags uint32 + Time uint32 + ExtraInfo uintptr +} + +type HARDWAREINPUT struct { + Msg uint32 + ParamL uint16 + ParamH uint16 +} + +func MouseInput(input MOUSEINPUT) INPUT { + return INPUT{ + Type: INPUT_MOUSE, + mouse: input, + } +} + +func KeyboardInput(input KEYBDINPUT) INPUT { + return INPUT{ + Type: INPUT_KEYBOARD, + mouse: *((*MOUSEINPUT)(unsafe.Pointer(&input))), + } +} + +func HardwareInput(input HARDWAREINPUT) INPUT { + return INPUT{ + Type: INPUT_HARDWARE, + mouse: *((*MOUSEINPUT)(unsafe.Pointer(&input))), + } +} + +type VS_FIXEDFILEINFO struct { + Signature uint32 + StrucVersion uint32 + FileVersionMS uint32 + FileVersionLS uint32 + ProductVersionMS uint32 + ProductVersionLS uint32 + FileFlagsMask uint32 + FileFlags uint32 + FileOS uint32 + FileType uint32 + FileSubtype uint32 + FileDateMS uint32 + FileDateLS uint32 +} + +// FileVersion concatenates FileVersionMS and FileVersionLS to a uint64 value. +func (fi VS_FIXEDFILEINFO) FileVersion() uint64 { + return uint64(fi.FileVersionMS)<<32 | uint64(fi.FileVersionLS) +} + +// FileDate concatenates FileDateMS and FileDateLS to a uint64 value. +func (fi VS_FIXEDFILEINFO) FileDate() uint64 { + return uint64(fi.FileDateMS)<<32 | uint64(fi.FileDateLS) +} + +type ACCEL struct { + // Virt is a bit mask which may contain: + // FALT, FCONTROL, FSHIFT: keys to be held for the accelerator + // FVIRTKEY: means that Key is a virtual key code, if not set, Key is + // interpreted as a character code + Virt byte + // Key can either be a virtual key code VK_... or a character + Key uint16 + // Cmd is the value passed to WM_COMMAND or WM_SYSCOMMAND when the + // accelerator triggers + Cmd uint16 +} + +type PHYSICAL_MONITOR struct { + Monitor HANDLE + Description [128]uint16 +} + +type MENUITEMINFO struct { + Size uint32 + Mask uint32 + Type uint32 + State uint32 + ID uint32 + SubMenu HMENU + BmpChecked HBITMAP + BmpUnChecked HBITMAP + ItemData uintptr + TypeData uintptr // UTF-16 string + CCH uint32 + BmpItem HBITMAP +} + +type TPMPARAMS struct { + Size uint32 + Exclude RECT +} + +type MENUINFO struct { + size uint32 + Mask uint32 + Style uint32 + YMax uint32 + Back HBRUSH + ContextHelpID uint32 + MenuData uintptr +} + +type MENUBARINFO struct { + size uint32 + Bar RECT + Menu HMENU + Window HWND + BarFocused int32 // bool + Focused int32 // bool +} + +type ACTCTX struct { + size uint32 + Flags uint32 + Source *uint16 // UTF-16 string + ProcessorArchitecture uint16 + LangID uint16 + AssemblyDirectory *uint16 // UTF-16 string + ResourceName *uint16 // UTF-16 string + ApplicationName *uint16 // UTF-16 string + Module HMODULE +} + +type DRAWITEMSTRUCT struct { + CtlType uint32 + CtlID uint32 + ItemID uint32 + ItemAction uint32 + ItemState uint32 + HwndItem HWND + HDC HDC + RcItem RECT + ItemData uintptr +} + +type BLENDFUNC struct { + BlendOp byte + BlendFlags byte + SourceConstantAlpha byte + AlphaFormat byte +} + +type NETRESOURCE struct { + Scope uint32 + Type uint32 + DisplayType uint32 + Usage uint32 + LocalName string + RemoteName string + Comment string + Provider string +} + +func (n *NETRESOURCE) toInternal() *netresource { + internal := &netresource{ + Scope: n.Scope, + Type: n.Type, + DisplayType: n.DisplayType, + Usage: n.Usage, + } + if n.LocalName != "" { + internal.LocalName = syscall.StringToUTF16Ptr(n.LocalName) + } + if n.RemoteName != "" { + internal.RemoteName = syscall.StringToUTF16Ptr(n.RemoteName) + } + if n.Comment != "" { + internal.Comment = syscall.StringToUTF16Ptr(n.Comment) + } + if n.Provider != "" { + internal.Provider = syscall.StringToUTF16Ptr(n.Provider) + } + return internal +} + +type netresource struct { + Scope uint32 + Type uint32 + DisplayType uint32 + Usage uint32 + LocalName *uint16 + RemoteName *uint16 + Comment *uint16 + Provider *uint16 +} + +type NMLVODSTATECHANGE struct { + Hdr NMHDR + From int32 + To int32 + NewState uint32 + OldState uint32 +} + +type SECURITY_ATTRIBUTES struct { + Length uint32 + SecurityDescriptor unsafe.Pointer + InheritHandle uint32 // bool value +} + +type OVERLAPPED struct { + Internal uintptr + InternalHigh uintptr + Pointer uintptr + Event HANDLE +} + +type STORAGE_DEVICE_DESCRIPTOR struct { + Version uint32 + Size uint32 + DeviceType byte + DeviceTypeModifier byte + RemovableMedia byte // bool value + CommandQueueing byte // bool value + VendorIdOffset uint32 + ProductIdOffset uint32 + ProductRevisionOffset uint32 + SerialNumberOffset uint32 + BusType uint32 // STORAGE_BUS_TYPE + RawPropertiesLength uint32 + RawDeviceProperties [1]byte +} + +type STORAGE_PROPERTY_QUERY struct { + PropertyId uint32 + QueryType uint32 + AdditionalParameters [1]byte +} + +// https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/ns-fileapi-_win32_find_stream_data +type WIN32_FIND_STREAM_DATA struct { + Size int64 + Name [MAX_PATH + 36]uint16 +} + +type MSGBOXPARAMS struct { + Size uint32 + Owner HWND + Instance HINSTANCE + Text *uint16 + Caption *uint16 + Style uint32 + Icon *uint16 + ContextHelpId *uint32 + MsgBoxCallback uintptr + LanguageId uint32 +} + +type POWERBROADCAST_SETTING struct { + PowerSetting GUID + DataLength uint32 + Data [1]byte +} + +// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ns-wdm-_osversioninfoexw +type RTL_OSVERSIONINFOEXW struct { + OSVersionInfoSize uint32 + MajorVersion uint32 + MinorVersion uint32 + BuildNumber uint32 + PlatformId uint32 + CSDVersion [128]uint16 + ServicePackMajor uint16 + ServicePackMinor uint16 + SuiteMask uint16 + ProductType byte + Reserved byte +} + +// https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/ns-sysinfoapi-system_info +type SYSTEM_INFO struct { + ProcessorArchitecture uint16 + Reserved uint16 + PageSize uint32 + MinimumApplicationAddress LPCVOID + MaximumApplicationAddress LPCVOID + ActiveProcessorMask *uint32 + NumberOfProcessors uint32 + ProcessorType uint32 + AllocationGranularity uint32 + ProcessorLevel uint16 + ProcessorRevision uint16 +} + +type SP_DEVINFO_DATA struct { + Size uint32 + ClassGuid GUID + DevInst uint32 + Reserved uintptr +} + +type WINDOWPOS struct { + Hwnd HWND + HwndInsertAfter HWND + X int32 + Y int32 + Cx int32 + Cy int32 + Flags uint32 +} + +type WINDOWINFO struct { + Cbsize uint32 + RcWindow RECT + RcClient RECT + DwStyle uint32 + DwExStyle uint32 + DwWindowStatus uint32 + CxWindowBorders uint32 + CyWindowBorders uint32 + AtomWindowType uint16 + WCreatorVersion uint16 +} diff --git a/v3/pkg/application/application.go b/v3/pkg/application/application.go index 80b4d7e99..c8a62502f 100644 --- a/v3/pkg/application/application.go +++ b/v3/pkg/application/application.go @@ -360,10 +360,10 @@ func (a *App) Run() error { } // set the application menu - a.impl.setApplicationMenu(a.ApplicationMenu) - - // set the application Icon - a.impl.setIcon(a.options.Icon) + if runtime.GOOS == "darwin" { + a.impl.setApplicationMenu(a.ApplicationMenu) + a.impl.setIcon(a.options.Icon) + } err := a.impl.run() if err != nil { diff --git a/v3/pkg/application/application_windows.go b/v3/pkg/application/application_windows.go index de791ce58..156414579 100644 --- a/v3/pkg/application/application_windows.go +++ b/v3/pkg/application/application_windows.go @@ -2,9 +2,19 @@ package application +import ( + "github.com/samber/lo" + "github.com/wailsapp/wails/v3/internal/w32" + "syscall" + "unsafe" +) + +var windowClassName = lo.Must(syscall.UTF16PtrFromString("WailsWebviewWindow")) + type windowsApp struct { - //applicationMenu unsafe.Pointer parent *App + + instance w32.HINSTANCE } func (m *windowsApp) dispatchOnMainThread(id uint) { @@ -23,11 +33,9 @@ func (m *windowsApp) getScreens() ([]*Screen, error) { } func (m *windowsApp) hide() { - //C.hide() } func (m *windowsApp) show() { - //C.show() } func (m *windowsApp) on(eventID uint) { @@ -73,6 +81,9 @@ func (m *windowsApp) run() error { for eventID := range m.parent.applicationEventListeners { m.on(eventID) } + + _ = m.runMainLoop() + //C.run() return nil } @@ -81,9 +92,58 @@ func (m *windowsApp) destroy() { //C.destroyApp() } -func newPlatformApp(app *App) *windowsApp { - //C.init() - return &windowsApp{ - parent: app, +func (m *windowsApp) init() { + // Register the window class + + icon := w32.LoadIconWithResourceID(m.instance, w32.IDI_APPLICATION) + + var wc w32.WNDCLASSEX + wc.Size = uint32(unsafe.Sizeof(wc)) + wc.Style = w32.CS_HREDRAW | w32.CS_VREDRAW + wc.WndProc = syscall.NewCallback(m.wndProc) + wc.Instance = m.instance + wc.Background = w32.COLOR_BTNFACE + 1 + wc.Icon = icon + wc.Cursor = w32.LoadCursorWithResourceID(0, w32.IDC_ARROW) + wc.ClassName = windowClassName + wc.MenuName = nil + wc.IconSm = icon + + if ret := w32.RegisterClassEx(&wc); ret == 0 { + panic(syscall.GetLastError()) } } + +func (m *windowsApp) wndProc(hwnd w32.HWND, msg uint32, wParam, lParam uintptr) uintptr { + switch msg { + case w32.WM_SIZE, w32.WM_PAINT: + return 0 + case w32.WM_CLOSE: + w32.PostQuitMessage(0) + return 0 + } + return w32.DefWindowProc(hwnd, msg, wParam, lParam) +} + +func (m *windowsApp) runMainLoop() int { + msg := (*w32.MSG)(unsafe.Pointer(w32.GlobalAlloc(0, uint32(unsafe.Sizeof(w32.MSG{}))))) + defer w32.GlobalFree(w32.HGLOBAL(unsafe.Pointer(m))) + + for w32.GetMessage(msg, 0, 0, 0) != 0 { + w32.TranslateMessage(msg) + w32.DispatchMessage(msg) + } + + return int(msg.WParam) +} + +func newPlatformApp(app *App) *windowsApp { + result := &windowsApp{ + parent: app, + instance: w32.GetModuleHandle(""), + } + + result.init() + + return result +} diff --git a/v3/pkg/application/menu.go b/v3/pkg/application/menu.go index e20f0e3a6..5a6139031 100644 --- a/v3/pkg/application/menu.go +++ b/v3/pkg/application/menu.go @@ -96,14 +96,3 @@ func (m *Menu) setContextData(data *ContextMenuData) { func (a *App) NewMenu() *Menu { return &Menu{} } - -func defaultApplicationMenu() *Menu { - menu := NewMenu() - menu.AddRole(AppMenu) - menu.AddRole(FileMenu) - menu.AddRole(EditMenu) - menu.AddRole(ViewMenu) - menu.AddRole(WindowMenu) - menu.AddRole(HelpMenu) - return menu -} diff --git a/v3/pkg/application/menu_darwin.go b/v3/pkg/application/menu_darwin.go index b14be232a..dc6493ad2 100644 --- a/v3/pkg/application/menu_darwin.go +++ b/v3/pkg/application/menu_darwin.go @@ -103,3 +103,14 @@ func (m *macosMenu) processMenu(parent unsafe.Pointer, menu *Menu) { } } + +func defaultApplicationMenu() *Menu { + menu := NewMenu() + menu.AddRole(AppMenu) + menu.AddRole(FileMenu) + menu.AddRole(EditMenu) + menu.AddRole(ViewMenu) + menu.AddRole(WindowMenu) + menu.AddRole(HelpMenu) + return menu +} diff --git a/v3/pkg/application/menu_windows.go b/v3/pkg/application/menu_windows.go index b60c0b35b..33cd608c2 100644 --- a/v3/pkg/application/menu_windows.go +++ b/v3/pkg/application/menu_windows.go @@ -50,3 +50,13 @@ func (m *windowsMenu) processMenu(parent unsafe.Pointer, menu *Menu) { // //} } + +func defaultApplicationMenu() *Menu { + menu := NewMenu() + menu.AddRole(FileMenu) + menu.AddRole(EditMenu) + menu.AddRole(ViewMenu) + menu.AddRole(WindowMenu) + menu.AddRole(HelpMenu) + return menu +} diff --git a/v3/pkg/application/options_webview_window.go b/v3/pkg/application/options_webview_window.go index 99e40d054..18f0e600c 100644 --- a/v3/pkg/application/options_webview_window.go +++ b/v3/pkg/application/options_webview_window.go @@ -35,6 +35,7 @@ type WebviewWindowOptions struct { EnableFraudulentWebsiteWarnings bool Zoom float64 EnableDragAndDrop bool + Windows WindowsWindow } var WebviewWindowDefaults = &WebviewWindowOptions{ diff --git a/v3/pkg/application/options_windows.go b/v3/pkg/application/options_windows.go new file mode 100644 index 000000000..0e118ddbd --- /dev/null +++ b/v3/pkg/application/options_windows.go @@ -0,0 +1,5 @@ +package application + +type WindowsWindow struct { + AlwaysOnTop bool +} diff --git a/v3/pkg/application/roles.go b/v3/pkg/application/roles.go index 0aec3bd48..fe48a0d1e 100644 --- a/v3/pkg/application/roles.go +++ b/v3/pkg/application/roles.go @@ -42,8 +42,9 @@ const ( ZoomOut Role = iota ToggleFullscreen Role = iota - Minimize Role = iota - Zoom Role = iota + Minimize Role = iota + Zoom Role = iota + FullScreen Role = iota //Front Role = iota //WindowRole Role = iota @@ -132,6 +133,12 @@ func newWindowMenu() *MenuItem { menu := NewMenu() menu.AddRole(Minimize) menu.AddRole(Zoom) + if runtime.GOOS == "darwin" { + menu.AddSeparator() + menu.AddRole(FullScreen) + } else { + menu.AddRole(Close) + } subMenu := newSubMenuItem("Window") subMenu.submenu = menu return subMenu diff --git a/v3/pkg/application/webview_window_windows.go b/v3/pkg/application/webview_window_windows.go index f651a7739..6e536ca50 100644 --- a/v3/pkg/application/webview_window_windows.go +++ b/v3/pkg/application/webview_window_windows.go @@ -3,6 +3,9 @@ package application import ( + "github.com/samber/lo" + "github.com/wailsapp/wails/v3/internal/w32" + "syscall" "unsafe" ) @@ -64,8 +67,43 @@ func (w *windowsWebviewWindow) setBackgroundColour(color *RGBA) { } func (w *windowsWebviewWindow) run() { - //TODO implement me - panic("implement me") + + var exStyle uint + options := w.parent.options + windowsOptions := options.Windows + //if windowsOptions != nil { + exStyle = w32.WS_EX_CONTROLPARENT | w32.WS_EX_APPWINDOW + // if windowsOptions.WindowIsTranslucent { + // exStyle |= w32.WS_EX_NOREDIRECTIONBITMAP + // } + //} + if windowsOptions.AlwaysOnTop { + exStyle |= w32.WS_EX_TOPMOST + } + var hwnd w32.HWND + hwnd = w32.CreateWindowEx( + exStyle, + windowClassName, + lo.Must(syscall.UTF16PtrFromString("My Window Title")), + w32.WS_OVERLAPPEDWINDOW|w32.WS_VISIBLE, + w32.CW_USEDEFAULT, + w32.CW_USEDEFAULT, + options.Width, + options.Height, + 0, + 0, + w32.GetModuleHandle(""), + nil) + + if hwnd == 0 { + panic("Unable to create window") + } + + if !options.Hidden { + w32.ShowWindow(hwnd, w32.SW_SHOW) + w32.UpdateWindow(hwnd) + } + w32.SetForegroundWindow(hwnd) } func (w *windowsWebviewWindow) center() { @@ -242,6 +280,7 @@ func newWindowImpl(parent *WebviewWindow) *windowsWebviewWindow { result := &windowsWebviewWindow{ parent: parent, } + return result } From ef184ec8bf4eab7574e965054736028e9337d6b3 Mon Sep 17 00:00:00 2001 From: stffabi Date: Wed, 26 Apr 2023 16:28:27 +0200 Subject: [PATCH 06/28] [v3, windows] Add MainThread dispatching and fixes the blocking window --- v3/examples/plain/main.go | 16 +++ v3/internal/w32/functions.go | 15 +++ v3/pkg/application/application_windows.go | 31 ++--- v3/pkg/application/mainthread_windows.go | 129 +++++++++++++++++++ v3/pkg/application/webview_window_windows.go | 10 +- 5 files changed, 179 insertions(+), 22 deletions(-) create mode 100644 v3/pkg/application/mainthread_windows.go diff --git a/v3/examples/plain/main.go b/v3/examples/plain/main.go index bc8406e82..63ba8d88b 100644 --- a/v3/examples/plain/main.go +++ b/v3/examples/plain/main.go @@ -4,6 +4,7 @@ import ( _ "embed" "log" "net/http" + "time" "github.com/wailsapp/wails/v3/pkg/application" ) @@ -38,6 +39,21 @@ func main() { println("clicked") }) + go func() { + time.Sleep(5 * time.Second) + + app.NewWebviewWindowWithOptions(&application.WebviewWindowOptions{ + Title: "Plain Bundle new Window from GoRoutine", + Width: 500, + Height: 500, + Mac: application.MacWindow{ + Backdrop: application.MacBackdropTranslucent, + TitleBar: application.MacTitleBarHiddenInsetUnified, + InvisibleTitleBarHeight: 50, + }, + }) + }() + err := app.Run() if err != nil { diff --git a/v3/internal/w32/functions.go b/v3/internal/w32/functions.go index d521a3397..d8ca0c43a 100644 --- a/v3/internal/w32/functions.go +++ b/v3/internal/w32/functions.go @@ -225,6 +225,7 @@ var ( destroyCursor = user32.NewProc("DestroyCursor") getDlgCtrlID = user32.NewProc("GetDlgCtrlID") systemParametersInfo = user32.NewProc("SystemParametersInfoW") + registerWindowMessage = user32.NewProc("RegisterWindowMessageW") regCreateKeyEx = advapi32.NewProc("RegCreateKeyExW") regOpenKeyEx = advapi32.NewProc("RegOpenKeyExW") @@ -364,6 +365,7 @@ var ( mulDiv = kernel32.NewProc("MulDiv") getConsoleWindow = kernel32.NewProc("GetConsoleWindow") getCurrentThread = kernel32.NewProc("GetCurrentThread") + getCurrentThreadId = kernel32.NewProc("GetCurrentThreadId") getLogicalDrives = kernel32.NewProc("GetLogicalDrives") getDriveType = kernel32.NewProc("GetDriveTypeW") getUserDefaultLCID = kernel32.NewProc("GetUserDefaultLCID") @@ -482,6 +484,14 @@ var ( setProcessDpiAwareness = shcore.NewProc("SetProcessDpiAwareness") ) +func RegisterWindowMessage(name string) uint32 { + ret, _, _ := registerWindowMessage.Call( + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(name))), + ) + + return uint32(ret) +} + // RegisterClassEx sets the Size of the WNDCLASSEX automatically. func RegisterClassEx(wndClassEx *WNDCLASSEX) ATOM { if wndClassEx != nil { @@ -3674,6 +3684,11 @@ func GetCurrentThread() HANDLE { return HANDLE(ret) } +func GetCurrentThreadId() HANDLE { + ret, _, _ := getCurrentThreadId.Call() + return HANDLE(ret) +} + func GetLogicalDrives() uint32 { ret, _, _ := getLogicalDrives.Call() return uint32(ret) diff --git a/v3/pkg/application/application_windows.go b/v3/pkg/application/application_windows.go index 156414579..851a4e8f0 100644 --- a/v3/pkg/application/application_windows.go +++ b/v3/pkg/application/application_windows.go @@ -3,10 +3,11 @@ package application import ( - "github.com/samber/lo" - "github.com/wailsapp/wails/v3/internal/w32" "syscall" "unsafe" + + "github.com/samber/lo" + "github.com/wailsapp/wails/v3/internal/w32" ) var windowClassName = lo.Must(syscall.UTF16PtrFromString("WailsWebviewWindow")) @@ -15,11 +16,9 @@ type windowsApp struct { parent *App instance w32.HINSTANCE -} -func (m *windowsApp) dispatchOnMainThread(id uint) { - //TODO implement me - panic("implement me") + mainThreadID w32.HANDLE + mainThreadWindowHWND w32.HWND } func (m *windowsApp) getPrimaryScreen() (*Screen, error) { @@ -116,27 +115,20 @@ func (m *windowsApp) init() { func (m *windowsApp) wndProc(hwnd w32.HWND, msg uint32, wParam, lParam uintptr) uintptr { switch msg { - case w32.WM_SIZE, w32.WM_PAINT: + case w32.WM_SIZE: return 0 case w32.WM_CLOSE: w32.PostQuitMessage(0) return 0 + case wmInvokeCallback: + if hwnd == m.mainThreadWindowHWND { + m.invokeCallback(wParam, lParam) + return 0 + } } return w32.DefWindowProc(hwnd, msg, wParam, lParam) } -func (m *windowsApp) runMainLoop() int { - msg := (*w32.MSG)(unsafe.Pointer(w32.GlobalAlloc(0, uint32(unsafe.Sizeof(w32.MSG{}))))) - defer w32.GlobalFree(w32.HGLOBAL(unsafe.Pointer(m))) - - for w32.GetMessage(msg, 0, 0, 0) != 0 { - w32.TranslateMessage(msg) - w32.DispatchMessage(msg) - } - - return int(msg.WParam) -} - func newPlatformApp(app *App) *windowsApp { result := &windowsApp{ parent: app, @@ -144,6 +136,7 @@ func newPlatformApp(app *App) *windowsApp { } result.init() + result.initMainLoop() return result } diff --git a/v3/pkg/application/mainthread_windows.go b/v3/pkg/application/mainthread_windows.go new file mode 100644 index 000000000..313848254 --- /dev/null +++ b/v3/pkg/application/mainthread_windows.go @@ -0,0 +1,129 @@ +//go:build windows + +package application + +import ( + "runtime" + "sort" + "syscall" + "unsafe" + + "github.com/samber/lo" + "github.com/wailsapp/wails/v3/internal/w32" +) + +var ( + wmInvokeCallback uint32 +) + +func init() { + wmInvokeCallback = w32.RegisterWindowMessage("WailsV0.InvokeCallback") +} + +// initMainLoop must be called with the same OSThread that is used to call runMainLoop() later. +func (m *windowsApp) initMainLoop() { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + if m.mainThreadWindowHWND != 0 { + panic("initMainLoop was already called") + } + + // We need a hidden window so we can PostMessage to it, if we don't use PostMessage for dispatching to a HWND + // messages might get lost if a modal inner loop is being run. + // We had this once in V2: https://github.com/wailsapp/wails/issues/969 + // See: https://devblogs.microsoft.com/oldnewthing/20050426-18/?p=35783 + // See also: https://learn.microsoft.com/en-us/windows/win32/winmsg/using-messages-and-message-queues#creating-a-message-loop + // > Because the system directs messages to individual windows in an application, a thread must create at least one window before starting its message loop. + m.mainThreadWindowHWND = w32.CreateWindowEx( + 0, + windowClassName, + lo.Must(syscall.UTF16PtrFromString("__wails_hidden_mainthread")), + w32.WS_DISABLED, + w32.CW_USEDEFAULT, + w32.CW_USEDEFAULT, + 0, + 0, + 0, + 0, + w32.GetModuleHandle(""), + nil) + + m.mainThreadID, _ = w32.GetWindowThreadProcessId(m.mainThreadWindowHWND) +} + +func (m *windowsApp) runMainLoop() int { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + if m.invokeRequired() { + panic("invokeRequired for runMainLoop, the mainloop must be running on the same OSThread as the mainThreadWindow has been created on") + } + + msg := (*w32.MSG)(unsafe.Pointer(w32.GlobalAlloc(0, uint32(unsafe.Sizeof(w32.MSG{}))))) + defer w32.GlobalFree(w32.HGLOBAL(unsafe.Pointer(m))) + + for w32.GetMessage(msg, 0, 0, 0) != 0 { + w32.TranslateMessage(msg) + w32.DispatchMessage(msg) + } + + return int(msg.WParam) +} + +func (m *windowsApp) dispatchOnMainThread(id uint) { + mainThreadHWND := m.mainThreadWindowHWND + if mainThreadHWND == 0 { + panic("initMainLoop was not called") + } + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + if m.invokeRequired() { + w32.PostMessage(mainThreadHWND, wmInvokeCallback, uintptr(id), 0) + } else { + mainThreadFunctionStoreLock.Lock() + fn := mainThreadFunctionStore[id] + delete(mainThreadFunctionStore, id) + mainThreadFunctionStoreLock.Unlock() + + if fn == nil { + Fatal("dispatchOnMainThread called with invalid id: %v", id) + } + fn() + } +} + +func (m *windowsApp) invokeRequired() bool { + mainThreadID := m.mainThreadID + if mainThreadID == 0 { + panic("initMainLoop was not called") + } + + return mainThreadID != w32.GetCurrentThreadId() +} + +func (m *windowsApp) invokeCallback(wParam, lParam uintptr) { + // TODO: Should we invoke just one or all queued? In v2 we always invoked all pendings... + runtime.LockOSThread() + defer runtime.UnlockOSThread() + if m.invokeRequired() { + panic("invokeCallback must always be called on the MainOSThread") + } + + mainThreadFunctionStoreLock.Lock() + fnIDs := make([]uint, 0, len(mainThreadFunctionStore)) + for id := range mainThreadFunctionStore { + fnIDs = append(fnIDs, id) + } + sort.Slice(fnIDs, func(i, j int) bool { return fnIDs[i] < fnIDs[j] }) + + fns := make([]func(), len(fnIDs)) + for i, id := range fnIDs { + fns[i] = mainThreadFunctionStore[id] + delete(mainThreadFunctionStore, id) + } + mainThreadFunctionStoreLock.Unlock() + + for _, fn := range fns { + fn() + } +} diff --git a/v3/pkg/application/webview_window_windows.go b/v3/pkg/application/webview_window_windows.go index 6e536ca50..25c8f8b18 100644 --- a/v3/pkg/application/webview_window_windows.go +++ b/v3/pkg/application/webview_window_windows.go @@ -3,10 +3,11 @@ package application import ( - "github.com/samber/lo" - "github.com/wailsapp/wails/v3/internal/w32" "syscall" "unsafe" + + "github.com/samber/lo" + "github.com/wailsapp/wails/v3/internal/w32" ) var showDevTools = func(window unsafe.Pointer) {} @@ -67,7 +68,10 @@ func (w *windowsWebviewWindow) setBackgroundColour(color *RGBA) { } func (w *windowsWebviewWindow) run() { + globalApplication.dispatchOnMainThread(w._run) +} +func (w *windowsWebviewWindow) _run() { var exStyle uint options := w.parent.options windowsOptions := options.Windows @@ -84,7 +88,7 @@ func (w *windowsWebviewWindow) run() { hwnd = w32.CreateWindowEx( exStyle, windowClassName, - lo.Must(syscall.UTF16PtrFromString("My Window Title")), + lo.Must(syscall.UTF16PtrFromString(options.Title)), w32.WS_OVERLAPPEDWINDOW|w32.WS_VISIBLE, w32.CW_USEDEFAULT, w32.CW_USEDEFAULT, From 7f3f51e36bfffb27baf7010dd89f20c30de9a588 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Fri, 28 Apr 2023 21:11:49 +1000 Subject: [PATCH 07/28] [windows] Support AlwaysOnTop, EnableResize at runtime. Added Solid/Transparent/Translucent options. --- v3/V3 Changes.md | 22 + v3/go.mod | 3 +- v3/go.sum | 6 +- v3/internal/w32/LICENSE | 48 - v3/internal/w32/README.md | 20 - v3/internal/w32/clipboard.go | 143 + v3/internal/w32/comctl32.go | 112 + v3/internal/w32/comdlg32.go | 40 + v3/internal/w32/constants.go | 3571 ++++-------- v3/internal/w32/consts.go | 83 + v3/internal/w32/dwmapi.go | 36 + v3/internal/w32/functions.go | 4809 ----------------- v3/internal/w32/functions_386.go | 29 - v3/internal/w32/functions_amd64.go | 43 - v3/internal/w32/functions_arm64.go | 43 - v3/internal/w32/gdi32.go | 526 ++ v3/internal/w32/gdiplus.go | 177 + v3/internal/w32/idispatch.go | 45 + v3/internal/w32/istream.go | 33 + v3/internal/w32/iunknown.go | 29 + v3/internal/w32/kernel32.go | 332 ++ v3/internal/w32/ole32.go | 65 + v3/internal/w32/oleaut32.go | 50 + v3/internal/w32/shcore.go | 29 + v3/internal/w32/shell32.go | 235 + v3/internal/w32/shlwapi.go | 26 + v3/internal/w32/theme.go | 119 + v3/internal/w32/toolbar.go | 216 + v3/internal/w32/{types.go => typedef.go} | 1032 ++-- v3/internal/w32/user32.go | 1281 +++++ v3/internal/w32/{com.go => utils.go} | 161 +- v3/internal/w32/uxtheme.go | 152 + v3/internal/w32/vars.go | 16 + v3/internal/w32/window.go | 137 + v3/pkg/application/mainthread_windows.go | 2 +- v3/pkg/application/messageprocessor_window.go | 2 +- v3/pkg/application/options_webview_window.go | 17 +- v3/pkg/application/options_windows.go | 15 +- v3/pkg/application/webview_window.go | 6 +- v3/pkg/application/webview_window_darwin.go | 2 +- v3/pkg/application/webview_window_windows.go | 173 +- 41 files changed, 5679 insertions(+), 8207 deletions(-) delete mode 100644 v3/internal/w32/LICENSE delete mode 100644 v3/internal/w32/README.md create mode 100644 v3/internal/w32/clipboard.go create mode 100644 v3/internal/w32/comctl32.go create mode 100644 v3/internal/w32/comdlg32.go create mode 100644 v3/internal/w32/consts.go create mode 100644 v3/internal/w32/dwmapi.go delete mode 100644 v3/internal/w32/functions.go delete mode 100644 v3/internal/w32/functions_386.go delete mode 100644 v3/internal/w32/functions_amd64.go delete mode 100644 v3/internal/w32/functions_arm64.go create mode 100644 v3/internal/w32/gdi32.go create mode 100644 v3/internal/w32/gdiplus.go create mode 100644 v3/internal/w32/idispatch.go create mode 100644 v3/internal/w32/istream.go create mode 100644 v3/internal/w32/iunknown.go create mode 100644 v3/internal/w32/kernel32.go create mode 100644 v3/internal/w32/ole32.go create mode 100644 v3/internal/w32/oleaut32.go create mode 100644 v3/internal/w32/shcore.go create mode 100644 v3/internal/w32/shell32.go create mode 100644 v3/internal/w32/shlwapi.go create mode 100644 v3/internal/w32/theme.go create mode 100644 v3/internal/w32/toolbar.go rename v3/internal/w32/{types.go => typedef.go} (55%) create mode 100644 v3/internal/w32/user32.go rename v3/internal/w32/{com.go => utils.go} (66%) create mode 100644 v3/internal/w32/uxtheme.go create mode 100644 v3/internal/w32/vars.go create mode 100644 v3/internal/w32/window.go diff --git a/v3/V3 Changes.md b/v3/V3 Changes.md index a002af2d5..9ec98b8e9 100644 --- a/v3/V3 Changes.md +++ b/v3/V3 Changes.md @@ -180,3 +180,25 @@ const MyEnum = { - Why use `float64`? Can't we use `int`? - Because JavaScript doesn't have a concept of `int`. Everything is a `number`, which translates to `float64` in Go. There are also restrictions on casting types in Go's reflection package, which means using `int` doesn't work. + +### BackgroundColour + +In v2, this was a pointer to an `RGBA` struct. In v3, this is an `RGBA` struct value. + +### WindowIsTranslucent + +This flag has been removed. Now there is a `BackgroundType` flag that can be used to set the type of background the window should have. +This flag can be set to any of the following values: +- `BackgroundTypeSolid` - The window will have a solid background +- `BackgroundTypeTransparent` - The window will have a transparent background +- `BackgroundTypeTranslucent` - The window will have a translucent background + +On Windows, if the `BackgroundType` is set to `BackgroundTypeTranslucent`, the type of translucency can be set using the +`BackdropType` flag in the `WindowsWindow` options. This can be set to any of the following values: +- `Auto` - The window will use an effect determined by the system +- `None` - The window will have no background +- `Mica` - The window will use the Mica effect +- `Acrylic` - The window will use the acrylic effect +- `Tabbed` - The window will use the tabbed effect + + diff --git a/v3/go.mod b/v3/go.mod index 84496cb50..edc912849 100644 --- a/v3/go.mod +++ b/v3/go.mod @@ -4,7 +4,6 @@ go 1.19 require ( github.com/go-task/task/v3 v3.20.0 - github.com/gonutz/w32/v2 v2.7.0 github.com/google/go-cmp v0.5.9 github.com/jackmordaunt/icns/v2 v2.2.1 github.com/json-iterator/go v1.1.12 @@ -18,6 +17,7 @@ require ( github.com/samber/lo v1.37.0 github.com/tc-hib/winres v0.1.6 github.com/wailsapp/wails/v2 v2.3.2-0.20230117193915-45c3a501d9e6 + golang.org/x/sys v0.7.0 modernc.org/sqlite v1.21.0 ) @@ -54,7 +54,6 @@ require ( golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect golang.org/x/net v0.7.0 // indirect golang.org/x/sync v0.1.0 // indirect - golang.org/x/sys v0.5.0 // indirect golang.org/x/term v0.5.0 // indirect golang.org/x/text v0.7.0 // indirect golang.org/x/tools v0.1.12 // indirect diff --git a/v3/go.sum b/v3/go.sum index 5cd5efb99..8fa850495 100644 --- a/v3/go.sum +++ b/v3/go.sum @@ -27,8 +27,6 @@ github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8Wd github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/task/v3 v3.20.0 h1:pTavuhP+AiEpKLzh5I6Lja9Ux7ypYO5QMsEPTbhYEDc= github.com/go-task/task/v3 v3.20.0/go.mod h1:y7rWakbLR5gFElGgo6rA2dyr6vU/zNIDVfn3S4Of6OI= -github.com/gonutz/w32/v2 v2.7.0 h1:O9lx/5tZ+WjZdxdvQFTh+/kP/7y95YCaL5MHqPrIHn4= -github.com/gonutz/w32/v2 v2.7.0/go.mod h1:MgtHx0AScDVNKyB+kjyPder4xIi3XAcHS6LDDU2DmdE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -184,8 +182,8 @@ golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= diff --git a/v3/internal/w32/LICENSE b/v3/internal/w32/LICENSE deleted file mode 100644 index 2a1db3e94..000000000 --- a/v3/internal/w32/LICENSE +++ /dev/null @@ -1,48 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2021 gonutz - -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. - - -This is the license from the original fork that this library is based on: - -Copyright (c) 2010-2012 The w32 Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/v3/internal/w32/README.md b/v3/internal/w32/README.md deleted file mode 100644 index b67af00ab..000000000 --- a/v3/internal/w32/README.md +++ /dev/null @@ -1,20 +0,0 @@ - -This is a fork of [gonutz/w32](https://github.com/gonutz/w32). - ------------------------ - -About w32 -========== - -w32 is a wrapper for a number of Windows APIs for the [Go Programming Language](https://golang.org/). - -This library has no other dependencies and you need no C-compiler, it is written in pure Go. Some function signatures have been adapted to make them work in Go, e.g. functions that take a pointer to an array and a count of items in C will now simply accept a slice in Go. - -If you miss any Windows API functions, just write an issue or create a pull request, the Win32 API is very large and has many rarely used functions in it so this wrapper is supposed to grow as needed by the Go community. - -Installation -============ - -Get the latest version with: - - go get github.com/gonutz/w32/v2 diff --git a/v3/internal/w32/clipboard.go b/v3/internal/w32/clipboard.go new file mode 100644 index 000000000..89334c0a4 --- /dev/null +++ b/v3/internal/w32/clipboard.go @@ -0,0 +1,143 @@ +//go:build windows + +/* + * Based on code originally from https://github.com/atotto/clipboard. Copyright (c) 2013 Ato Araki. All rights reserved. + */ + +package w32 + +import ( + "runtime" + "syscall" + "time" + "unsafe" +) + +const ( + cfUnicodetext = 13 + gmemMoveable = 0x0002 +) + +// waitOpenClipboard opens the clipboard, waiting for up to a second to do so. +func waitOpenClipboard() error { + started := time.Now() + limit := started.Add(time.Second) + var r uintptr + var err error + for time.Now().Before(limit) { + r, _, err = procOpenClipboard.Call(0) + if r != 0 { + return nil + } + time.Sleep(time.Millisecond) + } + return err +} + +func GetClipboardText() (string, error) { + // LockOSThread ensure that the whole method will keep executing on the same thread from begin to end (it actually locks the goroutine thread attribution). + // Otherwise if the goroutine switch thread during execution (which is a common practice), the OpenClipboard and CloseClipboard will happen on two different threads, and it will result in a clipboard deadlock. + runtime.LockOSThread() + defer runtime.UnlockOSThread() + if formatAvailable, _, err := procIsClipboardFormatAvailable.Call(cfUnicodetext); formatAvailable == 0 { + return "", err + } + err := waitOpenClipboard() + if err != nil { + return "", err + } + + h, _, err := procGetClipboardData.Call(cfUnicodetext) + if h == 0 { + _, _, _ = procCloseClipboard.Call() + return "", err + } + + l, _, err := kernelGlobalLock.Call(h) + if l == 0 { + _, _, _ = procCloseClipboard.Call() + return "", err + } + + text := syscall.UTF16ToString((*[1 << 20]uint16)(unsafe.Pointer(l))[:]) + + r, _, err := kernelGlobalUnlock.Call(h) + if r == 0 { + _, _, _ = procCloseClipboard.Call() + return "", err + } + + closed, _, err := procCloseClipboard.Call() + if closed == 0 { + return "", err + } + return text, nil +} + +func SetClipboardText(text string) error { + // LockOSThread ensure that the whole method will keep executing on the same thread from begin to end (it actually locks the goroutine thread attribution). + // Otherwise if the goroutine switch thread during execution (which is a common practice), the OpenClipboard and CloseClipboard will happen on two different threads, and it will result in a clipboard deadlock. + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + err := waitOpenClipboard() + if err != nil { + return err + } + + r, _, err := procEmptyClipboard.Call(0) + if r == 0 { + _, _, _ = procCloseClipboard.Call() + return err + } + + data, err := syscall.UTF16FromString(text) + if err != nil { + return err + } + + // "If the hMem parameter identifies a memory object, the object must have + // been allocated using the function with the GMEM_MOVEABLE flag." + h, _, err := kernelGlobalAlloc.Call(gmemMoveable, uintptr(len(data)*int(unsafe.Sizeof(data[0])))) + if h == 0 { + _, _, _ = procCloseClipboard.Call() + return err + } + defer func() { + if h != 0 { + kernelGlobalFree.Call(h) + } + }() + + l, _, err := kernelGlobalLock.Call(h) + if l == 0 { + _, _, _ = procCloseClipboard.Call() + return err + } + + r, _, err = kernelLstrcpy.Call(l, uintptr(unsafe.Pointer(&data[0]))) + if r == 0 { + _, _, _ = procCloseClipboard.Call() + return err + } + + r, _, err = kernelGlobalUnlock.Call(h) + if r == 0 { + if err.(syscall.Errno) != 0 { + _, _, _ = procCloseClipboard.Call() + return err + } + } + + r, _, err = procSetClipboardData.Call(cfUnicodetext, h) + if r == 0 { + _, _, _ = procCloseClipboard.Call() + return err + } + h = 0 // suppress deferred cleanup + closed, _, err := procCloseClipboard.Call() + if closed == 0 { + return err + } + return nil +} diff --git a/v3/internal/w32/comctl32.go b/v3/internal/w32/comctl32.go new file mode 100644 index 000000000..b66709f5f --- /dev/null +++ b/v3/internal/w32/comctl32.go @@ -0,0 +1,112 @@ +//go:build windows + +/* + * 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 +} diff --git a/v3/internal/w32/comdlg32.go b/v3/internal/w32/comdlg32.go new file mode 100644 index 000000000..d28922c33 --- /dev/null +++ b/v3/internal/w32/comdlg32.go @@ -0,0 +1,40 @@ +//go:build windows + +/* + * 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) +} diff --git a/v3/internal/w32/constants.go b/v3/internal/w32/constants.go index 3c4ba53c7..8105b1195 100644 --- a/v3/internal/w32/constants.go +++ b/v3/internal/w32/constants.go @@ -1,9 +1,10 @@ -package w32 +//go:build windows -// TODO Check that these messages are correct: -// WM_* -// TTM_* -// TBM_* +/* + * Copyright (C) 2019 The Winc Authors. All Rights Reserved. + * Copyright (C) 2010-2012 The W32 Authors. All Rights Reserved. + */ +package w32 const ( FALSE = 0 @@ -19,7 +20,6 @@ const ( ERROR_INVALID_HANDLE = 6 ERROR_BAD_FORMAT = 11 ERROR_INVALID_NAME = 123 - ERROR_ALREADY_EXISTS = 183 ERROR_MORE_DATA = 234 ERROR_NO_MORE_ITEMS = 259 ERROR_INVALID_SERVICE_CONTROL = 1052 @@ -53,7 +53,14 @@ const ( ) const ( - CW_USEDEFAULT = ^0x7FFFFFFF + CW_USEDEFAULT = ^0x7fffffff +) + +const ( + IMAGE_BITMAP = 0 + IMAGE_ICON = 1 + IMAGE_CURSOR = 2 + IMAGE_ENHMETAFILE = 3 ) // ShowWindow constants @@ -121,7 +128,6 @@ const ( IDI_EXCLAMATION = 32515 IDI_ASTERISK = 32516 IDI_WINLOGO = 32517 - IDI_SHIELD = 32518 IDI_WARNING = IDI_EXCLAMATION IDI_ERROR = IDI_HAND IDI_INFORMATION = IDI_ASTERISK @@ -155,6 +161,8 @@ const ( BS_USERBUTTON = 8 BS_VCENTER = 0xC00 BS_FLAT = 0x8000 + BS_SPLITBUTTON = 0x000C // >= Vista + BS_DEFSPLITBUTTON = 0x000D // >= Vista ) // Button state constants @@ -166,316 +174,42 @@ const ( BST_PUSHED = 4 ) -// Combo box style constants +// Predefined brushes constants 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 -) - -// Combo box message constants -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 - CB_MSGMAX = 0x0165 -) - -// Combo box return values -const ( - CB_OKAY = 0 - CB_ERR = -1 - CB_ERRSPACE = -2 -) - -// Combo box notification codes -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 -) - -// List box message constants -const ( - LB_ADDSTRING = 384 - LB_INSERTSTRING = 385 - LB_DELETESTRING = 386 - LB_SELITEMRANGEEX = 387 - LB_RESETCONTENT = 388 - LB_SETSEL = 389 - LB_SETCURSEL = 390 - LB_GETSEL = 391 - LB_GETCURSEL = 392 - LB_GETTEXT = 393 - LB_GETTEXTLEN = 394 - LB_GETCOUNT = 395 - LB_SELECTSTRING = 396 - LB_DIR = 397 - LB_GETTOPINDEX = 398 - LB_FINDSTRING = 399 - LB_GETSELCOUNT = 400 - LB_GETSELITEMS = 401 - LB_SETTABSTOPS = 402 - LB_GETHORIZONTALEXTENT = 403 - LB_SETHORIZONTALEXTENT = 404 - LB_SETCOLUMNWIDTH = 405 - LB_ADDFILE = 406 - LB_SETTOPINDEX = 407 - LB_GETITEMRECT = 408 - LB_GETITEMDATA = 409 - LB_SETITEMDATA = 410 - LB_SELITEMRANGE = 411 - LB_SETANCHORINDEX = 412 - LB_GETANCHORINDEX = 413 - LB_SETCARETINDEX = 414 - LB_GETCARETINDEX = 415 - LB_SETITEMHEIGHT = 416 - LB_GETITEMHEIGHT = 417 - LB_FINDSTRINGEXACT = 418 - LB_SETLOCALE = 421 - LB_GETLOCALE = 422 - LB_SETCOUNT = 423 - LB_INITSTORAGE = 424 - LB_ITEMFROMPOINT = 425 - LB_SETTEXT = 426 - LB_GETCHECKMARK = 427 - LB_SETCHECKMARK = 428 - LB_GETITEMADDDATA = 429 - LB_SETITEMADDDATA = 430 -) - -// List box styles -const ( - LBS_NOTIFY = 0x0001 - LBS_SORT = 0x0002 - LBS_NOREDRAW = 0x0004 - LBS_MULTIPLESEL = 0x0008 - LBS_OWNERDRAWFIXED = 0x0010 - LBS_OWNERDRAWVARIABLE = 0x0020 - LBS_HASSTRINGS = 0x0040 - LBS_USETABSTOPS = 0x0080 - LBS_NOINTEGRALHEIGHT = 0x0100 - LBS_MULTICOLUMN = 0x0200 - LBS_WANTKEYBOARDINPUT = 0x0400 - LBS_EXTENDEDSEL = 0x0800 - LBS_STANDARD = LBS_NOTIFY | LBS_SORT | WS_VSCROLL | WS_BORDER - LBS_CHECKBOX = 0x1000 - LBS_USEICON = 0x2000 - LBS_AUTOCHECK = 0x4000 - LBS_AUTOCHECKBOX = 0x5000 - LBS_PRELOADED = 0x4000 - LBS_COMBOLBOX = 0x8000 -) - -// List box notification messages -const ( - LBN_ERRSPACE = -2 - LBN_SELCHANGE = 1 - LBN_DBLCLK = 2 - LBN_SELCANCEL = 3 - LBN_SETFOCUS = 4 - LBN_KILLFOCUS = 5 - LBN_CLICKCHECKMARK = 6 -) - -// List box return values -const ( - LB_OKAY = 0 - LB_ERR = -1 - LB_ERRSPACE = -2 -) - -// Predefined color/brush constants. -const ( - // Scroll bar gray area. - COLOR_SCROLLBAR = 0 - - // Desktop. - COLOR_BACKGROUND = 1 - - // Desktop. - COLOR_DESKTOP = 1 - - // Active window title bar. The associated foreground color is - // COLOR_CAPTIONTEXT. Specifies the left side color in the color gradient of - // an active window's title bar if the gradient effect is enabled. - COLOR_ACTIVECAPTION = 2 - - // Inactive window caption. - // The associated foreground color is COLOR_INACTIVECAPTIONTEXT. - // Specifies the left side color in the color gradient of an inactive window's title bar if the gradient effect is enabled. - COLOR_INACTIVECAPTION = 3 - - // Menu background. The associated foreground color is COLOR_MENUTEXT. - COLOR_MENU = 4 - - // Window background. The associated foreground colors are COLOR_WINDOWTEXT - // and COLOR_HOTLITE. - COLOR_WINDOW = 5 - - // Window frame. - COLOR_WINDOWFRAME = 6 - - // Text in menus. The associated background color is COLOR_MENU. - COLOR_MENUTEXT = 7 - - // Text in windows. The associated background color is COLOR_WINDOW. - COLOR_WINDOWTEXT = 8 - - // Text in caption, size box, and scroll bar arrow box. The associated - // background color is COLOR_ACTIVECAPTION. - COLOR_CAPTIONTEXT = 9 - - // Active window border. - COLOR_ACTIVEBORDER = 10 - - // Inactive window border. - COLOR_INACTIVEBORDER = 11 - - // Background color of multiple document interface (MDI) applications. - COLOR_APPWORKSPACE = 12 - - // Item(s) selected in a control. The associated foreground color is - // COLOR_HIGHLIGHTTEXT. - COLOR_HIGHLIGHT = 13 - - // Text of item(s) selected in a control. The associated background color is - // COLOR_HIGHLIGHT. - COLOR_HIGHLIGHTTEXT = 14 - - // Face color for three-dimensional display elements and for dialog box - // backgrounds. - COLOR_3DFACE = 15 - - // Face color for three-dimensional display elements and for dialog box - // backgrounds. The associated foreground color is COLOR_BTNTEXT. - COLOR_BTNFACE = 15 - - // Shadow color for three-dimensional display elements (for edges facing - // away from the light source). - COLOR_3DSHADOW = 16 - - // Shadow color for three-dimensional display elements (for edges facing - // away from the light source). - COLOR_BTNSHADOW = 16 - - // Grayed (disabled) text. This color is set to 0 if the current display - // driver does not support a solid gray color. - COLOR_GRAYTEXT = 17 - - // Text on push buttons. The associated background color is COLOR_BTNFACE. - COLOR_BTNTEXT = 18 - - // Color of text in an inactive caption. The associated background color is - // COLOR_INACTIVECAPTION. - COLOR_INACTIVECAPTIONTEXT = 19 - - // Highlight color for three-dimensional display elements (for edges facing - // the light source.) - COLOR_3DHIGHLIGHT = 20 - - // Highlight color for three-dimensional display elements (for edges facing - // the light source.) - COLOR_3DHILIGHT = 20 - - // Highlight color for three-dimensional display elements (for edges facing - // the light source.) - COLOR_BTNHIGHLIGHT = 20 - - // Highlight color for three-dimensional display elements (for edges facing - // the light source.) - COLOR_BTNHILIGHT = 20 - - // Dark shadow for three-dimensional display elements. - COLOR_3DDKSHADOW = 21 - - // Light color for three-dimensional display elements (for edges facing the - // light source.) - COLOR_3DLIGHT = 22 - - // Text color for tooltip controls. The associated background color is - // COLOR_INFOBK. - COLOR_INFOTEXT = 23 - - // Background color for tooltip controls. The associated foreground color is - // COLOR_INFOTEXT. - COLOR_INFOBK = 24 - - // Color for a hyperlink or hot-tracked item. The associated background - // color is COLOR_WINDOW. - COLOR_HOTLIGHT = 26 - - // Right side color in the color gradient of an active window's title bar. - // COLOR_ACTIVECAPTION specifies the left side color. Use - // SPI_GETGRADIENTCAPTIONS with the SystemParametersInfo function to - // determine whether the gradient effect is enabled. - COLOR_GRADIENTACTIVECAPTION = 27 - - // Right side color in the color gradient of an inactive window's title bar. - // COLOR_INACTIVECAPTION specifies the left side color. + 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 - - // The color used to highlight menu items when the menu appears as a flat - // menu (see SystemParametersInfo). The highlighted menu item is outlined - // with COLOR_HIGHLIGHT. Windows 2000: This value is not supported. - COLOR_MENUHILIGHT = 29 - - // The background color for the menu bar when menus appear as flat menus - // (see SystemParametersInfo). However, COLOR_MENU continues to specify the - // background color of the menu popup. Windows 2000: This value is not - // supported. - COLOR_MENUBAR = 30 ) // Button message constants @@ -505,6 +239,27 @@ const ( 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 @@ -553,32 +308,32 @@ const ( // 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_LAYOUTRTL = 0x00400000 - WS_EX_COMPOSITED = 0x02000000 - WS_EX_NOACTIVATE = 0x08000000 + 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 @@ -599,7 +354,7 @@ const ( WM_CLEAR = 771 WM_CLOSE = 16 WM_COMMAND = 273 - WM_COMMNOTIFY = 68 // obsolete + WM_COMMNOTIFY = 68 /* OBSOLETE */ WM_COMPACTING = 65 WM_COMPAREITEM = 57 WM_CONTEXTMENU = 123 @@ -765,7 +520,7 @@ const ( WM_WINDOWPOSCHANGING = 70 WM_WININICHANGE = 26 WM_KEYFIRST = 256 - WM_KEYLAST = 265 + WM_KEYLAST = 264 WM_SYNCPAINT = 136 WM_MOUSEACTIVATE = 33 WM_MOUSEMOVE = 512 @@ -779,12 +534,11 @@ const ( WM_MBUTTONUP = 520 WM_MBUTTONDBLCLK = 521 WM_MOUSEWHEEL = 522 - WM_MOUSEHWHEEL = 526 WM_MOUSEFIRST = 512 WM_XBUTTONDOWN = 523 WM_XBUTTONUP = 524 WM_XBUTTONDBLCLK = 525 - WM_MOUSELAST = 526 + WM_MOUSELAST = 525 WM_MOUSEHOVER = 0x2A1 WM_MOUSELEAVE = 0x2A3 WM_CLIPBOARDUPDATE = 0x031D @@ -797,15 +551,7 @@ const ( WA_CLICKACTIVE = 2 ) -const ( - LF_FACESIZE = 32 - LF_FULLFACESIZE = 64 -) - -const ( - MM_MAX_NUMAXES = 16 - MM_MAX_AXES_NAMELEN = 16 -) +const LF_FACESIZE = 32 // Font weight constants const ( @@ -850,6 +596,23 @@ const ( MAC_CHARSET = 77 ) +const ( + // PBT_APMPOWERSTATUSCHANGE - Power status has changed. + PBT_APMPOWERSTATUSCHANGE = 10 + + // PBT_APMRESUMEAUTOMATIC -Operation is resuming automatically from a low-power state. This message is sent every time the system resumes. + PBT_APMRESUMEAUTOMATIC = 18 + + // PBT_APMRESUMESUSPEND - Operation is resuming from a low-power state. This message is sent after PBT_APMRESUMEAUTOMATIC if the resume is triggered by user input, such as pressing a key. + PBT_APMRESUMESUSPEND = 7 + + // PBT_APMSUSPEND - System is suspending operation. + PBT_APMSUSPEND = 4 + + // PBT_POWERSETTINGCHANGE - A power setting change event has been received. + PBT_POWERSETTINGCHANGE = 32787 +) + // Font output precision constants const ( OUT_DEFAULT_PRECIS = 0 @@ -1110,10 +873,10 @@ const ( SS_GRAYRECT = 5 SS_ICON = 3 SS_LEFT = 0 - SS_LEFTNOWORDWRAP = 0xC + SS_LEFTNOWORDWRAP = 0xc SS_NOPREFIX = 128 SS_NOTIFY = 256 - SS_OWNERDRAW = 0xD + SS_OWNERDRAW = 0xd SS_REALSIZECONTROL = 0x040 SS_REALSIZEIMAGE = 0x800 SS_RIGHT = 2 @@ -1164,135 +927,63 @@ const ( // 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 - EM_AUTOURLDETECT = 0x45B - EM_CANPASTE = 0x432 - EM_CANREDO = 0x455 - EM_DISPLAYBAND = 0x433 - EM_EXGETSEL = 0x434 - EM_EXLIMITTEXT = 0x435 - EM_EXLINEFROMCHAR = 0x436 - EM_EXSETSEL = 0x437 - EM_FINDTEXT = 0x438 - EM_FINDTEXTEX = 0x44F - EM_FINDTEXTEXW = 0x47C - EM_FINDTEXTW = 0x47B - EM_FINDWORDBREAK = 0x44C - EM_FORMATRANGE = 0x439 - EM_GETAUTOURLDETECT = 0x45C - EM_GETBIDIOPTIONS = 0x4C9 - EM_GETCHARFORMAT = 0x43A - EM_GETEDITSTYLE = 0x4CD - EM_GETEVENTMASK = 0x43B - EM_GETIMECOLOR = 0x469 - EM_GETIMECOMPMODE = 0x47A - EM_GETIMEOPTIONS = 0x46B - EM_GETLANGOPTIONS = 0x479 - EM_GETOLEINTERFACE = 0x43C - EM_GETOPTIONS = 0x44E - EM_GETPARAFORMAT = 0x43D - EM_GETPUNCTUATION = 0x465 - EM_GETREDONAME = 0x457 - EM_GETSCROLLPOS = 0x4DD - EM_GETSELTEXT = 0x43E - EM_GETTEXTEX = 0x45E - EM_GETTEXTLENGTHEX = 0x45F - EM_GETTEXTMODE = 0x45A - EM_GETTEXTRANGE = 0x44B - EM_GETTYPOGRAPHYOPTIONS = 0x4CB - EM_GETUNDONAME = 0x456 - EM_GETWORDBREAKPROCEX = 0x450 - EM_GETWORDWRAPMODE = 0x467 - EM_GETZOOM = 0x4E0 - EM_HIDESELECTION = 0x43F - EM_PASTESPECIAL = 0x440 - EM_RECONVERSION = 0x47D - EM_REDO = 0x454 - EM_REQUESTRESIZE = 0x441 - EM_SELECTIONTYPE = 0x442 - EM_SETBIDIOPTIONS = 0x4C8 - EM_SETBKGNDCOLOR = 0x443 - EM_SETCHARFORMAT = 0x444 - EM_SETEDITSTYLE = 0x4CC - EM_SETEVENTMASK = 0x445 - EM_SETFONTSIZE = 0x4DF - EM_SETIMECOLOR = 0x468 - EM_SETIMEOPTIONS = 0x46A - EM_SETLANGOPTIONS = 0x478 - EM_SETOLECALLBACK = 0x446 - EM_SETOPTIONS = 0x44D - EM_SETPALETTE = 0x45D - EM_SETPARAFORMAT = 0x447 - EM_SETPUNCTUATION = 0x464 - EM_SETSCROLLPOS = 0x4DE - EM_SETTARGETDEVICE = 0x448 - EM_SETTEXTEX = 0x461 - EM_SETTEXTMODE = 0x459 - EM_SETTYPOGRAPHYOPTIONS = 0x4CA - EM_SETUNDOLIMIT = 0x452 - EM_SETWORDBREAKPROCEX = 0x451 - EM_SETWORDWRAPMODE = 0x466 - EM_SETZOOM = 0x4E1 - EM_SHOWSCROLLBAR = 0x460 - EM_STOPGROUPTYPING = 0x458 - EM_STREAMIN = 0x449 - EM_STREAMOUT = 0x44A + 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 + 0x0200 - CCM_SETBKCOLOR = CCM_FIRST + 1 - CCM_SETCOLORSCHEME = CCM_FIRST + 2 - CCM_GETCOLORSCHEME = CCM_FIRST + 3 - CCM_GETDROPTARGET = CCM_FIRST + 4 - CCM_SETUNICODEFORMAT = CCM_FIRST + 5 - CCM_GETUNICODEFORMAT = CCM_FIRST + 6 - CCM_SETVERSION = CCM_FIRST + 7 - CCM_GETVERSION = CCM_FIRST + 8 - CCM_SETNOTIFYWINDOW = CCM_FIRST + 9 - CCM_SETWINDOWTHEME = CCM_FIRST + 11 - CCM_DPISCALE = CCM_FIRST + 12 + 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 @@ -1313,25 +1004,82 @@ const ( // ProgressBar messages const ( PROGRESS_CLASS = "msctls_progress32" - PBM_SETRANGE = WM_USER + 1 PBM_SETPOS = WM_USER + 2 PBM_DELTAPOS = WM_USER + 3 PBM_SETSTEP = WM_USER + 4 PBM_STEPIT = WM_USER + 5 - PBM_SETRANGE32 = WM_USER + 6 - PBM_GETRANGE = WM_USER + 7 - PBM_GETPOS = WM_USER + 8 - PBM_SETBARCOLOR = WM_USER + 9 - PBM_SETMARQUEE = WM_USER + 10 + PBM_SETRANGE32 = 1030 + PBM_GETRANGE = 1031 + PBM_GETPOS = 1032 + PBM_SETBARCOLOR = 1033 PBM_SETBKCOLOR = CCM_SETBKCOLOR + PBS_SMOOTH = 1 + PBS_VERTICAL = 4 ) -// Progress bar styles. +// Trackbar messages and constants const ( - PBS_SMOOTH = 0x01 - PBS_VERTICAL = 0x04 - PBS_MARQUEE = 0x08 - PBS_SMOOTHREVERSE = 0x10 + 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 @@ -1412,7 +1160,6 @@ const ( MB_DEFBUTTON2 = 0x00000100 MB_DEFBUTTON3 = 0x00000200 MB_DEFBUTTON4 = 0x00000300 - MB_TOPMOST = 0x00040000 ) // COM @@ -1520,7 +1267,7 @@ const ( SM_MEDIACENTER = 87 SM_STARTER = 88 SM_SERVERR2 = 89 - SM_CMETRICS = 97 + SM_CMETRICS = 91 SM_REMOTESESSION = 0x1000 SM_SHUTTINGDOWN = 0x2000 SM_REMOTECONTROL = 0x2001 @@ -1533,7 +1280,7 @@ const ( CLSCTX_LOCAL_SERVER = 4 CLSCTX_INPROC_SERVER16 = 8 CLSCTX_REMOTE_SERVER = 16 - CLSCTX_ALL = CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER | CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER + 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 ) @@ -1553,17 +1300,17 @@ const ( ) const ( - CC_FASTCALL = 0 - CC_CDECL = 1 - CC_MSCPASCAL = 2 - CC_PASCAL = CC_MSCPASCAL - CC_MACPASCAL = 3 - CC_STDCALL = 4 - CC_FPFASTCALL = 5 - CC_SYSCALL = 6 - CC_MPWCDECL = 7 - CC_MPWPASCAL = 8 - CC_MAX = 9 + 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 ( @@ -1577,11 +1324,11 @@ const ( 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_ERROR = 0xa + VT_BOOL = 0xb + VT_VARIANT = 0xc + VT_UNKNOWN = 0xd + VT_DECIMAL = 0xe VT_I1 = 0x10 VT_UI1 = 0x11 VT_UI2 = 0x12 @@ -1592,12 +1339,12 @@ const ( 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_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 @@ -1610,14 +1357,14 @@ const ( VT_BLOB_OBJECT = 0x46 VT_CF = 0x47 VT_CLSID = 0x48 - VT_BSTR_BLOB = 0xFFF + 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 + VT_ILLEGAL = 0xffff + VT_ILLEGALMASKED = 0xfff + VT_TYPEMASK = 0xfff ) const ( @@ -1683,122 +1430,121 @@ const ( // ListView messages const ( - // https://wiki.winehq.org/List_Of_Windows_Messages LVM_FIRST = 0x1000 - LVM_GETITEMCOUNT = 0x1004 - LVM_SETIMAGELIST = 0x1003 - LVM_GETIMAGELIST = 0x1002 - LVM_GETITEM = 0x104B - LVM_SETITEM = 0x104C - LVM_INSERTITEM = 0x104D - LVM_DELETEITEM = 0x1008 - LVM_DELETEALLITEMS = 0x1009 - LVM_GETCALLBACKMASK = 0x100A - LVM_SETCALLBACKMASK = 0x100B - LVM_SETUNICODEFORMAT = 0x2005 - LVM_GETNEXTITEM = 0x100C - LVM_FINDITEM = 0x1053 - LVM_GETITEMRECT = 0x100E - LVM_GETSTRINGWIDTH = 0x1057 - LVM_HITTEST = 0x1012 - LVM_ENSUREVISIBLE = 0x1013 - LVM_SCROLL = 0x1014 - LVM_REDRAWITEMS = 0x1015 - LVM_ARRANGE = 0x1016 - LVM_EDITLABEL = 0x1076 - LVM_GETEDITCONTROL = 0x1018 - LVM_GETCOLUMN = 0x105F - LVM_SETCOLUMN = 0x1060 - LVM_INSERTCOLUMN = 0x1061 - LVM_DELETECOLUMN = 0x101C - LVM_GETCOLUMNWIDTH = 0x101D - LVM_SETCOLUMNWIDTH = 0x101E - LVM_GETHEADER = 0x101F - LVM_CREATEDRAGIMAGE = 0x1021 - LVM_GETVIEWRECT = 0x1022 - LVM_GETTEXTCOLOR = 0x1023 - LVM_SETTEXTCOLOR = 0x1024 - LVM_GETTEXTBKCOLOR = 0x1025 - LVM_SETTEXTBKCOLOR = 0x1026 - LVM_GETTOPINDEX = 0x1027 - LVM_GETCOUNTPERPAGE = 0x1028 - LVM_GETORIGIN = 0x1029 - LVM_UPDATE = 0x102A - LVM_SETITEMSTATE = 0x102B - LVM_GETITEMSTATE = 0x102C - LVM_GETITEMTEXT = 0x1073 - LVM_SETITEMTEXT = 0x1074 - LVM_SETITEMCOUNT = 0x102F - LVM_SORTITEMS = 0x1030 - LVM_SETITEMPOSITION32 = 0x1031 - LVM_GETSELECTEDCOUNT = 0x1032 - LVM_GETITEMSPACING = 0x1033 - LVM_GETISEARCHSTRING = 0x1075 - LVM_SETICONSPACING = 0x1035 - LVM_SETEXTENDEDLISTVIEWSTYLE = 0x1036 - LVM_GETEXTENDEDLISTVIEWSTYLE = 0x1037 - LVM_GETSUBITEMRECT = 0x1038 - LVM_SUBITEMHITTEST = 0x1039 - LVM_SETCOLUMNORDERARRAY = 0x103A - LVM_GETCOLUMNORDERARRAY = 0x103B - LVM_SETHOTITEM = 0x103C - LVM_GETHOTITEM = 0x103D - LVM_SETHOTCURSOR = 0x103E - LVM_GETHOTCURSOR = 0x103F - LVM_APPROXIMATEVIEWRECT = 0x1040 - LVM_SETWORKAREAS = 0x1041 - LVM_GETWORKAREAS = 0x1046 - LVM_GETNUMBEROFWORKAREAS = 0x1049 - LVM_GETSELECTIONMARK = 0x1042 - LVM_SETSELECTIONMARK = 0x1043 - LVM_SETHOVERTIME = 0x1047 - LVM_GETHOVERTIME = 0x1048 - LVM_SETTOOLTIPS = 0x104A - LVM_GETTOOLTIPS = 0x104E - LVM_SORTITEMSEX = 0x1051 - LVM_SETBKIMAGE = 0x1044 - LVM_GETBKIMAGE = 0x108B - LVM_SETSELECTEDCOLUMN = 0x108C - LVM_SETVIEW = 0x108E - LVM_GETVIEW = 0x108F - LVM_INSERTGROUP = 0x1091 - LVM_SETGROUPINFO = 0x1093 - LVM_GETGROUPINFO = 0x1095 - LVM_REMOVEGROUP = 0x1096 - LVM_MOVEGROUP = 0x1097 - LVM_GETGROUPCOUNT = 0x1098 - LVM_GETGROUPINFOBYINDEX = 0x1099 - LVM_MOVEITEMTOGROUP = 0x109A - LVM_GETGROUPRECT = 0x1062 - LVM_SETGROUPMETRICS = 0x109B - LVM_GETGROUPMETRICS = 0x109C - LVM_ENABLEGROUPVIEW = 0x109D - LVM_SORTGROUPS = 0x109E - LVM_INSERTGROUPSORTED = 0x109F - LVM_REMOVEALLGROUPS = 0x10A0 - LVM_HASGROUP = 0x10A1 - LVM_GETGROUPSTATE = 0x105C - LVM_GETFOCUSEDGROUP = 0x105D - LVM_SETTILEVIEWINFO = 0x10A2 - LVM_GETTILEVIEWINFO = 0x10A3 - LVM_SETTILEINFO = 0x10A4 - LVM_GETTILEINFO = 0x10A5 - LVM_SETINSERTMARK = 0x10A6 - LVM_GETINSERTMARK = 0x10A7 - LVM_INSERTMARKHITTEST = 0x10A8 - LVM_GETINSERTMARKRECT = 0x10A9 - LVM_SETINSERTMARKCOLOR = 0x10AA - LVM_GETINSERTMARKCOLOR = 0x10AB - LVM_SETINFOTIP = 0x10AD - LVM_GETSELECTEDCOLUMN = 0x10AE - LVM_ISGROUPVIEWENABLED = 0x10AF - LVM_GETOUTLINECOLOR = 0x10B0 - LVM_SETOUTLINECOLOR = 0x10B1 - LVM_CANCELEDITLABEL = 0x10B3 - LVM_MAPINDEXTOID = 0x10B4 - LVM_MAPIDTOINDEX = 0x10B5 - LVM_ISITEMVISIBLE = 0x10B6 - LVM_GETNEXTITEMINDEX = 0x10D3 + 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 @@ -1823,16 +1569,21 @@ const ( LVN_ITEMACTIVATE = LVN_FIRST - 14 LVN_ODSTATECHANGED = LVN_FIRST - 15 LVN_HOTTRACK = LVN_FIRST - 21 - LVN_GETDISPINFO = LVN_FIRST - 50 - LVN_SETDISPINFO = LVN_FIRST - 51 + LVN_GETDISPINFO = LVN_FIRST - 77 + LVN_SETDISPINFO = LVN_FIRST - 78 LVN_KEYDOWN = LVN_FIRST - 55 LVN_MARQUEEBEGIN = LVN_FIRST - 56 - LVN_GETINFOTIP = LVN_FIRST - 57 - LVN_INCREMENTALSEARCH = LVN_FIRST - 62 + 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 @@ -1863,10 +1614,10 @@ const ( LVS_EDITLABELS = 0x0200 LVS_OWNERDATA = 0x1000 LVS_NOSCROLL = 0x2000 - LVS_TYPESTYLEMASK = 0xFC00 + LVS_TYPESTYLEMASK = 0xfc00 LVS_ALIGNTOP = 0x0000 LVS_ALIGNLEFT = 0x0800 - LVS_ALIGNMASK = 0x0C00 + LVS_ALIGNMASK = 0x0c00 LVS_OWNERDRAWFIXED = 0x0400 LVS_NOCOLUMNHEADER = 0x4000 LVS_NOSORTHEADER = 0x8000 @@ -1930,6 +1681,8 @@ const ( LVIF_COLUMNS = 0x00000200 ) +const LVFI_PARAM = 0x0001 + // ListView item states const ( LVIS_FOCUSED = 1 @@ -2045,9 +1798,9 @@ const ( 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_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 @@ -2089,6 +1842,7 @@ const ( ) // Virtual-Key Codes +/* const ( VK_LBUTTON = 0x01 VK_RBUTTON = 0x02 @@ -2108,12 +1862,10 @@ const ( VK_KANA = 0x15 VK_HANGEUL = 0x15 VK_HANGUL = 0x15 - VK_IME_ON = 0x16 VK_JUNJA = 0x17 VK_FINAL = 0x18 VK_HANJA = 0x19 VK_KANJI = 0x19 - VK_IME_OFF = 0x1A VK_ESCAPE = 0x1B VK_CONVERT = 0x1C VK_NONCONVERT = 0x1D @@ -2229,7 +1981,6 @@ const ( VK_ICO_00 = 0xE4 VK_PROCESSKEY = 0xE5 VK_ICO_CLEAR = 0xE6 - VK_PACKET = 0xE7 VK_OEM_RESET = 0xE9 VK_OEM_JUMP = 0xEA VK_OEM_PA1 = 0xEB @@ -2252,7 +2003,7 @@ const ( VK_NONAME = 0xFC VK_PA1 = 0xFD VK_OEM_CLEAR = 0xFE -) +)*/ // Registry Value Types const ( @@ -2285,39 +2036,39 @@ const ( // Tooltip messages const ( - TTM_ACTIVATE = WM_USER + 1 - TTM_SETDELAYTIME = WM_USER + 3 - TTM_ADDTOOL = WM_USER + 4 - TTM_DELTOOL = WM_USER + 5 - TTM_NEWTOOLRECT = WM_USER + 6 - TTM_RELAYEVENT = WM_USER + 7 - TTM_GETTOOLINFO = WM_USER + 8 - TTM_SETTOOLINFO = WM_USER + 9 - TTM_HITTEST = WM_USER + 10 - TTM_GETTEXT = WM_USER + 11 - TTM_UPDATETIPTEXT = WM_USER + 12 - TTM_GETTOOLCOUNT = WM_USER + 13 - TTM_ENUMTOOLS = WM_USER + 14 - TTM_GETCURRENTTOOL = WM_USER + 15 - 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 + 32 - TTM_POPUP = WM_USER + 34 - TTM_GETTITLE = WM_USER + 35 + 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 @@ -2335,10 +2086,10 @@ const ( const ( TTN_FIRST = -520 TTN_LAST = -549 - TTN_GETDISPINFO = TTN_FIRST - TTN_SHOW = TTN_FIRST - 1 - TTN_POP = TTN_FIRST - 2 - TTN_LINKCLICK = TTN_FIRST - 3 + TTN_GETDISPINFO = (TTN_FIRST - 10) + TTN_SHOW = (TTN_FIRST - 1) + TTN_POP = (TTN_FIRST - 2) + TTN_LINKCLICK = (TTN_FIRST - 3) TTN_NEEDTEXT = TTN_GETDISPINFO ) @@ -2482,8 +2233,8 @@ const ( // WM_NCHITTEST and MOUSEHOOKSTRUCT Mouse Position Codes const ( - HTERROR = -2 - HTTRANSPARENT = -1 + HTERROR = (-2) + HTTRANSPARENT = (-1) HTNOWHERE = 0 HTCLIENT = 1 HTCAPTION = 2 @@ -2566,8 +2317,8 @@ const ( GMEM_LOWER = GMEM_NOT_BANKED GMEM_VALID_FLAGS = 0x7F72 GMEM_INVALID_HANDLE = 0x8000 - GHND = GMEM_MOVEABLE | GMEM_ZEROINIT - GPTR = GMEM_FIXED | GMEM_ZEROINIT + GHND = (GMEM_MOVEABLE | GMEM_ZEROINIT) + GPTR = (GMEM_FIXED | GMEM_ZEROINIT) ) // Ternary raster operations @@ -2638,6 +2389,10 @@ const ( DIB_RGB_COLORS = 0 ) +const ( + STANDARD_RIGHTS_REQUIRED = 0x000F +) + // Service Control Manager object specific access types const ( SC_MANAGER_CONNECT = 0x0001 @@ -2660,7 +2415,7 @@ const ( SERVICE_WIN32_SHARE_PROCESS = 0x00000020 SERVICE_WIN32 = SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS SERVICE_INTERACTIVE_PROCESS = 0x00000100 - SERVICE_TYPE_ALL = 1023 + SERVICE_TYPE_ALL = SERVICE_WIN32 | SERVICE_ADAPTER | SERVICE_DRIVER | SERVICE_INTERACTIVE_PROCESS ) // Service State -- for CurrentState @@ -2794,12 +2549,13 @@ const ( // enum-lite implementation for the following constant structure type DWM_SOURCE_FRAME_SAMPLING int32 -// Flags used by the DwmSetPresentParameters function to specify the frame -// sampling type +// TODO: need to verify this construction +// Flags used by the DwmSetPresentParameters function +// to specify the frame sampling type const ( - DWM_SOURCE_FRAME_SAMPLING_POINT = 0 - DWM_SOURCE_FRAME_SAMPLING_COVERAGE = 1 - DWM_SOURCE_FRAME_SAMPLING_LAST = 2 + 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 @@ -2815,25 +2571,27 @@ const ( // enum-lite implementation for the following constant structure type DWMFLIP3DWINDOWPOLICY int32 -// Flags used by the DwmSetWindowAttribute function to specify the Flip3D window -// policy +// TODO: need to verify this construction +// Flags used by the DwmSetWindowAttribute function +// to specify the Flip3D window policy const ( - DWMFLIP3D_DEFAULT = 0 - DWMFLIP3D_EXCLUDEBELOW = 1 - DWMFLIP3D_EXCLUDEABOVE = 2 - DWMFLIP3D_LAST = 3 + DWMFLIP3D_DEFAULT = iota + 1 + DWMFLIP3D_EXCLUDEBELOW + DWMFLIP3D_EXCLUDEABOVE + DWMFLIP3D_LAST ) // enum-lite implementation for the following constant structure type DWMNCRENDERINGPOLICY int32 -// Flags used by the DwmSetWindowAttribute function to specify the non-client -// area rendering policy +// TODO: need to verify this construction +// Flags used by the DwmSetWindowAttribute function +// to specify the non-client area rendering policy const ( - DWMNCRP_USEWINDOWSTYLE = 0 - DWMNCRP_DISABLED = 1 - DWMNCRP_ENABLED = 2 - DWMNCRP_LAST = 3 + DWMNCRP_USEWINDOWSTYLE = iota + 1 + DWMNCRP_DISABLED + DWMNCRP_ENABLED + DWMNCRP_LAST ) // enum-lite implementation for the following constant structure @@ -2844,39 +2602,32 @@ const ( 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 = 1 - DWMWA_NCRENDERING_POLICY = 2 - DWMWA_TRANSITIONS_FORCEDISABLED = 3 - DWMWA_ALLOW_NCPAINT = 4 - DWMWA_CAPTION_BUTTON_BOUNDS = 5 - DWMWA_NONCLIENT_RTL_LAYOUT = 6 - DWMWA_FORCE_ICONIC_REPRESENTATION = 7 - DWMWA_FLIP3D_POLICY = 8 - DWMWA_EXTENDED_FRAME_BOUNDS = 9 - DWMWA_HAS_ICONIC_BITMAP = 10 - DWMWA_DISALLOW_PEEK = 11 - DWMWA_EXCLUDED_FROM_PEEK = 12 - DWMWA_CLOAK = 13 - DWMWA_CLOAKED = 14 - DWMWA_FREEZE_REPRESENTATION = 15 - DWMWA_LAST = 16 -) - -const ( - DWM_CLOAKED_APP = 1 - DWM_CLOAKED_SHELL = 2 - DWM_CLOAKED_INHERITED = 4 + 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 @@ -3029,13 +2780,6 @@ const ( MOUSEEVENTF_XUP = 0x0100 ) -const ( - KEYEVENTF_EXTENDEDKEY = 0x0001 - KEYEVENTF_KEYUP = 0x0002 - KEYEVENTF_SCANCODE = 0x0008 - KEYEVENTF_UNICODE = 0x0004 -) - // Windows Hooks (WH_*) // http://msdn.microsoft.com/en-us/library/windows/desktop/ms644990(v=vs.85).aspx const ( @@ -3056,562 +2800,451 @@ const ( WH_SYSMSGFILTER = 6 ) -// Process Security and Access Rights -// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684880(v=vs.85).aspx +// ComboBox return values const ( - PROCESS_TERMINATE = 0x0001 - PROCESS_CREATE_THREAD = 0x0002 - PROCESS_SET_SESSIONID = 0x0004 - PROCESS_VM_OPERATION = 0x0008 - PROCESS_VM_READ = 0x0010 - PROCESS_VM_WRITE = 0x0020 - PROCESS_DUP_HANDLE = 0x0040 - PROCESS_CREATE_PROCESS = 0x0080 - PROCESS_SET_QUOTA = 0x0100 - PROCESS_SET_INFORMATION = 0x0200 - PROCESS_QUERY_INFORMATION = 0x0400 - PROCESS_SUSPEND_RESUME = 0x0800 - PROCESS_QUERY_LIMITED_INFORMATION = 0x1000 - PROCESS_SET_LIMITED_INFORMATION = 0x2000 + 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 ( - IMAGE_BITMAP = 0 - IMAGE_ICON = 1 - IMAGE_CURSOR = 2 + 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 ( - LR_DEFAULTCOLOR = 0x0000 - LR_MONOCHROME = 0x0001 - LR_COLOR = 0x0002 - LR_COPYRETURNORG = 0x0004 - LR_COPYDELETEORG = 0x0008 - LR_LOADFROMFILE = 0x0010 - LR_LOADTRANSPARENT = 0x0020 - LR_DEFAULTSIZE = 0x0040 - LR_VGACOLOR = 0x0080 - LR_LOADMAP3DCOLORS = 0x1000 - LR_CREATEDIBSECTION = 0x2000 - LR_COPYFROMRESOURCE = 0x4000 - LR_SHARED = 0x8000 + 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 ( - MF_BITMAP = 0x0004 - MF_CHECKED = 0x0008 - MF_DISABLED = 0x0002 - MF_ENABLED = 0x0000 - MF_GRAYED = 0x0001 - MF_MENUBARBREAK = 0x0020 - MF_MENUBREAK = 0x0040 - MF_OWNERDRAW = 0x0100 - MF_POPUP = 0x0010 - MF_SEPARATOR = 0x0800 - MF_STRING = 0x0000 - MF_UNCHECKED = 0x0000 - MF_BYCOMMAND = 0x0000 - MF_BYPOSITION = 0x0400 + 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 ( - RID_INPUT = 0x10000003 - RID_HEADER = 0x10000005 + TVIS_EX_FLAT = 0x0001 + TVIS_EX_DISABLED = 0x0002 + TVIS_EX_ALL = 0x0002 ) const ( - RIM_TYPEMOUSE = 0 - RIM_TYPEKEYBOARD = 1 - RIM_TYPEHID = 2 + 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 ( - RI_KEY_MAKE = 0 // key is down - RI_KEY_BREAK = 1 // key is up - RI_KEY_E0 = 2 // scan code has e0 prefix - RI_KEY_E1 = 4 // scan code has e1 prefix - RI_KEY_TERMSRV_SET_LED = 8 - RI_KEY_TERMSRV_SHADOW = 0x10 + 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 ( - MOUSE_MOVE_RELATIVE = 0 - MOUSE_MOVE_ABSOLUTE = 1 - MOUSE_VIRTUAL_DESKTOP = 0x02 - MOUSE_ATTRIBUTES_CHANGED = 0x04 - MOUSE_MOVE_NOCOALESCE = 0x08 + TCS_EX_FLATSEPARATORS = 0x00000001 + TCS_EX_REGISTERDROP = 0x00000002 ) const ( - RI_MOUSE_LEFT_BUTTON_DOWN = 0x0001 - RI_MOUSE_LEFT_BUTTON_UP = 0x0002 - RI_MOUSE_RIGHT_BUTTON_DOWN = 0x0004 - RI_MOUSE_RIGHT_BUTTON_UP = 0x0008 - RI_MOUSE_MIDDLE_BUTTON_DOWN = 0x0010 - RI_MOUSE_MIDDLE_BUTTON_UP = 0x0020 - RI_MOUSE_BUTTON_1_DOWN = RI_MOUSE_LEFT_BUTTON_DOWN - RI_MOUSE_BUTTON_1_UP = RI_MOUSE_LEFT_BUTTON_UP - RI_MOUSE_BUTTON_2_DOWN = RI_MOUSE_RIGHT_BUTTON_DOWN - RI_MOUSE_BUTTON_2_UP = RI_MOUSE_RIGHT_BUTTON_UP - RI_MOUSE_BUTTON_3_DOWN = RI_MOUSE_MIDDLE_BUTTON_DOWN - RI_MOUSE_BUTTON_3_UP = RI_MOUSE_MIDDLE_BUTTON_UP - RI_MOUSE_BUTTON_4_DOWN = 0x0040 // XBUTTON1 changed to down - RI_MOUSE_BUTTON_4_UP = 0x0080 // XBUTTON1 changed to up - RI_MOUSE_BUTTON_5_DOWN = 0x100 // XBUTTON2 changed to down - RI_MOUSE_BUTTON_5_UP = 0x0200 // XBUTTON2 changed to up - RI_MOUSE_WHEEL = 0x0400 + 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 ( - RIDEV_REMOVE = 0x00000001 - RIDEV_EXCLUDE = 0x00000010 - RIDEV_PAGEONLY = 0x00000020 - RIDEV_NOLEGACY = 0x00000030 - RIDEV_INPUTSINK = 0x00000100 - RIDEV_CAPTUREMOUSE = 0x00000200 - RIDEV_NOHOTKEYS = 0x00000200 - RIDEV_APPKEYS = 0x00000400 - RIDEV_EXINPUTSINK = 0x00001000 - RIDEV_DEVNOTIFY = 0x00002000 -) - -// GDI+ constants -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 -) - -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}} + TCIF_TEXT = 0x0001 + TCIF_IMAGE = 0x0002 + TCIF_RTLREADING = 0x0004 + TCIF_PARAM = 0x0008 + TCIF_STATE = 0x0010 ) const ( - VS_FF_DEBUG = 0x00000001 - VS_FF_INFOINFERRED = 0x00000010 - VS_FF_PATCHED = 0x00000004 - VS_FF_PRERELEASE = 0x00000002 - VS_FF_PRIVATEBUILD = 0x00000008 - VS_FF_SPECIALBUILD = 0x00000020 - - VOS_DOS = 0x00010000 - VOS_NT = 0x00040000 - VOS__WINDOWS16 = 0x00000001 - VOS__WINDOWS32 = 0x00000004 - VOS_OS216 = 0x00020000 - VOS_OS232 = 0x00030000 - VOS__PM16 = 0x00000002 - VOS__PM32 = 0x00000003 - VOS_UNKNOWN = 0x00000000 - - VOS_DOS_WINDOWS16 = 0x00010001 - VOS_DOS_WINDOWS32 = 0x00010004 - VOS_NT_WINDOWS32 = 0x00040004 - VOS_OS216_PM16 = 0x00020002 - VOS_OS232_PM32 = 0x00030003 - - VFT_APP = 0x00000001 - VFT_DLL = 0x00000002 - VFT_DRV = 0x00000003 - VFT_FONT = 0x00000004 - VFT_STATIC_LIB = 0x00000007 - VFT_UNKNOWN = 0x00000000 - VFT_VXD = 0x00000005 - - VFT2_DRV_COMM = 0x0000000A - VFT2_DRV_DISPLAY = 0x00000004 - VFT2_DRV_INSTALLABLE = 0x00000008 - VFT2_DRV_KEYBOARD = 0x00000002 - VFT2_DRV_LANGUAGE = 0x00000003 - VFT2_DRV_MOUSE = 0x00000005 - VFT2_DRV_NETWORK = 0x00000006 - VFT2_DRV_PRINTER = 0x00000001 - VFT2_DRV_SOUND = 0x00000009 - VFT2_DRV_SYSTEM = 0x00000007 - VFT2_DRV_VERSIONED_PRINTER = 0x0000000C - VFT2_UNKNOWN = 0x00000000 - - VFT2_FONT_RASTER = 0x00000001 - VFT2_FONT_TRUETYPE = 0x00000003 - VFT2_FONT_VECTOR = 0x00000002 + TCIS_BUTTONPRESSED = 0x0001 + TCIS_HIGHLIGHTED = 0x0002 ) const ( - SND_SYNC = 0 - SND_ASYNC = 1 - SND_NODEFAULT = 2 - SND_MEMORY = 4 - SND_LOOP = 8 - SND_NOSTOP = 16 - SND_NOWAIT = 0x2000 - SND_ALIAS = 0x10000 - SND_ALIAS_ID = 0x110000 - SND_FILENAME = 0x20000 - SND_RESOURCE = 0x40004 - SND_PURGE = 0x40 - SND_APPLICATION = 0x80 - SND_ALIAS_START = 0 + TCHT_NOWHERE = 0x0001 + TCHT_ONITEMICON = 0x0002 + TCHT_ONITEMLABEL = 0x0004 + TCHT_ONITEM = TCHT_ONITEMICON | TCHT_ONITEMLABEL ) const ( - BLACKONWHITE = 1 - WHITEONBLACK = 2 - COLORONCOLOR = 3 - HALFTONE = 4 - STRETCH_ANDSCANS = BLACKONWHITE - STRETCH_DELETESCANS = COLORONCOLOR - STRETCH_HALFTONE = HALFTONE - STRETCH_ORSCANS = WHITEONBLACK + 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 ) -const ( - GW_HWNDFIRST = 0 - GW_HWNDLAST = 1 - GW_HWNDNEXT = 2 - GW_HWNDPREV = 3 - GW_OWNER = 4 - GW_CHILD = 5 - GW_ENABLEDPOPUP = 6 -) +type TCITEMHEADER struct { + Mask uint32 + LpReserved1 uint32 + LpReserved2 uint32 + PszText *uint16 + CchTextMax int32 + IImage int32 +} -// ACCEL behavior flags -const ( - FVIRTKEY = 0x01 - FNOINVERT = 0x02 - FSHIFT = 0x04 - FCONTROL = 0x08 - FALT = 0x10 -) +type TCITEM struct { + Mask uint32 + DwState uint32 + DwStateMask uint32 + PszText *uint16 + CchTextMax int32 + IImage int32 + LParam uintptr +} -// Mouse key flags -const ( - MK_LBUTTON = 0x0001 - MK_RBUTTON = 0x0002 - MK_SHIFT = 0x0004 - MK_CONTROL = 0x0008 - MK_MBUTTON = 0x0010 - MK_XBUTTON1 = 0x0020 - MK_XBUTTON2 = 0x0040 -) +type TCHITTESTINFO struct { + Pt POINT + flags uint32 +} -const UPDOWN_CLASS = "msctls_updown32" +type NMTCKEYDOWN struct { + Hdr NMHDR + WVKey uint16 + Flags uint32 +} -const ( - UDS_WRAP = 1 - UDS_SETBUDDYINT = 2 - UDS_ALIGNRIGHT = 4 - UDS_ALIGNLEFT = 8 - UDS_AUTOBUDDY = 16 - UDS_ARROWKEYS = 32 - UDS_HORZ = 64 - UDS_NOTHOUSANDS = 128 -) - -const ( - UDN_FIRST = 4294966575 - UDN_LAST = 4294966567 - UDN_DELTAPOS = UDN_FIRST - 1 -) - -const ( - UDM_SETRANGE = WM_USER + 101 - UDM_GETRANGE = WM_USER + 102 - UDM_SETPOS = WM_USER + 103 - UDM_GETPOS = WM_USER + 104 - UDM_SETBUDDY = WM_USER + 105 - UDM_GETBUDDY = WM_USER + 106 - UDM_SETACCEL = WM_USER + 107 - UDM_GETACCEL = WM_USER + 108 - UDM_SETBASE = WM_USER + 109 - UDM_GETBASE = WM_USER + 110 - UDM_SETRANGE32 = WM_USER + 111 - UDM_GETRANGE32 = WM_USER + 112 - UDM_SETPOS32 = WM_USER + 113 - UDM_GETPOS32 = WM_USER + 114 - UDM_SETUNICODEFORMAT = 0x2005 - UDM_GETUNICODEFORMAT = 0x2006 -) - -const ( - GCL_CBCLSEXTRA = -20 - GCL_CBWNDEXTRA = -18 - GCLP_HBRBACKGROUND = -10 - GCLP_HCURSOR = -12 - GCLP_HICON = -14 - GCLP_HICONSM = -34 - GCLP_HMODULE = -16 - GCLP_MENUNAME = -8 - GCL_STYLE = -26 - GCLP_WNDPROC = -24 -) - -// system commands -const ( - SC_CLOSE = 0xF060 - SC_CONTEXTHELP = 0xF180 - SC_DEFAULT = 0xF160 - SC_HOTKEY = 0xF150 - SC_HSCROLL = 0xF080 - SCF_ISSECURE = 0x0001 - SC_KEYMENU = 0xF100 - SC_MAXIMIZE = 0xF030 - SC_MINIMIZE = 0xF020 - SC_MONITORPOWER = 0xF170 - SC_MOUSEMENU = 0xF090 - SC_MOVE = 0xF010 - SC_NEXTWINDOW = 0xF040 - SC_PREVWINDOW = 0xF050 - SC_RESTORE = 0xF120 - SC_SCREENSAVE = 0xF140 - SC_SIZE = 0xF000 - SC_TASKLIST = 0xF130 - SC_VSCROLL = 0xF070 -) - -const AC_SRC_OVER = 0 - -const AC_SRC_ALPHA = 1 - -const ( - RESOURCE_CONNECTED = 0x00000001 - RESOURCE_GLOBALNET = 0x00000002 - RESOURCE_REMEMBERED = 0x00000003 - RESOURCE_RECENT = 0x00000004 - RESOURCE_CONTEXT = 0x00000005 -) - -const ( - RESOURCETYPE_ANY = 0x00000000 - RESOURCETYPE_DISK = 0x00000001 - RESOURCETYPE_PRINT = 0x00000002 - RESOURCETYPE_RESERVED = 0x00000008 - RESOURCETYPE_UNKNOWN = 0xFFFFFFFF -) - -const ( - RESOURCEUSAGE_CONNECTABLE = 0x00000001 - RESOURCEUSAGE_CONTAINER = 0x00000002 - RESOURCEUSAGE_NOLOCALDEVICE = 0x00000004 - RESOURCEUSAGE_SIBLING = 0x00000008 - RESOURCEUSAGE_ATTACHED = 0x00000010 - RESOURCEUSAGE_ALL = RESOURCEUSAGE_CONNECTABLE | RESOURCEUSAGE_CONTAINER | RESOURCEUSAGE_ATTACHED - RESOURCEUSAGE_RESERVED = 0x80000000 -) - -const ( - RESOURCEDISPLAYTYPE_GENERIC = 0x00000000 - RESOURCEDISPLAYTYPE_DOMAIN = 0x00000001 - RESOURCEDISPLAYTYPE_SERVER = 0x00000002 - RESOURCEDISPLAYTYPE_SHARE = 0x00000003 - RESOURCEDISPLAYTYPE_FILE = 0x00000004 - RESOURCEDISPLAYTYPE_GROUP = 0x00000005 - RESOURCEDISPLAYTYPE_NETWORK = 0x00000006 - RESOURCEDISPLAYTYPE_ROOT = 0x00000007 - RESOURCEDISPLAYTYPE_SHAREADMIN = 0x00000008 - RESOURCEDISPLAYTYPE_DIRECTORY = 0x00000009 - RESOURCEDISPLAYTYPE_TREE = 0x0000000A - RESOURCEDISPLAYTYPE_NDSCONTAINER = 0x0000000B -) - -const NETPROPERTY_PERSISTENT = 1 - -const ( - CONNECT_UPDATE_PROFILE = 0x00000001 - CONNECT_UPDATE_RECENT = 0x00000002 - CONNECT_TEMPORARY = 0x00000004 - CONNECT_INTERACTIVE = 0x00000008 - CONNECT_PROMPT = 0x00000010 - CONNECT_NEED_DRIVE = 0x00000020 - CONNECT_REFCOUNT = 0x00000040 - CONNECT_REDIRECT = 0x00000080 - CONNECT_LOCALDRIVE = 0x00000100 - CONNECT_CURRENT_MEDIA = 0x00000200 - CONNECT_DEFERRED = 0x00000400 - CONNECT_RESERVED = 0xFF000000 - CONNECT_COMMANDLINE = 0x00000800 - CONNECT_CMD_SAVECRED = 0x00001000 -) - -const PW_CLIENTONLY = 1 - -const ( - SEM_FAILCRITICALERRORS = 0x0001 - SEM_NOALIGNMENTFAULTEXCEPT = 0x0004 - SEM_NOGPFAULTERRORBOX = 0x0002 - SEM_NOOPENFILEERRORBOX = 0x8000 -) - -const ( - GENERIC_ALL = 0x10000000 - GENERIC_EXECUTE = 0x20000000 - GENERIC_WRITE = 0x40000000 - GENERIC_READ = 0x80000000 -) - -const SYNCHRONIZE = 0x100000 - -const ( - STANDARD_RIGHTS_REQUIRED = 0xF0000 - STANDARD_RIGHTS_READ = 0x20000 - STANDARD_RIGHTS_WRITE = 0x20000 - STANDARD_RIGHTS_EXECUTE = 0x20000 - STANDARD_RIGHTS_ALL = 0x1F0000 - SPECIFIC_RIGHTS_ALL = 0xFFFF - ACCESS_SYSTEM_SECURITY = 0x1000000 -) - -const ( - FILE_READ_DATA = 1 - FILE_LIST_DIRECTORY = 1 - FILE_WRITE_DATA = 2 - FILE_ADD_FILE = 2 - FILE_APPEND_DATA = 4 - FILE_ADD_SUBDIRECTORY = 4 - FILE_CREATE_PIPE_INSTANCE = 4 - FILE_READ_EA = 8 - FILE_READ_PROPERTIES = 8 - FILE_WRITE_EA = 16 - FILE_WRITE_PROPERTIES = 16 - FILE_EXECUTE = 32 - FILE_TRAVERSE = 32 - FILE_DELETE_CHILD = 64 - FILE_READ_ATTRIBUTES = 128 - FILE_WRITE_ATTRIBUTES = 256 - FILE_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF - FILE_GENERIC_READ = STANDARD_RIGHTS_READ | FILE_READ_DATA | FILE_READ_ATTRIBUTES | FILE_READ_EA | SYNCHRONIZE - FILE_GENERIC_WRITE = STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_APPEND_DATA | SYNCHRONIZE - FILE_GENERIC_EXECUTE = STANDARD_RIGHTS_EXECUTE | FILE_READ_ATTRIBUTES | FILE_EXECUTE | SYNCHRONIZE - FILE_SHARE_READ = 1 - FILE_SHARE_WRITE = 2 - FILE_SHARE_DELETE = 4 - FILE_ATTRIBUTE_READONLY = 1 - FILE_ATTRIBUTE_HIDDEN = 2 - FILE_ATTRIBUTE_SYSTEM = 4 - FILE_ATTRIBUTE_DIRECTORY = 16 - FILE_ATTRIBUTE_ARCHIVE = 32 - FILE_ATTRIBUTE_ENCRYPTED = 16384 - FILE_ATTRIBUTE_NORMAL = 128 - FILE_ATTRIBUTE_TEMPORARY = 256 - FILE_ATTRIBUTE_SPARSE_FILE = 512 - FILE_ATTRIBUTE_REPARSE_POINT = 1024 - FILE_ATTRIBUTE_COMPRESSED = 2048 - FILE_ATTRIBUTE_OFFLINE = 0x1000 - FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x2000 - FILE_NOTIFY_CHANGE_FILE_NAME = 1 - FILE_NOTIFY_CHANGE_DIR_NAME = 2 - FILE_NOTIFY_CHANGE_ATTRIBUTES = 4 - FILE_NOTIFY_CHANGE_SIZE = 8 - FILE_NOTIFY_CHANGE_LAST_WRITE = 16 - FILE_NOTIFY_CHANGE_LAST_ACCESS = 32 - FILE_NOTIFY_CHANGE_CREATION = 64 - FILE_NOTIFY_CHANGE_SECURITY = 256 - FILE_CASE_SENSITIVE_SEARCH = 1 - FILE_CASE_PRESERVED_NAMES = 2 - FILE_UNICODE_ON_DISK = 4 - FILE_PERSISTENT_ACLS = 8 - FILE_FILE_COMPRESSION = 16 - FILE_VOLUME_QUOTAS = 32 - FILE_SUPPORTS_SPARSE_FILES = 64 - FILE_SUPPORTS_REPARSE_POINTS = 128 -) - -const ( - CREATE_NEW = 1 - CREATE_ALWAYS = 2 - OPEN_EXISTING = 3 - OPEN_ALWAYS = 4 - TRUNCATE_EXISTING = 5 -) - -const ( - SECURITY_CONTEXT_TRACKING = 0x00040000 - SECURITY_EFFECTIVE_ONLY = 0x00080000 - SECURITY_SQOS_PRESENT = 0x00100000 - SECURITY_VALID_SQOS_FLAGS = 0x001F0000 -) - -const INVALID_HANDLE_VALUE = ^HANDLE(0) - -// STORAGE_BUS_TYPE values -const ( - BusTypeUnknown = 0 - BusTypeScsi = 1 - BusTypeAtapi = 2 - BusTypeAta = 3 - BusType1394 = 4 - BusTypeSsa = 5 - BusTypeFibre = 6 - BusTypeUsb = 7 - BusTypeRAID = 8 - BusTypeiScsi = 9 - BusTypeSas = 10 - BusTypeSata = 11 - BusTypeSd = 12 - BusTypeMmc = 13 - BusTypeVirtual = 14 - BusTypeFileBackedVirtual = 15 - BusTypeSpaces = 16 - BusTypeNvme = 17 - BusTypeMax = 20 - BusTypeMaxReserved = 0x7F -) - -// STORAGE_QUERY_TYPE values -const ( - PropertyStandardQuery = 0 - PropertyExistsQuery = 1 - PropertyMaskQuery = 2 - PropertyQueryMaxDefined = 3 -) - -// STORAGE_PROPERTY_ID values -const ( - StorageDeviceProperty = 0 - StorageAdapterProperty = 1 - StorageDeviceIdProperty = 2 - StorageDeviceUniqueIdProperty = 3 - StorageDeviceWriteCacheProperty = 4 - StorageMiniportProperty = 5 - StorageAccessAlignmentProperty = 6 - StorageDeviceSeekPenaltyProperty = 7 - StorageDeviceTrimProperty = 8 - StorageDeviceWriteAggregationProperty = 9 - StorageDeviceDeviceTelemetryProperty = 10 - StorageDeviceLBProvisioningProperty = 11 - StorageDevicePowerProperty = 12 - StorageDeviceCopyOffloadProperty = 13 - StorageDeviceResiliencyProperty = 14 - StorageDeviceMediumProductType = 15 -) - -// STREAM_INFO_LEVELS -const ( - FindStreamInfoStandard = 0 -) +// Menu support constants +// Constants for MENUITEMINFO.fMask const ( MIIM_STATE = 1 MIIM_ID = 2 @@ -3624,6 +3257,7 @@ const ( MIIM_FTYPE = 256 ) +// Constants for MENUITEMINFO.fType const ( MFT_BITMAP = 4 MFT_MENUBARBREAK = 32 @@ -3636,6 +3270,7 @@ const ( MFT_STRING = 0 ) +// Constants for MENUITEMINFO.fState const ( MFS_CHECKED = 8 MFS_DEFAULT = 4096 @@ -3647,1229 +3282,259 @@ const ( MFS_UNHILITE = 0 ) +// Constants for MENUITEMINFO.hbmp* const ( - // DEVICE_NOTIFY_WINDOW_HANDLE - // Notifications are sent using WM_POWERBROADCAST messages with a wParam - // parameter of PBT_POWERSETTINGCHANGE. - DEVICE_NOTIFY_WINDOW_HANDLE = 0 - - // DEVICE_NOTIFY_SERVICE_HANDLE - // Notifications are sent to the HandlerEx callback function with a - // dwControl parameter of SERVICE_CONTROL_POWEREVENT and a dwEventType of - // PBT_POWERSETTINGCHANGE. - DEVICE_NOTIFY_SERVICE_HANDLE = 1 + 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 ) -// Power setting GUIDs identify power change events. This topic lists power -// setting GUIDs for notifications that are most useful to applications. An -// application should register for each power change event that might impact its -// behavior. Notification is sent each time a setting changes, through -// WM_POWERBROADCAST. -var ( - // GUID_ACDC_POWER_SOURCE - // - // The system power source has changed. The Data member is a uint32 with - // values from the SYSTEM_POWER_CONDITION enumeration that indicates the - // current power source. - // - // PoAc (0) - The computer is powered by an AC power source (or similar, - // such as a laptop powered by a 12V automotive adapter). - // - // PoDc (1) - The computer is powered by an onboard battery power source. - // - // PoHot (2) - The computer is powered by a short-term power source such as - // a UPS device. - GUID_ACDC_POWER_SOURCE = &GUID{0x5d3e9a59, 0xe9D5, 0x4b00, [8]byte{0xa6, 0xbd, 0xff, 0x34, 0xff, 0x51, 0x65, 0x48}} +// MENUINFO mask constants +const ( + MIM_APPLYTOSUBMENUS = 0x80000000 + MIM_BACKGROUND = 0x00000002 + MIM_HELPID = 0x00000004 + MIM_MAXHEIGHT = 0x00000001 + MIM_MENUDATA = 0x00000008 + MIM_STYLE = 0x00000010 +) - // GUID_BATTERY_PERCENTAGE_REMAINING - // - // The remaining battery capacity has changed. The granularity varies from - // system to system but the finest granularity is 1 percent. The Data member - // is a uint32 that indicates the current battery capacity remaining as a - // percentage from 0 through 100. - GUID_BATTERY_PERCENTAGE_REMAINING = &GUID{0xa7ad8041, 0xb45a, 0x4cae, [8]byte{0x87, 0xa3, 0xee, 0xcb, 0xb4, 0x68, 0xa9, 0xe1}} - - // GUID_CONSOLE_DISPLAY_STATE - // - // The current monitor's display state has changed. - // - // Windows 7, Windows Server 2008 R2, Windows Vista and Windows Server 2008: - // This notification is available starting with Windows 8 and Windows Server - // 2012. - // - // The Data member is a uint32 with one of the following values. - // - // 0x0 - The display is off. - // - // 0x1 - The display is on. - // - // 0x2 - The display is dimmed. - GUID_CONSOLE_DISPLAY_STATE = &GUID{0x6fe69556, 0x704a, 0x47a0, [8]byte{0x8f, 0x24, 0xc2, 0x8d, 0x93, 0x6f, 0xda, 0x47}} - - // GUID_GLOBAL_USER_PRESENCE - // - // The user status associated with any session has changed. This represents - // the combined status of user presence across all local and remote sessions - // on the system. - // - // This notification is sent only to services and other programs running in - // session 0. User-mode applications should register for - // GUID_SESSION_USER_PRESENCE instead. - // - // Windows 7, Windows Server 2008 R2, Windows Vista and Windows Server 2008: - // This notification is available starting with Windows 8 and Windows Server - // 2012. - // - // The Data member is a DWORD with one of the following values. - // - // PowerUserPresent (0) - The user is present in any local or remote session - // on the system. - // - // PowerUserInactive (2) - The user is not present in any local or remote - // session on the system. - GUID_GLOBAL_USER_PRESENCE = &GUID{0x786E8A1D, 0xB427, 0x4344, [8]byte{0x92, 0x07, 0x09, 0xE7, 0x0B, 0xDC, 0xBE, 0xA9}} - - // GUID_IDLE_BACKGROUND_TASK - // - // The system is busy. This indicates that the system will not be moving - // into an idle state in the near future and that the current time is a good - // time for components to perform background or idle tasks that would - // otherwise prevent the computer from entering an idle state. - // - // There is no notification when the system is able to move into an idle - // state. The idle background task notification does not indicate whether a - // user is present at the computer. The Data member has no information and - // can be ignored. - GUID_IDLE_BACKGROUND_TASK = &GUID{0x515c31d8, 0xf734, 0x163d, [8]byte{0xa0, 0xfd, 0x11, 0xa0, 0x8c, 0x91, 0xe8, 0xf1}} - - // GUID_MONITOR_POWER_ON - // - // The primary system monitor has been powered on or off. This notification - // is useful for components that actively render content to the display - // device, such as media visualization. These applications should register - // for this notification and stop rendering graphics content when the - // monitor is off to reduce system power consumption. The Data member is a - // DWORD that indicates the current monitor state. - // - // 0x0 - The monitor is off. - // - // 0x1 - The monitor is on. - // - // Windows 8 and Windows Server 2012: New applications should use - // GUID_CONSOLE_DISPLAY_STATE instead of this notification. - GUID_MONITOR_POWER_ON = &GUID{0x02731015, 0x4510, 0x4526, [8]byte{0x99, 0xe6, 0xe5, 0xa1, 0x7e, 0xbd, 0x1a, 0xea}} - - // GUID_POWER_SAVING_STATUS - // - // Battery saver has been turned off or on in response to changing power - // conditions. This notification is useful for components that participate - // in energy conservation. These applications should register for this - // notification and save power when battery saver is on. - // - // The Data member is a DWORD that indicates battery saver state. - // - // 0x0 - Battery saver is off. - // - // 0x1 - Battery saver is on. Save energy where possible. - // - // For general information about battery saver, see battery saver (in the - // hardware component guidelines). - GUID_POWER_SAVING_STATUS = &GUID{0xE00958C0, 0xC213, 0x4ACE, [8]byte{0xAC, 0x77, 0xFE, 0xCC, 0xED, 0x2E, 0xEE, 0xA5}} - - // GUID_POWERSCHEME_PERSONALITY - // - // The active power scheme personality has changed. All power schemes map to - // one of these personalities. The Data member is a GUID that indicates the - // new active power scheme personality (GUID_MIN_POWER_SAVINGS, - // GUID_MAX_POWER_SAVINGS or GUID_TYPICAL_POWER_SAVINGS). - GUID_POWERSCHEME_PERSONALITY = &GUID{0x245d8541, 0x3943, 0x4422, [8]byte{0xb0, 0x25, 0x13, 0xA7, 0x84, 0xF6, 0x79, 0xB7}} - - // GUID_MIN_POWER_SAVINGS - // - // High Performance - The scheme is designed to deliver maximum performance - // at the expense of power consumption savings. - GUID_MIN_POWER_SAVINGS = &GUID{0x8c5e7fda, 0xe8bf, 0x4a96, [8]byte{0x9a, 0x85, 0xa6, 0xe2, 0x3a, 0x8c, 0x63, 0x5c}} - - // GUID_MAX_POWER_SAVINGS - // - // Power Saver - The scheme is designed to deliver maximum power consumption - // savings at the expense of system performance and responsiveness. - GUID_MAX_POWER_SAVINGS = &GUID{0xa1841308, 0x3541, 0x4fab, [8]byte{0xbc, 0x81, 0xf7, 0x15, 0x56, 0xf2, 0x0b, 0x4a}} - - // GUID_TYPICAL_POWER_SAVINGS - // - // Automatic - The scheme is designed to automatically balance performance - // and power consumption savings. - GUID_TYPICAL_POWER_SAVINGS = &GUID{0x381b4222, 0xf694, 0x41f0, [8]byte{0x96, 0x85, 0xff, 0x5b, 0xb2, 0x60, 0xdf, 0x2e}} - - // GUID_SESSION_DISPLAY_STATUS - // - // The display associated with the application's session has been powered on - // or off. - // - // Windows 7, Windows Server 2008 R2, Windows Vista and Windows Server 2008: - // This notification is available starting with Windows 8 and Windows Server - // 2012. - // - // This notification is sent only to user-mode applications. Services and - // other programs running in session 0 do not receive this notification. The - // Data member is a DWORD with one of the following values. - // - // 0x0 - The display is off. - // - // 0x1 - The display is on. - // - // 0x2 - The display is dimmed. - GUID_SESSION_DISPLAY_STATUS = &GUID{0x2B84C20E, 0xAD23, 0x4ddf, [8]byte{0x93, 0xDB, 0x05, 0xFF, 0xBD, 0x7E, 0xFC, 0xA5}} - - // GUID_SESSION_USER_PRESENCE - // - // The user status associated with the application's session has changed. - // - // Windows 7, Windows Server 2008 R2, Windows Vista and Windows Server 2008: - // This notification is available starting with Windows 8 and Windows Server - // 2012. - // - // This notification is sent only to user-mode applications running in an - // interactive session. Services and other programs running in session 0 - // should register for GUID_GLOBAL_USER_PRESENCE. The Data member is a DWORD - // with one of the following values. - // - // PowerUserPresent (0) - The user is providing input to the session. - // - // PowerUserInactive (2) - The user activity timeout has elapsed with no - // interaction from the user. - // - // NOTE All applications that run in an interactive user-mode session should - // use this setting. When kernel mode applications register for monitor - // status they should use GUID_CONSOLE_DISPLAY_STATUS instead. - GUID_SESSION_USER_PRESENCE = &GUID{0x3C0F4548, 0xC03F, 0x4c4d, [8]byte{0xB9, 0xF2, 0x23, 0x7E, 0xDE, 0x68, 0x63, 0x76}} - - // GUID_SYSTEM_AWAYMODE - // - // The system is entering or exiting away mode. The Data member is a DWORD - // that indicates the current away mode state. - // - // 0x0 - The computer is exiting away mode. - // - // 0x1 - The computer is entering away mode. - GUID_SYSTEM_AWAYMODE = &GUID{0x98a7f580, 0x01f7, 0x48aa, [8]byte{0x9c, 0x0f, 0x44, 0x35, 0x2c, 0x29, 0xe5, 0xC0}} - - // GUID_DEVINTERFACE_COMPORT is defined for COM ports. - GUID_DEVINTERFACE_COMPORT = &GUID{0x86E0D1E0, 0x8089, 0x11D0, [8]byte{0x9C, 0xE4, 0x08, 0x00, 0x3E, 0x30, 0x1F, 0x73}} +// MENUINFO style constants +const ( + MNS_AUTODISMISS = 0x10000000 + MNS_CHECKORBMP = 0x04000000 + MNS_DRAGDROP = 0x20000000 + MNS_MODELESS = 0x40000000 + MNS_NOCHECK = 0x80000000 + MNS_NOTIFYBYPOS = 0x08000000 ) const ( - // Power status has changed. - PBT_APMPOWERSTATUSCHANGE = 0x000A - - // Operation is resuming automatically from a low-power state. This message - // is sent every time the system resumes. - PBT_APMRESUMEAUTOMATIC = 0x0012 - - // Operation is resuming from a low-power state. This message is sent after - // PBT_APMRESUMEAUTOMATIC if the resume is triggered by user input, such as - // pressing a key. - PBT_APMRESUMESUSPEND = 0x0007 - - // System is suspending operation. - PBT_APMSUSPEND = 0x0004 - - // A power setting change event has been received. - PBT_POWERSETTINGCHANGE = 0x8013 + MF_BYCOMMAND = 0x00000000 + MF_BYPOSITION = 0x00000400 ) -// SYSTEM_POWER_CONDITION enumeration +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 ( - // PoAc: the computer is powered by an AC power source (or similar, such as - // a laptop powered by a 12V automotive adapter). - PoAc = 0 - // PoDc: the system is receiving power from built-in batteries. - PoDc = 1 - // PoHot: the computer is powered by a short-term power source such as a UPS - // device. - PoHot = 2 - // PoConditionMaximum: values equal to or greater than this value indicate - // an out of range value. - PoConditionMaximum = 3 + UIS_SET = 1 + UIS_CLEAR = 2 + UIS_INITIALIZE = 3 ) +// UI state constants const ( - CSIDL_DESKTOP = 0x0000 // - CSIDL_INTERNET = 0x0001 // Internet Explorer (icon on desktop) - CSIDL_PROGRAMS = 0x0002 // Start Menu\Programs - CSIDL_CONTROLS = 0x0003 // My Computer\Control Panel - CSIDL_PRINTERS = 0x0004 // My Computer\Printers - CSIDL_PERSONAL = 0x0005 // My Documents - CSIDL_FAVORITES = 0x0006 // \Favorites - CSIDL_STARTUP = 0x0007 // Start Menu\Programs\Startup - CSIDL_RECENT = 0x0008 // \Recent - CSIDL_SENDTO = 0x0009 // \SendTo - CSIDL_BITBUCKET = 0x000A // \Recycle Bin - CSIDL_STARTMENU = 0x000B // \Start Menu - CSIDL_MYDOCUMENTS = CSIDL_PERSONAL // Personal was just a silly name for My Documents - CSIDL_MYMUSIC = 0x000D // "My Music" folder - CSIDL_MYVIDEO = 0x000E // "My Videos" folder - CSIDL_DESKTOPDIRECTORY = 0x0010 // \Desktop - CSIDL_DRIVES = 0x0011 // My Computer - CSIDL_NETWORK = 0x0012 // Network Neighborhood (My Network Places) - CSIDL_NETHOOD = 0x0013 // \nethood - CSIDL_FONTS = 0x0014 // windows\fonts - CSIDL_TEMPLATES = 0x0015 - CSIDL_COMMON_STARTMENU = 0x0016 // All Users\Start Menu - CSIDL_COMMON_PROGRAMS = 0x0017 // All Users\Start Menu\Programs - CSIDL_COMMON_STARTUP = 0x0018 // All Users\Startup - CSIDL_COMMON_DESKTOPDIRECTORY = 0x0019 // All Users\Desktop - CSIDL_APPDATA = 0x001A // \Application Data - CSIDL_PRINTHOOD = 0x001B // \PrintHood - CSIDL_LOCAL_APPDATA = 0x001C // \Local Settings\Applicaiton Data (non roaming) - CSIDL_ALTSTARTUP = 0x001D // non localized startup - CSIDL_COMMON_ALTSTARTUP = 0x001E // non localized common startup - CSIDL_COMMON_FAVORITES = 0x001F - CSIDL_INTERNET_CACHE = 0x0020 - CSIDL_COOKIES = 0x0021 - CSIDL_HISTORY = 0x0022 - CSIDL_COMMON_APPDATA = 0x0023 // All Users\Application Data - CSIDL_WINDOWS = 0x0024 // GetWindowsDirectory() - CSIDL_SYSTEM = 0x0025 // GetSystemDirectory() - CSIDL_PROGRAM_FILES = 0x0026 // C:\Program Files - CSIDL_MYPICTURES = 0x0027 // C:\Program Files\My Pictures - CSIDL_PROFILE = 0x0028 // USERPROFILE - CSIDL_SYSTEMX86 = 0x0029 // x86 system directory on RISC - CSIDL_PROGRAM_FILESX86 = 0x002A // x86 C:\Program Files on RISC - CSIDL_PROGRAM_FILES_COMMON = 0x002B // C:\Program Files\Common - CSIDL_PROGRAM_FILES_COMMONX86 = 0x002C // x86 Program Files\Common on RISC - CSIDL_COMMON_TEMPLATES = 0x002D // All Users\Templates - CSIDL_COMMON_DOCUMENTS = 0x002E // All Users\Documents - CSIDL_COMMON_ADMINTOOLS = 0x002F // All Users\Start Menu\Programs\Administrative Tools - CSIDL_ADMINTOOLS = 0x0030 // \Start Menu\Programs\Administrative Tools - CSIDL_CONNECTIONS = 0x0031 // Network and Dial-up Connections - CSIDL_COMMON_MUSIC = 0x0035 // All Users\My Music - CSIDL_COMMON_PICTURES = 0x0036 // All Users\My Pictures - CSIDL_COMMON_VIDEO = 0x0037 // All Users\My Video - CSIDL_RESOURCES = 0x0038 // Resource Direcotry + UISF_HIDEFOCUS = 0x1 + UISF_HIDEACCEL = 0x2 + UISF_ACTIVE = 0x4 ) -// Drive types to use with GetDriveType. +// Virtual key codes const ( - DRIVE_UNKNOWN = 0 - DRIVE_NO_ROOT_DIR = 1 - DRIVE_REMOVABLE = 2 - DRIVE_FIXED = 3 - DRIVE_REMOTE = 4 - DRIVE_CDROM = 5 - DRIVE_RAMDISK = 6 + 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 ) -// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-osversioninfoexw +// ScrollBar constants const ( - VER_PLATFORM_WIN32_NT = 2 + SB_HORZ = 0 + SB_VERT = 1 + SB_CTL = 2 + SB_BOTH = 3 ) -// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-osversioninfoexw +// ScrollBar commands const ( - VER_NT_SERVER = 0x0000003 - VER_NT_DOMAIN_CONTROLLER = 0x0000002 - VER_NT_WORKSTATION = 0x0000001 + 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 ) -// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-osversioninfoexw +// [Get|Set]ScrollInfo mask constants const ( - VER_SUITE_BACKOFFICE = 0x00000004 - VER_SUITE_BLADE = 0x00000400 - VER_SUITE_COMPUTE_SERVER = 0x00004000 - VER_SUITE_DATACENTER = 0x00000080 - VER_SUITE_ENTERPRISE = 0x00000002 - VER_SUITE_EMBEDDEDNT = 0x00000040 - VER_SUITE_PERSONAL = 0x00000200 - VER_SUITE_SINGLEUSERTS = 0x00000100 - VER_SUITE_SMALLBUSINESS = 0x00000001 - VER_SUITE_SMALLBUSINESS_RESTRICTED = 0x00000020 - VER_SUITE_STORAGE_SERVER = 0x00002000 - VER_SUITE_TERMINAL = 0x00000010 - VER_SUITE_WH_SERVER = 0x00008000 - VER_SUITE_MULTIUSERTS = 0x00020000 -) - -// https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/ns-sysinfoapi-system_info -const ( - PROCESSOR_ARCHITECTURE_AMD64 = 9 - PROCESSOR_ARCHITECTURE_ARM = 5 - PROCESSOR_ARCHITECTURE_ARM64 = 12 - PROCESSOR_ARCHITECTURE_IA64 = 6 - PROCESSOR_ARCHITECTURE_INTEL = 0 - PROCESSOR_ARCHITECTURE_UNKNOWN = 0xFFFF -) - -// Flags for SetLayeredWindowAttributes. -const ( - LWA_COLORKEY = 0x1 - LWA_ALPHA = 0x2 -) - -// Flags for RedrawWindow. -const ( - RDW_INVALIDATE = 0x0001 - RDW_INTERNALPAINT = 0x0002 - RDW_ERASE = 0x0004 - RDW_VALIDATE = 0x0008 - RDW_NOINTERNALPAINT = 0x0010 - RDW_NOERASE = 0x0020 - RDW_NOCHILDREN = 0x0040 - RDW_ALLCHILDREN = 0x0080 - RDW_UPDATENOW = 0x0100 - RDW_ERASENOW = 0x0200 - RDW_FRAME = 0x0400 - RDW_NOFRAME = 0x0800 -) - -// DrawIconEx flags. -const ( - DI_COMPAT = 0x0004 - DI_DEFAULTSIZE = 0x0008 - DI_IMAGE = 0x0002 - DI_MASK = 0x0001 - DI_NOMIRROR = 0x0010 - DI_NORMAL = DI_IMAGE | DI_MASK -) - -// Track bar messages. -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 -) - -// Track bar styles. -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 -) - -// Track bar scroll notifications. -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 -) - -// Clip region types, e.g. returned from IntersectClipRect. -const ( - ERROR = 0 - NULLREGION = 1 - SIMPLEREGION = 2 - COMPLEXREGION = 3 -) - -// Modes for CombineRgn. -const ( - RGN_AND = 1 - RGN_OR = 2 - RGN_XOR = 3 - RGN_DIFF = 4 - RGN_COPY = 5 - RGN_MIN = RGN_AND - RGN_MAX = RGN_COPY -) - -const ( - DIGCF_PRESENT = 0x0002 - DIGCF_ALLCLASSES = 0x0004 - DIGCF_PROFILE = 0x0008 - DIGCF_DEVICEINTERFACE = 0x0010 - DIGCF_INTERFACEDEVICE = DIGCF_DEVICEINTERFACE -) - -const ( - DICS_FLAG_GLOBAL = 0x00000001 - DICS_FLAG_CONFIGSPECIFIC = 0x00000002 - DICS_FLAG_CONFIGGENERAL = 0x00000004 -) - -const ( - DIREG_DEV = 0x00000001 - DIREG_DRV = 0x00000002 - DIREG_BOTH = 0x00000004 -) - -const ( - ABM_NEW = 0x0 - ABM_REMOVE = 0x1 - ABM_QUERYPOS = 0x2 - ABM_SETPOS = 0x3 - ABM_GETSTATE = 0x4 - ABM_GETTASKBARPOS = 0x5 - ABM_ACTIVATE = 0x6 - ABM_GETAUTOHIDEBAR = 0x7 - ABM_SETAUTOHIDEBAR = 0x8 - ABM_WINDOWPOSCHANGED = 0x9 - ABM_SETSTATE = 0xA -) - -const ( - ACM_OPEN = 0x464 - ACM_PLAY = 0x465 - ACM_STOP = 0x466 -) - -const ( - CBEM_GETCOMBOCONTROL = 0x406 - CBEM_GETEDITCONTROL = 0x407 - CBEM_GETEXSTYLE = 0x409 - CBEM_GETEXTENDEDSTYLE = 0x409 - CBEM_GETIMAGELIST = 0x403 - CBEM_GETITEMA = 0x404 - CBEM_GETITEMW = 0x40D - CBEM_HASEDITCHANGED = 0x40A - CBEM_INSERTITEMA = 0x401 - CBEM_INSERTITEMW = 0x40B - CBEM_SETEXSTYLE = 0x408 - CBEM_SETEXTENDEDSTYLE = 0x40E - CBEM_SETIMAGELIST = 0x402 - CBEM_SETITEMA = 0x405 - CBEM_SETITEMW = 0x40C - CBEM_GETUNICODEFORMAT = 0x2006 - CBEM_SETUNICODEFORMAT = 0x2005 -) - -const ( - CDM_GETFILEPATH = 0x465 - CDM_GETFOLDERIDLIST = 0x467 - CDM_GETFOLDERPATH = 0x466 - CDM_GETSPEC = 0x464 - CDM_HIDECONTROL = 0x469 - CDM_SETCONTROLTEXT = 0x468 - CDM_SETDEFEXT = 0x46A -) - -const ( - DL_BEGINDRAG = 0x485 - DL_CANCELDRAG = 0x488 - DL_COPYCURSOR = 0x002 - DL_CURSORSET = 0x000 - DL_DRAGGING = 0x486 - DL_DROPPED = 0x487 - DL_MOVECURSOR = 0x003 - DL_STOPCURSOR = 0x001 -) - -const ( - DM_GETDEFID = 0x400 - DM_REPOSITION = 0x402 - DM_SETDEFID = 0x401 -) - -const ( - DTM_GETMCCOLOR = 0x1007 - DTM_GETMCFONT = 0x100A - DTM_GETMONTHCAL = 0x1008 - DTM_GETRANGE = 0x1003 - DTM_GETSYSTEMTIME = 0x1001 - DTM_SETFORMATA = 0x1005 - DTM_SETFORMATW = 0x1032 - DTM_SETMCCOLOR = 0x1006 - DTM_SETMCFONT = 0x1009 - DTM_SETRANGE = 0x1004 - DTM_SETSYSTEMTIME = 0x1002 -) - -const ( - HDM_CLEARFILTER = 0x1218 - HDM_CREATEDRAGIMAGE = 0x1210 - HDM_DELETEITEM = 0x1202 - HDM_EDITFILTER = 0x1217 - HDM_GETBITMAPMARGIN = 0x1215 - HDM_GETIMAGELIST = 0x1209 - HDM_GETITEM = 0x1203 - HDM_GETITEMCOUNT = 0x1200 - HDM_GETITEMRECT = 0x1207 - HDM_GETORDERARRAY = 0x1211 - HDM_GETUNICODEFORMAT = 0x2006 - HDM_HITTEST = 0x1206 - HDM_INSERTITEM = 0x1201 - HDM_LAYOUT = 0x1205 - HDM_ORDERTOINDEX = 0x120F - HDM_SETBITMAPMARGIN = 0x1214 - HDM_SETFILTERCHANGETIMEOUT = 0x1216 - HDM_SETHOTDIVIDER = 0x1213 - HDM_SETIMAGELIST = 0x1208 - HDM_SETITEM = 0x1204 - HDM_SETORDERARRAY = 0x1212 - HDM_SETUNICODEFORMAT = 0x2005 -) - -const ( - HKM_GETHOTKEY = 0x402 - HKM_SETHOTKEY = 0x401 - HKM_SETRULES = 0x403 -) - -const ( - IPM_CLEARADDRESS = 0x464 - IPM_GETADDRESS = 0x466 - IPM_ISBLANK = 0x469 - IPM_SETADDRESS = 0x465 - IPM_SETFOCUS = 0x468 - IPM_SETRANGE = 0x467 -) - -const ( - LBCB_CARETOFF = 0x01A4 - LBCB_CARETON = 0x01A3 -) - -const ( - MCM_GETCOLOR = 0x100B - MCM_GETCURSEL = 0x1001 - MCM_GETFIRSTDAYOFWEEK = 0x1010 - MCM_GETMAXSELCOUNT = 0x1003 - MCM_GETMAXTODAYWIDTH = 0x1015 - MCM_GETMINREQRECT = 0x1009 - MCM_GETMONTHDELTA = 0x1013 - MCM_GETMONTHRANGE = 0x1007 - MCM_GETRANGE = 0x1011 - MCM_GETSELRANGE = 0x1005 - MCM_GETTODAY = 0x100D - MCM_GETUNICODEFORMAT = 0x2006 - MCM_HITTEST = 0x100E - MCM_SETCOLOR = 0x100A - MCM_SETCURSEL = 0x1002 - MCM_SETDAYSTATE = 0x1008 - MCM_SETFIRSTDAYOFWEEK = 0x100F - MCM_SETMAXSELCOUNT = 0x1004 - MCM_SETMONTHDELTA = 0x1014 - MCM_SETRANGE = 0x1012 - MCM_SETSELRANGE = 0x1006 - MCM_SETTODAY = 0x100C - MCM_SETUNICODEFORMAT = 0x2005 -) - -const ( - MN_BUTTONDOWN = 0x01ED - MN_BUTTONUP = 0x01EF - MN_CANCELMENUS = 0x01E6 - MN_CLOSEHIERARCHY = 0x01E4 - MN_DBLCLK = 0x01F1 - MN_FINDMENUWINDOWFROMPOINT = 0x01EB - MN_GETHMENU = 0x01E1 - MN_GETPPOPUPMENU = 0x01EA - MN_MOUSEMOVE = 0x01EE - MN_OPENHIERARCHY = 0x01E3 - MN_SELECTFIRSTVALIDITEM = 0x01E7 - MN_SELECTITEM = 0x01E5 - MN_SETHMENU = 0x01E0 - MN_SETTIMERTOOPENHIERARCHY = 0x01F0 - MN_SHOWPOPUPWINDOW = 0x01EC - MN_SIZEWINDOW = 0x01E2 -) - -const ( - OCM_CHARTOITEM = 0x202F - OCM_COMMAND = 0x2111 - OCM_COMPAREITEM = 0x2039 - OCM_CTLCOLORBTN = 0x2135 - OCM_CTLCOLORDLG = 0x2136 - OCM_CTLCOLOREDIT = 0x2133 - OCM_CTLCOLORLISTBOX = 0x2134 - OCM_CTLCOLORMSGBOX = 0x2132 - OCM_CTLCOLORSCROLLBAR = 0x2137 - OCM_CTLCOLORSTATIC = 0x2138 - OCM_DELETEITEM = 0x202D - OCM_DRAWITEM = 0x202B - OCM_HSCROLL = 0x2114 - OCM_MEASUREITEM = 0x202C - OCM_NOTIFY = 0x204E - OCM_PARENTNOTIFY = 0x2210 - OCM_VKEYTOITEM = 0x202E - OCM_VSCROLL = 0x2115 -) - -const ( - PGM_FORWARDMOUSE = 0x1403 - PGM_GETBKCOLOR = 0x1405 - PGM_GETBORDER = 0x1407 - PGM_GETBUTTONSIZE = 0x140B - PGM_GETBUTTONSTATE = 0x140C - PGM_GETDROPTARGET = 0x2004 - PGM_GETPOS = 0x1409 - PGM_RECALCSIZE = 0x1402 - PGM_SETBKCOLOR = 0x1404 - PGM_SETBORDER = 0x1406 - PGM_SETBUTTONSIZE = 0x140A - PGM_SETCHILD = 0x1401 - PGM_SETPOS = 0x1408 -) - -const ( - PSM_ADDPAGE = 0x467 - PSM_APPLY = 0x46E - PSM_CANCELTOCLOSE = 0x46B - PSM_CHANGED = 0x468 - PSM_GETCURRENTPAGEHWND = 0x476 - PSM_GETRESULT = 0x487 - PSM_GETTABCONTROL = 0x474 - PSM_HWNDTOINDEX = 0x481 - PSM_IDTOINDEX = 0x485 - PSM_INDEXTOHWND = 0x482 - PSM_INDEXTOID = 0x486 - PSM_INDEXTOPAGE = 0x484 - PSM_INSERTPAGE = 0x477 - PSM_ISDIALOGMESSAGE = 0x475 - PSM_PAGETOINDEX = 0x483 - PSM_PRESSBUTTON = 0x471 - PSM_QUERYSIBLINGS = 0x46C - PSM_REBOOTSYSTEM = 0x46A - PSM_RECALCPAGESIZES = 0x488 - PSM_REMOVEPAGE = 0x466 - PSM_RESTARTWINDOWS = 0x469 - PSM_SETCURSEL = 0x465 - PSM_SETCURSELID = 0x472 - PSM_SETFINISHTEXT = 0x473 - PSM_SETHEADERSUBTITLEA = 0x47F - PSM_SETHEADERSUBTITLEW = 0x480 - PSM_SETHEADERTITLEA = 0x47D - PSM_SETHEADERTITLEW = 0x47E - PSM_SETTITLE = 0x46F - PSM_SETWIZBUTTONS = 0x470 - PSM_UNCHANGED = 0x46D -) - -const ( - RB_BEGINDRAG = 0x418 - RB_DELETEBAND = 0x402 - RB_DRAGMOVE = 0x41A - RB_ENDDRAG = 0x419 - RB_GETBANDBORDERS = 0x422 - RB_GETBANDCOUNT = 0x40C - RB_GETBANDINFO = 0x41D - RB_GETBANDINFOA = 0x41D - RB_GETBANDINFOW = 0x41C - RB_GETBARHEIGHT = 0x41B - RB_GETBARINFO = 0x403 - RB_GETBKCOLOR = 0x414 - RB_GETPALETTE = 0x426 - RB_GETRECT = 0x409 - RB_GETROWCOUNT = 0x40D - RB_GETROWHEIGHT = 0x40E - RB_GETTEXTCOLOR = 0x416 - RB_GETTOOLTIPS = 0x411 - RB_HITTEST = 0x408 - RB_IDTOINDEX = 0x410 - RB_INSERTBAND = 0x401 - RB_INSERTBANDA = 0x401 - RB_INSERTBANDW = 0x40A - RB_MAXIMIZEBAND = 0x41F - RB_MINIMIZEBAND = 0x41E - RB_MOVEBAND = 0x427 - RB_PUSHCHEVRON = 0x42B - RB_SETBANDINFO = 0x406 - RB_SETBANDINFOA = 0x406 - RB_SETBANDINFOW = 0x40B - RB_SETBARINFO = 0x404 - RB_SETBKCOLOR = 0x413 - RB_SETPALETTE = 0x425 - RB_SETPARENT = 0x407 - RB_SETTEXTCOLOR = 0x415 - RB_SETTOOLTIPS = 0x412 - RB_SHOWBAND = 0x423 - RB_SIZETORECT = 0x417 - RB_SETCOLORSCHEME = 0x2002 - RB_GETCOLORSCHEME = 0x2003 - RB_GETDROPTARGET = 0x2004 - RB_SETUNICODEFORMAT = 0x2005 - RB_GETUNICODEFORMAT = 0x2006 -) - -const ( - SBM_ENABLE_ARROWS = 0xE4 - SBM_GETPOS = 0xE1 - SBM_GETRANGE = 0xE3 - SBM_GETSCROLLINFO = 0xEA - SBM_SETPOS = 0xE0 - SBM_SETRANGE = 0xE2 - SBM_SETRANGEREDRAW = 0xE6 - SBM_SETSCROLLINFO = 0xE9 -) - -const ( - SB_GETBORDERS = 0x407 - SB_GETICON = 0x414 - SB_GETPARTS = 0x406 - SB_GETRECT = 0x40A - SB_GETTEXTA = 0x402 - SB_GETTEXTLENGTHA = 0x403 - SB_GETTEXTLENGTHW = 0x40C - SB_GETTEXTW = 0x40D - SB_GETTIPTEXTA = 0x412 - SB_GETTIPTEXTW = 0x413 - SB_ISSIMPLE = 0x40E - SB_SETICON = 0x40F - SB_SETMINHEIGHT = 0x408 - SB_SETPARTS = 0x404 - SB_SETTEXTA = 0x401 - SB_SETTEXTW = 0x40B - SB_SETTIPTEXTA = 0x410 - SB_SETTIPTEXTW = 0x411 - SB_SIMPLE = 0x409 - SB_SETBKCOLOR = 0x2001 - SB_SETUNICODEFORMAT = 0x2005 - SB_GETUNICODEFORMAT = 0x2006 -) - -const ( - STM_GETICON = 0x171 - STM_GETIMAGE = 0x173 - STM_SETICON = 0x170 - STM_SETIMAGE = 0x172 -) - -const ( - TB_ADDBITMAP = 0x413 - TB_ADDBUTTONS = 0x414 - TB_ADDSTRING = 0x41C - TB_AUTOSIZE = 0x421 - TB_BUTTONCOUNT = 0x418 - TB_BUTTONSTRUCTSIZE = 0x41E - TB_CHANGEBITMAP = 0x42B - TB_CHECKBUTTON = 0x402 - TB_COMMANDTOINDEX = 0x419 - TB_CUSTOMIZE = 0x41B - TB_DELETEBUTTON = 0x416 - TB_ENABLEBUTTON = 0x401 - TB_GETANCHORHIGHLIGHT = 0x44A - TB_GETBITMAP = 0x42C - TB_GETBITMAPFLAGS = 0x429 - TB_GETBUTTON = 0x417 - TB_GETBUTTONINFOA = 0x441 - TB_GETBUTTONINFOW = 0x43F - TB_GETBUTTONSIZE = 0x43A - TB_GETBUTTONTEXT = 0x42D - TB_GETCOLORSCHEME = 0x2003 - TB_GETDISABLEDIMAGELIST = 0x437 - TB_GETEXTENDEDSTYLE = 0x455 - TB_GETHOTIMAGELIST = 0x435 - TB_GETHOTITEM = 0x447 - TB_GETIMAGELIST = 0x431 - TB_GETINSERTMARK = 0x44F - TB_GETINSERTMARKCOLOR = 0x459 - TB_GETITEMRECT = 0x41D - TB_GETMAXSIZE = 0x453 - TB_GETOBJECT = 0x43E - TB_GETPADDING = 0x456 - TB_GETRECT = 0x433 - TB_GETROWS = 0x428 - TB_GETSTATE = 0x412 - TB_GETSTRING = 0x45C - TB_GETSTYLE = 0x439 - TB_GETTEXTROWS = 0x43D - TB_GETTOOLTIPS = 0x423 - TB_GETUNICODEFORMAT = 0x2006 - TB_HIDEBUTTON = 0x404 - TB_HITTEST = 0x445 - TB_INDETERMINATE = 0x405 - TB_INSERTBUTTON = 0x415 - TB_INSERTMARKHITTEST = 0x451 - TB_ISBUTTONCHECKED = 0x40A - TB_ISBUTTONENABLED = 0x409 - TB_ISBUTTONHIDDEN = 0x40C - TB_ISBUTTONHIGHLIGHTED = 0x40E - TB_ISBUTTONINDETERMINATE = 0x40D - TB_ISBUTTONPRESSED = 0x40B - TB_LOADIMAGES = 0x432 - TB_MAPACCELERATORA = 0x44E - TB_MAPACCELERATORW = 0x45A - TB_MARKBUTTON = 0x406 - TB_MOVEBUTTON = 0x452 - TB_PRESSBUTTON = 0x403 - TB_REPLACEBITMAP = 0x42E - TB_SAVERESTORE = 0x41A - TB_SETANCHORHIGHLIGHT = 0x449 - TB_SETBITMAPSIZE = 0x420 - TB_SETBUTTONINFOA = 0x442 - TB_SETBUTTONINFOW = 0x440 - TB_SETBUTTONSIZE = 0x41F - TB_SETBUTTONWIDTH = 0x43B - TB_SETCMDID = 0x42A - TB_SETCOLORSCHEME = 0x2002 - TB_SETDISABLEDIMAGELIST = 0x436 - TB_SETDRAWTEXTFLAGS = 0x446 - TB_SETEXTENDEDSTYLE = 0x454 - TB_SETHOTIMAGELIST = 0x434 - TB_SETHOTITEM = 0x448 - TB_SETIMAGELIST = 0x430 - TB_SETINDENT = 0x42F - TB_SETINSERTMARK = 0x450 - TB_SETINSERTMARKCOLOR = 0x458 - TB_SETMAXTEXTROWS = 0x43C - TB_SETPADDING = 0x457 - TB_SETPARENT = 0x425 - TB_SETROWS = 0x427 - TB_SETSTATE = 0x411 - TB_SETSTYLE = 0x438 - TB_SETTOOLTIPS = 0x424 - TB_SETUNICODEFORMAT = 0x2005 -) - -const ( - TCM_ADJUSTRECT = 0x1328 - TCM_DELETEALLITEMS = 0x1309 - TCM_DELETEITEM = 0x1308 - TCM_DESELECTALL = 0x1332 - TCM_GETCURFOCUS = 0x132F - TCM_GETCURSEL = 0x130B - TCM_GETEXTENDEDSTYLE = 0x1335 - TCM_GETIMAGELIST = 0x1302 - TCM_GETITEM = 0x1305 - TCM_GETITEMCOUNT = 0x1304 - TCM_GETITEMRECT = 0x130A - TCM_GETROWCOUNT = 0x132C - TCM_GETTOOLTIPS = 0x132D - TCM_GETUNICODEFORMAT = 0x2006 - TCM_HIGHLIGHTITEM = 0x1333 - TCM_HITTEST = 0x130D - TCM_INSERTITEM = 0x1307 - TCM_REMOVEIMAGE = 0x132A - TCM_SETCURFOCUS = 0x1330 - TCM_SETCURSEL = 0x130C - TCM_SETEXTENDEDSTYLE = 0x1334 - TCM_SETIMAGELIST = 0x1303 - TCM_SETITEM = 0x1306 - TCM_SETITEMEXTRA = 0x130E - TCM_SETITEMSIZE = 0x1329 - TCM_SETMINTABWIDTH = 0x1331 - TCM_SETPADDING = 0x132B - TCM_SETTOOLTIPS = 0x132E - TCM_SETUNICODEFORMAT = 0x2005 -) - -const ( - TVM_CREATEDRAGIMAGE = 0x1112 - TVM_DELETEITEM = 0x1101 - TVM_EDITLABEL = 0x110E - TVM_ENDEDITLABELNOW = 0x1116 - TVM_ENSUREVISIBLE = 0x1114 - TVM_EXPAND = 0x1102 - TVM_GETBKCOLOR = 0x111F - TVM_GETCOUNT = 0x1105 - TVM_GETEDITCONTROL = 0x110F - TVM_GETIMAGELIST = 0x1108 - TVM_GETINDENT = 0x1106 - TVM_GETINSERTMARKCOLOR = 0x1126 - TVM_GETISEARCHSTRING = 0x1117 - TVM_GETITEM = 0x110C - TVM_GETITEMHEIGHT = 0x111C - TVM_GETITEMRECT = 0x1104 - TVM_GETITEMSTATE = 0x1127 - TVM_GETLINECOLOR = 0x1129 - TVM_GETNEXTITEM = 0x110A - TVM_GETSCROLLTIME = 0x1122 - TVM_GETTEXTCOLOR = 0x1120 - TVM_GETTOOLTIPS = 0x1119 - TVM_GETUNICODEFORMAT = 0x2006 - TVM_GETVISIBLECOUNT = 0x1110 - TVM_HITTEST = 0x1111 - TVM_INSERTITEM = 0x1100 - TVM_SELECTITEM = 0x110B - TVM_SETBKCOLOR = 0x111D - TVM_SETIMAGELIST = 0x1109 - TVM_SETINDENT = 0x1107 - TVM_SETINSERTMARK = 0x111A - TVM_SETINSERTMARKCOLOR = 0x1125 - TVM_SETITEM = 0x110D - TVM_SETITEMHEIGHT = 0x111B - TVM_SETLINECOLOR = 0x1128 - TVM_SETSCROLLTIME = 0x1121 - TVM_SETTEXTCOLOR = 0x111E - TVM_SETTOOLTIPS = 0x1118 - TVM_SETUNICODEFORMAT = 0x2005 - TVM_SORTCHILDREN = 0x1113 - TVM_SORTCHILDRENCB = 0x1115 -) - -// PROCESS_DPI_AWARENESS -const ( - PROCESS_DPI_UNAWARE = 0 - PROCESS_SYSTEM_DPI_AWARE = 1 - PROCESS_PER_MONITOR_DPI_AWARE = 2 -) - -// WM_DEVICECHANGE WPARAM options -const ( - DBT_DEVNODES_CHANGED = 0x0007 - DBT_QUERYCHANGECONFIG = 0x0017 - DBT_CONFIGCHANGED = 0x0018 - DBT_CONFIGCHANGECANCELED = 0x0019 - DBT_DEVICEARRIVAL = 0x8000 - DBT_DEVICEQUERYREMOVE = 0x8001 - DBT_DEVICEQUERYREMOVEFAILED = 0x8002 - DBT_DEVICEREMOVEPENDING = 0x8003 - DBT_DEVICEREMOVECOMPLETE = 0x8004 - DBT_DEVICETYPESPECIFIC = 0x8005 - DBT_CUSTOMEVENT = 0x8006 - DBT_USERDEFINED = 0xFFFF -) - -const ( - SPI_GETACCESSTIMEOUT = 0x003C - SPI_GETAUDIODESCRIPTION = 0x0074 - SPI_GETCLIENTAREAANIMATION = 0x1042 - SPI_GETDISABLEOVERLAPPEDCONTENT = 0x1040 - SPI_GETFILTERKEYS = 0x0032 - SPI_GETFOCUSBORDERHEIGHT = 0x2010 - SPI_GETFOCUSBORDERWIDTH = 0x200E - SPI_GETHIGHCONTRAST = 0x0042 - SPI_GETLOGICALDPIOVERRIDE = 0x009E - SPI_GETMESSAGEDURATION = 0x2016 - SPI_GETMOUSECLICKLOCK = 0x101E - SPI_GETMOUSECLICKLOCKTIME = 0x2008 - SPI_GETMOUSEKEYS = 0x0036 - SPI_GETMOUSESONAR = 0x101C - SPI_GETMOUSEVANISH = 0x1020 - SPI_GETSCREENREADER = 0x0046 - SPI_GETSERIALKEYS = 0x003E - SPI_GETSHOWSOUNDS = 0x0038 - SPI_GETSOUNDSENTRY = 0x0040 - SPI_GETSTICKYKEYS = 0x003A - SPI_GETTOGGLEKEYS = 0x0034 - SPI_SETACCESSTIMEOUT = 0x003D - SPI_SETAUDIODESCRIPTION = 0x0075 - SPI_SETCLIENTAREAANIMATION = 0x1043 - SPI_SETDISABLEOVERLAPPEDCONTENT = 0x1041 - SPI_SETFILTERKEYS = 0x0033 - SPI_SETFOCUSBORDERHEIGHT = 0x2011 - SPI_SETFOCUSBORDERWIDTH = 0x200F - SPI_SETHIGHCONTRAST = 0x0043 - SPI_SETLOGICALDPIOVERRIDE = 0x009F - SPI_SETMESSAGEDURATION = 0x2017 - SPI_SETMOUSECLICKLOCK = 0x101F - SPI_SETMOUSECLICKLOCKTIME = 0x2009 - SPI_SETMOUSEKEYS = 0x0037 - SPI_SETMOUSESONAR = 0x101D - SPI_SETMOUSEVANISH = 0x1021 - SPI_SETSCREENREADER = 0x0047 - SPI_SETSERIALKEYS = 0x003F - SPI_SETSHOWSOUNDS = 0x0039 - SPI_SETSOUNDSENTRY = 0x0041 - SPI_SETSTICKYKEYS = 0x003B - SPI_SETTOGGLEKEYS = 0x0035 - SPI_GETCLEARTYPE = 0x1048 - SPI_GETDESKWALLPAPER = 0x0073 - SPI_GETDROPSHADOW = 0x1024 - SPI_GETFLATMENU = 0x1022 - SPI_GETFONTSMOOTHING = 0x004A - SPI_GETFONTSMOOTHINGCONTRAST = 0x200C - SPI_GETFONTSMOOTHINGORIENTATION = 0x2012 - SPI_GETFONTSMOOTHINGTYPE = 0x200A - SPI_GETWORKAREA = 0x0030 - SPI_SETCLEARTYPE = 0x1049 - SPI_SETCURSORS = 0x0057 - SPI_SETDESKPATTERN = 0x0015 - SPI_SETDESKWALLPAPER = 0x0014 - SPI_SETDROPSHADOW = 0x1025 - SPI_SETFLATMENU = 0x1023 - SPI_SETFONTSMOOTHING = 0x004B - SPI_SETFONTSMOOTHINGCONTRAST = 0x200D - SPI_SETFONTSMOOTHINGORIENTATION = 0x2013 - SPI_SETFONTSMOOTHINGTYPE = 0x200B - SPI_SETWORKAREA = 0x002F - SPI_GETICONMETRICS = 0x002D - SPI_GETICONTITLELOGFONT = 0x001F - SPI_GETICONTITLEWRAP = 0x0019 - SPI_ICONHORIZONTALSPACING = 0x000D - SPI_ICONVERTICALSPACING = 0x0018 - SPI_SETICONMETRICS = 0x002E - SPI_SETICONS = 0x0058 - SPI_SETICONTITLELOGFONT = 0x0022 - SPI_SETICONTITLEWRAP = 0x001A - SPI_GETBEEP = 0x0001 - SPI_GETBLOCKSENDINPUTRESETS = 0x1026 - SPI_GETCONTACTVISUALIZATION = 0x2018 - SPI_GETDEFAULTINPUTLANG = 0x0059 - SPI_GETGESTUREVISUALIZATION = 0x201A - SPI_GETKEYBOARDCUES = 0x100A - SPI_GETKEYBOARDDELAY = 0x0016 - SPI_GETKEYBOARDPREF = 0x0044 - SPI_GETKEYBOARDSPEED = 0x000A - SPI_GETMOUSE = 0x0003 - SPI_GETMOUSEHOVERHEIGHT = 0x0064 - SPI_GETMOUSEHOVERTIME = 0x0066 - SPI_GETMOUSEHOVERWIDTH = 0x0062 - SPI_GETMOUSESPEED = 0x0070 - SPI_GETMOUSETRAILS = 0x005E - SPI_GETMOUSEWHEELROUTING = 0x201C - SPI_GETPENVISUALIZATION = 0x201E - SPI_GETSNAPTODEFBUTTON = 0x005F - SPI_GETSYSTEMLANGUAGEBAR = 0x1050 - SPI_GETTHREADLOCALINPUTSETTINGS = 0x104E - SPI_GETWHEELSCROLLCHARS = 0x006C - SPI_GETWHEELSCROLLLINES = 0x0068 - SPI_SETBEEP = 0x0002 - SPI_SETBLOCKSENDINPUTRESETS = 0x1027 - SPI_SETCONTACTVISUALIZATION = 0x2019 - SPI_SETDEFAULTINPUTLANG = 0x005A - SPI_SETDOUBLECLICKTIME = 0x0020 - SPI_SETDOUBLECLKHEIGHT = 0x001E - SPI_SETDOUBLECLKWIDTH = 0x001D - SPI_SETGESTUREVISUALIZATION = 0x201B - SPI_SETKEYBOARDCUES = 0x100B - SPI_SETKEYBOARDDELAY = 0x0017 - SPI_SETKEYBOARDPREF = 0x0045 - SPI_SETKEYBOARDSPEED = 0x000B - SPI_SETLANGTOGGLE = 0x005B - SPI_SETMOUSE = 0x0004 - SPI_SETMOUSEBUTTONSWAP = 0x0021 - SPI_SETMOUSEHOVERHEIGHT = 0x0065 - SPI_SETMOUSEHOVERTIME = 0x0067 - SPI_SETMOUSEHOVERWIDTH = 0x0063 - SPI_SETMOUSESPEED = 0x0071 - SPI_SETMOUSETRAILS = 0x005D - SPI_SETMOUSEWHEELROUTING = 0x201D - SPI_SETPENVISUALIZATION = 0x201F - SPI_SETSNAPTODEFBUTTON = 0x0060 - SPI_SETSYSTEMLANGUAGEBAR = 0x1051 - SPI_SETTHREADLOCALINPUTSETTINGS = 0x104F - SPI_SETWHEELSCROLLCHARS = 0x006D - SPI_SETWHEELSCROLLLINES = 0x0069 - SPI_GETMENUDROPALIGNMENT = 0x001B - SPI_GETMENUFADE = 0x1012 - SPI_GETMENUSHOWDELAY = 0x006A - SPI_SETMENUDROPALIGNMENT = 0x001C - SPI_SETMENUFADE = 0x1013 - SPI_SETMENUSHOWDELAY = 0x006B - SPI_GETLOWPOWERACTIVE = 0x0053 - SPI_GETLOWPOWERTIMEOUT = 0x004F - SPI_GETPOWEROFFACTIVE = 0x0054 - SPI_GETPOWEROFFTIMEOUT = 0x0050 - SPI_SETLOWPOWERACTIVE = 0x0055 - SPI_SETLOWPOWERTIMEOUT = 0x0051 - SPI_SETPOWEROFFACTIVE = 0x0056 - SPI_SETPOWEROFFTIMEOUT = 0x0052 - SPI_GETSCREENSAVEACTIVE = 0x0010 - SPI_GETSCREENSAVERRUNNING = 0x0072 - SPI_GETSCREENSAVESECURE = 0x0076 - SPI_GETSCREENSAVETIMEOUT = 0x000E - SPI_SETSCREENSAVEACTIVE = 0x0011 - SPI_SETSCREENSAVESECURE = 0x0077 - SPI_SETSCREENSAVETIMEOUT = 0x000F - SPI_GETHUNGAPPTIMEOUT = 0x0078 - SPI_GETWAITTOKILLTIMEOUT = 0x007A - SPI_GETWAITTOKILLSERVICETIMEOUT = 0x007C - SPI_SETHUNGAPPTIMEOUT = 0x0079 - SPI_SETWAITTOKILLTIMEOUT = 0x007B - SPI_SETWAITTOKILLSERVICETIMEOUT = 0x007D - SPI_GETCOMBOBOXANIMATION = 0x1004 - SPI_GETCURSORSHADOW = 0x101A - SPI_GETGRADIENTCAPTIONS = 0x1008 - SPI_GETHOTTRACKING = 0x100E - SPI_GETLISTBOXSMOOTHSCROLLING = 0x1006 - SPI_GETMENUANIMATION = 0x1002 - SPI_GETMENUUNDERLINES = 0x100A - SPI_GETSELECTIONFADE = 0x1014 - SPI_GETTOOLTIPANIMATION = 0x1016 - SPI_GETTOOLTIPFADE = 0x1018 - SPI_GETUIEFFECTS = 0x103E - SPI_SETCOMBOBOXANIMATION = 0x1005 - SPI_SETCURSORSHADOW = 0x101B - SPI_SETGRADIENTCAPTIONS = 0x1009 - SPI_SETHOTTRACKING = 0x100F - SPI_SETLISTBOXSMOOTHSCROLLING = 0x1007 - SPI_SETMENUANIMATION = 0x1003 - SPI_SETMENUUNDERLINES = 0x100B - SPI_SETSELECTIONFADE = 0x1015 - SPI_SETTOOLTIPANIMATION = 0x1017 - SPI_SETTOOLTIPFADE = 0x1019 - SPI_SETUIEFFECTS = 0x103F - SPI_GETACTIVEWINDOWTRACKING = 0x1000 - SPI_GETACTIVEWNDTRKZORDER = 0x100C - SPI_GETACTIVEWNDTRKTIMEOUT = 0x2002 - SPI_GETANIMATION = 0x0048 - SPI_GETBORDER = 0x0005 - SPI_GETCARETWIDTH = 0x2006 - SPI_GETDOCKMOVING = 0x0090 - SPI_GETDRAGFROMMAXIMIZE = 0x008C - SPI_GETDRAGFULLWINDOWS = 0x0026 - SPI_GETFOREGROUNDFLASHCOUNT = 0x2004 - SPI_GETFOREGROUNDLOCKTIMEOUT = 0x2000 - SPI_GETMINIMIZEDMETRICS = 0x002B - SPI_GETMOUSEDOCKTHRESHOLD = 0x007E - SPI_GETMOUSEDRAGOUTTHRESHOLD = 0x0084 - SPI_GETMOUSESIDEMOVETHRESHOLD = 0x0088 - SPI_GETNONCLIENTMETRICS = 0x0029 - SPI_GETPENDOCKTHRESHOLD = 0x0080 - SPI_GETPENDRAGOUTTHRESHOLD = 0x0086 - SPI_GETPENSIDEMOVETHRESHOLD = 0x008A - SPI_GETSHOWIMEUI = 0x006E - SPI_GETSNAPSIZING = 0x008E - SPI_GETWINARRANGING = 0x0082 - SPI_SETACTIVEWINDOWTRACKING = 0x1001 - SPI_SETACTIVEWNDTRKZORDER = 0x100D - SPI_SETACTIVEWNDTRKTIMEOUT = 0x2003 - SPI_SETANIMATION = 0x0049 - SPI_SETBORDER = 0x0006 - SPI_SETCARETWIDTH = 0x2007 - SPI_SETDOCKMOVING = 0x0091 - SPI_SETDRAGFROMMAXIMIZE = 0x008D - SPI_SETDRAGFULLWINDOWS = 0x0025 - SPI_SETDRAGHEIGHT = 0x004D - SPI_SETDRAGWIDTH = 0x004C - SPI_SETFOREGROUNDFLASHCOUNT = 0x2005 - SPI_SETFOREGROUNDLOCKTIMEOUT = 0x2001 - SPI_SETMINIMIZEDMETRICS = 0x002C - SPI_SETMOUSEDOCKTHRESHOLD = 0x007F - SPI_SETMOUSEDRAGOUTTHRESHOLD = 0x0085 - SPI_SETMOUSESIDEMOVETHRESHOLD = 0x0089 - SPI_SETNONCLIENTMETRICS = 0x002A - SPI_SETPENDOCKTHRESHOLD = 0x0081 - SPI_SETPENDRAGOUTTHRESHOLD = 0x0087 - SPI_SETPENSIDEMOVETHRESHOLD = 0x008B - SPI_SETSHOWIMEUI = 0x006F - SPI_SETSNAPSIZING = 0x008F - SPI_SETWINARRANGING = 0x0083 -) - -const ( - SPIF_UPDATEINIFILE = 0x1 - SPIF_SENDCHANGE = 0x2 - SPIF_SENDWININICHANGE = SPIF_SENDCHANGE + 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 ) diff --git a/v3/internal/w32/consts.go b/v3/internal/w32/consts.go new file mode 100644 index 000000000..b9afe2794 --- /dev/null +++ b/v3/internal/w32/consts.go @@ -0,0 +1,83 @@ +//go:build windows + +package w32 + +import ( + "golang.org/x/sys/windows/registry" + "strconv" + "syscall" +) + +var ( + modwingdi = syscall.NewLazyDLL("gdi32.dll") + procCreateSolidBrush = modwingdi.NewProc("CreateSolidBrush") +) +var ( + kernel32 = syscall.NewLazyDLL("kernel32") + kernelGlobalAlloc = kernel32.NewProc("GlobalAlloc") + kernelGlobalFree = kernel32.NewProc("GlobalFree") + kernelGlobalLock = kernel32.NewProc("GlobalLock") + kernelGlobalUnlock = kernel32.NewProc("GlobalUnlock") + kernelLstrcpy = kernel32.NewProc("lstrcpyW") +) + +var windowsVersion, _ = getWindowsVersionInfo() + +func IsWindowsVersionAtLeast(major, minor, buildNumber int) bool { + return windowsVersion.Major >= major && + windowsVersion.Minor >= minor && + windowsVersion.Build >= buildNumber +} + +type WindowsVersionInfo struct { + Major int + Minor int + Build int + DisplayVersion string +} + +func (w *WindowsVersionInfo) IsWindowsVersionAtLeast(major, minor, buildNumber int) bool { + return w.Major >= major && w.Minor >= minor && w.Build >= buildNumber +} + +func getWindowsVersionInfo() (*WindowsVersionInfo, error) { + key, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE) + if err != nil { + return nil, err + } + + return &WindowsVersionInfo{ + Major: regDWORDKeyAsInt(key, "CurrentMajorVersionNumber"), + Minor: regDWORDKeyAsInt(key, "CurrentMinorVersionNumber"), + Build: regStringKeyAsInt(key, "CurrentBuildNumber"), + DisplayVersion: regKeyAsString(key, "DisplayVersion"), + }, nil +} + +func regDWORDKeyAsInt(key registry.Key, name string) int { + result, _, err := key.GetIntegerValue(name) + if err != nil { + return -1 + } + return int(result) +} + +func regStringKeyAsInt(key registry.Key, name string) int { + resultStr, _, err := key.GetStringValue(name) + if err != nil { + return -1 + } + result, err := strconv.Atoi(resultStr) + if err != nil { + return -1 + } + return result +} + +func regKeyAsString(key registry.Key, name string) string { + resultStr, _, err := key.GetStringValue(name) + if err != nil { + return "" + } + return resultStr +} diff --git a/v3/internal/w32/dwmapi.go b/v3/internal/w32/dwmapi.go new file mode 100644 index 000000000..4d3effeb4 --- /dev/null +++ b/v3/internal/w32/dwmapi.go @@ -0,0 +1,36 @@ +//go:build windows + +package w32 + +import ( + "syscall" + "unsafe" +) + +var ( + moddwmapi = syscall.NewLazyDLL("dwmapi.dll") + + procDwmSetWindowAttribute = moddwmapi.NewProc("DwmSetWindowAttribute") + procDwmExtendFrameIntoClientArea = moddwmapi.NewProc("DwmExtendFrameIntoClientArea") +) + +func DwmSetWindowAttribute(hwnd HWND, dwAttribute DWMWINDOWATTRIBUTE, pvAttribute LPCVOID, cbAttribute uint32) HRESULT { + ret, _, _ := procDwmSetWindowAttribute.Call( + hwnd, + uintptr(dwAttribute), + uintptr(pvAttribute), + uintptr(cbAttribute)) + return HRESULT(ret) +} + +func dwmExtendFrameIntoClientArea(hwnd uintptr, margins *MARGINS) error { + ret, _, _ := procDwmExtendFrameIntoClientArea.Call( + hwnd, + uintptr(unsafe.Pointer(margins))) + + if ret != 0 { + return syscall.GetLastError() + } + + return nil +} diff --git a/v3/internal/w32/functions.go b/v3/internal/w32/functions.go deleted file mode 100644 index d8ca0c43a..000000000 --- a/v3/internal/w32/functions.go +++ /dev/null @@ -1,4809 +0,0 @@ -package w32 - -import ( - "errors" - "fmt" - "strconv" - "syscall" - "unsafe" -) - -var ( - user32 = syscall.NewLazyDLL("user32.dll") - advapi32 = syscall.NewLazyDLL("advapi32.dll") - comctl32 = syscall.NewLazyDLL("comctl32.dll") - comdlg32 = syscall.NewLazyDLL("comdlg32.dll") - dwmapi = syscall.NewLazyDLL("dwmapi.dll") - gdi32 = syscall.NewLazyDLL("gdi32.dll") - kernel32 = syscall.NewLazyDLL("kernel32.dll") - ole32 = syscall.NewLazyDLL("ole32.dll") - oleaut32 = syscall.NewLazyDLL("oleaut32") - opengl32 = syscall.NewLazyDLL("opengl32.dll") - psapi = syscall.NewLazyDLL("psapi.dll") - shell32 = syscall.NewLazyDLL("shell32.dll") - gdiplus = syscall.NewLazyDLL("gdiplus.dll") - version = syscall.NewLazyDLL("version.dll") - winmm = syscall.NewLazyDLL("winmm.dll") - dxva2 = syscall.NewLazyDLL("dxva2.dll") - msimg32 = syscall.NewLazyDLL("msimg32.dll") - mpr = syscall.NewLazyDLL("mpr.dll") - ntoskrnl = syscall.NewLazyDLL("ntoskrnl.exe") - ntdll = syscall.NewLazyDLL("ntdll.dll") - setupAPI = syscall.NewLazyDLL("SetupAPI.dll") - shcore = syscall.NewLazyDLL("Shcore.dll") - - registerClassEx = user32.NewProc("RegisterClassExW") - unregisterClass = user32.NewProc("UnregisterClassW") - getClassInfoEx = user32.NewProc("GetClassInfoExW") - loadIcon = user32.NewProc("LoadIconW") - loadCursor = user32.NewProc("LoadCursorW") - showWindow = user32.NewProc("ShowWindow") - showWindowAsync = user32.NewProc("ShowWindowAsync") - updateWindow = user32.NewProc("UpdateWindow") - createWindow = user32.NewProc("CreateWindowW") - createWindowEx = user32.NewProc("CreateWindowExW") - adjustWindowRect = user32.NewProc("AdjustWindowRect") - adjustWindowRectEx = user32.NewProc("AdjustWindowRectEx") - destroyWindow = user32.NewProc("DestroyWindow") - defWindowProc = user32.NewProc("DefWindowProcW") - defDlgProc = user32.NewProc("DefDlgProcW") - postQuitMessage = user32.NewProc("PostQuitMessage") - getMessage = user32.NewProc("GetMessageW") - getMessageTime = user32.NewProc("GetMessageTime") - translateMessage = user32.NewProc("TranslateMessage") - dispatchMessage = user32.NewProc("DispatchMessageW") - sendMessage = user32.NewProc("SendMessageW") - postMessage = user32.NewProc("PostMessageW") - waitMessage = user32.NewProc("WaitMessage") - setWindowText = user32.NewProc("SetWindowTextW") - getWindowTextLength = user32.NewProc("GetWindowTextLengthW") - getWindowText = user32.NewProc("GetWindowTextW") - getWindowRect = user32.NewProc("GetWindowRect") - getWindowInfo = user32.NewProc("GetWindowInfo") - moveWindow = user32.NewProc("MoveWindow") - screenToClient = user32.NewProc("ScreenToClient") - callWindowProc = user32.NewProc("CallWindowProcW") - setWindowLong = user32.NewProc("SetWindowLongW") - setWindowLongPtr = user32.NewProc("SetWindowLongPtrW") - setClassLongPtr = user32.NewProc("SetClassLongPtrW") - setClassLong = user32.NewProc("SetClassLongW") - getWindowLong = user32.NewProc("GetWindowLongW") - getWindowLongPtr = user32.NewProc("GetWindowLongPtrW") - getClassLongPtr = user32.NewProc("GetClassLongPtrW") - getClassLong = user32.NewProc("GetClassLongW") - enableWindow = user32.NewProc("EnableWindow") - isWindowEnabled = user32.NewProc("IsWindowEnabled") - isWindowVisible = user32.NewProc("IsWindowVisible") - setFocus = user32.NewProc("SetFocus") - invalidateRect = user32.NewProc("InvalidateRect") - validateRect = user32.NewProc("ValidateRect") - getClientRect = user32.NewProc("GetClientRect") - getDC = user32.NewProc("GetDC") - releaseDC = user32.NewProc("ReleaseDC") - setCapture = user32.NewProc("SetCapture") - releaseCapture = user32.NewProc("ReleaseCapture") - getWindowThreadProcessId = user32.NewProc("GetWindowThreadProcessId") - messageBox = user32.NewProc("MessageBoxW") - messageBoxIndirect = user32.NewProc("MessageBoxIndirectW") - getSystemMetrics = user32.NewProc("GetSystemMetrics") - copyRect = user32.NewProc("CopyRect") - equalRect = user32.NewProc("EqualRect") - inflateRect = user32.NewProc("InflateRect") - intersectRect = user32.NewProc("IntersectRect") - isRectEmpty = user32.NewProc("IsRectEmpty") - offsetRect = user32.NewProc("OffsetRect") - ptInRect = user32.NewProc("PtInRect") - setRect = user32.NewProc("SetRect") - setRectEmpty = user32.NewProc("SetRectEmpty") - subtractRect = user32.NewProc("SubtractRect") - unionRect = user32.NewProc("UnionRect") - createDialogParam = user32.NewProc("CreateDialogParamW") - dialogBoxParam = user32.NewProc("DialogBoxParamW") - getDlgItem = user32.NewProc("GetDlgItem") - drawIcon = user32.NewProc("DrawIcon") - drawIconEx = user32.NewProc("DrawIconEx") - clientToScreen = user32.NewProc("ClientToScreen") - isDialogMessage = user32.NewProc("IsDialogMessageW") - isWindow = user32.NewProc("IsWindow") - endDialog = user32.NewProc("EndDialog") - peekMessage = user32.NewProc("PeekMessageW") - createAcceleratorTable = user32.NewProc("CreateAcceleratorTableW") - destroyAcceleratorTable = user32.NewProc("DestroyAcceleratorTable") - translateAccelerator = user32.NewProc("TranslateAcceleratorW") - setWindowPos = user32.NewProc("SetWindowPos") - fillRect = user32.NewProc("FillRect") - drawText = user32.NewProc("DrawTextW") - addClipboardFormatListener = user32.NewProc("AddClipboardFormatListener") - removeClipboardFormatListener = user32.NewProc("RemoveClipboardFormatListener") - openClipboard = user32.NewProc("OpenClipboard") - closeClipboard = user32.NewProc("CloseClipboard") - enumClipboardFormats = user32.NewProc("EnumClipboardFormats") - getClipboardData = user32.NewProc("GetClipboardData") - setClipboardData = user32.NewProc("SetClipboardData") - emptyClipboard = user32.NewProc("EmptyClipboard") - getClipboardFormatName = user32.NewProc("GetClipboardFormatNameW") - isClipboardFormatAvailable = user32.NewProc("IsClipboardFormatAvailable") - beginPaint = user32.NewProc("BeginPaint") - endPaint = user32.NewProc("EndPaint") - getKeyboardState = user32.NewProc("GetKeyboardState") - mapVirtualKey = user32.NewProc("MapVirtualKeyW") - mapVirtualKeyEx = user32.NewProc("MapVirtualKeyExW") - getAsyncKeyState = user32.NewProc("GetAsyncKeyState") - toAscii = user32.NewProc("ToAscii") - swapMouseButton = user32.NewProc("SwapMouseButton") - getCursorPos = user32.NewProc("GetCursorPos") - setCursorPos = user32.NewProc("SetCursorPos") - setCursor = user32.NewProc("SetCursor") - createIcon = user32.NewProc("CreateIcon") - createIconFromResource = user32.NewProc("CreateIconFromResource") - createIconFromResourceEx = user32.NewProc("CreateIconFromResourceEx") - destroyIcon = user32.NewProc("DestroyIcon") - monitorFromPoint = user32.NewProc("MonitorFromPoint") - monitorFromRect = user32.NewProc("MonitorFromRect") - monitorFromWindow = user32.NewProc("MonitorFromWindow") - getMonitorInfo = user32.NewProc("GetMonitorInfoW") - enumDisplayMonitors = user32.NewProc("EnumDisplayMonitors") - enumDisplaySettingsEx = user32.NewProc("EnumDisplaySettingsExW") - changeDisplaySettingsEx = user32.NewProc("ChangeDisplaySettingsExW") - sendInput = user32.NewProc("SendInput") - setWindowsHookEx = user32.NewProc("SetWindowsHookExW") - unhookWindowsHookEx = user32.NewProc("UnhookWindowsHookEx") - callNextHookEx = user32.NewProc("CallNextHookEx") - getWindowPlacement = user32.NewProc("GetWindowPlacement") - setWindowPlacement = user32.NewProc("SetWindowPlacement") - showCursor = user32.NewProc("ShowCursor") - loadImage = user32.NewProc("LoadImageW") - getForegroundWindow = user32.NewProc("GetForegroundWindow") - findWindow = user32.NewProc("FindWindowW") - getClassName = user32.NewProc("GetClassNameW") - getDesktopWindow = user32.NewProc("GetDesktopWindow") - getRawInputData = user32.NewProc("GetRawInputData") - registerPowerSettingNotification = user32.NewProc("RegisterPowerSettingNotification") - registerRawInputDevices = user32.NewProc("RegisterRawInputDevices") - setTimer = user32.NewProc("SetTimer") - getActiveWindow = user32.NewProc("GetActiveWindow") - messageBeep = user32.NewProc("MessageBeep") - beep = kernel32.NewProc("Beep") - getCaretBlinkTime = user32.NewProc("GetCaretBlinkTime") - getWindowDC = user32.NewProc("GetWindowDC") - enumWindows = user32.NewProc("EnumWindows") - enumChildWindows = user32.NewProc("EnumChildWindows") - getTopWindow = user32.NewProc("GetTopWindow") - getWindow = user32.NewProc("GetWindow") - getKeyState = user32.NewProc("GetKeyState") - getSysColor = user32.NewProc("GetSysColor") - getSysColorBrush = user32.NewProc("GetSysColorBrush") - appendMenu = user32.NewProc("AppendMenuW") - checkMenuItem = user32.NewProc("CheckMenuItem") - checkMenuRadioItem = user32.NewProc("CheckMenuRadioItem") - createMenu = user32.NewProc("CreateMenu") - createPopupMenu = user32.NewProc("CreatePopupMenu") - deleteMenu = user32.NewProc("DeleteMenu") - destroyMenu = user32.NewProc("DestroyMenu") - drawMenuBar = user32.NewProc("DrawMenuBar") - enableMenuItem = user32.NewProc("EnableMenuItem") - endMenu = user32.NewProc("EndMenu") - getMenu = user32.NewProc("GetMenu") - getMenuBarInfo = user32.NewProc("GetMenuBarInfo") - getMenuCheckMarkDimensions = user32.NewProc("GetMenuCheckMarkDimensions") - getMenuDefaultItem = user32.NewProc("GetMenuDefaultItem") - getMenuInfo = user32.NewProc("GetMenuInfo") - getMenuItemCount = user32.NewProc("GetMenuItemCount") - getMenuItemID = user32.NewProc("GetMenuItemID") - getMenuItemInfo = user32.NewProc("GetMenuItemInfoW") - getMenuItemRect = user32.NewProc("GetMenuItemRect") - getMenuState = user32.NewProc("GetMenuState") - getMenuString = user32.NewProc("GetMenuStringW") - getSubMenu = user32.NewProc("GetSubMenu") - getSystemMenu = user32.NewProc("GetSystemMenu") - hiliteMenuItem = user32.NewProc("HiliteMenuItem") - insertMenu = user32.NewProc("InsertMenuW") - insertMenuItem = user32.NewProc("InsertMenuItemW") - isMenu = user32.NewProc("IsMenu") - loadMenu = user32.NewProc("LoadMenuW") - loadMenuIndirect = user32.NewProc("LoadMenuIndirectW") - menuItemFromPoint = user32.NewProc("MenuItemFromPoint") - modifyMenu = user32.NewProc("ModifyMenuW") - removeMenu = user32.NewProc("RemoveMenu") - setMenu = user32.NewProc("SetMenu") - setMenuDefaultItem = user32.NewProc("SetMenuDefaultItem") - setMenuInfo = user32.NewProc("SetMenuInfo") - setMenuItemBitmaps = user32.NewProc("SetMenuItemBitmaps") - setMenuItemInfo = user32.NewProc("SetMenuItemInfoW") - trackPopupMenu = user32.NewProc("TrackPopupMenu") - trackPopupMenuEx = user32.NewProc("TrackPopupMenuEx") - isDlgButtonChecked = user32.NewProc("IsDlgButtonChecked") - sendDlgItemMessage = user32.NewProc("SendDlgItemMessageW") - lookupIconIdFromDirectoryEx = user32.NewProc("LookupIconIdFromDirectoryEx") - setForegroundWindow = user32.NewProc("SetForegroundWindow") - scrollWindow = user32.NewProc("ScrollWindow") - getFocus = user32.NewProc("GetFocus") - printWindow = user32.NewProc("PrintWindow") - setLayeredWindowAttributes = user32.NewProc("SetLayeredWindowAttributes") - redrawWindow = user32.NewProc("RedrawWindow") - createCursor = user32.NewProc("CreateCursor") - destroyCursor = user32.NewProc("DestroyCursor") - getDlgCtrlID = user32.NewProc("GetDlgCtrlID") - systemParametersInfo = user32.NewProc("SystemParametersInfoW") - registerWindowMessage = user32.NewProc("RegisterWindowMessageW") - - regCreateKeyEx = advapi32.NewProc("RegCreateKeyExW") - regOpenKeyEx = advapi32.NewProc("RegOpenKeyExW") - regCloseKey = advapi32.NewProc("RegCloseKey") - regGetValue = advapi32.NewProc("RegGetValueW") - regEnumKeyEx = advapi32.NewProc("RegEnumKeyExW") - regEnumValue = advapi32.NewProc("RegEnumValueW") - regSetValueEx = advapi32.NewProc("RegSetValueExW") - regDeleteKeyValue = advapi32.NewProc("RegDeleteKeyValueW") - regDeleteValue = advapi32.NewProc("RegDeleteValueW") - regDeleteTree = advapi32.NewProc("RegDeleteTreeW") - openEventLog = advapi32.NewProc("OpenEventLogW") - getNumberOfEventLogRecords = advapi32.NewProc("GetNumberOfEventLogRecords") - readEventLog = advapi32.NewProc("ReadEventLogW") - closeEventLog = advapi32.NewProc("CloseEventLog") - openSCManager = advapi32.NewProc("OpenSCManagerW") - closeServiceHandle = advapi32.NewProc("CloseServiceHandle") - openService = advapi32.NewProc("OpenServiceW") - startService = advapi32.NewProc("StartServiceW") - controlService = advapi32.NewProc("ControlService") - - initCommonControlsEx = comctl32.NewProc("InitCommonControlsEx") - imageList_Create = comctl32.NewProc("ImageList_Create") - imageList_Destroy = comctl32.NewProc("ImageList_Destroy") - imageList_GetImageCount = comctl32.NewProc("ImageList_GetImageCount") - imageList_SetImageCount = comctl32.NewProc("ImageList_SetImageCount") - imageList_Add = comctl32.NewProc("ImageList_Add") - imageList_ReplaceIcon = comctl32.NewProc("ImageList_ReplaceIcon") - imageList_Remove = comctl32.NewProc("ImageList_Remove") - trackMouseEvent = comctl32.NewProc("_TrackMouseEvent") - setWindowSubclass = comctl32.NewProc("SetWindowSubclass") - defSubclassProc = comctl32.NewProc("DefSubclassProc") - - getSaveFileName = comdlg32.NewProc("GetSaveFileNameW") - getOpenFileName = comdlg32.NewProc("GetOpenFileNameW") - commDlgExtendedError = comdlg32.NewProc("CommDlgExtendedError") - - dwmDefWindowProc = dwmapi.NewProc("DwmDefWindowProc") - dwmEnableBlurBehindWindow = dwmapi.NewProc("DwmEnableBlurBehindWindow") - dwmEnableMMCSS = dwmapi.NewProc("DwmEnableMMCSS") - dwmExtendFrameIntoClientArea = dwmapi.NewProc("DwmExtendFrameIntoClientArea") - dwmFlush = dwmapi.NewProc("DwmFlush") - dwmGetColorizationColor = dwmapi.NewProc("DwmGetColorizationColor") - dwmGetCompositionTimingInfo = dwmapi.NewProc("DwmGetCompositionTimingInfo") - dwmGetTransportAttributes = dwmapi.NewProc("DwmGetTransportAttributes") - dwmGetWindowAttribute = dwmapi.NewProc("DwmGetWindowAttribute") - dwmInvalidateIconicBitmaps = dwmapi.NewProc("DwmInvalidateIconicBitmaps") - dwmIsCompositionEnabled = dwmapi.NewProc("DwmIsCompositionEnabled") - dwmModifyPreviousDxFrameDuration = dwmapi.NewProc("DwmModifyPreviousDxFrameDuration") - dwmQueryThumbnailSourceSize = dwmapi.NewProc("DwmQueryThumbnailSourceSize") - dwmRegisterThumbnail = dwmapi.NewProc("DwmRegisterThumbnail") - dwmRenderGesture = dwmapi.NewProc("DwmRenderGesture") - dwmSetDxFrameDuration = dwmapi.NewProc("DwmSetDxFrameDuration") - dwmSetIconicLivePreviewBitmap = dwmapi.NewProc("DwmSetIconicLivePreviewBitmap") - dwmSetIconicThumbnail = dwmapi.NewProc("DwmSetIconicThumbnail") - dwmSetPresentParameters = dwmapi.NewProc("DwmSetPresentParameters") - dwmSetWindowAttribute = dwmapi.NewProc("DwmSetWindowAttribute") - dwmShowContact = dwmapi.NewProc("DwmShowContact") - dwmTetherContact = dwmapi.NewProc("DwmTetherContact") - dwmTransitionOwnedWindow = dwmapi.NewProc("DwmTransitionOwnedWindow") - dwmUnregisterThumbnail = dwmapi.NewProc("DwmUnregisterThumbnail") - dwmUpdateThumbnailProperties = dwmapi.NewProc("DwmUpdateThumbnailProperties") - - getDeviceCaps = gdi32.NewProc("GetDeviceCaps") - deleteObject = gdi32.NewProc("DeleteObject") - createFontIndirect = gdi32.NewProc("CreateFontIndirectW") - abortDoc = gdi32.NewProc("AbortDoc") - bitBlt = gdi32.NewProc("BitBlt") - maskBlt = gdi32.NewProc("MaskBlt") - patBlt = gdi32.NewProc("PatBlt") - closeEnhMetaFile = gdi32.NewProc("CloseEnhMetaFile") - copyEnhMetaFile = gdi32.NewProc("CopyEnhMetaFileW") - createBrushIndirect = gdi32.NewProc("CreateBrushIndirect") - createCompatibleDC = gdi32.NewProc("CreateCompatibleDC") - createCompatibleBitmap = gdi32.NewProc("CreateCompatibleBitmap") - createBitmap = gdi32.NewProc("CreateBitmap") - createDC = gdi32.NewProc("CreateDCW") - createDIBSection = gdi32.NewProc("CreateDIBSection") - createEnhMetaFile = gdi32.NewProc("CreateEnhMetaFileW") - createIC = gdi32.NewProc("CreateICW") - deleteDC = gdi32.NewProc("DeleteDC") - deleteEnhMetaFile = gdi32.NewProc("DeleteEnhMetaFile") - ellipse = gdi32.NewProc("Ellipse") - endDoc = gdi32.NewProc("EndDoc") - endPage = gdi32.NewProc("EndPage") - extCreatePen = gdi32.NewProc("ExtCreatePen") - getEnhMetaFile = gdi32.NewProc("GetEnhMetaFileW") - getEnhMetaFileHeader = gdi32.NewProc("GetEnhMetaFileHeader") - getObject = gdi32.NewProc("GetObjectW") - getStockObject = gdi32.NewProc("GetStockObject") - getTextExtentExPoint = gdi32.NewProc("GetTextExtentExPointW") - getTextExtentPoint32 = gdi32.NewProc("GetTextExtentPoint32W") - getTextMetrics = gdi32.NewProc("GetTextMetricsW") - lineTo = gdi32.NewProc("LineTo") - moveToEx = gdi32.NewProc("MoveToEx") - playEnhMetaFile = gdi32.NewProc("PlayEnhMetaFile") - rectangle = gdi32.NewProc("Rectangle") - resetDC = gdi32.NewProc("ResetDCW") - selectObject = gdi32.NewProc("SelectObject") - setBkMode = gdi32.NewProc("SetBkMode") - setBrushOrgEx = gdi32.NewProc("SetBrushOrgEx") - setStretchBltMode = gdi32.NewProc("SetStretchBltMode") - setTextColor = gdi32.NewProc("SetTextColor") - setBkColor = gdi32.NewProc("SetBkColor") - startDoc = gdi32.NewProc("StartDocW") - startPage = gdi32.NewProc("StartPage") - stretchBlt = gdi32.NewProc("StretchBlt") - setDIBitsToDevice = gdi32.NewProc("SetDIBitsToDevice") - choosePixelFormat = gdi32.NewProc("ChoosePixelFormat") - describePixelFormat = gdi32.NewProc("DescribePixelFormat") - getEnhMetaFilePixelFormat = gdi32.NewProc("GetEnhMetaFilePixelFormat") - getPixelFormat = gdi32.NewProc("GetPixelFormat") - setPixelFormat = gdi32.NewProc("SetPixelFormat") - swapBuffers = gdi32.NewProc("SwapBuffers") - textOut = gdi32.NewProc("TextOutW") - createSolidBrush = gdi32.NewProc("CreateSolidBrush") - getDIBits = gdi32.NewProc("GetDIBits") - pie = gdi32.NewProc("Pie") - setDCPenColor = gdi32.NewProc("SetDCPenColor") - setDCBrushColor = gdi32.NewProc("SetDCBrushColor") - createPen = gdi32.NewProc("CreatePen") - arc = gdi32.NewProc("Arc") - arcTo = gdi32.NewProc("ArcTo") - angleArc = gdi32.NewProc("AngleArc") - chord = gdi32.NewProc("Chord") - polygon = gdi32.NewProc("Polygon") - polyline = gdi32.NewProc("Polyline") - polyBezier = gdi32.NewProc("PolyBezier") - intersectClipRect = gdi32.NewProc("IntersectClipRect") - selectClipRgn = gdi32.NewProc("SelectClipRgn") - createRectRgn = gdi32.NewProc("CreateRectRgn") - combineRgn = gdi32.NewProc("CombineRgn") - enumFontFamiliesEx = gdi32.NewProc("EnumFontFamiliesExW") - - getModuleHandle = kernel32.NewProc("GetModuleHandleW") - getModuleFileName = kernel32.NewProc("GetModuleFileNameW") - mulDiv = kernel32.NewProc("MulDiv") - getConsoleWindow = kernel32.NewProc("GetConsoleWindow") - getCurrentThread = kernel32.NewProc("GetCurrentThread") - getCurrentThreadId = kernel32.NewProc("GetCurrentThreadId") - getLogicalDrives = kernel32.NewProc("GetLogicalDrives") - getDriveType = kernel32.NewProc("GetDriveTypeW") - getUserDefaultLCID = kernel32.NewProc("GetUserDefaultLCID") - lstrlen = kernel32.NewProc("lstrlenW") - lstrcpy = kernel32.NewProc("lstrcpyW") - globalAlloc = kernel32.NewProc("GlobalAlloc") - globalFree = kernel32.NewProc("GlobalFree") - globalLock = kernel32.NewProc("GlobalLock") - globalUnlock = kernel32.NewProc("GlobalUnlock") - moveMemory = kernel32.NewProc("RtlMoveMemory") - findResource = kernel32.NewProc("FindResourceW") - sizeofResource = kernel32.NewProc("SizeofResource") - lockResource = kernel32.NewProc("LockResource") - loadResource = kernel32.NewProc("LoadResource") - getLastError = kernel32.NewProc("GetLastError") - openProcess = kernel32.NewProc("OpenProcess") - terminateProcess = kernel32.NewProc("TerminateProcess") - closeHandle = kernel32.NewProc("CloseHandle") - createToolhelp32Snapshot = kernel32.NewProc("CreateToolhelp32Snapshot") - module32First = kernel32.NewProc("Module32FirstW") - module32Next = kernel32.NewProc("Module32NextW") - getSystemTimes = kernel32.NewProc("GetSystemTimes") - getConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo") - setConsoleTextAttribute = kernel32.NewProc("SetConsoleTextAttribute") - getDiskFreeSpaceEx = kernel32.NewProc("GetDiskFreeSpaceExW") - getProcessTimes = kernel32.NewProc("GetProcessTimes") - setSystemTime = kernel32.NewProc("SetSystemTime") - setLocalTime = kernel32.NewProc("SetLocalTime") - getSystemTime = kernel32.NewProc("GetSystemTime") - getSystemTimeAsFileTime = kernel32.NewProc("GetSystemTimeAsFileTime") - systemTimeToFileTime = kernel32.NewProc("SystemTimeToFileTime") - fileTimeToSystemTime = kernel32.NewProc("FileTimeToSystemTime") - copyMemory = kernel32.NewProc("RtlCopyMemory") - getCurrentProcess = kernel32.NewProc("GetCurrentProcess") - getCurrentProcessId = kernel32.NewProc("GetCurrentProcessId") - getVersion = kernel32.NewProc("GetVersion") - setEnvironmentVariable = kernel32.NewProc("SetEnvironmentVariableW") - getComputerName = kernel32.NewProc("GetComputerNameW") - activateActCtx = kernel32.NewProc("ActivateActCtx") - createActCtx = kernel32.NewProc("CreateActCtxW") - getCurrentActCtx = kernel32.NewProc("GetCurrentActCtx") - setErrorMode = kernel32.NewProc("SetErrorMode") - createFile = kernel32.NewProc("CreateFileW") - deviceIoControl = kernel32.NewProc("DeviceIoControl") - findFirstStream = kernel32.NewProc("FindFirstStreamW") - findNextStream = kernel32.NewProc("FindNextStreamW") - findClose = kernel32.NewProc("FindClose") - openMutex = kernel32.NewProc("OpenMutexW") - createMutex = kernel32.NewProc("CreateMutexW") - getNativeSystemInfo = kernel32.NewProc("GetNativeSystemInfo") - - coInitializeEx = ole32.NewProc("CoInitializeEx") - coInitialize = ole32.NewProc("CoInitialize") - coUninitialize = ole32.NewProc("CoUninitialize") - createStreamOnHGlobal = ole32.NewProc("CreateStreamOnHGlobal") - - variantInit = oleaut32.NewProc("VariantInit") - sysAllocString = oleaut32.NewProc("SysAllocString") - sysFreeString = oleaut32.NewProc("SysFreeString") - sysStringLen = oleaut32.NewProc("SysStringLen") - createDispTypeInfo = oleaut32.NewProc("CreateDispTypeInfo") - createStdDispatch = oleaut32.NewProc("CreateStdDispatch") - - wglCreateContext = opengl32.NewProc("wglCreateContext") - wglCreateLayerContext = opengl32.NewProc("wglCreateLayerContext") - wglDeleteContext = opengl32.NewProc("wglDeleteContext") - wglGetProcAddress = opengl32.NewProc("wglGetProcAddress") - wglMakeCurrent = opengl32.NewProc("wglMakeCurrent") - wglShareLists = opengl32.NewProc("wglShareLists") - - enumProcesses = psapi.NewProc("EnumProcesses") - - sHBrowseForFolder = shell32.NewProc("SHBrowseForFolderW") - sHGetPathFromIDList = shell32.NewProc("SHGetPathFromIDListW") - shGetSpecialFolderPath = shell32.NewProc("SHGetSpecialFolderPathW") - dragAcceptFiles = shell32.NewProc("DragAcceptFiles") - dragQueryFile = shell32.NewProc("DragQueryFileW") - dragQueryPoint = shell32.NewProc("DragQueryPoint") - dragFinish = shell32.NewProc("DragFinish") - shellExecute = shell32.NewProc("ShellExecuteW") - extractIcon = shell32.NewProc("ExtractIconW") - - gdipCreateBitmapFromFile = gdiplus.NewProc("GdipCreateBitmapFromFile") - gdipCreateBitmapFromHBITMAP = gdiplus.NewProc("GdipCreateBitmapFromHBITMAP") - gdipCreateHBITMAPFromBitmap = gdiplus.NewProc("GdipCreateHBITMAPFromBitmap") - gdipCreateBitmapFromResource = gdiplus.NewProc("GdipCreateBitmapFromResource") - gdipCreateBitmapFromStream = gdiplus.NewProc("GdipCreateBitmapFromStream") - gdipDisposeImage = gdiplus.NewProc("GdipDisposeImage") - gdiplusShutdown = gdiplus.NewProc("GdiplusShutdown") - gdiplusStartup = gdiplus.NewProc("GdiplusStartup") - - getFileVersionInfoSize = version.NewProc("GetFileVersionInfoSizeW") - getFileVersionInfo = version.NewProc("GetFileVersionInfoW") - verQueryValue = version.NewProc("VerQueryValueW") - - playSound = winmm.NewProc("PlaySoundW") - - getMonitorBrightness = dxva2.NewProc("GetMonitorBrightness") - setMonitorBrightness = dxva2.NewProc("SetMonitorBrightness") - getNumberOfPhysicalMonitorsFromHMONITOR = dxva2.NewProc("GetNumberOfPhysicalMonitorsFromHMONITOR") - getPhysicalMonitorsFromHMONITOR = dxva2.NewProc("GetPhysicalMonitorsFromHMONITOR") - - alphaBlend = msimg32.NewProc("AlphaBlend") - - wNetAddConnection2 = mpr.NewProc("WNetAddConnection2W") - wNetAddConnection3 = mpr.NewProc("WNetAddConnection3W") - wNetCancelConnection2 = mpr.NewProc("WNetCancelConnection2W") - - rtlGetVersion = ntdll.NewProc("RtlGetVersion") - - setupDiGetClassDevs = setupAPI.NewProc("SetupDiGetClassDevsW") - setupDiDestroyDeviceInfoList = setupAPI.NewProc("SetupDiDestroyDeviceInfoList") - setupDiEnumDeviceInfo = setupAPI.NewProc("SetupDiEnumDeviceInfo") - setupDiOpenDevRegKey = setupAPI.NewProc("SetupDiOpenDevRegKey") - - setProcessDpiAwareness = shcore.NewProc("SetProcessDpiAwareness") -) - -func RegisterWindowMessage(name string) uint32 { - ret, _, _ := registerWindowMessage.Call( - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(name))), - ) - - return uint32(ret) -} - -// RegisterClassEx sets the Size of the WNDCLASSEX automatically. -func RegisterClassEx(wndClassEx *WNDCLASSEX) ATOM { - if wndClassEx != nil { - wndClassEx.Size = uint32(unsafe.Sizeof(*wndClassEx)) - } - ret, _, _ := registerClassEx.Call(uintptr(unsafe.Pointer(wndClassEx))) - return ATOM(ret) -} - -func UnregisterClass(className string, instance HINSTANCE) bool { - ret, _, _ := unregisterClass.Call( - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(className))), - uintptr(instance), - ) - return ret != 0 -} - -func UnregisterClassAtom(atom ATOM, instance HINSTANCE) bool { - ret, _, _ := unregisterClass.Call( - uintptr(atom), - uintptr(instance), - ) - return ret != 0 -} - -func GetClassInfoEx(inst HINSTANCE, className string) (c WNDCLASSEX, found bool) { - ret, _, _ := getClassInfoEx.Call( - uintptr(inst), - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(className))), - uintptr(unsafe.Pointer(&c)), - ) - found = ret != 0 - return -} - -func LoadIcon(instance HINSTANCE, iconName *uint16) HICON { - ret, _, _ := loadIcon.Call( - uintptr(instance), - uintptr(unsafe.Pointer(iconName)), - ) - return HICON(ret) -} - -func LoadIconWithResourceID(instance HINSTANCE, res uint16) HICON { - ret, _, _ := loadIcon.Call( - uintptr(instance), - uintptr(res)) - - return HICON(ret) -} - -func LoadCursor(instance HINSTANCE, cursorName *uint16) HCURSOR { - ret, _, _ := loadCursor.Call( - uintptr(instance), - uintptr(unsafe.Pointer(cursorName)), - ) - return HCURSOR(ret) -} - -func LoadCursorWithResourceID(instance HINSTANCE, res uint16) HCURSOR { - ret, _, _ := loadCursor.Call( - uintptr(instance), - uintptr(res)) - - return HCURSOR(ret) -} - -func ShowWindow(hwnd HWND, cmdshow int) bool { - ret, _, _ := showWindow.Call( - uintptr(hwnd), - uintptr(cmdshow), - ) - return ret != 0 -} - -func ShowWindowAsync(hwnd HWND, cmdshow int) bool { - ret, _, _ := showWindowAsync.Call( - uintptr(hwnd), - uintptr(cmdshow), - ) - return ret != 0 -} - -func UpdateWindow(hwnd HWND) bool { - ret, _, _ := updateWindow.Call(uintptr(hwnd)) - return ret != 0 -} - -func CreateWindow(className, windowName *uint16, - style uint, x, y, width, height int, parent HWND, menu HMENU, - instance HINSTANCE, param unsafe.Pointer) HWND { - return CreateWindowEx( - 0, - className, windowName, - style, - x, y, width, height, - parent, menu, instance, param, - ) -} - -func CreateWindowStr(className, windowName string, - style uint, x, y, width, height int, parent HWND, menu HMENU, - instance HINSTANCE, param unsafe.Pointer) HWND { - return CreateWindow( - syscall.StringToUTF16Ptr(className), - syscall.StringToUTF16Ptr(windowName), - style, - x, y, width, height, - parent, menu, instance, param, - ) -} - -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, _, _ := createWindowEx.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 CreateWindowExStr(exStyle uint, className, windowName string, - style uint, x, y, width, height int, parent HWND, menu HMENU, - instance HINSTANCE, param unsafe.Pointer) HWND { - return CreateWindowEx( - exStyle, - syscall.StringToUTF16Ptr(className), - syscall.StringToUTF16Ptr(windowName), - style, - x, y, width, height, - parent, menu, instance, param, - ) -} - -func AdjustWindowRectEx(rect *RECT, style uint, menu bool, exStyle uint) bool { - ret, _, _ := adjustWindowRectEx.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, _, _ := adjustWindowRect.Call( - uintptr(unsafe.Pointer(rect)), - uintptr(style), - uintptr(BoolToBOOL(menu)), - ) - return ret != 0 -} - -func DestroyWindow(hwnd HWND) bool { - ret, _, _ := destroyWindow.Call(uintptr(hwnd)) - return ret != 0 -} - -func DefWindowProc(hwnd HWND, msg uint32, wParam, lParam uintptr) uintptr { - ret, _, _ := defWindowProc.Call( - uintptr(hwnd), - uintptr(msg), - wParam, - lParam, - ) - return ret -} - -func DefDlgProc(hwnd HWND, msg uint32, wParam, lParam uintptr) uintptr { - ret, _, _ := defDlgProc.Call( - uintptr(hwnd), - uintptr(msg), - wParam, - lParam, - ) - return ret -} - -func PostQuitMessage(exitCode int) { - postQuitMessage.Call(uintptr(exitCode)) -} - -func GetMessage(msg *MSG, hwnd HWND, msgFilterMin, msgFilterMax uint32) int { - ret, _, _ := getMessage.Call( - uintptr(unsafe.Pointer(msg)), - uintptr(hwnd), - uintptr(msgFilterMin), - uintptr(msgFilterMax), - ) - return int(ret) -} - -func GetMessageTime() int { - ret, _, _ := getMessageTime.Call() - return int(ret) -} - -func TranslateMessage(msg *MSG) bool { - ret, _, _ := translateMessage.Call(uintptr(unsafe.Pointer(msg))) - return ret != 0 - -} - -func DispatchMessage(msg *MSG) uintptr { - ret, _, _ := dispatchMessage.Call(uintptr(unsafe.Pointer(msg))) - return ret - -} - -func SendMessage(hwnd HWND, msg uint32, wParam, lParam uintptr) uintptr { - ret, _, _ := sendMessage.Call( - uintptr(hwnd), - uintptr(msg), - wParam, - lParam, - ) - return ret -} - -func PostMessage(hwnd HWND, msg uint32, wParam, lParam uintptr) bool { - ret, _, _ := postMessage.Call( - uintptr(hwnd), - uintptr(msg), - wParam, - lParam, - ) - return ret != 0 -} - -func WaitMessage() bool { - ret, _, _ := waitMessage.Call() - return ret != 0 -} - -func SetWindowText(hwnd HWND, text string) { - setWindowText.Call( - uintptr(hwnd), - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(text))), - ) -} - -func GetWindowTextLength(hwnd HWND) int { - ret, _, _ := getWindowTextLength.Call(uintptr(hwnd)) - return int(ret) -} - -func GetWindowText(hwnd HWND) string { - textLen := GetWindowTextLength(hwnd) + 1 - buf := make([]uint16, textLen) - len, _, _ := getWindowText.Call( - uintptr(hwnd), - uintptr(unsafe.Pointer(&buf[0])), - uintptr(textLen), - ) - return syscall.UTF16ToString(buf[:len]) -} - -func GetWindowRect(hwnd HWND) *RECT { - var rect RECT - getWindowRect.Call( - uintptr(hwnd), - uintptr(unsafe.Pointer(&rect)), - ) - return &rect -} - -func GetWindowInfo(hwnd HWND) (WINDOWINFO, bool) { - var wi WINDOWINFO - ret, _, _ := getWindowInfo.Call( - uintptr(hwnd), - uintptr(unsafe.Pointer(&wi)), - ) - return wi, ret != 0 -} - -func MoveWindow(hwnd HWND, x, y, width, height int, repaint bool) bool { - ret, _, _ := moveWindow.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, _, _ := screenToClient.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, _, _ := callWindowProc.Call( - preWndProc, - uintptr(hwnd), - uintptr(msg), - wParam, - lParam, - ) - return ret -} - -func GetWindowLong(hwnd HWND, index int) int32 { - ret, _, _ := getWindowLong.Call( - uintptr(hwnd), - uintptr(index), - ) - return int32(ret) -} - -func SetWindowLong(hwnd HWND, index int, value int32) int32 { - ret, _, _ := setWindowLong.Call( - uintptr(hwnd), - uintptr(index), - uintptr(value), - ) - return int32(ret) -} - -func GetClassLong(hwnd HWND, index int) uint32 { - ret, _, _ := getClassLong.Call( - uintptr(hwnd), - uintptr(index), - ) - return uint32(ret) -} - -func SetClassLong(hwnd HWND, index int, value int32) uint32 { - ret, _, _ := setClassLong.Call( - uintptr(hwnd), - uintptr(index), - uintptr(value), - ) - return uint32(ret) -} - -func EnableWindow(hwnd HWND, b bool) bool { - ret, _, _ := enableWindow.Call( - uintptr(hwnd), - uintptr(BoolToBOOL(b)), - ) - return ret != 0 -} - -func IsWindowEnabled(hwnd HWND) bool { - ret, _, _ := isWindowEnabled.Call(uintptr(hwnd)) - return ret != 0 -} - -func IsWindowVisible(hwnd HWND) bool { - ret, _, _ := isWindowVisible.Call(uintptr(hwnd)) - return ret != 0 -} - -func SetFocus(hwnd HWND) HWND { - ret, _, _ := setFocus.Call(uintptr(hwnd)) - return HWND(ret) -} - -func InvalidateRect(hwnd HWND, rect *RECT, erase bool) bool { - ret, _, _ := invalidateRect.Call( - uintptr(hwnd), - uintptr(unsafe.Pointer(rect)), - uintptr(BoolToBOOL(erase)), - ) - return ret != 0 -} - -func ValidateRect(hwnd HWND, rect *RECT) bool { - ret, _, _ := validateRect.Call( - uintptr(hwnd), - uintptr(unsafe.Pointer(rect)), - ) - return ret != 0 -} - -func GetClientRect(hwnd HWND) *RECT { - var rect RECT - ret, _, _ := getClientRect.Call( - uintptr(hwnd), - uintptr(unsafe.Pointer(&rect))) - if ret == 0 { - return nil - } - return &rect -} - -func GetDC(hwnd HWND) HDC { - ret, _, _ := getDC.Call(uintptr(hwnd)) - return HDC(ret) -} - -func ReleaseDC(hwnd HWND, hDC HDC) bool { - ret, _, _ := releaseDC.Call( - uintptr(hwnd), - uintptr(hDC), - ) - return ret != 0 -} - -func SetCapture(hwnd HWND) HWND { - ret, _, _ := setCapture.Call(uintptr(hwnd)) - return HWND(ret) -} - -func ReleaseCapture() bool { - ret, _, _ := releaseCapture.Call() - return ret != 0 -} - -func GetWindowThreadProcessId(hwnd HWND) (HANDLE, DWORD) { - var processId DWORD - ret, _, _ := getWindowThreadProcessId.Call( - uintptr(hwnd), - uintptr(unsafe.Pointer(&processId)), - ) - return HANDLE(ret), processId -} - -func MessageBox(hwnd HWND, text, caption string, flags uint) int { - ret, _, _ := messageBox.Call( - uintptr(hwnd), - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(text))), - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(caption))), - uintptr(flags), - ) - return int(ret) -} - -func MessageBoxIndirect(params *MSGBOXPARAMS) int { - if params != nil { - params.Size = uint32(unsafe.Sizeof(*params)) - } - ret, _, _ := messageBoxIndirect.Call(uintptr(unsafe.Pointer(params))) - return int(ret) -} - -func GetSystemMetrics(index int) int { - ret, _, _ := getSystemMetrics.Call(uintptr(index)) - return int(ret) -} - -func CopyRect(dst, src *RECT) bool { - ret, _, _ := copyRect.Call( - uintptr(unsafe.Pointer(dst)), - uintptr(unsafe.Pointer(src)), - ) - return ret != 0 -} - -func EqualRect(rect1, rect2 *RECT) bool { - ret, _, _ := equalRect.Call( - uintptr(unsafe.Pointer(rect1)), - uintptr(unsafe.Pointer(rect2)), - ) - return ret != 0 -} - -func InflateRect(rect *RECT, dx, dy int) bool { - ret, _, _ := inflateRect.Call( - uintptr(unsafe.Pointer(rect)), - uintptr(dx), - uintptr(dy), - ) - return ret != 0 -} - -func IntersectRect(dst, src1, src2 *RECT) bool { - ret, _, _ := intersectRect.Call( - uintptr(unsafe.Pointer(dst)), - uintptr(unsafe.Pointer(src1)), - uintptr(unsafe.Pointer(src2)), - ) - return ret != 0 -} - -func IsRectEmpty(rect *RECT) bool { - ret, _, _ := isRectEmpty.Call(uintptr(unsafe.Pointer(rect))) - return ret != 0 -} - -func OffsetRect(rect *RECT, dx, dy int) bool { - ret, _, _ := offsetRect.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, _, _ := ptInRect.Call( - uintptr(unsafe.Pointer(rect)), - uintptr(unsafe.Pointer(&pt)), - ) - return ret != 0 -} - -func SetRect(rect *RECT, left, top, right, bottom int) bool { - ret, _, _ := setRect.Call( - uintptr(unsafe.Pointer(rect)), - uintptr(left), - uintptr(top), - uintptr(right), - uintptr(bottom), - ) - return ret != 0 -} - -func SetRectEmpty(rect *RECT) bool { - ret, _, _ := setRectEmpty.Call(uintptr(unsafe.Pointer(rect))) - return ret != 0 -} - -func SubtractRect(dst, src1, src2 *RECT) bool { - ret, _, _ := subtractRect.Call( - uintptr(unsafe.Pointer(dst)), - uintptr(unsafe.Pointer(src1)), - uintptr(unsafe.Pointer(src2)), - ) - return ret != 0 -} - -func UnionRect(dst, src1, src2 *RECT) bool { - ret, _, _ := unionRect.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, _, _ := createDialogParam.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, _, _ := dialogBoxParam.Call( - uintptr(hInstance), - uintptr(unsafe.Pointer(lpTemplateName)), - uintptr(hWndParent), - lpDialogProc, - 0, - ) - return int(ret) -} - -func GetDlgItem(hDlg HWND, nIDDlgItem int) HWND { - ret, _, _ := getDlgItem.Call( - uintptr(unsafe.Pointer(hDlg)), - uintptr(nIDDlgItem), - ) - return HWND(ret) -} - -func DrawIconEx( - hDC HDC, x, y int, hIcon HICON, width, height int, - frame uint, flickerFreeDraw HBRUSH, flags uint, -) bool { - ret, _, _ := drawIconEx.Call( - uintptr(unsafe.Pointer(hDC)), - uintptr(x), - uintptr(y), - uintptr(unsafe.Pointer(hIcon)), - uintptr(width), - uintptr(height), - uintptr(frame), - uintptr(flickerFreeDraw), - uintptr(flags), - ) - return ret != 0 -} - -func DrawIcon(hDC HDC, x, y int, hIcon HICON) bool { - ret, _, _ := drawIcon.Call( - uintptr(unsafe.Pointer(hDC)), - uintptr(x), - uintptr(y), - uintptr(unsafe.Pointer(hIcon)), - ) - return ret != 0 -} - -func ClientToScreen(hwnd HWND, x, y int) (int, int) { - pt := POINT{X: int32(x), Y: int32(y)} - clientToScreen.Call( - uintptr(hwnd), - uintptr(unsafe.Pointer(&pt)), - ) - return int(pt.X), int(pt.Y) -} - -func IsDialogMessage(hwnd HWND, msg *MSG) bool { - ret, _, _ := isDialogMessage.Call( - uintptr(hwnd), - uintptr(unsafe.Pointer(msg)), - ) - return ret != 0 -} - -func IsWindow(hwnd HWND) bool { - ret, _, _ := isWindow.Call(uintptr(hwnd)) - return ret != 0 -} - -func EndDialog(hwnd HWND, nResult uintptr) bool { - ret, _, _ := endDialog.Call( - uintptr(hwnd), - nResult, - ) - return ret != 0 -} - -func PeekMessage(lpMsg *MSG, hwnd HWND, wMsgFilterMin, wMsgFilterMax, wRemoveMsg uint32) bool { - ret, _, _ := peekMessage.Call( - uintptr(unsafe.Pointer(lpMsg)), - uintptr(hwnd), - uintptr(wMsgFilterMin), - uintptr(wMsgFilterMax), - uintptr(wRemoveMsg), - ) - return ret != 0 -} - -func CreateAcceleratorTable(acc []ACCEL) HACCEL { - if len(acc) == 0 { - return 0 - } - ret, _, _ := createAcceleratorTable.Call( - uintptr(unsafe.Pointer(&acc[0])), - uintptr(len(acc)), - ) - return HACCEL(ret) -} - -func DestroyAcceleratorTable(acc HACCEL) bool { - ret, _, _ := destroyAcceleratorTable.Call(uintptr(acc)) - return ret != 0 -} - -func TranslateAccelerator(hwnd HWND, hAccTable HACCEL, lpMsg *MSG) bool { - ret, _, _ := translateAccelerator.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, _, _ := setWindowPos.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, _, _ := fillRect.Call( - uintptr(hDC), - uintptr(unsafe.Pointer(lprc)), - uintptr(hbr), - ) - return ret != 0 -} - -// DrawText does not support DT_MODIFYSTRING in this implementation. -func DrawText(hDC HDC, text string, lpRect *RECT, uFormat uint) int { - // suppress DT_MODIFYSTRING because the given text is not a pointer and we - // do not return any text changes. - mod := uint(DT_MODIFYSTRING) - uFormat = uFormat & ^mod - count := -1 // because the text pointer is NULL terminated - ret, _, _ := drawText.Call( - uintptr(hDC), - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(text))), - uintptr(count), - uintptr(unsafe.Pointer(lpRect)), - uintptr(uFormat), - ) - return int(ret) -} - -func AddClipboardFormatListener(hwnd HWND) bool { - ret, _, _ := addClipboardFormatListener.Call(uintptr(hwnd)) - return ret != 0 -} - -func RemoveClipboardFormatListener(hwnd HWND) bool { - ret, _, _ := removeClipboardFormatListener.Call(uintptr(hwnd)) - return ret != 0 -} - -func OpenClipboard(hWndNewOwner HWND) bool { - ret, _, _ := openClipboard.Call(uintptr(hWndNewOwner)) - return ret != 0 -} - -func CloseClipboard() bool { - ret, _, _ := closeClipboard.Call() - return ret != 0 -} - -func EnumClipboardFormats(format uint) uint { - ret, _, _ := enumClipboardFormats.Call(uintptr(format)) - return uint(ret) -} - -func GetClipboardData(uFormat uint) HANDLE { - ret, _, _ := getClipboardData.Call(uintptr(uFormat)) - return HANDLE(ret) -} - -func SetClipboardData(uFormat uint, hMem HANDLE) HANDLE { - ret, _, _ := setClipboardData.Call( - uintptr(uFormat), - uintptr(hMem), - ) - return HANDLE(ret) -} - -func EmptyClipboard() bool { - ret, _, _ := emptyClipboard.Call() - return ret != 0 -} - -func GetClipboardFormatName(format uint) (string, bool) { - cchMaxCount := 255 - buf := make([]uint16, cchMaxCount) - ret, _, _ := getClipboardFormatName.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, _, _ := isClipboardFormatAvailable.Call(uintptr(format)) - return ret != 0 -} - -func BeginPaint(hwnd HWND, paint *PAINTSTRUCT) HDC { - ret, _, _ := beginPaint.Call( - uintptr(hwnd), - uintptr(unsafe.Pointer(paint)), - ) - return HDC(ret) -} - -func EndPaint(hwnd HWND, paint *PAINTSTRUCT) { - endPaint.Call( - uintptr(hwnd), - uintptr(unsafe.Pointer(paint)), - ) -} - -func GetKeyboardState(keyState []byte) bool { - if len(keyState) < 256 { - return false - } - ret, _, _ := getKeyboardState.Call(uintptr(unsafe.Pointer(&keyState[0]))) - return ret != 0 -} - -func MapVirtualKey(uCode, uMapType uint) uint { - ret, _, _ := mapVirtualKey.Call( - uintptr(uCode), - uintptr(uMapType), - ) - return uint(ret) -} - -func MapVirtualKeyEx(uCode, uMapType uint, dwhkl HKL) uint { - ret, _, _ := mapVirtualKeyEx.Call( - uintptr(uCode), - uintptr(uMapType), - uintptr(dwhkl), - ) - return uint(ret) -} - -func GetAsyncKeyState(vKey int) uint16 { - ret, _, _ := getAsyncKeyState.Call(uintptr(vKey)) - return uint16(ret) -} - -func ToAscii(uVirtKey, uScanCode uint, lpKeyState *byte, lpChar *uint16, uFlags uint) int { - ret, _, _ := toAscii.Call( - uintptr(uVirtKey), - uintptr(uScanCode), - uintptr(unsafe.Pointer(lpKeyState)), - uintptr(unsafe.Pointer(lpChar)), - uintptr(uFlags), - ) - return int(ret) -} - -func SwapMouseButton(fSwap bool) bool { - ret, _, _ := swapMouseButton.Call(uintptr(BoolToBOOL(fSwap))) - return ret != 0 -} - -func GetCursorPos() (x, y int, ok bool) { - var pt POINT - ret, _, _ := getCursorPos.Call(uintptr(unsafe.Pointer(&pt))) - return int(pt.X), int(pt.Y), ret != 0 -} - -func SetCursorPos(x, y int) bool { - ret, _, _ := setCursorPos.Call( - uintptr(x), - uintptr(y), - ) - return ret != 0 -} - -func SetCursor(cursor HCURSOR) HCURSOR { - ret, _, _ := setCursor.Call(uintptr(cursor)) - return HCURSOR(ret) -} - -func CreateIcon(instance HINSTANCE, nWidth, nHeight int, cPlanes, cBitsPerPixel byte, ANDbits, XORbits *byte) HICON { - ret, _, _ := createIcon.Call( - uintptr(instance), - uintptr(nWidth), - uintptr(nHeight), - uintptr(cPlanes), - uintptr(cBitsPerPixel), - uintptr(unsafe.Pointer(ANDbits)), - uintptr(unsafe.Pointer(XORbits)), - ) - return HICON(ret) -} - -func CreateIconFromResource( - mem unsafe.Pointer, - memSize uint32, - icon bool, - version uint32, -) HICON { - ret, _, _ := createIconFromResource.Call( - uintptr(mem), - uintptr(memSize), - uintptr(BoolToBOOL(icon)), - uintptr(version), - ) - return HICON(ret) -} - -func CreateIconFromResourceEx( - mem unsafe.Pointer, - memSize uint32, - icon bool, - version uint32, - width int, - height int, - flags uint, -) HICON { - ret, _, _ := createIconFromResourceEx.Call( - uintptr(mem), - uintptr(memSize), - uintptr(BoolToBOOL(icon)), - uintptr(version), - uintptr(width), - uintptr(height), - uintptr(flags), - ) - return HICON(ret) -} - -func DestroyIcon(icon HICON) bool { - ret, _, _ := destroyIcon.Call(uintptr(icon)) - return ret != 0 -} - -func MonitorFromPoint(x, y int, dwFlags uint32) HMONITOR { - ret, _, _ := monitorFromPoint.Call( - uintptr(x), - uintptr(y), - uintptr(dwFlags), - ) - return HMONITOR(ret) -} - -func MonitorFromRect(rc *RECT, dwFlags uint32) HMONITOR { - ret, _, _ := monitorFromRect.Call( - uintptr(unsafe.Pointer(rc)), - uintptr(dwFlags), - ) - return HMONITOR(ret) -} - -func MonitorFromWindow(hwnd HWND, dwFlags uint32) HMONITOR { - ret, _, _ := monitorFromWindow.Call( - uintptr(hwnd), - uintptr(dwFlags), - ) - return HMONITOR(ret) -} - -// GetMonitorInfo automatically sets the MONITORINFO's CbSize field. -func GetMonitorInfo(hMonitor HMONITOR, lmpi *MONITORINFO) bool { - if lmpi != nil { - lmpi.CbSize = uint32(unsafe.Sizeof(*lmpi)) - } - ret, _, _ := getMonitorInfo.Call( - uintptr(hMonitor), - uintptr(unsafe.Pointer(lmpi)), - ) - return ret != 0 -} - -func EnumDisplayMonitors(hdc HDC, clip *RECT, fnEnum, dwData uintptr) bool { - ret, _, _ := enumDisplayMonitors.Call( - uintptr(hdc), - uintptr(unsafe.Pointer(clip)), - fnEnum, - dwData, - ) - return ret != 0 -} - -func EnumDisplaySettingsEx(szDeviceName *uint16, iModeNum uint32, devMode *DEVMODE, dwFlags uint32) bool { - ret, _, _ := enumDisplaySettingsEx.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, _, _ := changeDisplaySettingsEx.Call( - uintptr(unsafe.Pointer(szDeviceName)), - uintptr(unsafe.Pointer(devMode)), - uintptr(hwnd), - uintptr(dwFlags), - lParam, - ) - return int32(ret) -} - -func SendInput(inputs ...INPUT) uint32 { - if len(inputs) == 0 { - return 0 - } - ret, _, _ := sendInput.Call( - uintptr(len(inputs)), - uintptr(unsafe.Pointer(&inputs[0])), - unsafe.Sizeof(inputs[0]), - ) - return uint32(ret) -} - -func SetWindowsHookEx(idHook int, lpfn HOOKPROC, hMod HINSTANCE, dwThreadId DWORD) HHOOK { - ret, _, _ := setWindowsHookEx.Call( - uintptr(idHook), - uintptr(syscall.NewCallback(lpfn)), - uintptr(hMod), - uintptr(dwThreadId), - ) - return HHOOK(ret) -} - -func UnhookWindowsHookEx(hhk HHOOK) bool { - ret, _, _ := unhookWindowsHookEx.Call(uintptr(hhk)) - return ret != 0 -} - -func CallNextHookEx(hhk HHOOK, nCode int, wParam WPARAM, lParam LPARAM) LRESULT { - ret, _, _ := callNextHookEx.Call( - uintptr(hhk), - uintptr(nCode), - uintptr(wParam), - uintptr(lParam), - ) - return LRESULT(ret) -} - -// GetWindowPlacement automatically sets the WINDOWPLACEMENT's Length field. -func GetWindowPlacement(hwnd HWND, placement *WINDOWPLACEMENT) bool { - if placement != nil { - placement.Length = uint32(unsafe.Sizeof(*placement)) - } - ret, _, _ := getWindowPlacement.Call( - uintptr(hwnd), - uintptr(unsafe.Pointer(placement)), - ) - return ret != 0 -} - -func SetWindowPlacement(hwnd HWND, placement *WINDOWPLACEMENT) bool { - ret, _, _ := setWindowPlacement.Call( - uintptr(hwnd), - uintptr(unsafe.Pointer(placement)), - ) - return ret != 0 -} - -func ShowCursor(show bool) int { - ret, _, _ := showCursor.Call(uintptr(BoolToBOOL(show))) - return int(int32(ret)) -} - -func LoadImage( - inst HINSTANCE, - name *uint16, - typ uint, - desiredWidth, desiredHeight int, - load uint, -) HANDLE { - ret, _, _ := loadImage.Call( - uintptr(inst), - uintptr(unsafe.Pointer(name)), - uintptr(typ), - uintptr(desiredWidth), - uintptr(desiredHeight), - uintptr(load), - ) - return HANDLE(ret) -} - -func GetForegroundWindow() HWND { - ret, _, _ := getForegroundWindow.Call() - return HWND(ret) -} - -func FindWindow(className, windowName string) HWND { - var class, window uintptr - if className != "" { - class = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(className))) - } - if windowName != "" { - window = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(windowName))) - } - ret, _, _ := findWindow.Call(class, window) - return HWND(ret) -} - -func GetClassName(window HWND) (string, bool) { - var output [256]uint16 - ret, _, _ := getClassName.Call( - uintptr(window), - uintptr(unsafe.Pointer(&output[0])), - uintptr(len(output)), - ) - return syscall.UTF16ToString(output[:]), ret != 0 -} - -func GetDesktopWindow() HWND { - ret, _, _ := getDesktopWindow.Call() - return HWND(ret) -} - -func GetRawInputData(input HRAWINPUT, command uint) (raw RAWINPUT, ok bool) { - size := uint(unsafe.Sizeof(raw)) - ret, _, _ := getRawInputData.Call( - uintptr(input), - uintptr(command), - uintptr(unsafe.Pointer(&raw)), - uintptr(unsafe.Pointer(&size)), - unsafe.Sizeof(raw.Header), - ) - var fail uint32 - fail-- - ok = uint32(ret) != fail - return -} - -func RegisterPowerSettingNotification( - recipient HANDLE, - powerSettingGUID *GUID, - flags uint32, -) HANDLE { - ret, _, _ := registerPowerSettingNotification.Call( - uintptr(recipient), - uintptr(unsafe.Pointer(powerSettingGUID)), - uintptr(flags), - ) - return HANDLE(ret) -} - -func RegisterRawInputDevices(devices ...RAWINPUTDEVICE) bool { - if len(devices) == 0 { - return true - } - ret, _, _ := registerRawInputDevices.Call( - uintptr(unsafe.Pointer(&devices[0])), - uintptr(len(devices)), - unsafe.Sizeof(devices[0]), - ) - return ret != 0 -} - -func SetTimer(window HWND, idEvent uintptr, elapse uint, timerFunc uintptr) uintptr { - ret, _, _ := setTimer.Call( - uintptr(window), - idEvent, - uintptr(elapse), - timerFunc, - ) - return ret -} - -func GetActiveWindow() HWND { - ret, _, _ := getActiveWindow.Call() - return HWND(ret) -} - -func MessageBeep(typ uint) bool { - ret, _, _ := messageBeep.Call(uintptr(typ)) - return ret != 0 -} - -// Beep generates simple tones on the speaker. The function is synchronous; it -// performs an alertable wait and does not return control to its caller until -// the sound finishes. -// The frequency must be in the range 37 through 32,767 (0x25 through 0x7FFF). -func Beep(frequencyInHz, durationInMs uint32) bool { - ret, _, _ := beep.Call(uintptr(frequencyInHz), uintptr(durationInMs)) - return ret != 0 -} - -// GetCaretBlinkTime returns the time required to invert the caret's pixels, in -// milliseconds. If the number is negative, the time is infinite and thus the -// cursor does not blink. -func GetCaretBlinkTime() int { - ret, _, _ := getCaretBlinkTime.Call() - return int(int32(ret)) -} - -func GetWindowDC(window HWND) HDC { - ret, _, _ := getWindowDC.Call(uintptr(window)) - return HDC(ret) -} - -func EnumWindows(callback func(window HWND) bool) bool { - f := syscall.NewCallback(func(w, _ uintptr) uintptr { - if callback(HWND(w)) { - return 1 - } - return 0 - }) - ret, _, _ := enumWindows.Call(f, 0) - return ret != 0 -} - -func EnumChildWindows(parent HWND, callback func(window HWND) bool) bool { - f := syscall.NewCallback(func(w, _ uintptr) uintptr { - if callback(HWND(w)) { - return 1 - } - return 0 - }) - ret, _, _ := enumChildWindows.Call(uintptr(parent), f, 0) - return ret != 0 -} - -func GetTopWindow(of HWND) HWND { - ret, _, _ := getTopWindow.Call(uintptr(of)) - return HWND(ret) -} - -func GetWindow(rel HWND, cmd uint) HWND { - ret, _, _ := getWindow.Call(uintptr(rel), uintptr(cmd)) - return HWND(ret) -} - -func GetNextWindow(rel HWND, cmd uint) HWND { - return GetWindow(rel, cmd) -} - -func GetKeyState(key int) uint16 { - ret, _, _ := getKeyState.Call(uintptr(key)) - return uint16(ret) -} - -func GetSysColor(index int) uint32 { - ret, _, _ := getSysColor.Call(uintptr(index)) - return uint32(ret) -} - -func GetSysColorBrush(index int) HBRUSH { - ret, _, _ := getSysColorBrush.Call(uintptr(index)) - return HBRUSH(ret) -} - -func AppendMenu(m HMENU, flags uint, id uintptr, item string) bool { - ret, _, _ := appendMenu.Call( - uintptr(m), - uintptr(flags), - id, - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(item))), - ) - return ret != 0 -} - -func CheckMenuItem(m HMENU, item, check uint) uint32 { - ret, _, _ := checkMenuItem.Call( - uintptr(m), - uintptr(item), - uintptr(check), - ) - return uint32(ret) -} - -func CheckMenuRadioItem(m HMENU, first, last, check, flags uint) bool { - ret, _, _ := checkMenuRadioItem.Call( - uintptr(m), - uintptr(first), - uintptr(last), - uintptr(check), - uintptr(flags), - ) - return ret != 0 -} - -func CreateMenu() HMENU { - ret, _, _ := createMenu.Call() - return HMENU(ret) -} - -func CreatePopupMenu() HMENU { - ret, _, _ := createPopupMenu.Call() - return HMENU(ret) -} - -func DeleteMenu(m HMENU, pos, flags uint) bool { - ret, _, _ := deleteMenu.Call( - uintptr(m), - uintptr(pos), - uintptr(flags), - ) - return ret != 0 -} - -func DestroyMenu(m HMENU) bool { - ret, _, _ := destroyMenu.Call(uintptr(m)) - return ret != 0 -} - -func DrawMenuBar(window HWND) bool { - ret, _, _ := drawMenuBar.Call(uintptr(window)) - return ret != 0 -} - -func EnableMenuItem(m HMENU, item, enable uint) int { - ret, _, _ := enableMenuItem.Call( - uintptr(m), - uintptr(item), - uintptr(enable), - ) - return int(ret) -} - -func EndMenu() bool { - ret, _, _ := endMenu.Call() - return ret != 0 -} - -func GetMenu(window HWND) HMENU { - ret, _, _ := getMenu.Call(uintptr(window)) - return HMENU(ret) -} - -func GetMenuBarInfo(w HWND, object, item int, info *MENUBARINFO) bool { - if info != nil { - info.size = uint32(unsafe.Sizeof(*info)) - } - ret, _, _ := getMenuBarInfo.Call( - uintptr(w), - uintptr(object), - uintptr(item), - uintptr(unsafe.Pointer(info)), - ) - return ret != 0 -} - -func GetMenuCheckMarkDimensions() (w, h int) { - ret, _, _ := getMenuCheckMarkDimensions.Call() - return int(ret & 0x00FFFF), int(ret&0xFFFF0000) >> 16 -} - -func GetMenuDefaultItem(m HMENU, byPos, flags uint) int { - ret, _, _ := getMenuDefaultItem.Call( - uintptr(m), - uintptr(byPos), - uintptr(flags), - ) - return int(ret) -} - -func GetMenuInfo(m HMENU, info *MENUINFO) bool { - if info != nil { - info.size = uint32(unsafe.Sizeof(*info)) - } - ret, _, _ := getMenuInfo.Call( - uintptr(m), - uintptr(unsafe.Pointer(info)), - ) - return ret != 0 -} - -func GetMenuItemCount(m HMENU) int { - ret, _, _ := getMenuItemCount.Call(uintptr(m)) - return int(ret) -} - -func GetMenuItemID(m HMENU, pos int) int { - ret, _, _ := getMenuItemID.Call(uintptr(m), uintptr(pos)) - return int(ret) -} - -func GetMenuItemInfo(m HMENU, item uint, byPos bool, info *MENUITEMINFO) bool { - if info != nil { - info.Size = uint32(unsafe.Sizeof(*info)) - } - ret, _, _ := getMenuItemInfo.Call( - uintptr(m), - uintptr(item), - uintptr(BoolToBOOL(byPos)), - uintptr(unsafe.Pointer(info)), - ) - return ret != 0 -} - -func GetMenuItemRect(w HWND, m HMENU, item uint, r *RECT) bool { - ret, _, _ := getMenuItemRect.Call( - uintptr(w), - uintptr(m), - uintptr(item), - uintptr(unsafe.Pointer(r)), - ) - return ret != 0 -} - -func GetMenuState(m HMENU, id, flags uint) int { - ret, _, _ := getMenuState.Call( - uintptr(m), - uintptr(id), - uintptr(flags), - ) - return int(ret) -} - -func GetMenuString(m HMENU, item, flags uint) string { - length, _, _ := getMenuString.Call( - uintptr(m), - uintptr(item), - 0, - 0, - uintptr(flags), - ) - if length == 0 { - return "" - } - buf := make([]uint16, length+1) - getMenuString.Call( - uintptr(m), - uintptr(item), - uintptr(unsafe.Pointer(&buf[0])), - length+1, - uintptr(flags), - ) - buf[length] = 0 - return syscall.UTF16ToString(buf) -} - -func GetSubMenu(menu HMENU, pos int) HMENU { - ret, _, _ := getSubMenu.Call(uintptr(menu), uintptr(pos)) - return HMENU(ret) -} - -func GetSystemMenu(w HWND, revert bool) HMENU { - ret, _, _ := getSystemMenu.Call( - uintptr(w), - uintptr(BoolToBOOL(revert)), - ) - return HMENU(ret) -} - -func HiliteMenuItem(w HWND, m HMENU, item, hilite uint) bool { - ret, _, _ := hiliteMenuItem.Call( - uintptr(w), - uintptr(m), - uintptr(item), - uintptr(hilite), - ) - return ret != 0 -} - -func InsertMenu(m HMENU, pos, flags uint, id uintptr, item string) bool { - ret, _, _ := insertMenu.Call( - uintptr(m), - uintptr(pos), - uintptr(flags), - id, - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(item))), - ) - return ret != 0 -} - -func InsertMenuItem(m HMENU, item uint, byPos bool, newItem *MENUITEMINFO) bool { - ret, _, _ := insertMenuItem.Call( - uintptr(m), - uintptr(item), - uintptr(BoolToBOOL(byPos)), - uintptr(unsafe.Pointer(newItem)), - ) - return ret != 0 -} - -func IsMenu(m HMENU) bool { - ret, _, _ := isMenu.Call(uintptr(m)) - return ret != 0 -} - -func LoadMenu(inst HINSTANCE, menuName string) HMENU { - ret, _, _ := loadMenu.Call( - uintptr(inst), - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(menuName))), - ) - return HMENU(ret) -} - -// TODO create nice API for this -func LoadMenuIndirect(template uintptr) HMENU { - ret, _, _ := loadMenuIndirect.Call(template) - return HMENU(ret) -} - -// ModifyMenu changes an existing menu item. This function is used to specify -// the content, appearance, and behavior of the menu item. -// -// Note The ModifyMenu function has been superseded by the SetMenuItemInfo -// function. You can still use ModifyMenu, however, if you do not need any of -// the extended features of SetMenuItemInfo. -func ModifyMenu(m HMENU, pos, flags uint, idNewItem uintptr, newItem string) bool { - ret, _, _ := modifyMenu.Call( - uintptr(m), - uintptr(pos), - uintptr(flags), - idNewItem, - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(newItem))), - ) - return ret != 0 -} - -// RemoveMenu deletes a menu item or detaches a submenu from the specified menu. -// If the menu item opens a drop-down menu or submenu, RemoveMenu does not -// destroy the menu or its handle, allowing the menu to be reused. Before this -// function is called, the GetSubMenu function should retrieve a handle to the -// drop-down menu or submenu. -func RemoveMenu(m HMENU, pos, flags uint) bool { - ret, _, _ := removeMenu.Call( - uintptr(m), - uintptr(pos), - uintptr(flags), - ) - return ret != 0 -} - -func SetMenu(w HWND, m HMENU) bool { - ret, _, _ := setMenu.Call(uintptr(w), uintptr(m)) - return ret != 0 -} - -// SetMenuDefaultItem sets the default menu item for the specified menu. -func SetMenuDefaultItem(m HMENU, item, byPos uint) bool { - ret, _, _ := setMenuDefaultItem.Call( - uintptr(m), - uintptr(item), - uintptr(byPos), - ) - return ret != 0 -} - -// SetMenuInfo sets information for a specified menu. -func SetMenuInfo(m HMENU, info *MENUINFO) bool { - ret, _, _ := setMenuInfo.Call( - uintptr(m), - uintptr(unsafe.Pointer(info)), - ) - return ret != 0 -} - -// SetMenuItemBitmaps associates the specified bitmap with a menu item. Whether -// the menu item is selected or clear, the system displays the appropriate -// bitmap next to the menu item. -func SetMenuItemBitmaps(m HMENU, pos, flags uint, unchecked, checked HBITMAP) bool { - ret, _, _ := setMenuItemBitmaps.Call( - uintptr(m), - uintptr(pos), - uintptr(flags), - uintptr(unchecked), - uintptr(checked), - ) - return ret != 0 -} - -// SetMenuItemInfo changes information about a menu item. -func SetMenuItemInfo(m HMENU, item uint, byPos bool, mii *MENUITEMINFO) bool { - if mii != nil { - mii.Size = uint32(unsafe.Sizeof(*mii)) - } - ret, _, _ := setMenuItemInfo.Call( - uintptr(m), - uintptr(item), - uintptr(BoolToBOOL(byPos)), - uintptr(unsafe.Pointer(mii)), - ) - return ret != 0 -} - -// TrackPopupMenu displays a shortcut menu at the specified location and tracks -// the selection of items on the menu. The shortcut menu can appear anywhere on -// the screen. -func TrackPopupMenu(m HMENU, flags uint, x, y int, w HWND, r *RECT) int { - ret, _, _ := trackPopupMenu.Call( - uintptr(m), - uintptr(flags), - uintptr(x), - uintptr(y), - 0, // reserved parameter - uintptr(w), - uintptr(unsafe.Pointer(r)), - ) - return int(ret) -} - -// TrackPopupMenuEx displays a shortcut menu at the specified location and -// tracks the selection of items on the shortcut menu. The shortcut menu can -// appear anywhere on the screen. -func TrackPopupMenuEx(m HMENU, flags uint, x, y int, w HWND, tpm *TPMPARAMS) int { - ret, _, _ := trackPopupMenuEx.Call( - uintptr(m), - uintptr(flags), - uintptr(x), - uintptr(y), - uintptr(w), - uintptr(unsafe.Pointer(tpm)), - ) - return int(ret) -} - -func IsDlgButtonChecked(dlg HWND, id uintptr) uint { - ret, _, _ := isDlgButtonChecked.Call(uintptr(dlg), id) - return uint(ret) -} - -func SendDlgItemMessage(dlg HWND, id int, msg uint, w, l uintptr) uintptr { - ret, _, _ := sendDlgItemMessage.Call( - uintptr(dlg), - uintptr(id), - uintptr(msg), - uintptr(w), - uintptr(l), - ) - return ret -} - -func LookupIconIdFromDirectoryEx(mem unsafe.Pointer, icon bool, width, height int, flags uint) int { - ret, _, _ := lookupIconIdFromDirectoryEx.Call( - uintptr(mem), - uintptr(BoolToBOOL(icon)), - uintptr(width), - uintptr(height), - uintptr(flags), - ) - return int(ret) -} - -func SetForegroundWindow(window HWND) bool { - ret, _, _ := setForegroundWindow.Call(uintptr(window)) - return ret != 0 -} - -func ScrollWindow(window HWND, dx, dy int, r, clip *RECT) bool { - ret, _, _ := scrollWindow.Call( - uintptr(window), - uintptr(dx), - uintptr(dy), - uintptr(unsafe.Pointer(r)), - uintptr(unsafe.Pointer(clip)), - ) - return ret != 0 -} - -func GetFocus() HWND { - ret, _, _ := getFocus.Call() - return HWND(ret) -} - -func PrintWindow(w HWND, dc HDC, flags uint) bool { - ret, _, _ := printWindow.Call( - uintptr(w), - uintptr(dc), - uintptr(flags), - ) - return ret != 0 -} - -func SetLayeredWindowAttributes(window HWND, key COLORREF, alpha uint8, flags uint32) bool { - ret, _, _ := setLayeredWindowAttributes.Call( - uintptr(window), - uintptr(key), - uintptr(alpha), - uintptr(flags), - ) - return ret != 0 -} - -func RedrawWindow(window HWND, updateRect *RECT, updateRegion HRGN, flags uint32) bool { - ret, _, _ := redrawWindow.Call( - uintptr(window), - uintptr(unsafe.Pointer(updateRect)), - uintptr(updateRegion), - uintptr(flags), - ) - return ret != 0 -} - -func CreateCursor( - instance HINSTANCE, - xHotSpot, yHotSpot, width, height int, - andPlane, xorPlane []byte, -) HCURSOR { - var and, xor uintptr - if len(andPlane) > 0 { - and = uintptr(unsafe.Pointer(&andPlane[0])) - } - if len(xorPlane) > 0 { - xor = uintptr(unsafe.Pointer(&xorPlane[0])) - } - ret, _, _ := createCursor.Call( - uintptr(instance), - uintptr(xHotSpot), - uintptr(yHotSpot), - uintptr(width), - uintptr(height), - and, - xor, - ) - return HCURSOR(ret) -} - -func DestroyCursor(c HCURSOR) bool { - ret, _, _ := destroyCursor.Call(uintptr(c)) - return ret != 0 -} - -func GetDlgCtrlID(w HWND) int { - ret, _, _ := getDlgCtrlID.Call(uintptr(w)) - return int(ret) -} - -func SystemParametersInfo(action, param uint, data uintptr, winIni uint) bool { - ret, _, _ := systemParametersInfo.Call( - uintptr(action), - uintptr(param), - data, - uintptr(winIni), - ) - return ret != 0 -} - -func SystemParametersInfoString(action, param uint, data string, winIni uint) bool { - return SystemParametersInfo( - action, - param, - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(data))), - winIni, - ) -} - -func RegCreateKey(hKey HKEY, subKey string) HKEY { - var result HKEY - ret, _, _ := regCreateKeyEx.Call( - uintptr(hKey), - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))), - uintptr(0), - uintptr(0), - uintptr(0), - uintptr(KEY_ALL_ACCESS), - uintptr(0), - uintptr(unsafe.Pointer(&result)), - uintptr(0)) - _ = ret - return result -} - -func RegOpenKeyEx(hKey HKEY, subKey string, samDesired uint32) HKEY { - var result HKEY - ret, _, _ := regOpenKeyEx.Call( - uintptr(hKey), - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))), - uintptr(0), - uintptr(samDesired), - uintptr(unsafe.Pointer(&result))) - if ret != ERROR_SUCCESS { - return HKEY(INVALID_HANDLE_VALUE) - } - return result -} - -func RegCloseKey(hKey HKEY) error { - var err error - ret, _, _ := regCloseKey.Call( - uintptr(hKey)) - - if ret != ERROR_SUCCESS { - err = errors.New("RegCloseKey failed") - } - return err -} - -func RegGetRaw(hKey HKEY, subKey string, value string) []byte { - var bufLen uint32 - var valptr unsafe.Pointer - if len(value) > 0 { - valptr = unsafe.Pointer(syscall.StringToUTF16Ptr(value)) - } - regGetValue.Call( - uintptr(hKey), - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))), - uintptr(valptr), - uintptr(RRF_RT_ANY), - 0, - 0, - uintptr(unsafe.Pointer(&bufLen)), - ) - - if bufLen == 0 { - return nil - } - - buf := make([]byte, bufLen) - ret, _, _ := regGetValue.Call( - uintptr(hKey), - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))), - uintptr(valptr), - uintptr(RRF_RT_ANY), - 0, - uintptr(unsafe.Pointer(&buf[0])), - uintptr(unsafe.Pointer(&bufLen)), - ) - - if ret != ERROR_SUCCESS { - return nil - } - - return buf -} - -func RegSetBinary(hKey HKEY, subKey string, value []byte) (errno int) { - var lptr, vptr unsafe.Pointer - if len(subKey) > 0 { - lptr = unsafe.Pointer(syscall.StringToUTF16Ptr(subKey)) - } - if len(value) > 0 { - vptr = unsafe.Pointer(&value[0]) - } - ret, _, _ := regSetValueEx.Call( - uintptr(hKey), - uintptr(lptr), - uintptr(0), - uintptr(REG_BINARY), - uintptr(vptr), - uintptr(len(value)), - ) - return int(ret) -} - -func RegSetString(hKey HKEY, subKey string, value string) (errno int) { - var lptr, vptr unsafe.Pointer - if subKey != "" { - lptr = unsafe.Pointer(syscall.StringToUTF16Ptr(subKey)) - } - var dataLength int - if value != "" { - buf, err := syscall.UTF16FromString(value) - if err != nil { - return ERROR_BAD_FORMAT - } - vptr = unsafe.Pointer(&buf[0]) - dataLength = len(buf) * 2 - } - ret, _, _ := regSetValueEx.Call( - uintptr(hKey), - uintptr(lptr), - uintptr(0), - uintptr(REG_SZ), - uintptr(vptr), - uintptr(dataLength), - ) - return int(ret) -} - -func RegSetUint32(hKey HKEY, subKey string, value uint32) (errno int) { - var lptr unsafe.Pointer - if len(subKey) > 0 { - lptr = unsafe.Pointer(syscall.StringToUTF16Ptr(subKey)) - } - vptr := unsafe.Pointer(&value) - ret, _, _ := regSetValueEx.Call( - uintptr(hKey), - uintptr(lptr), - uintptr(0), - uintptr(REG_DWORD), - uintptr(vptr), - uintptr(unsafe.Sizeof(value)), - ) - return int(ret) -} - -func RegGetString(hKey HKEY, subKey string, value string) string { - var bufLen uint32 - regGetValue.Call( - uintptr(hKey), - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))), - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(value))), - uintptr(RRF_RT_REG_SZ), - 0, - 0, - uintptr(unsafe.Pointer(&bufLen)), - ) - - if bufLen == 0 { - return "" - } - - buf := make([]uint16, bufLen) - ret, _, _ := regGetValue.Call( - uintptr(hKey), - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))), - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(value))), - uintptr(RRF_RT_REG_SZ), - 0, - uintptr(unsafe.Pointer(&buf[0])), - uintptr(unsafe.Pointer(&bufLen)), - ) - - if ret != ERROR_SUCCESS { - return "" - } - - return syscall.UTF16ToString(buf) -} - -func RegGetUint32(hKey HKEY, subKey string, value string) (data uint32, errno int) { - var dataLen uint32 = uint32(unsafe.Sizeof(data)) - ret, _, _ := regGetValue.Call( - uintptr(hKey), - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))), - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(value))), - uintptr(RRF_RT_REG_DWORD), - 0, - uintptr(unsafe.Pointer(&data)), - uintptr(unsafe.Pointer(&dataLen)), - ) - errno = int(ret) - return -} - -func RegDeleteKeyValue(hKey HKEY, subKey string, valueName string) (errno int) { - ret, _, _ := regDeleteKeyValue.Call( - uintptr(hKey), - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))), - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(valueName))), - ) - return int(ret) -} - -func RegDeleteValue(hKey HKEY, valueName string) (errno int) { - ret, _, _ := regDeleteValue.Call( - uintptr(hKey), - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(valueName))), - ) - return int(ret) -} - -func RegDeleteTree(hKey HKEY, subKey string) (errno int) { - ret, _, _ := regDeleteTree.Call( - uintptr(hKey), - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))), - ) - return int(ret) -} - -func RegEnumKeyEx(hKey HKEY, index uint32) string { - var bufLen uint32 = 255 - buf := make([]uint16, bufLen) - regEnumKeyEx.Call( - uintptr(hKey), - uintptr(index), - uintptr(unsafe.Pointer(&buf[0])), - uintptr(unsafe.Pointer(&bufLen)), - 0, - 0, - 0, - 0, - ) - return syscall.UTF16ToString(buf) -} - -func RegEnumValue(key HKEY, index uint32) { - var valueLen uint32 - _, _, _ = regEnumValue.Call( - uintptr(key), - uintptr(index), - 0, - uintptr(unsafe.Pointer(&valueLen)), - 0, - ) -} - -func OpenEventLog(servername string, sourcename string) HANDLE { - ret, _, _ := openEventLog.Call( - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(servername))), - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(sourcename))), - ) - return HANDLE(ret) -} - -func GetNumberOfEventLogRecords(eventlog HANDLE) (n uint32, ok bool) { - ret, _, _ := getNumberOfEventLogRecords.Call( - uintptr(eventlog), - uintptr(unsafe.Pointer(&n)), - ) - ok = ret != 0 - return -} - -func ReadEventLog(eventlog HANDLE, readflags, recordoffset uint32, buffer []byte, numberofbytestoread uint32, bytesread, minnumberofbytesneeded *uint32) bool { - ret, _, _ := readEventLog.Call( - uintptr(eventlog), - uintptr(readflags), - uintptr(recordoffset), - uintptr(unsafe.Pointer(&buffer[0])), - uintptr(numberofbytestoread), - uintptr(unsafe.Pointer(bytesread)), - uintptr(unsafe.Pointer(minnumberofbytesneeded)), - ) - return ret != 0 -} - -func CloseEventLog(eventlog HANDLE) bool { - ret, _, _ := closeEventLog.Call(uintptr(eventlog)) - return ret != 0 -} - -func OpenSCManager(lpMachineName, lpDatabaseName string, dwDesiredAccess uint32) (HANDLE, error) { - var p1, p2 uintptr - if len(lpMachineName) > 0 { - p1 = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpMachineName))) - } - if len(lpDatabaseName) > 0 { - p2 = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpDatabaseName))) - } - ret, _, _ := openSCManager.Call( - p1, - p2, - uintptr(dwDesiredAccess)) - - if ret == 0 { - return 0, syscall.GetLastError() - } - return HANDLE(ret), nil -} - -func CloseServiceHandle(hSCObject HANDLE) error { - ret, _, _ := closeServiceHandle.Call(uintptr(hSCObject)) - if ret == 0 { - return syscall.GetLastError() - } - return nil -} - -func OpenService(hSCManager HANDLE, lpServiceName string, dwDesiredAccess uint32) (HANDLE, error) { - ret, _, _ := openService.Call( - uintptr(hSCManager), - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpServiceName))), - uintptr(dwDesiredAccess), - ) - - if ret == 0 { - return 0, syscall.GetLastError() - } - - return HANDLE(ret), nil -} - -func StartService(hService HANDLE, lpServiceArgVectors []string) error { - l := len(lpServiceArgVectors) - var ret uintptr - if l == 0 { - ret, _, _ = startService.Call( - uintptr(hService), - 0, - 0, - ) - } else { - lpArgs := make([]uintptr, l) - for i := 0; i < l; i++ { - lpArgs[i] = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpServiceArgVectors[i]))) - } - - ret, _, _ = startService.Call( - uintptr(hService), - uintptr(l), - uintptr(unsafe.Pointer(&lpArgs[0])), - ) - } - - if ret == 0 { - return syscall.GetLastError() - } - - return nil -} - -func ControlService(service HANDLE, control uint32, serviceStatus *SERVICE_STATUS) bool { - ret, _, _ := controlService.Call( - uintptr(service), - uintptr(control), - uintptr(unsafe.Pointer(serviceStatus)), - ) - return ret != 0 -} - -func InitCommonControlsEx(lpInitCtrls *INITCOMMONCONTROLSEX) bool { - if lpInitCtrls != nil { - lpInitCtrls.size = 8 - } - ret, _, _ := initCommonControlsEx.Call(uintptr(unsafe.Pointer(lpInitCtrls))) - return ret != 0 -} - -func ImageList_Create(cx, cy int, flags uint, cInitial, cGrow int) HIMAGELIST { - ret, _, _ := imageList_Create.Call( - uintptr(cx), - uintptr(cy), - uintptr(flags), - uintptr(cInitial), - uintptr(cGrow), - ) - return HIMAGELIST(ret) -} - -func ImageList_Destroy(himl HIMAGELIST) bool { - ret, _, _ := imageList_Destroy.Call(uintptr(himl)) - return ret != 0 -} - -func ImageList_GetImageCount(himl HIMAGELIST) int { - ret, _, _ := imageList_GetImageCount.Call(uintptr(himl)) - return int(ret) -} - -func ImageList_SetImageCount(himl HIMAGELIST, uNewCount uint) bool { - ret, _, _ := imageList_SetImageCount.Call( - uintptr(himl), - uintptr(uNewCount), - ) - return ret != 0 -} - -func ImageList_Add(himl HIMAGELIST, hbmImage, hbmMask HBITMAP) int { - ret, _, _ := imageList_Add.Call( - uintptr(himl), - uintptr(hbmImage), - uintptr(hbmMask), - ) - return int(ret) -} - -func ImageList_ReplaceIcon(himl HIMAGELIST, i int, hicon HICON) int { - ret, _, _ := imageList_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, _, _ := imageList_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, _, _ := trackMouseEvent.Call(uintptr(unsafe.Pointer(tme))) - return ret != 0 -} - -func SetWindowSubclass(window HWND, proc uintptr, id uintptr, refData uintptr) bool { - ret, _, _ := setWindowSubclass.Call( - uintptr(window), - proc, - uintptr(id), - refData, - ) - return ret != 0 -} - -func DefSubclassProc(window HWND, msg uint32, w, l uintptr) uintptr { - ret, _, _ := defSubclassProc.Call( - uintptr(window), - uintptr(msg), - w, - l, - ) - return ret -} - -// GetOpenFileName automatically sets the StructSize member of the OPENFILENAME. -func GetOpenFileName(ofn *OPENFILENAME) bool { - if ofn != nil { - ofn.StructSize = uint32(unsafe.Sizeof(*ofn)) - } - ret, _, _ := getOpenFileName.Call(uintptr(unsafe.Pointer(ofn))) - return ret != 0 -} - -// GetSaveFileName automatically sets the StructSize member of the OPENFILENAME. -func GetSaveFileName(ofn *OPENFILENAME) bool { - if ofn != nil { - ofn.StructSize = uint32(unsafe.Sizeof(*ofn)) - } - ret, _, _ := getSaveFileName.Call(uintptr(unsafe.Pointer(ofn))) - return ret != 0 -} - -func CommDlgExtendedError() uint { - ret, _, _ := commDlgExtendedError.Call() - return uint(ret) -} - -func DwmDefWindowProc(hWnd HWND, msg uint, wParam, lParam uintptr) (bool, uint) { - var result uint - ret, _, _ := dwmDefWindowProc.Call( - uintptr(hWnd), - uintptr(msg), - wParam, - lParam, - uintptr(unsafe.Pointer(&result)), - ) - return ret != 0, result -} - -func DwmEnableBlurBehindWindow(hWnd HWND, pBlurBehind *DWM_BLURBEHIND) HRESULT { - ret, _, _ := dwmEnableBlurBehindWindow.Call( - uintptr(hWnd), - uintptr(unsafe.Pointer(pBlurBehind)), - ) - return HRESULT(ret) -} - -func DwmEnableMMCSS(fEnableMMCSS bool) HRESULT { - ret, _, _ := dwmEnableMMCSS.Call(uintptr(BoolToBOOL(fEnableMMCSS))) - return HRESULT(ret) -} - -func DwmExtendFrameIntoClientArea(hWnd HWND, pMarInset *MARGINS) HRESULT { - ret, _, _ := dwmExtendFrameIntoClientArea.Call( - uintptr(hWnd), - uintptr(unsafe.Pointer(pMarInset)), - ) - return HRESULT(ret) -} - -func DwmFlush() HRESULT { - ret, _, _ := dwmFlush.Call() - return HRESULT(ret) -} - -func DwmGetColorizationColor(pcrColorization *uint32, pfOpaqueBlend *BOOL) HRESULT { - ret, _, _ := dwmGetColorizationColor.Call( - uintptr(unsafe.Pointer(pcrColorization)), - uintptr(unsafe.Pointer(pfOpaqueBlend)), - ) - return HRESULT(ret) -} - -func DwmGetCompositionTimingInfo(hWnd HWND, pTimingInfo *DWM_TIMING_INFO) HRESULT { - ret, _, _ := dwmGetCompositionTimingInfo.Call( - uintptr(hWnd), - uintptr(unsafe.Pointer(pTimingInfo)), - ) - return HRESULT(ret) -} - -func DwmGetTransportAttributes(pfIsRemoting *BOOL, pfIsConnected *BOOL, pDwGeneration *uint32) HRESULT { - ret, _, _ := dwmGetTransportAttributes.Call( - uintptr(unsafe.Pointer(pfIsRemoting)), - uintptr(unsafe.Pointer(pfIsConnected)), - uintptr(unsafe.Pointer(pDwGeneration)), - ) - return HRESULT(ret) -} - -func DwmGetWindowAttributeNCRENDERING_ENABLED(window HWND) (ok, enabled bool) { - var b uint32 - ret, _, _ := dwmGetWindowAttribute.Call( - uintptr(window), - uintptr(DWMWA_NCRENDERING_ENABLED), - uintptr(unsafe.Pointer(&b)), - 4, // size of uint32 - ) - ok = ret == S_OK - enabled = b != 0 - return -} - -func DwmGetWindowAttributeCAPTION_BUTTON_BOUNDS(window HWND) (ok bool, r RECT) { - ret, _, _ := dwmGetWindowAttribute.Call( - uintptr(window), - uintptr(DWMWA_CAPTION_BUTTON_BOUNDS), - uintptr(unsafe.Pointer(&r)), - 16, // size of RECT - ) - ok = ret == S_OK - return -} - -func DwmGetWindowAttributeEXTENDED_FRAME_BOUNDS(window HWND) (ok bool, r RECT) { - ret, _, _ := dwmGetWindowAttribute.Call( - uintptr(window), - uintptr(DWMWA_EXTENDED_FRAME_BOUNDS), - uintptr(unsafe.Pointer(&r)), - 16, // size of RECT - ) - ok = ret == S_OK - return -} - -// DwmGetWindowAttributeCLOAKED returns one of the DWM_... constants. -func DwmGetWindowAttributeCLOAKED(window HWND) (ok bool, cloaked uint32) { - ret, _, _ := dwmGetWindowAttribute.Call( - uintptr(window), - uintptr(DWMWA_CLOAKED), - uintptr(unsafe.Pointer(&cloaked)), - 16, // size of uint32 - ) - ok = ret == S_OK - return -} - -func DwmInvalidateIconicBitmaps(hWnd HWND) HRESULT { - ret, _, _ := dwmInvalidateIconicBitmaps.Call(uintptr(hWnd)) - return HRESULT(ret) -} - -func DwmIsCompositionEnabled(pfEnabled *BOOL) HRESULT { - ret, _, _ := dwmIsCompositionEnabled.Call(uintptr(unsafe.Pointer(pfEnabled))) - return HRESULT(ret) -} - -func DwmModifyPreviousDxFrameDuration(hWnd HWND, cRefreshes int, fRelative bool) HRESULT { - ret, _, _ := dwmModifyPreviousDxFrameDuration.Call( - uintptr(hWnd), - uintptr(cRefreshes), - uintptr(BoolToBOOL(fRelative)), - ) - return HRESULT(ret) -} - -func DwmQueryThumbnailSourceSize(hThumbnail HTHUMBNAIL, pSize *SIZE) HRESULT { - ret, _, _ := dwmQueryThumbnailSourceSize.Call( - uintptr(hThumbnail), - uintptr(unsafe.Pointer(pSize)), - ) - return HRESULT(ret) -} - -func DwmRegisterThumbnail(hWndDestination HWND, hWndSource HWND, phThumbnailId *HTHUMBNAIL) HRESULT { - ret, _, _ := dwmRegisterThumbnail.Call( - uintptr(hWndDestination), - uintptr(hWndSource), - uintptr(unsafe.Pointer(phThumbnailId)), - ) - return HRESULT(ret) -} - -func DwmRenderGesture(gt GESTURE_TYPE, cContacts uint, pdwPointerID *uint32, pPoints *POINT) { - dwmRenderGesture.Call( - uintptr(gt), - uintptr(cContacts), - uintptr(unsafe.Pointer(pdwPointerID)), - uintptr(unsafe.Pointer(pPoints)), - ) - return -} - -func DwmSetDxFrameDuration(hWnd HWND, cRefreshes int) HRESULT { - ret, _, _ := dwmSetDxFrameDuration.Call( - uintptr(hWnd), - uintptr(cRefreshes), - ) - return HRESULT(ret) -} - -func DwmSetIconicLivePreviewBitmap(hWnd HWND, hbmp HBITMAP, pptClient *POINT, dwSITFlags uint32) HRESULT { - ret, _, _ := dwmSetIconicLivePreviewBitmap.Call( - uintptr(hWnd), - uintptr(hbmp), - uintptr(unsafe.Pointer(pptClient)), - uintptr(dwSITFlags), - ) - return HRESULT(ret) -} - -func DwmSetIconicThumbnail(hWnd HWND, hbmp HBITMAP, dwSITFlags uint32) HRESULT { - ret, _, _ := dwmSetIconicThumbnail.Call( - uintptr(hWnd), - uintptr(hbmp), - uintptr(dwSITFlags), - ) - return HRESULT(ret) -} - -func DwmSetPresentParameters(hWnd HWND, pPresentParams *DWM_PRESENT_PARAMETERS) HRESULT { - ret, _, _ := dwmSetPresentParameters.Call( - uintptr(hWnd), - uintptr(unsafe.Pointer(pPresentParams)), - ) - return HRESULT(ret) -} - -func DwmSetWindowAttribute(hWnd HWND, dwAttribute uint32, pvAttribute LPCVOID, cbAttribute uint32) HRESULT { - ret, _, _ := dwmSetWindowAttribute.Call( - uintptr(hWnd), - uintptr(dwAttribute), - uintptr(pvAttribute), - uintptr(cbAttribute), - ) - return HRESULT(ret) -} - -func DwmShowContact(dwPointerID uint32, eShowContact DWM_SHOWCONTACT) { - dwmShowContact.Call( - uintptr(dwPointerID), - uintptr(eShowContact), - ) - return -} - -func DwmTetherContact(dwPointerID uint32, fEnable bool, ptTether POINT) { - dwmTetherContact.Call( - uintptr(dwPointerID), - uintptr(BoolToBOOL(fEnable)), - uintptr(unsafe.Pointer(&ptTether)), - ) - return -} - -func DwmTransitionOwnedWindow(hWnd HWND, target DWMTRANSITION_OWNEDWINDOW_TARGET) { - dwmTransitionOwnedWindow.Call( - uintptr(hWnd), - uintptr(target), - ) - return -} - -func DwmUnregisterThumbnail(hThumbnailId HTHUMBNAIL) HRESULT { - ret, _, _ := dwmUnregisterThumbnail.Call(uintptr(hThumbnailId)) - return HRESULT(ret) -} - -func DwmUpdateThumbnailProperties(hThumbnailId HTHUMBNAIL, ptnProperties *DWM_THUMBNAIL_PROPERTIES) HRESULT { - ret, _, _ := dwmUpdateThumbnailProperties.Call( - uintptr(hThumbnailId), - uintptr(unsafe.Pointer(ptnProperties)), - ) - return HRESULT(ret) -} - -func GetDeviceCaps(hdc HDC, index int) int { - ret, _, _ := getDeviceCaps.Call( - uintptr(hdc), - uintptr(index), - ) - return int(ret) -} - -func DeleteObject(hObject HGDIOBJ) bool { - ret, _, _ := deleteObject.Call(uintptr(hObject)) - return ret != 0 -} - -func CreateFontIndirect(logFont *LOGFONT) HFONT { - ret, _, _ := createFontIndirect.Call(uintptr(unsafe.Pointer(logFont))) - return HFONT(ret) -} - -func AbortDoc(hdc HDC) int { - ret, _, _ := abortDoc.Call(uintptr(hdc)) - return int(ret) -} - -func BitBlt(hdcDest HDC, nXDest, nYDest, nWidth, nHeight int, hdcSrc HDC, nXSrc, nYSrc int, dwRop uint) bool { - ret, _, _ := bitBlt.Call( - uintptr(hdcDest), - uintptr(nXDest), - uintptr(nYDest), - uintptr(nWidth), - uintptr(nHeight), - uintptr(hdcSrc), - uintptr(nXSrc), - uintptr(nYSrc), - uintptr(dwRop), - ) - return ret != 0 -} - -func MaskBlt( - dest HDC, destX, destY, destWidth, destHeight int, - source HDC, sourceX, sourceY int, - mask HBITMAP, maskX, maskY int, - operation uint, -) bool { - ret, _, _ := maskBlt.Call( - uintptr(dest), - uintptr(destX), - uintptr(destY), - uintptr(destWidth), - uintptr(destHeight), - uintptr(source), - uintptr(sourceX), - uintptr(sourceY), - uintptr(mask), - uintptr(maskX), - uintptr(maskX), - uintptr(operation), - ) - return ret != 0 -} - -func PatBlt(hdc HDC, nXLeft, nYLeft, nWidth, nHeight int, dwRop uint) bool { - ret, _, _ := patBlt.Call( - uintptr(hdc), - uintptr(nXLeft), - uintptr(nYLeft), - uintptr(nWidth), - uintptr(nHeight), - uintptr(dwRop), - ) - return ret != 0 -} - -func CloseEnhMetaFile(hdc HDC) HENHMETAFILE { - ret, _, _ := closeEnhMetaFile.Call(uintptr(hdc)) - return HENHMETAFILE(ret) -} - -func CopyEnhMetaFile(hemfSrc HENHMETAFILE, lpszFile *uint16) HENHMETAFILE { - ret, _, _ := copyEnhMetaFile.Call( - uintptr(hemfSrc), - uintptr(unsafe.Pointer(lpszFile)), - ) - return HENHMETAFILE(ret) -} - -func CreateBrushIndirect(lplb *LOGBRUSH) HBRUSH { - ret, _, _ := createBrushIndirect.Call(uintptr(unsafe.Pointer(lplb))) - return HBRUSH(ret) -} - -func CreateCompatibleDC(hdc HDC) HDC { - ret, _, _ := createCompatibleDC.Call(uintptr(hdc)) - return HDC(ret) -} - -func CreateCompatibleBitmap(hdc HDC, width, height int) HBITMAP { - ret, _, _ := createCompatibleBitmap.Call( - uintptr(hdc), - uintptr(width), - uintptr(height), - ) - return HBITMAP(ret) -} - -func CreateBitmap(width, height int, planes, bitCount uint, bits unsafe.Pointer) HBITMAP { - ret, _, _ := createBitmap.Call( - uintptr(width), - uintptr(height), - uintptr(planes), - uintptr(bitCount), - uintptr(bits), - ) - return HBITMAP(ret) -} - -func CreateDC(lpszDriver, lpszDevice, lpszOutput *uint16, lpInitData *DEVMODE) HDC { - ret, _, _ := createDC.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, _, _ := createDIBSection.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, _, _ := createEnhMetaFile.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, _, _ := createIC.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, _, _ := deleteDC.Call(uintptr(hdc)) - return ret != 0 -} - -func DeleteEnhMetaFile(hemf HENHMETAFILE) bool { - ret, _, _ := deleteEnhMetaFile.Call(uintptr(hemf)) - return ret != 0 -} - -func Ellipse(hdc HDC, nLeftRect, nTopRect, nRightRect, nBottomRect int) bool { - ret, _, _ := ellipse.Call( - uintptr(hdc), - uintptr(nLeftRect), - uintptr(nTopRect), - uintptr(nRightRect), - uintptr(nBottomRect), - ) - return ret != 0 -} - -func EndDoc(hdc HDC) int { - ret, _, _ := endDoc.Call(uintptr(hdc)) - return int(ret) -} - -func EndPage(hdc HDC) int { - ret, _, _ := endPage.Call(uintptr(hdc)) - return int(ret) -} - -func ExtCreatePen(dwPenStyle, dwWidth uint, lplb *LOGBRUSH, dwStyleCount uint, lpStyle *uint) HPEN { - ret, _, _ := extCreatePen.Call( - uintptr(dwPenStyle), - uintptr(dwWidth), - uintptr(unsafe.Pointer(lplb)), - uintptr(dwStyleCount), - uintptr(unsafe.Pointer(lpStyle)), - ) - return HPEN(ret) -} - -func GetEnhMetaFile(lpszMetaFile *uint16) HENHMETAFILE { - ret, _, _ := getEnhMetaFile.Call(uintptr(unsafe.Pointer(lpszMetaFile))) - return HENHMETAFILE(ret) -} - -func GetEnhMetaFileHeader(hemf HENHMETAFILE, cbBuffer uint, lpemh *ENHMETAHEADER) uint { - ret, _, _ := getEnhMetaFileHeader.Call( - uintptr(hemf), - uintptr(cbBuffer), - uintptr(unsafe.Pointer(lpemh)), - ) - return uint(ret) -} - -func GetObject(hgdiobj HGDIOBJ, cbBuffer uintptr, lpvObject unsafe.Pointer) int { - ret, _, _ := getObject.Call( - uintptr(hgdiobj), - uintptr(cbBuffer), - uintptr(lpvObject), - ) - return int(ret) -} - -func GetStockObject(fnObject int) HGDIOBJ { - ret, _, _ := getStockObject.Call(uintptr(fnObject)) - return HGDIOBJ(ret) -} - -func GetTextExtentExPoint(hdc HDC, lpszStr *uint16, cchString, nMaxExtent int, lpnFit, alpDx *int, lpSize *SIZE) bool { - ret, _, _ := getTextExtentExPoint.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, text string) (SIZE, bool) { - var s SIZE - str, err := syscall.UTF16FromString(text) - if err != nil { - return s, false - } - ret, _, _ := getTextExtentPoint32.Call( - uintptr(hdc), - uintptr(unsafe.Pointer(&str[0])), - uintptr(len(str)-1), // -1 for the trailing '\0' - uintptr(unsafe.Pointer(&s)), - ) - return s, ret != 0 -} - -func GetTextMetrics(hdc HDC, lptm *TEXTMETRIC) bool { - ret, _, _ := getTextMetrics.Call( - uintptr(hdc), - uintptr(unsafe.Pointer(lptm)), - ) - return ret != 0 -} - -func LineTo(hdc HDC, nXEnd, nYEnd int) bool { - ret, _, _ := lineTo.Call( - uintptr(hdc), - uintptr(nXEnd), - uintptr(nYEnd), - ) - return ret != 0 -} - -func MoveToEx(hdc HDC, x, y int, lpPoint *POINT) bool { - ret, _, _ := moveToEx.Call( - uintptr(hdc), - uintptr(x), - uintptr(y), - uintptr(unsafe.Pointer(lpPoint)), - ) - return ret != 0 -} - -func PlayEnhMetaFile(hdc HDC, hemf HENHMETAFILE, lpRect *RECT) bool { - ret, _, _ := playEnhMetaFile.Call( - uintptr(hdc), - uintptr(hemf), - uintptr(unsafe.Pointer(lpRect)), - ) - return ret != 0 -} - -func Rectangle(hdc HDC, nLeftRect, nTopRect, nRightRect, nBottomRect int) bool { - ret, _, _ := rectangle.Call( - uintptr(hdc), - uintptr(nLeftRect), - uintptr(nTopRect), - uintptr(nRightRect), - uintptr(nBottomRect), - ) - return ret != 0 -} - -func ResetDC(hdc HDC, lpInitData *DEVMODE) HDC { - ret, _, _ := resetDC.Call( - uintptr(hdc), - uintptr(unsafe.Pointer(lpInitData)), - ) - return HDC(ret) -} - -func SelectObject(hdc HDC, hgdiobj HGDIOBJ) HGDIOBJ { - ret, _, _ := selectObject.Call( - uintptr(hdc), - uintptr(hgdiobj), - ) - return HGDIOBJ(ret) -} - -func SetBkMode(hdc HDC, iBkMode int) int { - ret, _, _ := setBkMode.Call( - uintptr(hdc), - uintptr(iBkMode), - ) - return int(ret) -} - -func SetBrushOrgEx(hdc HDC, nXOrg, nYOrg int, lppt *POINT) bool { - ret, _, _ := setBrushOrgEx.Call( - uintptr(hdc), - uintptr(nXOrg), - uintptr(nYOrg), - uintptr(unsafe.Pointer(lppt)), - ) - return ret != 0 -} - -func SetStretchBltMode(hdc HDC, iStretchMode int) int { - ret, _, _ := setStretchBltMode.Call( - uintptr(hdc), - uintptr(iStretchMode), - ) - return int(ret) -} - -func SetTextColor(hdc HDC, crColor COLORREF) COLORREF { - ret, _, _ := setTextColor.Call( - uintptr(hdc), - uintptr(crColor), - ) - return COLORREF(ret) -} - -func SetBkColor(hdc HDC, crColor COLORREF) COLORREF { - ret, _, _ := setBkColor.Call( - uintptr(hdc), - uintptr(crColor), - ) - return COLORREF(ret) -} - -func StartDoc(hdc HDC, lpdi *DOCINFO) int { - ret, _, _ := startDoc.Call( - uintptr(hdc), - uintptr(unsafe.Pointer(lpdi)), - ) - return int(ret) -} - -func StartPage(hdc HDC) int { - ret, _, _ := startPage.Call(uintptr(hdc)) - return int(ret) -} - -func StretchBlt(hdcDest HDC, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest int, hdcSrc HDC, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc int, dwRop uint) bool { - ret, _, _ := stretchBlt.Call( - uintptr(hdcDest), - uintptr(nXOriginDest), - uintptr(nYOriginDest), - uintptr(nWidthDest), - uintptr(nHeightDest), - uintptr(hdcSrc), - uintptr(nXOriginSrc), - uintptr(nYOriginSrc), - uintptr(nWidthSrc), - uintptr(nHeightSrc), - uintptr(dwRop), - ) - return ret != 0 -} - -func SetDIBitsToDevice(hdc HDC, xDest, yDest, dwWidth, dwHeight, xSrc, ySrc int, uStartScan, cScanLines uint, lpvBits []byte, lpbmi *BITMAPINFO, fuColorUse uint) int { - ret, _, _ := setDIBitsToDevice.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, _, _ := choosePixelFormat.Call( - uintptr(hdc), - uintptr(unsafe.Pointer(pfd)), - ) - return int(ret) -} - -func DescribePixelFormat(hdc HDC, iPixelFormat int, nBytes uint, pfd *PIXELFORMATDESCRIPTOR) int { - ret, _, _ := describePixelFormat.Call( - uintptr(hdc), - uintptr(iPixelFormat), - uintptr(nBytes), - uintptr(unsafe.Pointer(pfd)), - ) - return int(ret) -} - -func GetEnhMetaFilePixelFormat(hemf HENHMETAFILE, cbBuffer uint32, pfd *PIXELFORMATDESCRIPTOR) uint { - ret, _, _ := getEnhMetaFilePixelFormat.Call( - uintptr(hemf), - uintptr(cbBuffer), - uintptr(unsafe.Pointer(pfd)), - ) - return uint(ret) -} - -func GetPixelFormat(hdc HDC) int { - ret, _, _ := getPixelFormat.Call(uintptr(hdc)) - return int(ret) -} - -func SetPixelFormat(hdc HDC, iPixelFormat int, pfd *PIXELFORMATDESCRIPTOR) bool { - ret, _, _ := setPixelFormat.Call( - uintptr(hdc), - uintptr(iPixelFormat), - uintptr(unsafe.Pointer(pfd)), - ) - return ret == TRUE -} - -func SwapBuffers(hdc HDC) bool { - ret, _, _ := swapBuffers.Call(uintptr(hdc)) - return ret == TRUE -} - -func TextOut(hdc HDC, x, y int, s string) bool { - str, err := syscall.UTF16FromString(s) - if err != nil { - return false - } - ret, _, _ := textOut.Call( - uintptr(hdc), - uintptr(x), - uintptr(y), - uintptr(unsafe.Pointer(&str[0])), - uintptr(len(str)-1), // -1 for the trailing '\0' - ) - return ret != 0 -} - -func CreateSolidBrush(color uint32) HBRUSH { - ret, _, _ := createSolidBrush.Call(uintptr(color)) - return HBRUSH(ret) -} - -func GetDIBits( - dc HDC, - bmp HBITMAP, - startScan, scanLines uint, - bits unsafe.Pointer, - info *BITMAPINFO, - usage uint, -) int { - ret, _, _ := getDIBits.Call( - uintptr(dc), - uintptr(bmp), - uintptr(startScan), - uintptr(scanLines), - uintptr(bits), - uintptr(unsafe.Pointer(info)), - uintptr(usage), - ) - return int(ret) -} - -func Pie(hdc HDC, left, top, right, bottom, xr1, yr1, xr2, yr2 int) bool { - ret, _, _ := pie.Call( - uintptr(hdc), - uintptr(left), - uintptr(top), - uintptr(right), - uintptr(bottom), - uintptr(xr1), - uintptr(yr1), - uintptr(xr2), - uintptr(yr2), - ) - return ret != 0 -} - -func SetDCPenColor(hdc HDC, color COLORREF) COLORREF { - ret, _, _ := setDCPenColor.Call(uintptr(hdc), uintptr(color)) - return COLORREF(ret) -} - -func SetDCBrushColor(hdc HDC, color COLORREF) COLORREF { - ret, _, _ := setDCBrushColor.Call(uintptr(hdc), uintptr(color)) - return COLORREF(ret) -} - -func CreatePen(style int, width int, color COLORREF) HPEN { - ret, _, _ := createPen.Call( - uintptr(style), - uintptr(width), - uintptr(color), - ) - return HPEN(ret) -} - -func Arc(hdc HDC, x1, y1, x2, y2, x3, y3, x4, y4 int) bool { - ret, _, _ := arc.Call( - uintptr(hdc), - uintptr(x1), - uintptr(y1), - uintptr(x2), - uintptr(y2), - uintptr(x3), - uintptr(y3), - uintptr(x4), - uintptr(y4), - ) - return ret != 0 -} - -func ArcTo(hdc HDC, left, top, right, bottom, xr1, yr1, xr2, yr2 int) bool { - ret, _, _ := arcTo.Call( - uintptr(hdc), - uintptr(left), - uintptr(top), - uintptr(right), - uintptr(bottom), - uintptr(xr1), - uintptr(yr1), - uintptr(xr2), - uintptr(yr2), - ) - return ret != 0 -} - -func AngleArc(hdc HDC, x, y, r int, startAngle, sweepAngle float32) bool { - ret, _, _ := angleArc.Call( - uintptr(hdc), - uintptr(x), - uintptr(y), - uintptr(r), - uintptr(startAngle), - uintptr(sweepAngle), - ) - return ret != 0 -} - -func Chord(hdc HDC, x1, y1, x2, y2, x3, y3, x4, y4 int) bool { - ret, _, _ := chord.Call( - uintptr(hdc), - uintptr(x1), - uintptr(y1), - uintptr(x2), - uintptr(y2), - uintptr(x3), - uintptr(y3), - uintptr(x4), - uintptr(y4), - ) - return ret != 0 -} - -func Polygon(hdc HDC, p []POINT) bool { - if len(p) == 0 { - return true - } - ret, _, _ := polygon.Call( - uintptr(hdc), - uintptr(unsafe.Pointer(&p[0])), - uintptr(len(p)), - ) - return ret != 0 -} - -func PolygonMem(hdc HDC, start unsafe.Pointer, pointCount int) bool { - ret, _, _ := polygon.Call( - uintptr(hdc), - uintptr(start), - uintptr(pointCount), - ) - return ret != 0 -} - -func Polyline(hdc HDC, p []POINT) bool { - if len(p) == 0 { - return true - } - ret, _, _ := polyline.Call( - uintptr(hdc), - uintptr(unsafe.Pointer(&p[0])), - uintptr(len(p)), - ) - return ret != 0 -} - -func PolylineMem(hdc HDC, start unsafe.Pointer, pointCount int) bool { - ret, _, _ := polyline.Call( - uintptr(hdc), - uintptr(start), - uintptr(pointCount), - ) - return ret != 0 -} - -func PolyBezier(hdc HDC, p []POINT) bool { - if len(p) == 0 { - return true - } - ret, _, _ := polyBezier.Call( - uintptr(hdc), - uintptr(unsafe.Pointer(&p[0])), - uintptr(len(p)), - ) - return ret != 0 -} - -func PolyBezierMem(hdc HDC, start unsafe.Pointer, pointCount int) bool { - ret, _, _ := polyline.Call( - uintptr(hdc), - uintptr(start), - uintptr(pointCount), - ) - return ret != 0 -} - -func IntersectClipRect(hdc HDC, left, top, right, bottom int) int { - ret, _, _ := intersectClipRect.Call( - uintptr(hdc), - uintptr(left), - uintptr(top), - uintptr(right), - uintptr(bottom), - ) - return int(ret) -} - -func SelectClipRgn(hdc HDC, region HRGN) int { - ret, _, _ := selectClipRgn.Call(uintptr(hdc), uintptr(region)) - return int(ret) -} - -func CreateRectRgn(x1, y1, x2, y2 int) HRGN { - ret, _, _ := createRectRgn.Call( - uintptr(x1), - uintptr(y1), - uintptr(x2), - uintptr(y2), - ) - return HRGN(ret) -} - -func CombineRgn(dest, src1, src2 HRGN, mode int) int { - ret, _, _ := combineRgn.Call( - uintptr(dest), - uintptr(src1), - uintptr(src2), - uintptr(mode), - ) - return int(ret) -} - -type FontType int - -const ( - RASTER_FONTTYPE FontType = 1 - DEVICE_FONTTYPE FontType = 2 - TRUETYPE_FONTTYPE FontType = 4 -) - -func (t FontType) String() string { - switch t { - case RASTER_FONTTYPE: - return "RASTER_FONTTYPE" - case DEVICE_FONTTYPE: - return "DEVICE_FONTTYPE" - case TRUETYPE_FONTTYPE: - return "TRUETYPE_FONTTYPE" - } - return strconv.Itoa(int(t)) -} - -func EnumFontFamiliesEx(hdc HDC, font LOGFONT, f func(font *ENUMLOGFONTEX, metric *ENUMTEXTMETRIC, fontType FontType) bool) { - callback := syscall.NewCallback(func(font, metric uintptr, typ uint32, _ uintptr) uintptr { - if f( - (*ENUMLOGFONTEX)(unsafe.Pointer(font)), - (*ENUMTEXTMETRIC)(unsafe.Pointer(metric)), - FontType(typ), - ) { - return 1 - } - return 0 - }) - enumFontFamiliesEx.Call( - uintptr(hdc), - uintptr(unsafe.Pointer(&font)), - callback, - 0, - 0, - ) -} - -func GetModuleHandle(modulename string) HINSTANCE { - var mn uintptr - if modulename == "" { - mn = 0 - } else { - mn = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(modulename))) - } - ret, _, _ := getModuleHandle.Call(mn) - return HINSTANCE(ret) -} - -func GetModuleFileName(mod HMODULE) string { - var path [32768]uint16 - ret, _, _ := getModuleFileName.Call( - uintptr(mod), - uintptr(unsafe.Pointer(&path[0])), - uintptr(len(path)), - ) - if ret == 0 { - return "" - } - return syscall.UTF16ToString(path[:]) -} - -func MulDiv(number, numerator, denominator int) int { - ret, _, _ := mulDiv.Call( - uintptr(number), - uintptr(numerator), - uintptr(denominator), - ) - return int(ret) -} - -func GetConsoleWindow() HWND { - ret, _, _ := getConsoleWindow.Call() - return HWND(ret) -} - -func GetCurrentThread() HANDLE { - ret, _, _ := getCurrentThread.Call() - return HANDLE(ret) -} - -func GetCurrentThreadId() HANDLE { - ret, _, _ := getCurrentThreadId.Call() - return HANDLE(ret) -} - -func GetLogicalDrives() uint32 { - ret, _, _ := getLogicalDrives.Call() - return uint32(ret) -} - -func GetDriveType(drive string) uint { - ret, _, _ := getDriveType.Call(uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(drive)))) - return uint(ret) -} - -func GetUserDefaultLCID() uint32 { - ret, _, _ := getUserDefaultLCID.Call() - return uint32(ret) -} - -func Lstrlen(lpString *uint16) int { - ret, _, _ := lstrlen.Call(uintptr(unsafe.Pointer(lpString))) - return int(ret) -} - -func Lstrcpy(buf []uint16, lpString *uint16) { - lstrcpy.Call( - uintptr(unsafe.Pointer(&buf[0])), - uintptr(unsafe.Pointer(lpString)), - ) -} - -func GlobalAlloc(uFlags uint, dwBytes uint32) HGLOBAL { - ret, _, _ := globalAlloc.Call( - uintptr(uFlags), - uintptr(dwBytes)) - return HGLOBAL(ret) -} - -func GlobalFree(hMem HGLOBAL) { - globalFree.Call(uintptr(hMem)) -} - -func GlobalLock(hMem HGLOBAL) unsafe.Pointer { - ret, _, _ := globalLock.Call(uintptr(hMem)) - return unsafe.Pointer(ret) -} - -func GlobalUnlock(hMem HGLOBAL) bool { - ret, _, _ := globalUnlock.Call(uintptr(hMem)) - return ret != 0 -} - -func MoveMemory(destination, source unsafe.Pointer, length uint32) { - moveMemory.Call( - uintptr(unsafe.Pointer(destination)), - uintptr(source), - uintptr(length), - ) -} - -func FindResource(hModule HMODULE, lpName, lpType *uint16) (HRSRC, error) { - ret, _, _ := findResource.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, _, _ := sizeofResource.Call( - uintptr(hModule), - uintptr(hResInfo)) - return uint32(ret) -} - -func LockResource(hResData HGLOBAL) unsafe.Pointer { - ret, _, _ := lockResource.Call(uintptr(hResData)) - return unsafe.Pointer(ret) -} - -func LoadResource(hModule HMODULE, hResInfo HRSRC) HGLOBAL { - ret, _, _ := loadResource.Call( - uintptr(hModule), - uintptr(hResInfo), - ) - return HGLOBAL(ret) -} - -func GetLastError() uint32 { - ret, _, _ := getLastError.Call() - return uint32(ret) -} - -func OpenProcess(desiredAccess uint32, inheritHandle bool, processId uint32) HANDLE { - inherit := 0 - if inheritHandle { - inherit = 1 - } - ret, _, _ := openProcess.Call( - uintptr(desiredAccess), - uintptr(inherit), - uintptr(processId), - ) - return HANDLE(ret) -} - -func TerminateProcess(hProcess HANDLE, uExitCode uint) bool { - ret, _, _ := terminateProcess.Call( - uintptr(hProcess), - uintptr(uExitCode), - ) - return ret != 0 -} - -func CloseHandle(object HANDLE) bool { - ret, _, _ := closeHandle.Call(uintptr(object)) - return ret != 0 -} - -func CreateToolhelp32Snapshot(flags, processId uint32) HANDLE { - ret, _, _ := createToolhelp32Snapshot.Call( - uintptr(flags), - uintptr(processId), - ) - if ret <= 0 { - return HANDLE(0) - } - return HANDLE(ret) -} - -func Module32First(snapshot HANDLE, me *MODULEENTRY32) bool { - ret, _, _ := module32First.Call( - uintptr(snapshot), - uintptr(unsafe.Pointer(me)), - ) - return ret != 0 -} - -func Module32Next(snapshot HANDLE, me *MODULEENTRY32) bool { - ret, _, _ := module32Next.Call( - uintptr(snapshot), - uintptr(unsafe.Pointer(me)), - ) - return ret != 0 -} - -func GetSystemTimes(lpIdleTime, lpKernelTime, lpUserTime *FILETIME) bool { - ret, _, _ := getSystemTimes.Call( - uintptr(unsafe.Pointer(lpIdleTime)), - uintptr(unsafe.Pointer(lpKernelTime)), - uintptr(unsafe.Pointer(lpUserTime)), - ) - return ret != 0 -} - -func GetProcessTimes(hProcess HANDLE) (creationTime, exitTime, kernelTime, userTime FILETIME, ok bool) { - ret, _, _ := getProcessTimes.Call( - uintptr(hProcess), - uintptr(unsafe.Pointer(&creationTime)), - uintptr(unsafe.Pointer(&exitTime)), - uintptr(unsafe.Pointer(&kernelTime)), - uintptr(unsafe.Pointer(&userTime)), - ) - ok = ret != 0 - return -} - -func GetConsoleScreenBufferInfo(hConsoleOutput HANDLE) *CONSOLE_SCREEN_BUFFER_INFO { - var csbi CONSOLE_SCREEN_BUFFER_INFO - ret, _, _ := getConsoleScreenBufferInfo.Call( - uintptr(hConsoleOutput), - uintptr(unsafe.Pointer(&csbi)), - ) - if ret == 0 { - return nil - } - return &csbi -} - -func SetConsoleTextAttribute(hConsoleOutput HANDLE, wAttributes uint16) bool { - ret, _, _ := setConsoleTextAttribute.Call( - uintptr(hConsoleOutput), - uintptr(wAttributes), - ) - return ret != 0 -} - -func GetDiskFreeSpaceEx(dirName string) (r bool, - freeBytesAvailable, totalNumberOfBytes, totalNumberOfFreeBytes uint64) { - ret, _, _ := getDiskFreeSpaceEx.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() (time SYSTEMTIME) { - getSystemTime.Call(uintptr(unsafe.Pointer(&time))) - return -} - -func GetSystemTimeAsFileTime() (time FILETIME) { - getSystemTimeAsFileTime.Call(uintptr(unsafe.Pointer(&time))) - return -} - -func SystemTimeToFileTime(sysTime SYSTEMTIME) (fileTime FILETIME, ok bool) { - ret, _, _ := systemTimeToFileTime.Call( - uintptr(unsafe.Pointer(&sysTime)), - uintptr(unsafe.Pointer(&fileTime)), - ) - ok = ret != 0 - return -} - -func FileTimeToSystemTime(fileTime FILETIME) (sysTime SYSTEMTIME, ok bool) { - ret, _, _ := fileTimeToSystemTime.Call( - uintptr(unsafe.Pointer(&fileTime)), - uintptr(unsafe.Pointer(&sysTime)), - ) - ok = ret != 0 - return -} - -func SetSystemTime(time SYSTEMTIME) bool { - ret, _, _ := setSystemTime.Call(uintptr(unsafe.Pointer(&time))) - return ret != 0 -} - -func SetLocalTime(time SYSTEMTIME) bool { - ret, _, _ := setLocalTime.Call(uintptr(unsafe.Pointer(&time))) - return ret != 0 -} - -func CopyMemory(dest, source unsafe.Pointer, sizeInBytes int) { - copyMemory.Call( - uintptr(dest), - uintptr(source), - uintptr(sizeInBytes), - ) -} - -func GetCurrentProcess() HANDLE { - id, _, _ := getCurrentProcess.Call() - return HANDLE(id) -} - -func GetCurrentProcessId() DWORD { - id, _, _ := getCurrentProcessId.Call() - return DWORD(id) -} - -func GetVersion() uint32 { - ret, _, _ := getVersion.Call() - return uint32(ret) -} - -func SetEnvironmentVariable(name, value string) bool { - ret, _, _ := setEnvironmentVariable.Call( - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(name))), - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(value))), - ) - return ret != 0 -} - -func GetComputerName() string { - const maxLen = 128 - var buf [maxLen]uint16 - var size uint32 = maxLen - ret, _, _ := getComputerName.Call( - uintptr(unsafe.Pointer(&buf[0])), - uintptr(unsafe.Pointer(&size)), - ) - if ret != 0 { - return syscall.UTF16ToString(buf[:]) - } - return "" -} - -func ActivateActCtx(ctx HANDLE) (uintptr, bool) { - var cookie uintptr - ret, _, _ := activateActCtx.Call( - uintptr(ctx), - uintptr(unsafe.Pointer(&cookie)), - ) - return cookie, ret != 0 -} - -func CreateActCtx(ctx *ACTCTX) HANDLE { - if ctx != nil { - ctx.size = uint32(unsafe.Sizeof(*ctx)) - } - ret, _, _ := createActCtx.Call(uintptr(unsafe.Pointer(ctx))) - return HANDLE(ret) -} - -func GetCurrentActCtx() (HANDLE, bool) { - var h HANDLE - ret, _, _ := getCurrentActCtx.Call(uintptr(unsafe.Pointer(&h))) - return h, ret != 0 -} - -func SetErrorMode(mode uint) uint { - ret, _, _ := setErrorMode.Call(uintptr(mode)) - return uint(ret) -} - -func CreateFile( - filename string, - access uint32, - shareMode uint32, - security *SECURITY_ATTRIBUTES, - disposition uint32, - flags uint32, - templateFile HANDLE, -) HANDLE { - ret, _, _ := createFile.Call( - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(filename))), - uintptr(access), - uintptr(shareMode), - uintptr(unsafe.Pointer(security)), - uintptr(disposition), - uintptr(flags), - uintptr(templateFile), - ) - return HANDLE(ret) -} - -func DeviceIoControl( - dev HANDLE, - controlCode uint32, - inBuffer unsafe.Pointer, - inBufferSize uint32, - outBuffer unsafe.Pointer, - outBufferSize uint32, - overlapped *OVERLAPPED, -) (outBufWrittenBytes uint32, ok bool) { - ret, _, _ := deviceIoControl.Call( - uintptr(dev), - uintptr(controlCode), - uintptr(inBuffer), - uintptr(inBufferSize), - uintptr(outBuffer), - uintptr(outBufferSize), - uintptr(unsafe.Pointer(&outBufWrittenBytes)), - uintptr(unsafe.Pointer(overlapped)), - ) - ok = ret != 0 - return -} - -func FindFirstStream(filename string, data *WIN32_FIND_STREAM_DATA) (HANDLE, bool) { - ret, _, _ := findFirstStream.Call( - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(filename))), - FindStreamInfoStandard, - uintptr(unsafe.Pointer(data)), - 0, - ) - h := HANDLE(ret) - return h, h != INVALID_HANDLE_VALUE -} - -func FindNextStream(finder HANDLE, data *WIN32_FIND_STREAM_DATA) bool { - ret, _, _ := findNextStream.Call( - uintptr(finder), - uintptr(unsafe.Pointer(data)), - ) - return ret != 0 -} - -func FindClose(finder HANDLE) bool { - ret, _, _ := findClose.Call( - uintptr(finder), - ) - return ret != 0 -} - -func OpenMutex(desiredAccess uint32, inheritHandle bool, name string) HANDLE { - ret, _, _ := openMutex.Call( - uintptr(desiredAccess), - uintptr(BoolToBOOL(inheritHandle)), - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(name))), - ) - return HANDLE(ret) -} - -func CreateMutex(attributes *SECURITY_ATTRIBUTES, initialOwner bool, name string) HANDLE { - ret, _, _ := createMutex.Call( - uintptr(unsafe.Pointer(attributes)), - uintptr(BoolToBOOL(initialOwner)), - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(name))), - ) - return HANDLE(ret) -} - -func CoInitializeEx(coInit uint32) HRESULT { - ret, _, _ := coInitializeEx.Call(0, uintptr(coInit)) - return HRESULT(ret) -} - -func CoInitialize() { - coInitialize.Call(0) -} - -func CoUninitialize() { - coUninitialize.Call() -} - -func CreateStreamOnHGlobal(global HGLOBAL, deleteOnRelease bool) (*IStream, HRESULT) { - stream := new(IStream) - ret, _, _ := createStreamOnHGlobal.Call( - uintptr(global), - uintptr(BoolToBOOL(deleteOnRelease)), - uintptr(unsafe.Pointer(&stream)), - ) - - return stream, HRESULT(ret) -} - -func VariantInit(v *VARIANT) { - variantInit.Call(uintptr(unsafe.Pointer(v))) -} - -func SysAllocString(v string) (ss *int16) { - pss, _, _ := sysAllocString.Call( - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(v))), - ) - ss = (*int16)(unsafe.Pointer(pss)) - return -} - -func SysFreeString(v *int16) { - sysFreeString.Call(uintptr(unsafe.Pointer(v))) -} - -func SysStringLen(v *int16) uint { - l, _, _ := sysStringLen.Call(uintptr(unsafe.Pointer(v))) - return uint(l) -} - -func WglCreateContext(hdc HDC) HGLRC { - ret, _, _ := wglCreateContext.Call( - uintptr(hdc), - ) - return HGLRC(ret) -} - -func WglCreateLayerContext(hdc HDC, iLayerPlane int) HGLRC { - ret, _, _ := wglCreateLayerContext.Call( - uintptr(hdc), - uintptr(iLayerPlane), - ) - return HGLRC(ret) -} - -func WglDeleteContext(hglrc HGLRC) bool { - ret, _, _ := wglDeleteContext.Call( - uintptr(hglrc), - ) - return ret == TRUE -} - -func WglGetProcAddress(szProc string) uintptr { - ret, _, _ := wglGetProcAddress.Call( - uintptr(unsafe.Pointer(syscall.StringBytePtr(szProc))), - ) - return ret -} - -func WglMakeCurrent(hdc HDC, hglrc HGLRC) bool { - ret, _, _ := wglMakeCurrent.Call( - uintptr(hdc), - uintptr(hglrc), - ) - return ret == TRUE -} - -func WglShareLists(hglrc1, hglrc2 HGLRC) bool { - ret, _, _ := wglShareLists.Call( - uintptr(hglrc1), - uintptr(hglrc2), - ) - return ret == TRUE -} - -// EnumAllProcesses retrieves the process identifier for each process object in -// the system. It returns ok = true on success. If ok = false call GetLastError -// to see why it failed. -func EnumAllProcesses() (processIDs []uint32, ok bool) { - n := 128 - for { - processIDs, ok = EnumProcesses(make([]uint32, n)) - if !ok || len(processIDs) < n { - return - } - n *= 2 - } -} - -// EnumProcesses retrieves the process identifier for each process object in the -// system. It takes a pre-sized slice to fill and returns the filled sub-slice -// and an OK status to report success. If ok is false, call GetLastError to see -// what the problem was. -// If the given slice is filled completely, there might be more unenumerated -// process IDs. In that case increase the buffer size and call EnumProcesses -// again. You can also call EnumAllProcesses which does this automatically. -func EnumProcesses(into []uint32) (processIDs []uint32, ok bool) { - if len(into) == 0 { - return nil, true - } - var writtenBytes uint32 - ret, _, _ := enumProcesses.Call( - uintptr(unsafe.Pointer(&into[0])), - uintptr(len(into)*4), - uintptr(unsafe.Pointer(&writtenBytes)), - ) - writtenIDs := writtenBytes / 4 - return into[:writtenIDs], ret != 0 -} - -func SHBrowseForFolder(bi *BROWSEINFO) uintptr { - ret, _, _ := sHBrowseForFolder.Call(uintptr(unsafe.Pointer(bi))) - return ret -} - -func SHGetPathFromIDList(idl uintptr) string { - buf := make([]uint16, 1024) - sHGetPathFromIDList.Call( - idl, - uintptr(unsafe.Pointer(&buf[0])), - ) - return syscall.UTF16ToString(buf) -} - -func SHGetSpecialFolderPath(window HWND, id int, create bool) (string, bool) { - var buf [MAX_PATH]uint16 - ret, _, _ := shGetSpecialFolderPath.Call( - uintptr(window), - uintptr(unsafe.Pointer(&buf[0])), - uintptr(id), - uintptr(BoolToBOOL(create)), - ) - return syscall.UTF16ToString(buf[:]), ret != 0 -} - -func DragAcceptFiles(hwnd HWND, accept bool) { - dragAcceptFiles.Call( - uintptr(hwnd), - uintptr(BoolToBOOL(accept)), - ) -} - -func DragQueryFile(drop HDROP, file uint) string { - ret, _, _ := dragQueryFile.Call( - uintptr(drop), - uintptr(file), - 0, - 0, - ) - - stringSize := uint(ret) - var fileName string - - if file != 0xFFFFFFFF { - buf := make([]uint16, stringSize+1) - - ret, _, _ := dragQueryFile.Call( - uintptr(drop), - uintptr(file), - uintptr(unsafe.Pointer(&buf[0])), - uintptr(len(buf)), - ) - if ret != 0 { - fileName = syscall.UTF16ToString(buf) - } - } - - return fileName -} - -func DragQueryPoint(hDrop HDROP) (x, y int, isClientArea bool) { - var pt POINT - ret, _, _ := dragQueryPoint.Call( - uintptr(hDrop), - uintptr(unsafe.Pointer(&pt)), - ) - return int(pt.X), int(pt.Y), (ret == 1) -} - -func DragFinish(hDrop HDROP) { - dragFinish.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, _, _ := shellExecute.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, _, _ := extractIcon.Call( - 0, - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpszExeFileName))), - uintptr(nIconIndex), - ) - return HICON(ret) -} - -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" -} - -func GdipCreateBitmapFromFile(filename string) (*uintptr, error) { - var bitmap *uintptr - ret, _, _ := gdipCreateBitmapFromFile.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, _, _ := gdipCreateBitmapFromResource.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, _, _ := gdipCreateBitmapFromStream.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, _, _ := gdipCreateHBITMAPFromBitmap.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) { - gdipDisposeImage.Call(uintptr(unsafe.Pointer(image))) -} - -func GdiplusShutdown(token uintptr) { - gdiplusShutdown.Call(token) -} - -func GdiplusStartup(input *GdiplusStartupInput, output *GdiplusStartupOutput) (token uintptr, status uint32) { - ret, _, _ := gdiplusStartup.Call( - uintptr(unsafe.Pointer(&token)), - uintptr(unsafe.Pointer(input)), - uintptr(unsafe.Pointer(output)), - ) - status = uint32(ret) - return -} - -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 BoolToBOOL(value bool) BOOL { - if value { - return 1 - } - return 0 -} - -func GetFileVersionInfoSize(path string) uint32 { - ret, _, _ := getFileVersionInfoSize.Call( - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(path))), - 0, - ) - return uint32(ret) -} - -func GetFileVersionInfo(path string, data []byte) bool { - ret, _, _ := getFileVersionInfo.Call( - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(path))), - 0, - uintptr(len(data)), - uintptr(unsafe.Pointer(&data[0])), - ) - return ret != 0 -} - -// VerQueryValueRoot calls VerQueryValue -// (https://msdn.microsoft.com/en-us/library/windows/desktop/ms647464(v=vs.85).aspx) -// with `\` (root) to retieve the VS_FIXEDFILEINFO. -func VerQueryValueRoot(block []byte) (VS_FIXEDFILEINFO, bool) { - var offset uintptr - var length uint - blockStart := uintptr(unsafe.Pointer(&block[0])) - ret, _, _ := verQueryValue.Call( - blockStart, - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(`\`))), - uintptr(unsafe.Pointer(&offset)), - uintptr(unsafe.Pointer(&length)), - ) - if ret == 0 { - return VS_FIXEDFILEINFO{}, false - } - start := int(offset) - int(blockStart) - end := start + int(length) - if start < 0 || start >= len(block) || end < start || end > len(block) { - return VS_FIXEDFILEINFO{}, false - } - data := block[start:end] - info := *((*VS_FIXEDFILEINFO)(unsafe.Pointer(&data[0]))) - return info, true -} - -// VerQueryValueTranslations calls VerQueryValue -// (https://msdn.microsoft.com/en-us/library/windows/desktop/ms647464(v=vs.85).aspx) -// with `\VarFileInfo\Translation` to retrieve a list of 4-character translation -// strings as required by VerQueryValueString. -func VerQueryValueTranslations(block []byte) ([]string, bool) { - var offset uintptr - var length uint - blockStart := uintptr(unsafe.Pointer(&block[0])) - ret, _, _ := verQueryValue.Call( - blockStart, - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(`\VarFileInfo\Translation`))), - uintptr(unsafe.Pointer(&offset)), - uintptr(unsafe.Pointer(&length)), - ) - if ret == 0 { - return nil, false - } - start := int(offset) - int(blockStart) - end := start + int(length) - if start < 0 || start >= len(block) || end < start || end > len(block) { - return nil, false - } - data := block[start:end] - // each translation consists of a 16-bit language ID and a 16-bit code page - // ID, so each entry has 4 bytes - if len(data)%4 != 0 { - return nil, false - } - trans := make([]string, len(data)/4) - for i := range trans { - t := data[i*4 : (i+1)*4] - // handle endianness of the 16-bit values - t[0], t[1] = t[1], t[0] - t[2], t[3] = t[3], t[2] - trans[i] = fmt.Sprintf("%x", t) - } - return trans, true -} - -// these constants can be passed to VerQueryValueString as the item -const ( - CompanyName = "CompanyName" - FileDescription = "FileDescription" - FileVersion = "FileVersion" - LegalCopyright = "LegalCopyright" - LegalTrademarks = "LegalTrademarks" - OriginalFilename = "OriginalFilename" - ProductVersion = "ProductVersion" - PrivateBuild = "PrivateBuild" - SpecialBuild = "SpecialBuild" -) - -// VerQueryValueString calls VerQueryValue -// (https://msdn.microsoft.com/en-us/library/windows/desktop/ms647464(v=vs.85).aspx) -// with `\StringFileInfo\...` to retrieve a specific piece of information as -// string in a specific translation. -func VerQueryValueString(block []byte, translation, item string) (string, bool) { - var offset uintptr - var utf16Length uint - blockStart := uintptr(unsafe.Pointer(&block[0])) - id := `\StringFileInfo\` + translation + `\` + item - ret, _, _ := verQueryValue.Call( - blockStart, - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(id))), - uintptr(unsafe.Pointer(&offset)), - uintptr(unsafe.Pointer(&utf16Length)), - ) - if ret == 0 { - return "", false - } - start := int(offset) - int(blockStart) - end := start + int(2*utf16Length) - if start < 0 || start >= len(block) || end < start || end > len(block) { - return "", false - } - data := block[start:end] - u16 := make([]uint16, utf16Length) - for i := range u16 { - u16[i] = uint16(data[i*2+1])<<8 | uint16(data[i*2+0]) - } - return syscall.UTF16ToString(u16), true -} - -func PlaySound(sound string, mod HMODULE, flags uint32) bool { - return PlaySoundPointer(syscall.StringToUTF16Ptr(sound), mod, flags) -} - -func PlaySoundPointer(sound *uint16, mod HMODULE, flags uint32) bool { - ret, _, _ := playSound.Call( - uintptr(unsafe.Pointer(sound)), - uintptr(mod), - uintptr(flags), - ) - return ret != 0 -} - -func GetMonitorBrightness(monitor HANDLE) (ok bool, min, cur, max DWORD) { - ret, _, _ := getMonitorBrightness.Call( - uintptr(monitor), - uintptr(unsafe.Pointer(&min)), - uintptr(unsafe.Pointer(&cur)), - uintptr(unsafe.Pointer(&max)), - ) - ok = ret != 0 - return -} - -func SetMonitorBrightness(monitor HANDLE, value DWORD) bool { - ret, _, _ := setMonitorBrightness.Call( - uintptr(monitor), - uintptr(value), - ) - return ret != 0 -} - -func GetNumberOfPhysicalMonitorsFromHMONITOR(monitor HMONITOR) (bool, DWORD) { - var n DWORD - ret, _, _ := getNumberOfPhysicalMonitorsFromHMONITOR.Call( - uintptr(monitor), - uintptr(unsafe.Pointer(&n)), - ) - return ret != 0, n -} - -// len(buf) must not be 0. -func GetPhysicalMonitorsFromHMONITOR(monitor HMONITOR, buf []PHYSICAL_MONITOR) bool { - ret, _, _ := getPhysicalMonitorsFromHMONITOR.Call( - uintptr(monitor), - uintptr(len(buf)), - uintptr(unsafe.Pointer(&buf[0])), - ) - return ret != 0 -} - -func MAKEWPARAM(low, high uint16) uintptr { - return uintptr(low) | uintptr(high)<<16 -} - -func MAKELPARAM(low, high uint16) uintptr { - return MAKEWPARAM(low, high) -} - -func AlphaBlend( - dest HDC, destX, destY, destW, destH int, - src HDC, srcX, srcY, srcW, srcH int, - f BLENDFUNC, -) bool { - ret, _, _ := alphaBlend.Call( - uintptr(dest), - uintptr(destX), - uintptr(destY), - uintptr(destW), - uintptr(destH), - uintptr(src), - uintptr(srcX), - uintptr(srcY), - uintptr(srcW), - uintptr(srcH), - uintptr(*((*uintptr)(unsafe.Pointer(&f)))), - ) - return ret != 0 -} - -func WNetAddConnection2(rsc *NETRESOURCE, pass, user string, flags uint32) uint32 { - var resource *netresource - if rsc != nil { - resource = rsc.toInternal() - } - ret, _, _ := wNetAddConnection2.Call( - uintptr(unsafe.Pointer(resource)), - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(pass))), - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(user))), - uintptr(flags), - ) - return uint32(ret) -} - -func WNetAddConnection3(owner HWND, rsc *NETRESOURCE, pass, user string, flags uint32) uint32 { - var resource *netresource - if rsc != nil { - resource = rsc.toInternal() - } - ret, _, _ := wNetAddConnection3.Call( - uintptr(owner), - uintptr(unsafe.Pointer(resource)), - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(pass))), - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(user))), - uintptr(flags), - ) - return uint32(ret) -} - -func WNetCancelConnection2(name string, flags uint32, force bool) uint32 { - ret, _, _ := wNetCancelConnection2.Call( - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(name))), - uintptr(flags), - uintptr(BoolToBOOL(force)), - ) - return uint32(ret) -} - -// https://docs.microsoft.com/en-us/windows/win32/devnotes/rtlgetversion -func RtlGetVersion() RTL_OSVERSIONINFOEXW { - var info RTL_OSVERSIONINFOEXW - info.OSVersionInfoSize = 5*4 + 128*2 + 3*2 + 2*1 - rtlGetVersion.Call(uintptr(unsafe.Pointer(&info))) - return info -} - -// https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getnativesysteminfo -func GetNativeSystemInfo() SYSTEM_INFO { - var info SYSTEM_INFO - getNativeSystemInfo.Call(uintptr(unsafe.Pointer(&info))) - return info -} - -// https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdigetclassdevsw -func SetupDiGetClassDevs(classGUID *GUID, flags uint32) HANDLE { - ret, _, _ := setupDiGetClassDevs.Call( - uintptr(unsafe.Pointer(classGUID)), - 0, - 0, - uintptr(flags), - ) - return HANDLE(ret) -} - -func SetupDiDestroyDeviceInfoList(list HANDLE) bool { - ret, _, _ := setupDiDestroyDeviceInfoList.Call(uintptr(list)) - return ret != 0 -} - -func SetupDiEnumDeviceInfo(deviceInfoList HANDLE, index uint32) (SP_DEVINFO_DATA, bool) { - var data SP_DEVINFO_DATA - data.Size = uint32(unsafe.Sizeof(data)) - ret, _, _ := setupDiEnumDeviceInfo.Call( - uintptr(deviceInfoList), - uintptr(index), - uintptr(unsafe.Pointer(&data)), - ) - return data, ret != 0 -} - -func SetupDiOpenDevRegKey( - DeviceInfoList HANDLE, - data *SP_DEVINFO_DATA, - scope, hwProfile, keyType, access uint32, -) HKEY { - ret, _, _ := setupDiOpenDevRegKey.Call( - uintptr(DeviceInfoList), - uintptr(unsafe.Pointer(data)), - uintptr(scope), - uintptr(hwProfile), - uintptr(keyType), - uintptr(access), - ) - return HKEY(ret) -} - -func SetProcessDpiAwareness(value int) HRESULT { - ret, _, _ := setProcessDpiAwareness.Call(uintptr(value)) - return HRESULT(ret) -} diff --git a/v3/internal/w32/functions_386.go b/v3/internal/w32/functions_386.go deleted file mode 100644 index 968cafec6..000000000 --- a/v3/internal/w32/functions_386.go +++ /dev/null @@ -1,29 +0,0 @@ -package w32 - -// MenuItemFromPoint determines which menu item, if any, is at the specified -// location. -func MenuItemFromPoint(w HWND, m HMENU, screen POINT) int { - ret, _, _ := menuItemFromPoint.Call( - uintptr(w), - uintptr(m), - uintptr(screen.X), - uintptr(screen.Y), - ) - return int(ret) -} - -func GetClassLongPtr(w HWND, index int) uintptr { - return uintptr(GetClassLong(w, index)) -} - -func SetClassLongPtr(w HWND, index int, value uintptr) uintptr { - return uintptr(SetClassLong(w, index, int32(value))) -} - -func GetWindowLongPtr(hwnd HWND, index int) uintptr { - return uintptr(GetWindowLong(hwnd, index)) -} - -func SetWindowLongPtr(hwnd HWND, index int, value uintptr) uintptr { - return uintptr(SetWindowLong(hwnd, index, int32(value))) -} diff --git a/v3/internal/w32/functions_amd64.go b/v3/internal/w32/functions_amd64.go deleted file mode 100644 index 0e12a6210..000000000 --- a/v3/internal/w32/functions_amd64.go +++ /dev/null @@ -1,43 +0,0 @@ -package w32 - -// MenuItemFromPoint determines which menu item, if any, is at the specified -// location. -func MenuItemFromPoint(w HWND, m HMENU, screen POINT) int { - ret, _, _ := menuItemFromPoint.Call( - uintptr(w), - uintptr(m), - uintptr(uint64(screen.X)<<32|uint64(screen.Y)), - ) - return int(ret) -} - -func GetClassLongPtr(w HWND, index int) uintptr { - ret, _, _ := getClassLongPtr.Call(uintptr(w), uintptr(index)) - return ret -} - -func SetClassLongPtr(w HWND, index int, value uintptr) uintptr { - ret, _, _ := setClassLongPtr.Call( - uintptr(w), - uintptr(index), - value, - ) - return ret -} - -func GetWindowLongPtr(hwnd HWND, index int) uintptr { - ret, _, _ := getWindowLongPtr.Call( - uintptr(hwnd), - uintptr(index), - ) - return ret -} - -func SetWindowLongPtr(hwnd HWND, index int, value uintptr) uintptr { - ret, _, _ := setWindowLongPtr.Call( - uintptr(hwnd), - uintptr(index), - value, - ) - return ret -} diff --git a/v3/internal/w32/functions_arm64.go b/v3/internal/w32/functions_arm64.go deleted file mode 100644 index 0e12a6210..000000000 --- a/v3/internal/w32/functions_arm64.go +++ /dev/null @@ -1,43 +0,0 @@ -package w32 - -// MenuItemFromPoint determines which menu item, if any, is at the specified -// location. -func MenuItemFromPoint(w HWND, m HMENU, screen POINT) int { - ret, _, _ := menuItemFromPoint.Call( - uintptr(w), - uintptr(m), - uintptr(uint64(screen.X)<<32|uint64(screen.Y)), - ) - return int(ret) -} - -func GetClassLongPtr(w HWND, index int) uintptr { - ret, _, _ := getClassLongPtr.Call(uintptr(w), uintptr(index)) - return ret -} - -func SetClassLongPtr(w HWND, index int, value uintptr) uintptr { - ret, _, _ := setClassLongPtr.Call( - uintptr(w), - uintptr(index), - value, - ) - return ret -} - -func GetWindowLongPtr(hwnd HWND, index int) uintptr { - ret, _, _ := getWindowLongPtr.Call( - uintptr(hwnd), - uintptr(index), - ) - return ret -} - -func SetWindowLongPtr(hwnd HWND, index int, value uintptr) uintptr { - ret, _, _ := setWindowLongPtr.Call( - uintptr(hwnd), - uintptr(index), - value, - ) - return ret -} diff --git a/v3/internal/w32/gdi32.go b/v3/internal/w32/gdi32.go new file mode 100644 index 000000000..b4b9053e6 --- /dev/null +++ b/v3/internal/w32/gdi32.go @@ -0,0 +1,526 @@ +//go:build windows + +/* + * 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 +} diff --git a/v3/internal/w32/gdiplus.go b/v3/internal/w32/gdiplus.go new file mode 100644 index 000000000..2591ed71b --- /dev/null +++ b/v3/internal/w32/gdiplus.go @@ -0,0 +1,177 @@ +//go:build windows + +/* + * 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))) + } +} diff --git a/v3/internal/w32/idispatch.go b/v3/internal/w32/idispatch.go new file mode 100644 index 000000000..4f610f3ff --- /dev/null +++ b/v3/internal/w32/idispatch.go @@ -0,0 +1,45 @@ +//go:build windows + +/* + * 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...) +} diff --git a/v3/internal/w32/istream.go b/v3/internal/w32/istream.go new file mode 100644 index 000000000..a47fbbce1 --- /dev/null +++ b/v3/internal/w32/istream.go @@ -0,0 +1,33 @@ +//go:build windows + +/* + * 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))) +} diff --git a/v3/internal/w32/iunknown.go b/v3/internal/w32/iunknown.go new file mode 100644 index 000000000..8ddc605cc --- /dev/null +++ b/v3/internal/w32/iunknown.go @@ -0,0 +1,29 @@ +//go:build windows + +/* + * 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) +} diff --git a/v3/internal/w32/kernel32.go b/v3/internal/w32/kernel32.go new file mode 100644 index 000000000..063a1b0ea --- /dev/null +++ b/v3/internal/w32/kernel32.go @@ -0,0 +1,332 @@ +//go:build windows + +/* + * 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) +} diff --git a/v3/internal/w32/ole32.go b/v3/internal/w32/ole32.go new file mode 100644 index 000000000..004099316 --- /dev/null +++ b/v3/internal/w32/ole32.go @@ -0,0 +1,65 @@ +//go:build windows + +/* + * 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 +} diff --git a/v3/internal/w32/oleaut32.go b/v3/internal/w32/oleaut32.go new file mode 100644 index 000000000..0bb8ef7da --- /dev/null +++ b/v3/internal/w32/oleaut32.go @@ -0,0 +1,50 @@ +//go:build windows + +/* + * 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) +} diff --git a/v3/internal/w32/shcore.go b/v3/internal/w32/shcore.go new file mode 100644 index 000000000..72e9aab3d --- /dev/null +++ b/v3/internal/w32/shcore.go @@ -0,0 +1,29 @@ +//go:build windows + +package w32 + +import ( + "syscall" + "unsafe" +) + +var ( + modshcore = syscall.NewLazyDLL("shcore.dll") + + procGetDpiForMonitor = modshcore.NewProc("GetDpiForMonitor") +) + +func HasGetDPIForMonitorFunc() bool { + err := procGetDpiForMonitor.Find() + return err == nil +} + +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 +} diff --git a/v3/internal/w32/shell32.go b/v3/internal/w32/shell32.go new file mode 100644 index 000000000..458fbc645 --- /dev/null +++ b/v3/internal/w32/shell32.go @@ -0,0 +1,235 @@ +//go:build windows + +/* + * 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 +} diff --git a/v3/internal/w32/shlwapi.go b/v3/internal/w32/shlwapi.go new file mode 100644 index 000000000..89d17ce6f --- /dev/null +++ b/v3/internal/w32/shlwapi.go @@ -0,0 +1,26 @@ +//go:build windows + +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 +} diff --git a/v3/internal/w32/theme.go b/v3/internal/w32/theme.go new file mode 100644 index 000000000..1b358789f --- /dev/null +++ b/v3/internal/w32/theme.go @@ -0,0 +1,119 @@ +//go:build windows + +package w32 + +import ( + "unsafe" + + "golang.org/x/sys/windows/registry" +) + +type DWMWINDOWATTRIBUTE int32 + +const DwmwaUseImmersiveDarkModeBefore20h1 DWMWINDOWATTRIBUTE = 19 +const DwmwaUseImmersiveDarkMode DWMWINDOWATTRIBUTE = 20 +const DwmwaBorderColor DWMWINDOWATTRIBUTE = 34 +const DwmwaCaptionColor DWMWINDOWATTRIBUTE = 35 +const DwmwaTextColor DWMWINDOWATTRIBUTE = 36 +const DwmwaSystemBackdropType DWMWINDOWATTRIBUTE = 38 + +const SPI_GETHIGHCONTRAST = 0x0042 +const HCF_HIGHCONTRASTON = 0x00000001 + +// BackdropType defines the type of translucency we wish to use +type BackdropType int32 + +func dwmSetWindowAttribute(hwnd uintptr, dwAttribute DWMWINDOWATTRIBUTE, pvAttribute unsafe.Pointer, cbAttribute uintptr) { + ret, _, err := procDwmSetWindowAttribute.Call( + hwnd, + uintptr(dwAttribute), + uintptr(pvAttribute), + cbAttribute) + if ret != 0 { + _ = err + // println(err.Error()) + } +} + +func SupportsThemes() bool { + // We can't support Windows versions before 17763 + return IsWindowsVersionAtLeast(10, 0, 17763) +} + +func SupportsCustomThemes() bool { + return IsWindowsVersionAtLeast(10, 0, 17763) +} + +func SupportsBackdropTypes() bool { + return IsWindowsVersionAtLeast(10, 0, 22621) +} + +func SupportsImmersiveDarkMode() bool { + return IsWindowsVersionAtLeast(10, 0, 18985) +} + +func SetTheme(hwnd uintptr, useDarkMode bool) { + if SupportsThemes() { + attr := DwmwaUseImmersiveDarkModeBefore20h1 + if SupportsImmersiveDarkMode() { + attr = DwmwaUseImmersiveDarkMode + } + var winDark int32 + if useDarkMode { + winDark = 1 + } + dwmSetWindowAttribute(hwnd, attr, unsafe.Pointer(&winDark), unsafe.Sizeof(winDark)) + } +} + +func EnableTranslucency(hwnd uintptr, backdrop BackdropType) { + if SupportsBackdropTypes() { + dwmSetWindowAttribute(hwnd, DwmwaSystemBackdropType, unsafe.Pointer(&backdrop), unsafe.Sizeof(backdrop)) + } else { + println("Warning: Translucency type unavailable on Windows < 22621") + } +} + +func SetTitleBarColour(hwnd uintptr, titleBarColour int32) { + dwmSetWindowAttribute(hwnd, DwmwaCaptionColor, unsafe.Pointer(&titleBarColour), unsafe.Sizeof(titleBarColour)) +} + +func SetTitleTextColour(hwnd uintptr, titleTextColour int32) { + dwmSetWindowAttribute(hwnd, DwmwaTextColor, unsafe.Pointer(&titleTextColour), unsafe.Sizeof(titleTextColour)) +} + +func SetBorderColour(hwnd uintptr, titleBorderColour int32) { + dwmSetWindowAttribute(hwnd, DwmwaBorderColor, unsafe.Pointer(&titleBorderColour), unsafe.Sizeof(titleBorderColour)) +} + +func IsCurrentlyDarkMode() bool { + key, err := registry.OpenKey(registry.CURRENT_USER, `SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize`, registry.QUERY_VALUE) + if err != nil { + return false + } + defer key.Close() + + AppsUseLightTheme, _, err := key.GetIntegerValue("AppsUseLightTheme") + if err != nil { + return false + } + return AppsUseLightTheme == 0 +} + +type highContrast struct { + CbSize uint32 + DwFlags uint32 + LpszDefaultScheme *int16 +} + +func IsCurrentlyHighContrastMode() bool { + var result highContrast + result.CbSize = uint32(unsafe.Sizeof(result)) + res, _, err := procSystemParametersInfo.Call(SPI_GETHIGHCONTRAST, uintptr(result.CbSize), uintptr(unsafe.Pointer(&result)), 0) + if res == 0 { + _ = err + return false + } + r := result.DwFlags&HCF_HIGHCONTRASTON == HCF_HIGHCONTRASTON + return r +} diff --git a/v3/internal/w32/toolbar.go b/v3/internal/w32/toolbar.go new file mode 100644 index 000000000..ac9261fc4 --- /dev/null +++ b/v3/internal/w32/toolbar.go @@ -0,0 +1,216 @@ +//go:build windows + +/* + * 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 +} diff --git a/v3/internal/w32/types.go b/v3/internal/w32/typedef.go similarity index 55% rename from v3/internal/w32/types.go rename to v3/internal/w32/typedef.go index 7f27bc9b4..13735204c 100644 --- a/v3/internal/w32/types.go +++ b/v3/internal/w32/typedef.go @@ -1,61 +1,228 @@ -// Copyright 2010-2012 The W32 Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +//go:build windows + +/* + * Copyright (C) 2019 Tad Vizbaras. All Rights Reserved. + * Copyright (C) 2010-2012 The W32 Authors. All Rights Reserved. + */ package w32 import ( - "syscall" - "time" - "unicode/utf16" + "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 - 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 - WPARAM uintptr - HRAWINPUT HANDLE + 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 @@ -68,12 +235,8 @@ type RECT struct { Left, Top, Right, Bottom int32 } -func (r *RECT) Width() int32 { - return r.Right - r.Left -} - -func (r *RECT) Height() int32 { - return r.Bottom - r.Top +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 @@ -92,6 +255,11 @@ type WNDCLASSEX struct { 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 @@ -102,6 +270,15 @@ type MSG struct { 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 @@ -120,106 +297,6 @@ type LOGFONT struct { FaceName [LF_FACESIZE]uint16 } -func toString(s []uint16) string { - for i, c := range s { - if c == 0 { - return string(utf16.Decode(s[:i])) - } - } - return string(utf16.Decode(s)) -} - -func (f *LOGFONT) GetFaceName() string { - return toString(f.FaceName[:]) -} - -func (f *LOGFONT) SetFaceName(name string) { - s := utf16.Encode([]rune(name)) - max := len(f.FaceName) - 1 - if len(s) > max { - s = s[:max] - } - copy(f.FaceName[:], s) - f.FaceName[len(s)] = 0 -} - -type ENUMLOGFONTEX struct { - LOGFONT - FullName [LF_FULLFACESIZE]uint16 - Style [LF_FACESIZE]uint16 - Script [LF_FACESIZE]uint16 -} - -func (f *ENUMLOGFONTEX) GetFullName() string { - return toString(f.FullName[:]) -} - -func (f *ENUMLOGFONTEX) GetStyle() string { - return toString(f.Style[:]) -} - -func (f *ENUMLOGFONTEX) GetScript() string { - return toString(f.Script[:]) -} - -type ENUMTEXTMETRIC struct { - NEWTEXTMETRICEX - AXESLIST -} - -type NEWTEXTMETRICEX struct { - NEWTEXTMETRIC - FONTSIGNATURE -} - -type NEWTEXTMETRIC struct { - Height int32 - Ascent int32 - Descent int32 - InternalLeading int32 - ExternalLeading int32 - AveCharWidth int32 - MaxCharWidth int32 - Weight int32 - Overhang int32 - DigitizedAspectX int32 - DigitizedAspectY int32 - FirstChar uint16 - LastChar uint16 - DefaultChar uint16 - BreakChar uint16 - Italic byte - Underlined byte - StruckOut byte - PitchAndFamily byte - CharSet byte - Flags uint32 - SizeEM uint32 - CellHeight uint32 - AvgWidth uint32 -} - -type FONTSIGNATURE struct { - Usb [4]uint32 - Csb [2]uint32 -} - -type AXESLIST struct { - Reserved uint32 - NumAxes uint32 - AxisInfo [MM_MAX_NUMAXES]AXISINFO -} - -type AXISINFO struct { - MinValue int32 - MaxValue int32 - AxisName [MM_MAX_AXES_NAMELEN]uint16 -} - -func (i *AXISINFO) GetAxisName() string { - return toString(i.AxisName[:]) -} - // http://msdn.microsoft.com/en-us/library/windows/desktop/ms646839.aspx type OPENFILENAME struct { StructSize uint32 @@ -382,15 +459,6 @@ type BITMAP struct { BmBits unsafe.Pointer } -// https://msdn.microsoft.com/en-us/library/windows/desktop/dd183374(v=vs.85).aspx -type BITMAPFILEHEADER struct { - BfType uint16 - BfSize uint32 - BfReserved1 uint16 - BfReserved2 uint16 - BfOffBits uint32 -} - // http://msdn.microsoft.com/en-us/library/windows/desktop/dd183567.aspx type DIBSECTION struct { DsBm BITMAP @@ -468,12 +536,6 @@ type NMHDR struct { Code uint32 } -type NMUPDOWN struct { - Hdr NMHDR - Pos int32 - Delta int32 -} - // http://msdn.microsoft.com/en-us/library/windows/desktop/bb774743.aspx type LVCOLUMN struct { Mask uint32 @@ -484,9 +546,6 @@ type LVCOLUMN struct { ISubItem int32 IImage int32 IOrder int32 - CxMin int32 - CxDefault int32 - CxIdeal int32 } // http://msdn.microsoft.com/en-us/library/windows/desktop/bb774760.aspx @@ -504,8 +563,14 @@ type LVITEM struct { IGroupId int32 CColumns uint32 PuColumns uint32 - PiColFmt *int32 - IGroup int32 +} + +type LVFINDINFO struct { + Flags uint32 + PszText *uint16 + LParam uintptr + Pt POINT + VkDirection uint32 } // http://msdn.microsoft.com/en-us/library/windows/desktop/bb774754.aspx @@ -530,6 +595,12 @@ type NMITEMACTIVATE struct { 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 @@ -550,8 +621,8 @@ type NMLVDISPINFO struct { // http://msdn.microsoft.com/en-us/library/windows/desktop/bb775507.aspx type INITCOMMONCONTROLSEX struct { - size uint32 - ICC uint32 + DwSize uint32 + DwICC uint32 } // http://msdn.microsoft.com/en-us/library/windows/desktop/bb760256.aspx @@ -630,6 +701,73 @@ type SERVICE_STATUS struct { 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 @@ -650,23 +788,6 @@ type FILETIME struct { DwHighDateTime uint32 } -func (t FILETIME) Uint64() uint64 { - return uint64(t.DwHighDateTime)<<32 | uint64(t.DwLowDateTime) -} - -func (t FILETIME) Time() time.Time { - // https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime - ref := time.Date(1601, time.January, 1, 0, 0, 0, 0, time.UTC) - const tick = 100 * time.Nanosecond - // The FILETIME is a uint64 of 100-nanosecond intervals since 1601. - // Unfortunately time.Duration is really an int64 so if we cast our uint64 - // to a time.Duration it becomes negative. Thus we do it in 2 steps, adding - // half the time each step to avoid overflow. - return ref. - Add(time.Duration(t.Uint64()) * (tick / 2)). - Add(time.Duration(t.Uint64()) * (tick / 2)) -} - // http://msdn.microsoft.com/en-us/library/windows/desktop/ms682119.aspx type COORD struct { X, Y int16 @@ -799,6 +920,44 @@ type MONITORINFO struct { 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 @@ -830,6 +989,55 @@ type PIXELFORMATDESCRIPTOR struct { 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 @@ -842,19 +1050,6 @@ type SYSTEMTIME struct { Milliseconds uint16 } -func (t SYSTEMTIME) Time() time.Time { - return time.Date( - int(t.Year), - time.Month(t.Month), - int(t.Day), - int(t.Hour), - int(t.Minute), - int(t.Second), - int(t.Milliseconds)*int(time.Millisecond/time.Nanosecond), - time.UTC, - ) -} - // http://msdn.microsoft.com/en-us/library/windows/desktop/ms644967(v=vs.85).aspx type KBDLLHOOKSTRUCT struct { VkCode DWORD @@ -875,423 +1070,12 @@ type WINDOWPLACEMENT struct { RcNormalPosition RECT } -type MINMAXINFO struct { - PtReserved POINT - PtMaxSize POINT - PtMaxPosition POINT - PtMinTrackSize POINT - PtMaxTrackSize POINT -} - -type RAWINPUTHEADER struct { - Type uint32 - Size uint32 - Device HANDLE - WParam WPARAM -} - -type RAWINPUT struct { - Header RAWINPUTHEADER - // NOTE that there is no support for C unions in Go, this would actually be - // a union of RAWMOUSE, RAWKEYBOARD and RAWHID. Since RAWMOUSE is the - // largest of those three, use it here and cast unsafely to get the other - // types. - mouse RAWMOUSE -} - -// GetMouse returns the raw input as a RAWMOUSE. Make sure to check the Header's -// Type flag so this is valid. -func (i *RAWINPUT) GetMouse() RAWMOUSE { - return i.mouse -} - -// GetKeyboard returns the raw input as a RAWKEYBOARD. Make sure to check the -// Header's Type flag so this is valid. -func (i *RAWINPUT) GetKeyboard() RAWKEYBOARD { - return *((*RAWKEYBOARD)(unsafe.Pointer(&i.mouse))) -} - -// GetHid returns the raw input as a RAWHID. Make sure to check the Header's -// Type flag so this is valid. -func (i *RAWINPUT) GetHid() RAWHID { - return *((*RAWHID)(unsafe.Pointer(&i.mouse))) -} - -type RAWKEYBOARD struct { - MakeCode uint16 - Flags uint16 - Reserved uint16 - VKey uint16 - Message uint32 - ExtraInformation uint32 -} - -type RAWHID struct { - SizeHid uint32 - Count uint32 - RawData [1]byte -} - -type RAWMOUSE struct { - Flags uint16 - Buttons uint32 - RawButtons uint32 - LastX int32 - LastY int32 - ExtraInformation uint32 -} - -func (m *RAWMOUSE) ButtonFlags() uint16 { - return uint16(m.Buttons & 0xFFFF) -} - -func (m *RAWMOUSE) ButtonData() uint16 { - return uint16((m.Buttons & 0xFFFF0000) >> 16) -} - -type RAWINPUTDEVICE struct { - UsagePage uint16 - Usage uint16 - Flags uint32 - Target HWND -} - -// INPUT is used in SendInput. To create a concrete INPUT type, use the helper -// functions MouseInput, KeyboardInput and HardwareInput. These are necessary -// because the C API uses a union here, which Go does not provide. -type INPUT struct { - Type uint32 - // use MOUSEINPUT for the union because it is the largest of all allowed - // structures - mouse MOUSEINPUT -} - -type MOUSEINPUT struct { - Dx int32 - Dy int32 - MouseData uint32 - Flags uint32 - Time uint32 - ExtraInfo uintptr -} - -type KEYBDINPUT struct { - Vk uint16 - Scan uint16 - Flags uint32 - Time uint32 - ExtraInfo uintptr -} - -type HARDWAREINPUT struct { - Msg uint32 - ParamL uint16 - ParamH uint16 -} - -func MouseInput(input MOUSEINPUT) INPUT { - return INPUT{ - Type: INPUT_MOUSE, - mouse: input, - } -} - -func KeyboardInput(input KEYBDINPUT) INPUT { - return INPUT{ - Type: INPUT_KEYBOARD, - mouse: *((*MOUSEINPUT)(unsafe.Pointer(&input))), - } -} - -func HardwareInput(input HARDWAREINPUT) INPUT { - return INPUT{ - Type: INPUT_HARDWARE, - mouse: *((*MOUSEINPUT)(unsafe.Pointer(&input))), - } -} - -type VS_FIXEDFILEINFO struct { - Signature uint32 - StrucVersion uint32 - FileVersionMS uint32 - FileVersionLS uint32 - ProductVersionMS uint32 - ProductVersionLS uint32 - FileFlagsMask uint32 - FileFlags uint32 - FileOS uint32 - FileType uint32 - FileSubtype uint32 - FileDateMS uint32 - FileDateLS uint32 -} - -// FileVersion concatenates FileVersionMS and FileVersionLS to a uint64 value. -func (fi VS_FIXEDFILEINFO) FileVersion() uint64 { - return uint64(fi.FileVersionMS)<<32 | uint64(fi.FileVersionLS) -} - -// FileDate concatenates FileDateMS and FileDateLS to a uint64 value. -func (fi VS_FIXEDFILEINFO) FileDate() uint64 { - return uint64(fi.FileDateMS)<<32 | uint64(fi.FileDateLS) -} - -type ACCEL struct { - // Virt is a bit mask which may contain: - // FALT, FCONTROL, FSHIFT: keys to be held for the accelerator - // FVIRTKEY: means that Key is a virtual key code, if not set, Key is - // interpreted as a character code - Virt byte - // Key can either be a virtual key code VK_... or a character - Key uint16 - // Cmd is the value passed to WM_COMMAND or WM_SYSCOMMAND when the - // accelerator triggers - Cmd uint16 -} - -type PHYSICAL_MONITOR struct { - Monitor HANDLE - Description [128]uint16 -} - -type MENUITEMINFO struct { - Size uint32 - Mask uint32 - Type uint32 - State uint32 - ID uint32 - SubMenu HMENU - BmpChecked HBITMAP - BmpUnChecked HBITMAP - ItemData uintptr - TypeData uintptr // UTF-16 string - CCH uint32 - BmpItem HBITMAP -} - -type TPMPARAMS struct { - Size uint32 - Exclude RECT -} - -type MENUINFO struct { - size uint32 - Mask uint32 - Style uint32 - YMax uint32 - Back HBRUSH - ContextHelpID uint32 - MenuData uintptr -} - -type MENUBARINFO struct { - size uint32 - Bar RECT - Menu HMENU - Window HWND - BarFocused int32 // bool - Focused int32 // bool -} - -type ACTCTX struct { - size uint32 - Flags uint32 - Source *uint16 // UTF-16 string - ProcessorArchitecture uint16 - LangID uint16 - AssemblyDirectory *uint16 // UTF-16 string - ResourceName *uint16 // UTF-16 string - ApplicationName *uint16 // UTF-16 string - Module HMODULE -} - -type DRAWITEMSTRUCT struct { - CtlType uint32 - CtlID uint32 - ItemID uint32 - ItemAction uint32 - ItemState uint32 - HwndItem HWND - HDC HDC - RcItem RECT - ItemData uintptr -} - -type BLENDFUNC struct { - BlendOp byte - BlendFlags byte - SourceConstantAlpha byte - AlphaFormat byte -} - -type NETRESOURCE struct { - Scope uint32 - Type uint32 - DisplayType uint32 - Usage uint32 - LocalName string - RemoteName string - Comment string - Provider string -} - -func (n *NETRESOURCE) toInternal() *netresource { - internal := &netresource{ - Scope: n.Scope, - Type: n.Type, - DisplayType: n.DisplayType, - Usage: n.Usage, - } - if n.LocalName != "" { - internal.LocalName = syscall.StringToUTF16Ptr(n.LocalName) - } - if n.RemoteName != "" { - internal.RemoteName = syscall.StringToUTF16Ptr(n.RemoteName) - } - if n.Comment != "" { - internal.Comment = syscall.StringToUTF16Ptr(n.Comment) - } - if n.Provider != "" { - internal.Provider = syscall.StringToUTF16Ptr(n.Provider) - } - return internal -} - -type netresource struct { - Scope uint32 - Type uint32 - DisplayType uint32 - Usage uint32 - LocalName *uint16 - RemoteName *uint16 - Comment *uint16 - Provider *uint16 -} - -type NMLVODSTATECHANGE struct { - Hdr NMHDR - From int32 - To int32 - NewState uint32 - OldState uint32 -} - -type SECURITY_ATTRIBUTES struct { - Length uint32 - SecurityDescriptor unsafe.Pointer - InheritHandle uint32 // bool value -} - -type OVERLAPPED struct { - Internal uintptr - InternalHigh uintptr - Pointer uintptr - Event HANDLE -} - -type STORAGE_DEVICE_DESCRIPTOR struct { - Version uint32 - Size uint32 - DeviceType byte - DeviceTypeModifier byte - RemovableMedia byte // bool value - CommandQueueing byte // bool value - VendorIdOffset uint32 - ProductIdOffset uint32 - ProductRevisionOffset uint32 - SerialNumberOffset uint32 - BusType uint32 // STORAGE_BUS_TYPE - RawPropertiesLength uint32 - RawDeviceProperties [1]byte -} - -type STORAGE_PROPERTY_QUERY struct { - PropertyId uint32 - QueryType uint32 - AdditionalParameters [1]byte -} - -// https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/ns-fileapi-_win32_find_stream_data -type WIN32_FIND_STREAM_DATA struct { - Size int64 - Name [MAX_PATH + 36]uint16 -} - -type MSGBOXPARAMS struct { - Size uint32 - Owner HWND - Instance HINSTANCE - Text *uint16 - Caption *uint16 - Style uint32 - Icon *uint16 - ContextHelpId *uint32 - MsgBoxCallback uintptr - LanguageId uint32 -} - -type POWERBROADCAST_SETTING struct { - PowerSetting GUID - DataLength uint32 - Data [1]byte -} - -// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ns-wdm-_osversioninfoexw -type RTL_OSVERSIONINFOEXW struct { - OSVersionInfoSize uint32 - MajorVersion uint32 - MinorVersion uint32 - BuildNumber uint32 - PlatformId uint32 - CSDVersion [128]uint16 - ServicePackMajor uint16 - ServicePackMinor uint16 - SuiteMask uint16 - ProductType byte - Reserved byte -} - -// https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/ns-sysinfoapi-system_info -type SYSTEM_INFO struct { - ProcessorArchitecture uint16 - Reserved uint16 - PageSize uint32 - MinimumApplicationAddress LPCVOID - MaximumApplicationAddress LPCVOID - ActiveProcessorMask *uint32 - NumberOfProcessors uint32 - ProcessorType uint32 - AllocationGranularity uint32 - ProcessorLevel uint16 - ProcessorRevision uint16 -} - -type SP_DEVINFO_DATA struct { - Size uint32 - ClassGuid GUID - DevInst uint32 - Reserved uintptr -} - -type WINDOWPOS struct { - Hwnd HWND - HwndInsertAfter HWND - X int32 - Y int32 - Cx int32 - Cy int32 - Flags uint32 -} - -type WINDOWINFO struct { - Cbsize uint32 - RcWindow RECT - RcClient RECT - DwStyle uint32 - DwExStyle uint32 - DwWindowStatus uint32 - CxWindowBorders uint32 - CyWindowBorders uint32 - AtomWindowType uint16 - WCreatorVersion uint16 +type SCROLLINFO struct { + CbSize uint32 + FMask uint32 + NMin int32 + NMax int32 + NPage uint32 + NPos int32 + NTrackPos int32 } diff --git a/v3/internal/w32/user32.go b/v3/internal/w32/user32.go new file mode 100644 index 000000000..146472254 --- /dev/null +++ b/v3/internal/w32/user32.go @@ -0,0 +1,1281 @@ +//go:build windows + +/* + * 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") + procRegisterWindowMessageA = moduser32.NewProc("RegisterWindowMessageA") + //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") + procGetDpiForSystem = moduser32.NewProc("GetDpiForSystem") + procGetDpiForWindow = moduser32.NewProc("GetDpiForWindow") + 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") + + procSystemParametersInfo = moduser32.NewProc("SystemParametersInfoW") + procSetClassLong = moduser32.NewProc("SetClassLongW") + procSetClassLongPtr = moduser32.NewProc("SetClassLongPtrW") + + 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 LoadIconWithResourceID(instance HINSTANCE, res uint16) HICON { + ret, _, _ := procLoadIcon.Call( + uintptr(instance), + uintptr(res)) + + return HICON(ret) +} + +func LoadCursor(instance HINSTANCE, cursorName *uint16) HCURSOR { + ret, _, _ := procLoadCursor.Call( + uintptr(instance), + uintptr(unsafe.Pointer(cursorName))) + + return HCURSOR(ret) +} + +func LoadCursorWithResourceID(instance HINSTANCE, res uint16) HCURSOR { + ret, _, _ := procLoadCursor.Call( + uintptr(instance), + uintptr(res)) + + 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 RegisterWindowMessage(name *uint16) uint32 { + ret, _, _ := procRegisterWindowMessageA.Call( + uintptr(unsafe.Pointer(name))) + + return uint32(ret) +} + +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 HasGetDpiForWindowFunc() bool { + err := procGetDpiForWindow.Find() + return err == nil +} + +func GetDpiForWindow(hwnd HWND) UINT { + dpi, _, _ := procGetDpiForWindow.Call(hwnd) + return uint(dpi) +} + +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 uintptr, dwData unsafe.Pointer) bool { + ret, _, _ := procEnumDisplayMonitors.Call( + hdc, + uintptr(unsafe.Pointer(clip)), + fnEnum, + uintptr(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 +} diff --git a/v3/internal/w32/com.go b/v3/internal/w32/utils.go similarity index 66% rename from v3/internal/w32/com.go rename to v3/internal/w32/utils.go index 8542af1b1..8a72d4846 100644 --- a/v3/internal/w32/com.go +++ b/v3/internal/w32/utils.go @@ -1,92 +1,81 @@ +//go:build windows + +/* + * Copyright (C) 2019 Tad Vizbaras. All Rights Reserved. + * Copyright (C) 2010-2012 The W32 Authors. All Rights Reserved. + */ + package w32 import ( - "errors" "syscall" "unicode/utf16" "unsafe" ) -type pIUnknownVtbl struct { - queryInterface uintptr - addRef uintptr - release uintptr +func MustLoadLibrary(name string) uintptr { + lib, err := syscall.LoadLibrary(name) + if err != nil { + panic(err) + } + + return uintptr(lib) } -type IUnknown struct { - lpVtbl *pIUnknownVtbl +func MustGetProcAddress(lib uintptr, name string) uintptr { + addr, err := syscall.GetProcAddress(syscall.Handle(lib), name) + if err != nil { + panic(err) + } + + return uintptr(addr) } -func (u *IUnknown) QueryInterface(id *GUID) (*IDispatch, HRESULT) { - return ComQueryInterface(u, id) +func SUCCEEDED(hr HRESULT) bool { + return hr >= 0 } -func (u *IUnknown) AddRef() int32 { - return ComAddRef(u) +func FAILED(hr HRESULT) bool { + return hr < 0 } -func (u *IUnknown) Release() int32 { - return ComRelease(u) +func LOWORD(dw uint32) uint16 { + return uint16(dw) } -type pIDispatchVtbl struct { - queryInterface uintptr - addRef uintptr - release uintptr - getTypeInfoCount uintptr - getTypeInfo uintptr - getIDsOfNames uintptr - invoke uintptr +func HIWORD(dw uint32) uint16 { + return uint16(dw >> 16 & 0xffff) } -type IDispatch struct { - lpVtbl *pIDispatchVtbl +func MAKELONG(lo, hi uint16) uint32 { + return uint32(uint32(lo) | ((uint32(hi)) << 16)) } -func (d *IDispatch) QueryInterface(id *GUID) (*IDispatch, HRESULT) { - return ComQueryInterface((*IUnknown)(unsafe.Pointer(d)), id) +func BoolToBOOL(value bool) BOOL { + if value { + return 1 + } + + return 0 } -func (d *IDispatch) AddRef() int32 { - return ComAddRef((*IUnknown)(unsafe.Pointer(d))) -} +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) + } + } -func (d *IDispatch) Release() int32 { - return ComRelease((*IUnknown)(unsafe.Pointer(d))) -} - -func (d *IDispatch) GetIDsOfName(names []string) ([]int32, HRESULT) { - return ComGetIDsOfName(d, names) -} - -func (d *IDispatch) Invoke(dispid int32, dispatch int16, params ...interface{}) (*VARIANT, error) { - return ComInvoke(d, dispid, dispatch, params...) -} - -type pIStreamVtbl struct { - qeryInterface uintptr - addRef uintptr - release uintptr -} - -type IStream struct { - lpVtbl *pIStreamVtbl -} - -func (s *IStream) QueryInterface(id *GUID) (*IDispatch, HRESULT) { - return ComQueryInterface((*IUnknown)(unsafe.Pointer(s)), id) -} - -func (s *IStream) AddRef() int32 { - return ComAddRef((*IUnknown)(unsafe.Pointer(s))) -} - -func (s *IStream) Release() int32 { - return ComRelease((*IUnknown)(unsafe.Pointer(s))) + return "" } func ComAddRef(unknown *IUnknown) int32 { - ret, _, _ := syscall.Syscall(unknown.lpVtbl.addRef, 1, + ret, _, _ := syscall.Syscall(unknown.lpVtbl.pAddRef, 1, uintptr(unsafe.Pointer(unknown)), 0, 0) @@ -94,41 +83,45 @@ func ComAddRef(unknown *IUnknown) int32 { } func ComRelease(unknown *IUnknown) int32 { - ret, _, _ := syscall.Syscall(unknown.lpVtbl.release, 1, + ret, _, _ := syscall.Syscall(unknown.lpVtbl.pRelease, 1, uintptr(unsafe.Pointer(unknown)), 0, 0) return int32(ret) } -func ComQueryInterface(unknown *IUnknown, id *GUID) (*IDispatch, HRESULT) { +func ComQueryInterface(unknown *IUnknown, id *GUID) *IDispatch { var disp *IDispatch - hr, _, _ := syscall.Syscall(unknown.lpVtbl.queryInterface, 3, + hr, _, _ := syscall.Syscall(unknown.lpVtbl.pQueryInterface, 3, uintptr(unsafe.Pointer(unknown)), uintptr(unsafe.Pointer(id)), - uintptr(unsafe.Pointer(&disp)), - ) - return disp, HRESULT(hr) + uintptr(unsafe.Pointer(&disp))) + if hr != 0 { + panic("Invoke QieryInterface error.") + } + return disp } -func ComGetIDsOfName(disp *IDispatch, names []string) ([]int32, HRESULT) { +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.getIDsOfNames, 6, + 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])), - ) - return dispid, HRESULT(hr) + 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, err error) { +func ComInvoke(disp *IDispatch, dispid int32, dispatch int16, params ...interface{}) (result *VARIANT) { var dispparams DISPPARAMS if dispatch&DISPATCH_PROPERTYPUT != 0 { @@ -140,6 +133,7 @@ func ComInvoke(disp *IDispatch, dispid int32, dispatch int16, params ...interfac 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) { @@ -200,7 +194,7 @@ func ComInvoke(disp *IDispatch, dispid int32, dispatch int16, params ...interfac case *VARIANT: vargs[n] = VARIANT{VT_VARIANT | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*VARIANT))))} default: - return nil, errors.New("w32.ComInvoke: unknown variant type") + panic("unknown type") } } dispparams.Rgvarg = uintptr(unsafe.Pointer(&vargs[0])) @@ -210,7 +204,7 @@ func ComInvoke(disp *IDispatch, dispid int32, dispatch int16, params ...interfac var ret VARIANT var excepInfo EXCEPINFO VariantInit(&ret) - hr, _, _ := syscall.Syscall9(disp.lpVtbl.invoke, 8, + hr, _, _ := syscall.Syscall9(disp.lpVtbl.pInvoke, 8, uintptr(unsafe.Pointer(disp)), uintptr(dispid), uintptr(unsafe.Pointer(IID_NULL)), @@ -223,7 +217,7 @@ func ComInvoke(disp *IDispatch, dispid int32, dispatch int16, params ...interfac if hr != 0 { if excepInfo.BstrDescription != nil { bs := UTF16PtrToString(excepInfo.BstrDescription) - return nil, errors.New(bs) + panic(bs) } } for _, varg := range vargs { @@ -234,18 +228,3 @@ func ComInvoke(disp *IDispatch, dispid int32, dispatch int16, params ...interfac result = &ret return } - -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 "" -} diff --git a/v3/internal/w32/uxtheme.go b/v3/internal/w32/uxtheme.go new file mode 100644 index 000000000..51ec0035f --- /dev/null +++ b/v3/internal/w32/uxtheme.go @@ -0,0 +1,152 @@ +//go:build windows + +/* + * 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) +} diff --git a/v3/internal/w32/vars.go b/v3/internal/w32/vars.go new file mode 100644 index 000000000..cb69f9d19 --- /dev/null +++ b/v3/internal/w32/vars.go @@ -0,0 +1,16 @@ +//go:build windows + +/* + * 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}} +) diff --git a/v3/internal/w32/window.go b/v3/internal/w32/window.go new file mode 100644 index 000000000..67e20f017 --- /dev/null +++ b/v3/internal/w32/window.go @@ -0,0 +1,137 @@ +package w32 + +import ( + "fmt" + "log" + "strconv" + "syscall" + "unsafe" +) + +const ( + GCLP_HBRBACKGROUND int32 = -10 +) + +func ExtendFrameIntoClientArea(hwnd uintptr, extend bool) { + // -1: Adds the default frame styling (aero shadow and e.g. rounded corners on Windows 11) + // Also shows the caption buttons if transparent ant translucent but they don't work. + // 0: Adds the default frame styling but no aero shadow, does not show the caption buttons. + // 1: Adds the default frame styling (aero shadow and e.g. rounded corners on Windows 11) but no caption buttons + // are shown if transparent ant translucent. + var margins MARGINS + if extend { + margins = MARGINS{1, 1, 1, 1} // Only extend 1 pixel to have the default frame styling but no caption buttons + } + if err := dwmExtendFrameIntoClientArea(hwnd, &margins); err != nil { + log.Fatal(fmt.Errorf("DwmExtendFrameIntoClientArea failed: %s", err)) + } +} + +func IsVisible(hwnd uintptr) bool { + ret, _, _ := procIsWindowVisible.Call(hwnd) + return ret != 0 +} + +func IsWindowFullScreen(hwnd uintptr) bool { + wRect := GetWindowRect(hwnd) + m := MonitorFromWindow(hwnd, MONITOR_DEFAULTTOPRIMARY) + var mi MONITORINFO + mi.CbSize = uint32(unsafe.Sizeof(mi)) + if !GetMonitorInfo(m, &mi) { + return false + } + return wRect.Left == mi.RcMonitor.Left && + wRect.Top == mi.RcMonitor.Top && + wRect.Right == mi.RcMonitor.Right && + wRect.Bottom == mi.RcMonitor.Bottom +} + +func IsWindowMaximised(hwnd uintptr) bool { + style := uint32(getWindowLong(hwnd, GWL_STYLE)) + return style&WS_MAXIMIZE != 0 +} +func IsWindowMinimised(hwnd uintptr) bool { + style := uint32(getWindowLong(hwnd, GWL_STYLE)) + return style&WS_MINIMIZE != 0 +} + +func RestoreWindow(hwnd uintptr) { + showWindow(hwnd, SW_RESTORE) +} + +func ShowWindowMaximised(hwnd uintptr) { + showWindow(hwnd, SW_MAXIMIZE) +} +func ShowWindowMinimised(hwnd uintptr) { + showWindow(hwnd, SW_MINIMIZE) +} + +func SetBackgroundColour(hwnd uintptr, r, g, b uint8) { + col := uint32(r) | uint32(g)<<8 | uint32(b)<<16 + hbrush, _, _ := procCreateSolidBrush.Call(uintptr(col)) + setClassLongPtr(hwnd, GCLP_HBRBACKGROUND, hbrush) +} + +func IsWindowNormal(hwnd uintptr) bool { + return !IsWindowMaximised(hwnd) && !IsWindowMinimised(hwnd) && !IsWindowFullScreen(hwnd) +} + +func setClassLongPtr(hwnd uintptr, param int32, val uintptr) bool { + proc := procSetClassLongPtr + if strconv.IntSize == 32 { + /* + https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setclasslongptrw + Note: To write code that is compatible with both 32-bit and 64-bit Windows, use SetClassLongPtr. + When compiling for 32-bit Windows, SetClassLongPtr is defined as a call to the SetClassLong function + + => We have to do this dynamically when directly calling the DLL procedures + */ + proc = procSetClassLong + } + + ret, _, _ := proc.Call( + hwnd, + uintptr(param), + val, + ) + return ret != 0 +} + +func getWindowLong(hwnd uintptr, index int) int32 { + ret, _, _ := procGetWindowLong.Call( + hwnd, + uintptr(index)) + + return int32(ret) +} + +func showWindow(hwnd uintptr, cmdshow int) bool { + ret, _, _ := procShowWindow.Call( + hwnd, + uintptr(cmdshow)) + return ret != 0 +} + +func MustStringToUTF16Ptr(input string) *uint16 { + ret, err := syscall.UTF16PtrFromString(input) + if err != nil { + panic(err) + } + return ret +} + +func MustStringToUTF16uintptr(input string) uintptr { + ret, err := syscall.UTF16PtrFromString(input) + if err != nil { + panic(err) + } + return uintptr(unsafe.Pointer(ret)) +} + +func MustUTF16FromString(input string) []uint16 { + ret, err := syscall.UTF16FromString(input) + if err != nil { + panic(err) + } + return ret +} diff --git a/v3/pkg/application/mainthread_windows.go b/v3/pkg/application/mainthread_windows.go index 313848254..92cec88d7 100644 --- a/v3/pkg/application/mainthread_windows.go +++ b/v3/pkg/application/mainthread_windows.go @@ -17,7 +17,7 @@ var ( ) func init() { - wmInvokeCallback = w32.RegisterWindowMessage("WailsV0.InvokeCallback") + wmInvokeCallback = w32.RegisterWindowMessage(w32.MustStringToUTF16Ptr("WailsV0.InvokeCallback")) } // initMainLoop must be called with the same OSThread that is used to call runMainLoop() later. diff --git a/v3/pkg/application/messageprocessor_window.go b/v3/pkg/application/messageprocessor_window.go index cf36b9c31..ab4507073 100644 --- a/v3/pkg/application/messageprocessor_window.go +++ b/v3/pkg/application/messageprocessor_window.go @@ -102,7 +102,7 @@ func (m *MessageProcessor) processWindowMethod(method string, rw http.ResponseWr m.Error("Invalid SetBackgroundColour Message: 'a' value required") return } - window.SetBackgroundColour(&RGBA{ + window.SetBackgroundColour(RGBA{ Red: *r, Green: *g, Blue: *b, diff --git a/v3/pkg/application/options_webview_window.go b/v3/pkg/application/options_webview_window.go index 18f0e600c..367ac2ce4 100644 --- a/v3/pkg/application/options_webview_window.go +++ b/v3/pkg/application/options_webview_window.go @@ -23,7 +23,8 @@ type WebviewWindowOptions struct { MaxHeight int StartState WindowState Mac MacWindow - BackgroundColour *RGBA + BackgroundType BackgroundType + BackgroundColour RGBA HTML string JS string CSS string @@ -43,8 +44,22 @@ var WebviewWindowDefaults = &WebviewWindowOptions{ Width: 800, Height: 600, URL: "", + BackgroundColour: RGBA{ + Red: 255, + Green: 255, + Blue: 255, + Alpha: 255, + }, } type RGBA struct { Red, Green, Blue, Alpha uint8 } + +type BackgroundType int + +const ( + BackgroundTypeSolid BackgroundType = iota + BackgroundTypeTransparent + BackgroundTypeTranslucent +) diff --git a/v3/pkg/application/options_windows.go b/v3/pkg/application/options_windows.go index 0e118ddbd..703b92601 100644 --- a/v3/pkg/application/options_windows.go +++ b/v3/pkg/application/options_windows.go @@ -1,5 +1,18 @@ package application +type BackdropType int32 + +const ( + Auto BackdropType = 0 + None BackdropType = 1 + Mica BackdropType = 2 + Acrylic BackdropType = 3 + Tabbed BackdropType = 4 +) + type WindowsWindow struct { - AlwaysOnTop bool + // Select the type of translucent backdrop. Requires Windows 11 22621 or later. + BackdropType BackdropType + // Disable the icon in the titlebar + DisableIcon bool } diff --git a/v3/pkg/application/webview_window.go b/v3/pkg/application/webview_window.go index e9899fe82..67cfc3c2c 100644 --- a/v3/pkg/application/webview_window.go +++ b/v3/pkg/application/webview_window.go @@ -21,7 +21,7 @@ type ( setMaxSize(width, height int) execJS(js string) restore() - setBackgroundColour(color *RGBA) + setBackgroundColour(color RGBA) run() center() size() (int, int) @@ -171,7 +171,7 @@ func (w *WebviewWindow) run() { func (w *WebviewWindow) SetAlwaysOnTop(b bool) *WebviewWindow { w.options.AlwaysOnTop = b - if w.impl == nil { + if w.impl != nil { w.impl.setAlwaysOnTop(b) } return w @@ -346,7 +346,7 @@ func (w *WebviewWindow) IsFullscreen() bool { return w.impl.isFullscreen() } -func (w *WebviewWindow) SetBackgroundColour(colour *RGBA) *WebviewWindow { +func (w *WebviewWindow) SetBackgroundColour(colour RGBA) *WebviewWindow { w.options.BackgroundColour = colour if w.impl != nil { w.impl.setBackgroundColour(colour) diff --git a/v3/pkg/application/webview_window_darwin.go b/v3/pkg/application/webview_window_darwin.go index c8728f2e9..5be173fea 100644 --- a/v3/pkg/application/webview_window_darwin.go +++ b/v3/pkg/application/webview_window_darwin.go @@ -1147,7 +1147,7 @@ func (w *macosWebviewWindow) run() { }) } -func (w *macosWebviewWindow) setBackgroundColour(colour *RGBA) { +func (w *macosWebviewWindow) setBackgroundColour(colour RGBA) { if colour == nil { return } diff --git a/v3/pkg/application/webview_window_windows.go b/v3/pkg/application/webview_window_windows.go index 25c8f8b18..77136a49b 100644 --- a/v3/pkg/application/webview_window_windows.go +++ b/v3/pkg/application/webview_window_windows.go @@ -3,11 +3,13 @@ package application import ( + "errors" + "fmt" + "github.com/wailsapp/wails/v3/internal/w32" "syscall" "unsafe" "github.com/samber/lo" - "github.com/wailsapp/wails/v3/internal/w32" ) var showDevTools = func(window unsafe.Pointer) {} @@ -15,6 +17,7 @@ var showDevTools = func(window unsafe.Pointer) {} type windowsWebviewWindow struct { windowImpl unsafe.Pointer parent *WebviewWindow + hwnd w32.HWND } func (w *windowsWebviewWindow) setTitle(title string) { @@ -23,13 +26,18 @@ func (w *windowsWebviewWindow) setTitle(title string) { } func (w *windowsWebviewWindow) setSize(width, height int) { - //TODO implement me - panic("implement me") + x, y := w.position() + w32.MoveWindow(w.hwnd, x, y, width, height, true) } func (w *windowsWebviewWindow) setAlwaysOnTop(alwaysOnTop bool) { - //TODO implement me - panic("implement me") + globalApplication.dispatchOnMainThread(func() { + position := w32.HWND_NOTOPMOST + if alwaysOnTop { + position = w32.HWND_TOPMOST + } + w32.SetWindowPos(w.hwnd, position, 0, 0, 0, 0, uint(w32.SWP_NOMOVE|w32.SWP_NOSIZE)) + }) } func (w *windowsWebviewWindow) setURL(url string) { @@ -38,8 +46,9 @@ func (w *windowsWebviewWindow) setURL(url string) { } func (w *windowsWebviewWindow) setResizable(resizable bool) { - //TODO implement me - panic("implement me") + globalApplication.dispatchOnMainThread(func() { + w.setStyle(resizable, w32.WS_THICKFRAME) + }) } func (w *windowsWebviewWindow) setMinSize(width, height int) { @@ -62,9 +71,8 @@ func (w *windowsWebviewWindow) restore() { panic("implement me") } -func (w *windowsWebviewWindow) setBackgroundColour(color *RGBA) { - //TODO implement me - panic("implement me") +func (w *windowsWebviewWindow) setBackgroundColour(color RGBA) { + w32.SetBackgroundColour(w.hwnd, color.Red, color.Green, color.Blue) } func (w *windowsWebviewWindow) run() { @@ -74,22 +82,18 @@ func (w *windowsWebviewWindow) run() { func (w *windowsWebviewWindow) _run() { var exStyle uint options := w.parent.options - windowsOptions := options.Windows - //if windowsOptions != nil { exStyle = w32.WS_EX_CONTROLPARENT | w32.WS_EX_APPWINDOW - // if windowsOptions.WindowIsTranslucent { - // exStyle |= w32.WS_EX_NOREDIRECTIONBITMAP - // } - //} - if windowsOptions.AlwaysOnTop { + if options.BackgroundType != BackgroundTypeSolid { + exStyle |= w32.WS_EX_NOREDIRECTIONBITMAP + } + if options.AlwaysOnTop { exStyle |= w32.WS_EX_TOPMOST } - var hwnd w32.HWND - hwnd = w32.CreateWindowEx( + w.hwnd = w32.CreateWindowEx( exStyle, windowClassName, lo.Must(syscall.UTF16PtrFromString(options.Title)), - w32.WS_OVERLAPPEDWINDOW|w32.WS_VISIBLE, + w32.WS_OVERLAPPEDWINDOW, w32.CW_USEDEFAULT, w32.CW_USEDEFAULT, options.Width, @@ -99,15 +103,38 @@ func (w *windowsWebviewWindow) _run() { w32.GetModuleHandle(""), nil) - if hwnd == 0 { + if w.hwnd == 0 { panic("Unable to create window") } - if !options.Hidden { - w32.ShowWindow(hwnd, w32.SW_SHOW) - w32.UpdateWindow(hwnd) + if options.DisableResize { + w.setResizable(false) } - w32.SetForegroundWindow(hwnd) + + // Icon + if !options.Windows.DisableIcon { + // App icon ID is 3 + icon, err := NewIconFromResource(w32.GetModuleHandle(""), uint16(3)) + if err == nil { + w.setIcon(icon) + } + } else { + w.disableIcon() + } + + switch options.BackgroundType { + case BackgroundTypeSolid: + w.setBackgroundColour(options.BackgroundColour) + case BackgroundTypeTransparent: + case BackgroundTypeTranslucent: + w.setBackdropType(options.Windows.BackdropType) + } + + if !options.Hidden { + w.show() + w.update() + } + w.setForeground() } func (w *windowsWebviewWindow) center() { @@ -120,19 +147,27 @@ func (w *windowsWebviewWindow) size() (int, int) { panic("implement me") } +func (w *windowsWebviewWindow) setForeground() { + w32.SetForegroundWindow(w.hwnd) +} + +func (w *windowsWebviewWindow) update() { + w32.UpdateWindow(w.hwnd) +} + func (w *windowsWebviewWindow) width() int { - //TODO implement me - panic("implement me") + rect := w32.GetWindowRect(w.hwnd) + return int(rect.Right - rect.Left) } func (w *windowsWebviewWindow) height() int { - //TODO implement me - panic("implement me") + rect := w32.GetWindowRect(w.hwnd) + return int(rect.Bottom - rect.Top) } func (w *windowsWebviewWindow) position() (int, int) { - //TODO implement me - panic("implement me") + rect := w32.GetWindowRect(w.hwnd) + return int(rect.Left), int(rect.Right) } func (w *windowsWebviewWindow) destroy() { @@ -261,8 +296,7 @@ func (w *windowsWebviewWindow) setFullscreenButtonEnabled(enabled bool) { } func (w *windowsWebviewWindow) show() { - //TODO implement me - panic("implement me") + w32.ShowWindow(w.hwnd, w32.SW_SHOW) } func (w *windowsWebviewWindow) hide() { @@ -294,3 +328,76 @@ func (w *windowsWebviewWindow) openContextMenu(menu *Menu, data *ContextMenuData thisMenu.update() //C.windowShowMenu(w.nsWindow, thisMenu.nsMenu, C.int(data.X), C.int(data.Y)) } + +func (w *windowsWebviewWindow) setStyle(b bool, style int) { + currentStyle := int(w32.GetWindowLongPtr(w.hwnd, w32.GWL_STYLE)) + if currentStyle != 0 { + if b { + currentStyle |= style + } else { + currentStyle &^= style + } + w32.SetWindowLongPtr(w.hwnd, w32.GWL_STYLE, uintptr(currentStyle)) + } +} +func (w *windowsWebviewWindow) setExStyle(b bool, style int) { + currentStyle := int(w32.GetWindowLongPtr(w.hwnd, w32.GWL_EXSTYLE)) + if currentStyle != 0 { + if b { + currentStyle |= style + } else { + currentStyle &^= style + } + w32.SetWindowLongPtr(w.hwnd, w32.GWL_EXSTYLE, uintptr(currentStyle)) + } +} + +func (w *windowsWebviewWindow) setBackdropType(backdropType BackdropType) { + if !w32.IsWindowsVersionAtLeast(10, 0, 22621) { + var accent = w32.ACCENT_POLICY{ + AccentState: w32.ACCENT_ENABLE_BLURBEHIND, + } + var data w32.WINDOWCOMPOSITIONATTRIBDATA + data.Attrib = w32.WCA_ACCENT_POLICY + data.PvData = w32.PVOID(&accent) + data.CbData = w32.SIZE_T(unsafe.Sizeof(accent)) + + w32.SetWindowCompositionAttribute(w.hwnd, &data) + } else { + backdropValue := backdropType + // We default to None, but in win32 None = 1 and Auto = 0 + // So we check if the value given was Auto and set it to 0 + if backdropType == Auto { + backdropValue = None + } + w32.DwmSetWindowAttribute(w.hwnd, w32.DwmwaSystemBackdropType, w32.LPCVOID(&backdropValue), uint32(unsafe.Sizeof(backdropValue))) + } +} + +func (w *windowsWebviewWindow) setIcon(icon w32.HICON) { + w32.SendMessage(w.hwnd, w32.BM_SETIMAGE, w32.IMAGE_ICON, uintptr(icon)) +} + +func (w *windowsWebviewWindow) disableIcon() { + + // TODO: If frameless, return + + exStyle := w32.GetWindowLong(w.hwnd, w32.GWL_EXSTYLE) + w32.SetWindowLong(w.hwnd, w32.GWL_EXSTYLE, uint32(exStyle|w32.WS_EX_DLGMODALFRAME)) + w32.SetWindowPos(w.hwnd, 0, 0, 0, 0, 0, + uint( + w32.SWP_FRAMECHANGED| + w32.SWP_NOMOVE| + w32.SWP_NOSIZE| + w32.SWP_NOZORDER), + ) +} + +func NewIconFromResource(instance w32.HINSTANCE, resId uint16) (w32.HICON, error) { + var err error + var result w32.HICON + if result = w32.LoadIconWithResourceID(instance, resId); result == 0 { + err = errors.New(fmt.Sprintf("Cannot load icon from resource with id %v", resId)) + } + return result, err +} From 57422dccf346b489822b5d2767697a987ba9ed03 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Sat, 29 Apr 2023 12:14:12 +1000 Subject: [PATCH 08/28] [windows] Split out wndProc. Generate windows events, support per-window themes --- v3/internal/w32/user32.go | 6 ++ v3/pkg/application/application_windows.go | 59 +++++++++++--- v3/pkg/application/options_windows.go | 32 ++++++++ v3/pkg/application/webview_window_windows.go | 81 +++++++++++++++++++- v3/pkg/events/events.go | 12 +++ v3/pkg/events/events.txt | 2 +- v3/tasks/events/generate.go | 67 +++++++++++++++- 7 files changed, 242 insertions(+), 17 deletions(-) diff --git a/v3/internal/w32/user32.go b/v3/internal/w32/user32.go index 146472254..d337a6145 100644 --- a/v3/internal/w32/user32.go +++ b/v3/internal/w32/user32.go @@ -136,6 +136,7 @@ var ( procSetWindowsHookEx = moduser32.NewProc("SetWindowsHookExW") procUnhookWindowsHookEx = moduser32.NewProc("UnhookWindowsHookEx") procCallNextHookEx = moduser32.NewProc("CallNextHookEx") + procGetForegroundWindow = moduser32.NewProc("GetForegroundWindow") procSystemParametersInfo = moduser32.NewProc("SystemParametersInfoW") procSetClassLong = moduser32.NewProc("SetClassLongW") @@ -301,6 +302,11 @@ func GetDpiForWindow(hwnd HWND) UINT { return uint(dpi) } +func GetForegroundWindow() HWND { + ret, _, _ := procGetForegroundWindow.Call() + return HWND(ret) +} + func SetWindowCompositionAttribute(hwnd HWND, data *WINDOWCOMPOSITIONATTRIBDATA) bool { if procSetWindowCompositionAttribute != nil { ret, _, _ := procSetWindowCompositionAttribute.Call( diff --git a/v3/pkg/application/application_windows.go b/v3/pkg/application/application_windows.go index 851a4e8f0..e24c0d154 100644 --- a/v3/pkg/application/application_windows.go +++ b/v3/pkg/application/application_windows.go @@ -3,6 +3,7 @@ package application import ( + "github.com/wailsapp/wails/v3/pkg/events" "syscall" "unsafe" @@ -17,8 +18,13 @@ type windowsApp struct { instance w32.HINSTANCE + windowMap map[w32.HWND]*windowsWebviewWindow + mainThreadID w32.HANDLE mainThreadWindowHWND w32.HWND + + // system theme + isDarkMode bool } func (m *windowsApp) getPrimaryScreen() (*Screen, error) { @@ -111,28 +117,57 @@ func (m *windowsApp) init() { if ret := w32.RegisterClassEx(&wc); ret == 0 { panic(syscall.GetLastError()) } + + m.isDarkMode = w32.IsCurrentlyDarkMode() } func (m *windowsApp) wndProc(hwnd w32.HWND, msg uint32, wParam, lParam uintptr) uintptr { - switch msg { - case w32.WM_SIZE: + + // Handle the invoke callback + if msg == wmInvokeCallback { + m.invokeCallback(wParam, lParam) return 0 - case w32.WM_CLOSE: - w32.PostQuitMessage(0) - return 0 - case wmInvokeCallback: - if hwnd == m.mainThreadWindowHWND { - m.invokeCallback(wParam, lParam) - return 0 - } } + switch msg { + case w32.WM_SETTINGCHANGE: + settingChanged := w32.UTF16PtrToString((*uint16)(unsafe.Pointer(lParam))) + if settingChanged == "ImmersiveColorSet" { + isDarkMode := w32.IsCurrentlyDarkMode() + if isDarkMode != m.isDarkMode { + applicationEvents <- uint(events.Windows.SystemThemeChanged) + m.isDarkMode = isDarkMode + } + } + return 0 + } + + if window, ok := m.windowMap[hwnd]; ok { + return window.WndProc(msg, wParam, lParam) + } + + // Dispatch the message to the appropriate window + return w32.DefWindowProc(hwnd, msg, wParam, lParam) } +func (m *windowsApp) registerWindow(result *windowsWebviewWindow) { + m.windowMap[result.hwnd] = result +} + +func (m *windowsApp) unregisterWindow(w *windowsWebviewWindow) { + delete(m.windowMap, w.hwnd) + + // If this was the last window... + if len(m.windowMap) == 0 { + w32.PostQuitMessage(0) + } +} + func newPlatformApp(app *App) *windowsApp { result := &windowsApp{ - parent: app, - instance: w32.GetModuleHandle(""), + parent: app, + instance: w32.GetModuleHandle(""), + windowMap: make(map[w32.HWND]*windowsWebviewWindow), } result.init() diff --git a/v3/pkg/application/options_windows.go b/v3/pkg/application/options_windows.go index 703b92601..55f69a7e2 100644 --- a/v3/pkg/application/options_windows.go +++ b/v3/pkg/application/options_windows.go @@ -15,4 +15,36 @@ type WindowsWindow struct { BackdropType BackdropType // Disable the icon in the titlebar DisableIcon bool + // Theme. Defaults to SystemDefault which will use whatever the system theme is. The application will follow system theme changes. + Theme Theme + // Custom colours for dark/light mode + CustomTheme *ThemeSettings +} + +type Theme int + +const ( + // SystemDefault will use whatever the system theme is. The application will follow system theme changes. + SystemDefault Theme = 0 + // Dark Mode + Dark Theme = 1 + // Light Mode + Light Theme = 2 +) + +// ThemeSettings defines custom colours to use in dark or light mode. +// They may be set using the hex values: 0x00BBGGRR +type ThemeSettings struct { + DarkModeTitleBar int32 + DarkModeTitleBarInactive int32 + DarkModeTitleText int32 + DarkModeTitleTextInactive int32 + DarkModeBorder int32 + DarkModeBorderInactive int32 + LightModeTitleBar int32 + LightModeTitleBarInactive int32 + LightModeTitleText int32 + LightModeTitleTextInactive int32 + LightModeBorder int32 + LightModeBorderInactive int32 } diff --git a/v3/pkg/application/webview_window_windows.go b/v3/pkg/application/webview_window_windows.go index 77136a49b..409964dd0 100644 --- a/v3/pkg/application/webview_window_windows.go +++ b/v3/pkg/application/webview_window_windows.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "github.com/wailsapp/wails/v3/internal/w32" + "github.com/wailsapp/wails/v3/pkg/events" "syscall" "unsafe" @@ -107,6 +108,10 @@ func (w *windowsWebviewWindow) _run() { panic("Unable to create window") } + // Register the window with the application + windowsApp := globalApplication.impl.(*windowsApp) + windowsApp.registerWindow(w) + if options.DisableResize { w.setResizable(false) } @@ -129,12 +134,25 @@ func (w *windowsWebviewWindow) _run() { case BackgroundTypeTranslucent: w.setBackdropType(options.Windows.BackdropType) } + w.setForeground() + + // Process the theme + switch options.Windows.Theme { + case SystemDefault: + w.updateTheme(w32.IsCurrentlyDarkMode()) + globalApplication.On(events.Windows.SystemThemeChanged, func() { + w.updateTheme(w32.IsCurrentlyDarkMode()) + }) + case Light: + w.updateTheme(false) + case Dark: + w.updateTheme(true) + } if !options.Hidden { w.show() w.update() } - w.setForeground() } func (w *windowsWebviewWindow) center() { @@ -365,7 +383,7 @@ func (w *windowsWebviewWindow) setBackdropType(backdropType BackdropType) { w32.SetWindowCompositionAttribute(w.hwnd, &data) } else { backdropValue := backdropType - // We default to None, but in win32 None = 1 and Auto = 0 + // We default to None, but in w32 None = 1 and Auto = 0 // So we check if the value given was Auto and set it to 0 if backdropType == Auto { backdropValue = None @@ -393,6 +411,65 @@ func (w *windowsWebviewWindow) disableIcon() { ) } +func (w *windowsWebviewWindow) updateTheme(isDarkMode bool) { + + if w32.IsCurrentlyHighContrastMode() { + return + } + + if !w32.SupportsThemes() { + return + } + + w32.SetTheme(w.hwnd, isDarkMode) + + // Custom theme processing + customTheme := w.parent.options.Windows.CustomTheme + // Custom theme + if w32.SupportsCustomThemes() && customTheme != nil { + if w.isActive() { + if isDarkMode { + w32.SetTitleBarColour(w.hwnd, customTheme.DarkModeTitleBar) + w32.SetTitleTextColour(w.hwnd, customTheme.DarkModeTitleText) + w32.SetBorderColour(w.hwnd, customTheme.DarkModeBorder) + } else { + w32.SetTitleBarColour(w.hwnd, customTheme.LightModeTitleBar) + w32.SetTitleTextColour(w.hwnd, customTheme.LightModeTitleText) + w32.SetBorderColour(w.hwnd, customTheme.LightModeBorder) + } + } else { + if isDarkMode { + w32.SetTitleBarColour(w.hwnd, customTheme.DarkModeTitleBarInactive) + w32.SetTitleTextColour(w.hwnd, customTheme.DarkModeTitleTextInactive) + w32.SetBorderColour(w.hwnd, customTheme.DarkModeBorderInactive) + } else { + w32.SetTitleBarColour(w.hwnd, customTheme.LightModeTitleBarInactive) + w32.SetTitleTextColour(w.hwnd, customTheme.LightModeTitleTextInactive) + w32.SetBorderColour(w.hwnd, customTheme.LightModeBorderInactive) + } + } + } +} + +func (w *windowsWebviewWindow) isActive() bool { + return w32.GetForegroundWindow() == w.hwnd +} + +func (w *windowsWebviewWindow) WndProc(msg uint32, wparam, lparam uintptr) uintptr { + switch msg { + case w32.WM_SIZE: + return 0 + case w32.WM_CLOSE: + w32.PostMessage(w.hwnd, w32.WM_QUIT, 0, 0) + // Unregister the window with the application + windowsApp := globalApplication.impl.(*windowsApp) + windowsApp.unregisterWindow(w) + return 0 + default: + return w32.DefWindowProc(w.hwnd, msg, wparam, lparam) + } +} + func NewIconFromResource(instance w32.HINSTANCE, resId uint16) (w32.HICON, error) { var err error var result w32.HICON diff --git a/v3/pkg/events/events.go b/v3/pkg/events/events.go index f26f53b2e..23c0cf7b5 100644 --- a/v3/pkg/events/events.go +++ b/v3/pkg/events/events.go @@ -260,3 +260,15 @@ func newMacEvents() macEvents { WindowFileDraggingExited: 1145, } } + +var Windows = newWindowsEvents() + +type windowsEvents struct { + SystemThemeChanged ApplicationEventType +} + +func newWindowsEvents() windowsEvents { + return windowsEvents{ + SystemThemeChanged: 1146, + } +} diff --git a/v3/pkg/events/events.txt b/v3/pkg/events/events.txt index dbbe98db4..ae0338627 100644 --- a/v3/pkg/events/events.txt +++ b/v3/pkg/events/events.txt @@ -120,4 +120,4 @@ mac:WebViewDidCommitNavigation mac:WindowFileDraggingEntered mac:WindowFileDraggingPerformed mac:WindowFileDraggingExited - +windows:SystemThemeChanged \ No newline at end of file diff --git a/v3/tasks/events/generate.go b/v3/tasks/events/generate.go index eafa27f89..2c5869a1e 100644 --- a/v3/tasks/events/generate.go +++ b/v3/tasks/events/generate.go @@ -25,6 +25,18 @@ func newMacEvents() macEvents { return macEvents{ $$MACEVENTSVALUES } } + +var Windows = newWindowsEvents() + +type windowsEvents struct { +$$WINDOWSEVENTSDECL} + +func newWindowsEvents() windowsEvents { + return windowsEvents{ +$$WINDOWSEVENTSVALUES } +} + + ` var eventsH = `//go:build darwin @@ -53,7 +65,11 @@ func main() { applicationDelegateEvents := bytes.NewBufferString("") webviewDelegateEvents := bytes.NewBufferString("") + windowsEventsDecl := bytes.NewBufferString("") + windowsEventsValues := bytes.NewBufferString("") + var id int + var maxMacEvents int var line []byte // Loop over each line in the file for id, line = range bytes.Split(eventNames, []byte{'\n'}) { @@ -94,6 +110,7 @@ func main() { macEventsDecl.WriteString("\t" + eventTitle + " " + eventType + "\n") macEventsValues.WriteString("\t\t" + event + ": " + strconv.Itoa(id) + ",\n") cHeaderEvents.WriteString("#define Event" + eventTitle + " " + strconv.Itoa(id) + "\n") + maxMacEvents = id if ignoreEvent { continue } @@ -128,15 +145,61 @@ func main() { `) } - + case "windows": + eventType := "ApplicationEventType" + if strings.HasPrefix(event, "Window") { + eventType = "WindowEventType" + } + if strings.HasPrefix(event, "WebView") { + eventType = "WindowEventType" + } + windowsEventsDecl.WriteString("\t" + eventTitle + " " + eventType + "\n") + windowsEventsValues.WriteString("\t\t" + event + ": " + strconv.Itoa(id) + ",\n") + // cHeaderEvents.WriteString("#define Event" + eventTitle + " " + strconv.Itoa(id) + "\n") + // if ignoreEvent { + // continue + // } + // // Check if this is a window event + // if strings.HasPrefix(event, "Window") { + // windowDelegateEvents.WriteString(`- (void)` + delegateEventFunction + `:(NSNotification *)notification { + // if( hasListeners(Event` + eventTitle + `) ) { + // processWindowEvent(self.windowId, Event` + eventTitle + `); + // } + //} + // + //`) + // } + // // Check if this is a webview event + // if strings.HasPrefix(event, "WebView") { + // webViewFunction := strings.TrimPrefix(event, "WebView") + // webViewFunction = string(bytes.ToLower([]byte{webViewFunction[0]})) + webViewFunction[1:] + // webviewDelegateEvents.WriteString(`- (void)webView:(WKWebView *)webview ` + webViewFunction + `:(WKNavigation *)navigation { + // if( hasListeners(Event` + eventTitle + `) ) { + // processWindowEvent(self.windowId, Event` + eventTitle + `); + // } + //} + // + //`) + // } + // if strings.HasPrefix(event, "Application") { + // applicationDelegateEvents.WriteString(`- (void)` + delegateEventFunction + `:(NSNotification *)notification { + // if( hasListeners(Event` + eventTitle + `) ) { + // processApplicationEvent(Event` + eventTitle + `); + // } + //} + // + //`) + // } } } - cHeaderEvents.WriteString("\n#define MAX_EVENTS " + strconv.Itoa(id-1) + "\n") + cHeaderEvents.WriteString("\n#define MAX_EVENTS " + strconv.Itoa(maxMacEvents+1) + "\n") // Save the eventsGo template substituting the values and decls templateToWrite := strings.ReplaceAll(eventsGo, "$$MACEVENTSDECL", macEventsDecl.String()) templateToWrite = strings.ReplaceAll(templateToWrite, "$$MACEVENTSVALUES", macEventsValues.String()) + templateToWrite = strings.ReplaceAll(templateToWrite, "$$WINDOWSEVENTSDECL", windowsEventsDecl.String()) + templateToWrite = strings.ReplaceAll(templateToWrite, "$$WINDOWSEVENTSVALUES", windowsEventsValues.String()) err = os.WriteFile("../../pkg/events/events.go", []byte(templateToWrite), 0644) if err != nil { panic(err) From 676787417f0e78aa4029949c34c691eeada5ffb4 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Sat, 29 Apr 2023 19:39:05 +1000 Subject: [PATCH 09/28] [v3] Update `application.On` and `window.On` to return functions that unregister the listener. `WebviewWindow.onApplicationEvent` is a helper which will manage the unregistering for you on window destroy. --- v3/pkg/application/application.go | 26 ++++++++-- v3/pkg/application/webview_window.go | 50 +++++++++++++++++--- v3/pkg/application/webview_window_windows.go | 3 +- 3 files changed, 66 insertions(+), 13 deletions(-) diff --git a/v3/pkg/application/application.go b/v3/pkg/application/application.go index c8a62502f..9cc7bae08 100644 --- a/v3/pkg/application/application.go +++ b/v3/pkg/application/application.go @@ -1,6 +1,7 @@ package application import ( + "github.com/samber/lo" "log" "net/http" "os" @@ -23,6 +24,10 @@ func init() { runtime.LockOSThread() } +type EventListener struct { + callback func() +} + func New(appOptions Options) *App { if globalApplication != nil { return globalApplication @@ -32,7 +37,7 @@ func New(appOptions Options) *App { result := &App{ options: appOptions, - applicationEventListeners: make(map[uint][]func()), + applicationEventListeners: make(map[uint][]*EventListener), systemTrays: make(map[uint]*SystemTray), log: logger.New(appOptions.Logger.CustomLoggers...), contextMenus: make(map[string]*Menu), @@ -155,7 +160,7 @@ var webviewRequests = make(chan *webViewAssetRequest) type App struct { options Options - applicationEventListeners map[uint][]func() + applicationEventListeners map[uint][]*EventListener applicationEventListenersLock sync.RWMutex // Windows @@ -216,14 +221,25 @@ func (a *App) deleteWindowByID(id uint) { delete(a.windows, id) } -func (a *App) On(eventType events.ApplicationEventType, callback func()) { +func (a *App) On(eventType events.ApplicationEventType, callback func()) func() { eventID := uint(eventType) a.applicationEventListenersLock.Lock() defer a.applicationEventListenersLock.Unlock() - a.applicationEventListeners[eventID] = append(a.applicationEventListeners[eventID], callback) + listener := &EventListener{ + callback: callback, + } + a.applicationEventListeners[eventID] = append(a.applicationEventListeners[eventID], listener) if a.impl != nil { go a.impl.on(eventID) } + + return func() { + // lock the map + a.applicationEventListenersLock.Lock() + defer a.applicationEventListenersLock.Unlock() + // Remove listener + a.applicationEventListeners[eventID] = lo.Without(a.applicationEventListeners[eventID], listener) + } } func (a *App) NewWebviewWindow() *WebviewWindow { return a.NewWebviewWindowWithOptions(&WebviewWindowOptions{}) @@ -383,7 +399,7 @@ func (a *App) handleApplicationEvent(event uint) { return } for _, listener := range listeners { - go listener() + go listener.callback() } } diff --git a/v3/pkg/application/webview_window.go b/v3/pkg/application/webview_window.go index 67cfc3c2c..0dc2b1355 100644 --- a/v3/pkg/application/webview_window.go +++ b/v3/pkg/application/webview_window.go @@ -2,6 +2,7 @@ package application import ( "fmt" + "github.com/samber/lo" "sync" "time" @@ -61,17 +62,25 @@ type ( } ) +type WindowEventListener struct { + callback func(ctx *WindowEventContext) +} + type WebviewWindow struct { options *WebviewWindowOptions impl webviewWindowImpl implLock sync.RWMutex id uint - eventListeners map[uint][]func(ctx *WindowEventContext) + eventListeners map[uint][]*WindowEventListener eventListenersLock sync.RWMutex contextMenus map[string]*Menu contextMenusLock sync.RWMutex + + // A map of listener cancellation functions + cancellersLock sync.RWMutex + cancellers []func() } var windowID uint @@ -84,6 +93,13 @@ func getWindowID() uint { return windowID } +// Use onApplicationEvent to register a callback for an application event from a window. +// This will handle tidying up the callback when the window is destroyed +func (w *WebviewWindow) onApplicationEvent(eventType events.ApplicationEventType, callback func()) { + cancelFn := globalApplication.On(eventType, callback) + w.addCancellationFunction(cancelFn) +} + func NewWindow(options *WebviewWindowOptions) *WebviewWindow { if options.Width == 0 { options.Width = 800 @@ -98,13 +114,19 @@ func NewWindow(options *WebviewWindowOptions) *WebviewWindow { result := &WebviewWindow{ id: getWindowID(), options: options, - eventListeners: make(map[uint][]func(ctx *WindowEventContext)), + eventListeners: make(map[uint][]*WindowEventListener), contextMenus: make(map[string]*Menu), } return result } +func (w *WebviewWindow) addCancellationFunction(canceller func()) { + w.cancellersLock.Lock() + defer w.cancellersLock.Unlock() + w.cancellers = append(w.cancellers, canceller) +} + func (w *WebviewWindow) SetTitle(title string) *WebviewWindow { w.implLock.RLock() defer w.implLock.RUnlock() @@ -371,20 +393,30 @@ func (w *WebviewWindow) Center() { w.impl.center() } -func (w *WebviewWindow) On(eventType events.WindowEventType, callback func(ctx *WindowEventContext)) { +func (w *WebviewWindow) On(eventType events.WindowEventType, callback func(ctx *WindowEventContext)) func() { eventID := uint(eventType) w.eventListenersLock.Lock() defer w.eventListenersLock.Unlock() - w.eventListeners[eventID] = append(w.eventListeners[eventID], callback) + windowEventListener := &WindowEventListener{ + callback: callback, + } + w.eventListeners[eventID] = append(w.eventListeners[eventID], windowEventListener) if w.impl != nil { w.impl.on(eventID) } + + return func() { + w.eventListenersLock.Lock() + defer w.eventListenersLock.Unlock() + w.eventListeners[eventID] = lo.Without(w.eventListeners[eventID], windowEventListener) + } + } func (w *WebviewWindow) handleWindowEvent(id uint) { w.eventListenersLock.RLock() - for _, callback := range w.eventListeners[id] { - go callback(blankWindowEventContext) + for _, listener := range w.eventListeners[id] { + go listener.callback(blankWindowEventContext) } w.eventListenersLock.RUnlock() } @@ -416,6 +448,10 @@ func (w *WebviewWindow) Destroy() { if w.impl == nil { return } + // Cancel the callbacks + for _, cancelFunc := range w.cancellers { + cancelFunc() + } w.impl.destroy() } @@ -631,7 +667,7 @@ func (w *WebviewWindow) handleDragAndDropMessage(event *dragAndDropMessage) { ctx := newWindowEventContext() ctx.setDroppedFiles(event.filenames) for _, listener := range w.eventListeners[uint(events.FilesDropped)] { - listener(ctx) + listener.callback(ctx) } } diff --git a/v3/pkg/application/webview_window_windows.go b/v3/pkg/application/webview_window_windows.go index 409964dd0..b47b3738e 100644 --- a/v3/pkg/application/webview_window_windows.go +++ b/v3/pkg/application/webview_window_windows.go @@ -140,7 +140,8 @@ func (w *windowsWebviewWindow) _run() { switch options.Windows.Theme { case SystemDefault: w.updateTheme(w32.IsCurrentlyDarkMode()) - globalApplication.On(events.Windows.SystemThemeChanged, func() { + // Setup a listener to respond to theme changes + w.parent.onApplicationEvent(events.Windows.SystemThemeChanged, func() { w.updateTheme(w32.IsCurrentlyDarkMode()) }) case Light: From 1128662c8987220535ff7e7b5459fee7318908c9 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Sat, 29 Apr 2023 20:33:33 +1000 Subject: [PATCH 10/28] [v3 windows] Add APM Events --- v3/pkg/application/application_windows.go | 14 ++++++++++++++ v3/pkg/events/events.go | 14 ++++++++++++-- v3/pkg/events/events.txt | 7 ++++++- 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/v3/pkg/application/application_windows.go b/v3/pkg/application/application_windows.go index e24c0d154..7253d7cbc 100644 --- a/v3/pkg/application/application_windows.go +++ b/v3/pkg/application/application_windows.go @@ -139,6 +139,20 @@ func (m *windowsApp) wndProc(hwnd w32.HWND, msg uint32, wParam, lParam uintptr) } } return 0 + case w32.WM_POWERBROADCAST: + switch wParam { + case w32.PBT_APMPOWERSTATUSCHANGE: + applicationEvents <- uint(events.Windows.APMPowerStatusChange) + case w32.PBT_APMSUSPEND: + applicationEvents <- uint(events.Windows.APMSuspend) + case w32.PBT_APMRESUMEAUTOMATIC: + applicationEvents <- uint(events.Windows.APMResumeAutomatic) + case w32.PBT_APMRESUMESUSPEND: + applicationEvents <- uint(events.Windows.APMResumeSuspend) + case w32.PBT_POWERSETTINGCHANGE: + applicationEvents <- uint(events.Windows.APMPowerSettingChange) + } + return 0 } if window, ok := m.windowMap[hwnd]; ok { diff --git a/v3/pkg/events/events.go b/v3/pkg/events/events.go index 23c0cf7b5..5e97f358c 100644 --- a/v3/pkg/events/events.go +++ b/v3/pkg/events/events.go @@ -264,11 +264,21 @@ func newMacEvents() macEvents { var Windows = newWindowsEvents() type windowsEvents struct { - SystemThemeChanged ApplicationEventType + SystemThemeChanged ApplicationEventType + APMPowerStatusChange ApplicationEventType + APMSuspend ApplicationEventType + APMResumeAutomatic ApplicationEventType + APMResumeSuspend ApplicationEventType + APMPowerSettingChange ApplicationEventType } func newWindowsEvents() windowsEvents { return windowsEvents{ - SystemThemeChanged: 1146, + SystemThemeChanged: 1146, + APMPowerStatusChange: 1147, + APMSuspend: 1148, + APMResumeAutomatic: 1149, + APMResumeSuspend: 1150, + APMPowerSettingChange: 1151, } } diff --git a/v3/pkg/events/events.txt b/v3/pkg/events/events.txt index ae0338627..e1ddfb262 100644 --- a/v3/pkg/events/events.txt +++ b/v3/pkg/events/events.txt @@ -120,4 +120,9 @@ mac:WebViewDidCommitNavigation mac:WindowFileDraggingEntered mac:WindowFileDraggingPerformed mac:WindowFileDraggingExited -windows:SystemThemeChanged \ No newline at end of file +windows:SystemThemeChanged +windows:APMPowerStatusChange +windows:APMSuspend +windows:APMResumeAutomatic +windows:APMResumeSuspend +windows:APMPowerSettingChange From c53443b62b097f17bf6ffbb972256795d9941ad1 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Sun, 30 Apr 2023 09:10:00 +1000 Subject: [PATCH 11/28] [v3 windows] Rename `options_windows.go` -> `options_win.go` --- v3/pkg/application/{options_windows.go => options_win.go} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename v3/pkg/application/{options_windows.go => options_win.go} (100%) diff --git a/v3/pkg/application/options_windows.go b/v3/pkg/application/options_win.go similarity index 100% rename from v3/pkg/application/options_windows.go rename to v3/pkg/application/options_win.go From 6e565425867a59f941edf0f203f275276f0239c7 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Sun, 30 Apr 2023 09:49:50 +1000 Subject: [PATCH 12/28] [v3 windows] Add `WndProcInterceptor` for custom message processing --- v3/V3 Changes.md | 14 ++++++++++++++ v3/pkg/application/application_windows.go | 9 +++++++++ v3/pkg/application/options_application.go | 1 + v3/pkg/application/options_win.go | 8 ++++++++ 4 files changed, 32 insertions(+) diff --git a/v3/V3 Changes.md b/v3/V3 Changes.md index 9ec98b8e9..f391029cf 100644 --- a/v3/V3 Changes.md +++ b/v3/V3 Changes.md @@ -202,3 +202,17 @@ On Windows, if the `BackgroundType` is set to `BackgroundTypeTranslucent`, the t - `Tabbed` - The window will use the tabbed effect +## Windows Application Options + +### WndProcInterceptor + +If this is set, the WndProc will be intercepted and the function will be called. This allows you to handle Windows +messages directly. The function should have the following signature: + +```go +func(hwnd uintptr, msg uint32, wParam, lParam uintptr) (returnValue uintptr, shouldReturn) +``` + +The `shouldReturn` value should be set to `true` if the returnValue should be returned by the main wndProc method. +If it is set to `false`, the return value will be ignored and the message will continue to be processed by the main +wndProc method. \ No newline at end of file diff --git a/v3/pkg/application/application_windows.go b/v3/pkg/application/application_windows.go index 7253d7cbc..82c65abf1 100644 --- a/v3/pkg/application/application_windows.go +++ b/v3/pkg/application/application_windows.go @@ -128,6 +128,15 @@ func (m *windowsApp) wndProc(hwnd w32.HWND, msg uint32, wParam, lParam uintptr) m.invokeCallback(wParam, lParam) return 0 } + + // If the WndProcInterceptor is set in options, pass the message on + if m.parent.options.Windows.WndProcInterceptor != nil { + returnValue, shouldReturn := m.parent.options.Windows.WndProcInterceptor(hwnd, msg, wParam, lParam) + if shouldReturn { + return returnValue + } + } + switch msg { case w32.WM_SETTINGCHANGE: settingChanged := w32.UTF16PtrToString((*uint16)(unsafe.Pointer(lParam))) diff --git a/v3/pkg/application/options_application.go b/v3/pkg/application/options_application.go index 0a768a0b7..f37b2dc7e 100644 --- a/v3/pkg/application/options_application.go +++ b/v3/pkg/application/options_application.go @@ -12,6 +12,7 @@ type Options struct { Description string Icon []byte Mac MacOptions + Windows WindowsApplicationOptions Bind []any Logger struct { Silent bool diff --git a/v3/pkg/application/options_win.go b/v3/pkg/application/options_win.go index 55f69a7e2..e060d9e9c 100644 --- a/v3/pkg/application/options_win.go +++ b/v3/pkg/application/options_win.go @@ -1,5 +1,13 @@ package application +type WindowsApplicationOptions struct { + // WndProcInterceptor is a function that will be called for every message sent in the application. + // Use this to hook into the main message loop. This is useful for handling custom window messages. + // If `shouldReturn` is `true` then `returnCode` will be returned by the main message loop. + // If `shouldReturn` is `false` then returnCode will be ignored and the message will be processed by the main message loop. + WndProcInterceptor func(hwnd uintptr, msg uint32, wParam, lParam uintptr) (returnCode uintptr, shouldReturn bool) +} + type BackdropType int32 const ( From 79f8d9208465672b48e92262afa63c9a45a869a9 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Sun, 30 Apr 2023 10:02:00 +1000 Subject: [PATCH 13/28] [v3 windows] Moved `w32` from `internal` to `pkg` so it may be used by applications --- v3/pkg/application/application_windows.go | 2 +- v3/pkg/application/mainthread_windows.go | 2 +- v3/pkg/application/webview_window_windows.go | 2 +- v3/{internal => pkg}/w32/clipboard.go | 0 v3/{internal => pkg}/w32/comctl32.go | 0 v3/{internal => pkg}/w32/comdlg32.go | 0 v3/{internal => pkg}/w32/constants.go | 0 v3/{internal => pkg}/w32/consts.go | 0 v3/{internal => pkg}/w32/dwmapi.go | 0 v3/{internal => pkg}/w32/gdi32.go | 0 v3/{internal => pkg}/w32/gdiplus.go | 0 v3/{internal => pkg}/w32/idispatch.go | 0 v3/{internal => pkg}/w32/istream.go | 0 v3/{internal => pkg}/w32/iunknown.go | 0 v3/{internal => pkg}/w32/kernel32.go | 0 v3/{internal => pkg}/w32/ole32.go | 0 v3/{internal => pkg}/w32/oleaut32.go | 0 v3/{internal => pkg}/w32/shcore.go | 0 v3/{internal => pkg}/w32/shell32.go | 0 v3/{internal => pkg}/w32/shlwapi.go | 0 v3/{internal => pkg}/w32/theme.go | 0 v3/{internal => pkg}/w32/toolbar.go | 0 v3/{internal => pkg}/w32/typedef.go | 0 v3/{internal => pkg}/w32/user32.go | 0 v3/{internal => pkg}/w32/utils.go | 0 v3/{internal => pkg}/w32/uxtheme.go | 0 v3/{internal => pkg}/w32/vars.go | 0 v3/{internal => pkg}/w32/window.go | 0 28 files changed, 3 insertions(+), 3 deletions(-) rename v3/{internal => pkg}/w32/clipboard.go (100%) rename v3/{internal => pkg}/w32/comctl32.go (100%) rename v3/{internal => pkg}/w32/comdlg32.go (100%) rename v3/{internal => pkg}/w32/constants.go (100%) rename v3/{internal => pkg}/w32/consts.go (100%) rename v3/{internal => pkg}/w32/dwmapi.go (100%) rename v3/{internal => pkg}/w32/gdi32.go (100%) rename v3/{internal => pkg}/w32/gdiplus.go (100%) rename v3/{internal => pkg}/w32/idispatch.go (100%) rename v3/{internal => pkg}/w32/istream.go (100%) rename v3/{internal => pkg}/w32/iunknown.go (100%) rename v3/{internal => pkg}/w32/kernel32.go (100%) rename v3/{internal => pkg}/w32/ole32.go (100%) rename v3/{internal => pkg}/w32/oleaut32.go (100%) rename v3/{internal => pkg}/w32/shcore.go (100%) rename v3/{internal => pkg}/w32/shell32.go (100%) rename v3/{internal => pkg}/w32/shlwapi.go (100%) rename v3/{internal => pkg}/w32/theme.go (100%) rename v3/{internal => pkg}/w32/toolbar.go (100%) rename v3/{internal => pkg}/w32/typedef.go (100%) rename v3/{internal => pkg}/w32/user32.go (100%) rename v3/{internal => pkg}/w32/utils.go (100%) rename v3/{internal => pkg}/w32/uxtheme.go (100%) rename v3/{internal => pkg}/w32/vars.go (100%) rename v3/{internal => pkg}/w32/window.go (100%) diff --git a/v3/pkg/application/application_windows.go b/v3/pkg/application/application_windows.go index 82c65abf1..3f9225673 100644 --- a/v3/pkg/application/application_windows.go +++ b/v3/pkg/application/application_windows.go @@ -4,11 +4,11 @@ package application import ( "github.com/wailsapp/wails/v3/pkg/events" + "github.com/wailsapp/wails/v3/pkg/w32" "syscall" "unsafe" "github.com/samber/lo" - "github.com/wailsapp/wails/v3/internal/w32" ) var windowClassName = lo.Must(syscall.UTF16PtrFromString("WailsWebviewWindow")) diff --git a/v3/pkg/application/mainthread_windows.go b/v3/pkg/application/mainthread_windows.go index 92cec88d7..80967ccab 100644 --- a/v3/pkg/application/mainthread_windows.go +++ b/v3/pkg/application/mainthread_windows.go @@ -3,13 +3,13 @@ package application import ( + "github.com/wailsapp/wails/v3/pkg/w32" "runtime" "sort" "syscall" "unsafe" "github.com/samber/lo" - "github.com/wailsapp/wails/v3/internal/w32" ) var ( diff --git a/v3/pkg/application/webview_window_windows.go b/v3/pkg/application/webview_window_windows.go index b47b3738e..a7b888f75 100644 --- a/v3/pkg/application/webview_window_windows.go +++ b/v3/pkg/application/webview_window_windows.go @@ -5,8 +5,8 @@ package application import ( "errors" "fmt" - "github.com/wailsapp/wails/v3/internal/w32" "github.com/wailsapp/wails/v3/pkg/events" + "github.com/wailsapp/wails/v3/pkg/w32" "syscall" "unsafe" diff --git a/v3/internal/w32/clipboard.go b/v3/pkg/w32/clipboard.go similarity index 100% rename from v3/internal/w32/clipboard.go rename to v3/pkg/w32/clipboard.go diff --git a/v3/internal/w32/comctl32.go b/v3/pkg/w32/comctl32.go similarity index 100% rename from v3/internal/w32/comctl32.go rename to v3/pkg/w32/comctl32.go diff --git a/v3/internal/w32/comdlg32.go b/v3/pkg/w32/comdlg32.go similarity index 100% rename from v3/internal/w32/comdlg32.go rename to v3/pkg/w32/comdlg32.go diff --git a/v3/internal/w32/constants.go b/v3/pkg/w32/constants.go similarity index 100% rename from v3/internal/w32/constants.go rename to v3/pkg/w32/constants.go diff --git a/v3/internal/w32/consts.go b/v3/pkg/w32/consts.go similarity index 100% rename from v3/internal/w32/consts.go rename to v3/pkg/w32/consts.go diff --git a/v3/internal/w32/dwmapi.go b/v3/pkg/w32/dwmapi.go similarity index 100% rename from v3/internal/w32/dwmapi.go rename to v3/pkg/w32/dwmapi.go diff --git a/v3/internal/w32/gdi32.go b/v3/pkg/w32/gdi32.go similarity index 100% rename from v3/internal/w32/gdi32.go rename to v3/pkg/w32/gdi32.go diff --git a/v3/internal/w32/gdiplus.go b/v3/pkg/w32/gdiplus.go similarity index 100% rename from v3/internal/w32/gdiplus.go rename to v3/pkg/w32/gdiplus.go diff --git a/v3/internal/w32/idispatch.go b/v3/pkg/w32/idispatch.go similarity index 100% rename from v3/internal/w32/idispatch.go rename to v3/pkg/w32/idispatch.go diff --git a/v3/internal/w32/istream.go b/v3/pkg/w32/istream.go similarity index 100% rename from v3/internal/w32/istream.go rename to v3/pkg/w32/istream.go diff --git a/v3/internal/w32/iunknown.go b/v3/pkg/w32/iunknown.go similarity index 100% rename from v3/internal/w32/iunknown.go rename to v3/pkg/w32/iunknown.go diff --git a/v3/internal/w32/kernel32.go b/v3/pkg/w32/kernel32.go similarity index 100% rename from v3/internal/w32/kernel32.go rename to v3/pkg/w32/kernel32.go diff --git a/v3/internal/w32/ole32.go b/v3/pkg/w32/ole32.go similarity index 100% rename from v3/internal/w32/ole32.go rename to v3/pkg/w32/ole32.go diff --git a/v3/internal/w32/oleaut32.go b/v3/pkg/w32/oleaut32.go similarity index 100% rename from v3/internal/w32/oleaut32.go rename to v3/pkg/w32/oleaut32.go diff --git a/v3/internal/w32/shcore.go b/v3/pkg/w32/shcore.go similarity index 100% rename from v3/internal/w32/shcore.go rename to v3/pkg/w32/shcore.go diff --git a/v3/internal/w32/shell32.go b/v3/pkg/w32/shell32.go similarity index 100% rename from v3/internal/w32/shell32.go rename to v3/pkg/w32/shell32.go diff --git a/v3/internal/w32/shlwapi.go b/v3/pkg/w32/shlwapi.go similarity index 100% rename from v3/internal/w32/shlwapi.go rename to v3/pkg/w32/shlwapi.go diff --git a/v3/internal/w32/theme.go b/v3/pkg/w32/theme.go similarity index 100% rename from v3/internal/w32/theme.go rename to v3/pkg/w32/theme.go diff --git a/v3/internal/w32/toolbar.go b/v3/pkg/w32/toolbar.go similarity index 100% rename from v3/internal/w32/toolbar.go rename to v3/pkg/w32/toolbar.go diff --git a/v3/internal/w32/typedef.go b/v3/pkg/w32/typedef.go similarity index 100% rename from v3/internal/w32/typedef.go rename to v3/pkg/w32/typedef.go diff --git a/v3/internal/w32/user32.go b/v3/pkg/w32/user32.go similarity index 100% rename from v3/internal/w32/user32.go rename to v3/pkg/w32/user32.go diff --git a/v3/internal/w32/utils.go b/v3/pkg/w32/utils.go similarity index 100% rename from v3/internal/w32/utils.go rename to v3/pkg/w32/utils.go diff --git a/v3/internal/w32/uxtheme.go b/v3/pkg/w32/uxtheme.go similarity index 100% rename from v3/internal/w32/uxtheme.go rename to v3/pkg/w32/uxtheme.go diff --git a/v3/internal/w32/vars.go b/v3/pkg/w32/vars.go similarity index 100% rename from v3/internal/w32/vars.go rename to v3/pkg/w32/vars.go diff --git a/v3/internal/w32/window.go b/v3/pkg/w32/window.go similarity index 100% rename from v3/internal/w32/window.go rename to v3/pkg/w32/window.go From 9a05b49e3d9eebd56871bbc41e223a476e3e1d36 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Sun, 30 Apr 2023 10:17:03 +1000 Subject: [PATCH 14/28] [v3 Breaking Change] Add `NativeWindowHandle` method to `WebviewWindow`. --- v3/pkg/application/webview_window.go | 9 +++++++++ v3/pkg/application/webview_window_windows.go | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/v3/pkg/application/webview_window.go b/v3/pkg/application/webview_window.go index 0dc2b1355..3b22e111d 100644 --- a/v3/pkg/application/webview_window.go +++ b/v3/pkg/application/webview_window.go @@ -1,6 +1,7 @@ package application import ( + "errors" "fmt" "github.com/samber/lo" "sync" @@ -59,6 +60,7 @@ type ( getScreen() (*Screen, error) setFrameless(bool) openContextMenu(menu *Menu, data *ContextMenuData) + nativeWindowHandle() uintptr } ) @@ -693,3 +695,10 @@ func (w *WebviewWindow) RegisterContextMenu(name string, menu *Menu) { defer w.contextMenusLock.Unlock() w.contextMenus[name] = menu } + +func (w *WebviewWindow) NativeWindowHandle() (uintptr, error) { + if w.impl == nil { + return 0, errors.New("native handle unavailable as window is not running") + } + return w.impl.nativeWindowHandle(), nil +} diff --git a/v3/pkg/application/webview_window_windows.go b/v3/pkg/application/webview_window_windows.go index a7b888f75..2a471eb3f 100644 --- a/v3/pkg/application/webview_window_windows.go +++ b/v3/pkg/application/webview_window_windows.go @@ -21,6 +21,10 @@ type windowsWebviewWindow struct { hwnd w32.HWND } +func (w *windowsWebviewWindow) nativeWindowHandle() uintptr { + return w.hwnd +} + func (w *windowsWebviewWindow) setTitle(title string) { //TODO implement me panic("implement me") From 1e8fc29ee48d1537a35984bf16d39808a18190e0 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Sun, 30 Apr 2023 20:55:51 +1000 Subject: [PATCH 15/28] [v3 Windows] Add Support for SetTitle, Center, Un/Minimise/Maximise, IsMin/Maximised, IsNormal, Show/Hide --- v3/STATUS.md | 250 ++++++++++--------- v3/pkg/application/webview_window.go | 82 ++++-- v3/pkg/application/webview_window_windows.go | 56 +++-- v3/pkg/w32/window.go | 36 +++ 4 files changed, 259 insertions(+), 165 deletions(-) diff --git a/v3/STATUS.md b/v3/STATUS.md index 148c217b8..e84e0e58a 100644 --- a/v3/STATUS.md +++ b/v3/STATUS.md @@ -8,19 +8,19 @@ Application interface methods | Method | Windows | Linux | Mac | Notes | |---------------------------------------------------------------|---------|-------|-----|-------| -| run() error | | | ✅ | | -| destroy() | | | ✅ | | -| setApplicationMenu(menu *Menu) | | | ✅ | | -| name() string | | | ✅ | | -| getCurrentWindowID() uint | | | ✅ | | -| showAboutDialog(name string, description string, icon []byte) | | | ✅ | | -| setIcon(icon []byte) | | | ✅ | | -| on(id uint) | | | ✅ | | -| dispatchOnMainThread(id uint) | | | ✅ | | -| hide() | | | ✅ | | -| show() | | | ✅ | | -| getPrimaryScreen() (*Screen, error) | | | ✅ | | -| getScreens() ([]*Screen, error) | | | ✅ | | +| run() error | | | Y | | +| destroy() | | | Y | | +| setApplicationMenu(menu *Menu) | | | Y | | +| name() string | | | Y | | +| getCurrentWindowID() uint | | | Y | | +| showAboutDialog(name string, description string, icon []byte) | | | Y | | +| setIcon(icon []byte) | | | Y | | +| on(id uint) | | | Y | | +| dispatchOnMainThread(fn func()) | Y | | Y | | +| hide() | | | Y | | +| show() | | | Y | | +| getPrimaryScreen() (*Screen, error) | | | Y | | +| getScreens() ([]*Screen, error) | | | Y | | ## Webview Window @@ -28,52 +28,53 @@ Webview Window Interface Methods | Method | Windows | Linux | Mac | Notes | |----------------------------------------------------|---------|-------|-----|-------| -| setTitle(title string) | | | ✅ | | -| setSize(width, height int) | | | ✅ | | -| setAlwaysOnTop(alwaysOnTop bool) | | | ✅ | | -| setURL(url string) | | | ✅ | | -| setResizable(resizable bool) | | | ✅ | | -| setMinSize(width, height int) | | | ✅ | | -| setMaxSize(width, height int) | | | ✅ | | -| execJS(js string) | | | ✅ | | -| restore() | | | ✅ | | -| setBackgroundColour(color *RGBA) | | | ✅ | | -| run() | | | ✅ | | -| center() | | | ✅ | | -| size() (int, int) | | | ✅ | | -| width() int | | | ✅ | | -| height() int | | | ✅ | | -| position() (int, int) | | | ✅ | | -| destroy() | | | ✅ | | -| reload() | | | ✅ | | -| forceReload() | | | ✅ | | -| toggleDevTools() | | | ✅ | | -| zoomReset() | | | ✅ | | -| zoomIn() | | | ✅ | | -| zoomOut() | | | ✅ | | -| getZoom() float64 | | | ✅ | | -| setZoom(zoom float64) | | | ✅ | | -| close() | | | ✅ | | -| zoom() | | | ✅ | | -| setHTML(html string) | | | ✅ | | -| setPosition(x int, y int) | | | ✅ | | -| on(eventID uint) | | | ✅ | | -| minimise() | | | ✅ | | -| unminimise() | | | ✅ | | -| maximise() | | | ✅ | | -| unmaximise() | | | ✅ | | -| fullscreen() | | | ✅ | | -| unfullscreen() | | | ✅ | | -| isMinimised() bool | | | ✅ | | -| isMaximised() bool | | | ✅ | | -| isFullscreen() bool | | | ✅ | | -| disableSizeConstraints() | | | ✅ | | -| setFullscreenButtonEnabled(enabled bool) | | | ✅ | | -| show() | | | ✅ | | -| hide() | | | ✅ | | -| getScreen() (*Screen, error) | | | ✅ | | -| setFrameless(bool) | | | ✅ | | -| openContextMenu(menu *Menu, data *ContextMenuData) | | | ✅ | | +| setTitle(title string) | Y | | Y | | +| setSize(width, height int) | Y | | Y | | +| setAlwaysOnTop(alwaysOnTop bool) | Y | | Y | | +| setURL(url string) | | | Y | | +| setResizable(resizable bool) | Y | | Y | | +| setMinSize(width, height int) | | | Y | | +| setMaxSize(width, height int) | | | Y | | +| execJS(js string) | | | Y | | +| restore() | | | Y | | +| setBackgroundColour(color RGBA) | Y | | Y | | +| run() | Y | | Y | | +| center() | Y | | Y | | +| size() (int, int) | | | Y | | +| width() int | Y | | Y | | +| height() int | Y | | Y | | +| position() (int, int) | Y | | Y | | +| destroy() | | | Y | | +| reload() | | | Y | | +| forceReload() | | | Y | | +| toggleDevTools() | | | Y | | +| zoomReset() | | | Y | | +| zoomIn() | | | Y | | +| zoomOut() | | | Y | | +| getZoom() float64 | | | Y | | +| setZoom(zoom float64) | | | Y | | +| close() | | | Y | | +| zoom() | | | Y | | +| setHTML(html string) | | | Y | | +| setPosition(x int, y int) | | | Y | | +| on(eventID uint) | | | Y | | +| minimise() | Y | | Y | | +| unminimise() | Y | | Y | | +| maximise() | Y | | Y | | +| unmaximise() | Y | | Y | | +| fullscreen() | | | Y | | +| unfullscreen() | | | Y | | +| isMinimised() bool | Y | | Y | | +| isMaximised() bool | Y | | Y | | +| isFullscreen() bool | | | Y | | +| disableSizeConstraints() | | | Y | | +| setFullscreenButtonEnabled(enabled bool) | | | Y | | +| show() | Y | | Y | | +| hide() | Y | | Y | | +| getScreen() (*Screen, error) | | | Y | | +| setFrameless(bool) | | | Y | | +| openContextMenu(menu *Menu, data *ContextMenuData) | | | Y | | +| nativeWindowHandle() (uintptr, error) | Y | | | | ## Runtime @@ -81,73 +82,73 @@ Webview Window Interface Methods | Feature | Windows | Linux | Mac | Notes | |---------|---------|-------|-----|-------| -| Quit | | | ✅ | | -| Hide | | | ✅ | | -| Show | | | ✅ | | +| Quit | | | Y | | +| Hide | | | Y | | +| Show | | | Y | | ### Dialogs | Feature | Windows | Linux | Mac | Notes | |----------|---------|-------|-----|-------| -| Info | | | ✅ | | -| Warning | | | ✅ | | -| Error | | | ✅ | | -| Question | | | ✅ | | -| OpenFile | | | ✅ | | -| SaveFile | | | ✅ | | +| Info | | | Y | | +| Warning | | | Y | | +| Error | | | Y | | +| Question | | | Y | | +| OpenFile | | | Y | | +| SaveFile | | | Y | | ### Clipboard | Feature | Windows | Linux | Mac | Notes | |---------|---------|-------|-----|-------| -| SetText | | | ✅ | | -| Text | | | ✅ | | +| SetText | | | Y | | +| Text | | | Y | | ### ContextMenu | Feature | Windows | Linux | Mac | Notes | |-----------------|---------|-------|-----|-------| -| OpenContextMenu | | | ✅ | | +| OpenContextMenu | | | Y | | ### Screens | Feature | Windows | Linux | Mac | Notes | |------------|---------|-------|-----|-------| -| GetAll | | | ✅ | | -| GetPrimary | | | ✅ | | -| GetCurrent | | | ✅ | | +| GetAll | | | Y | | +| GetPrimary | | | Y | | +| GetCurrent | | | Y | | ### Window | Feature | Windows | Linux | Mac | Notes | |---------------------|---------|-------|-----|--------------------------------------------------------------------------------------| -| SetTitle | | | ✅ | | -| SetSize | | | ✅ | | -| Size | | | ✅ | | -| SetPosition | | | ✅ | | -| Position | | | ✅ | | -| FullScreen | | | ✅ | | -| UnFullscreen | | | ✅ | | -| Minimise | | | ✅ | | -| UnMinimise | | | ✅ | | -| Maximise | | | ✅ | | -| UnMaximise | | | ✅ | | -| Show | | | ✅ | | -| Hide | | | ✅ | | -| Center | | | ✅ | | -| SetBackgroundColour | | | ✅ | https://github.com/MicrosoftEdge/WebView2Feedback/issues/1621#issuecomment-938234294 | -| SetAlwaysOnTop | | | ✅ | | -| SetResizable | | | ✅ | | -| SetMinSize | | | ✅ | | -| SetMaxSize | | | ✅ | | -| Width | | | ✅ | | -| Height | | | ✅ | | -| ZoomIn | | | ✅ | Increase view scale | -| ZoomOut | | | ✅ | Decrease view scale | -| ZoomReset | | | ✅ | Reset view scale | -| GetZoom | | | ✅ | Get current view scale | -| SetZoom | | | ✅ | Set view scale | -| Screen | | | ✅ | Get screen for window | +| SetTitle | | | Y | | +| SetSize | | | Y | | +| Size | | | Y | | +| SetPosition | | | Y | | +| Position | | | Y | | +| FullScreen | | | Y | | +| UnFullscreen | | | Y | | +| Minimise | | | Y | | +| UnMinimise | | | Y | | +| Maximise | | | Y | | +| UnMaximise | | | Y | | +| Show | | | Y | | +| Hide | | | Y | | +| Center | | | Y | | +| SetBackgroundColour | | | Y | https://github.com/MicrosoftEdge/WebView2Feedback/issues/1621#issuecomment-938234294 | +| SetAlwaysOnTop | | | Y | | +| SetResizable | | | Y | | +| SetMinSize | | | Y | | +| SetMaxSize | | | Y | | +| Width | | | Y | | +| Height | | | Y | | +| ZoomIn | | | Y | Increase view scale | +| ZoomOut | | | Y | Decrease view scale | +| ZoomReset | | | Y | Reset view scale | +| GetZoom | | | Y | Get current view scale | +| SetZoom | | | Y | Set view scale | +| Screen | | | Y | Get screen for window | ### Log @@ -157,16 +158,16 @@ To log or not to log? System logger vs custom logger. | Event | Windows | Linux | Mac | Notes | |--------------------------|---------|-------|-----|-------| -| Default Application Menu | | | ✅ | | +| Default Application Menu | | | Y | | ## Tray Menus | Feature | Windows | Linux | Mac | Notes | |--------------------|---------|-------|-----|-------| -| Icon | | | ✅ | | -| Label | | | ✅ | | +| Icon | | | Y | | +| Label | | | Y | | | Label (ANSI Codes) | | | | | -| Menu | | | ✅ | | +| Menu | | | Y | | ## Cross Platform Events @@ -196,11 +197,11 @@ TBD ## Theme -| Plugin | Windows | Linux | Mac | Notes | -|-----------------|---------|-------|-----|-------| -| Dark | | | | | -| Light | | | | | -| System | | | | | +| Plugin | Windows | Linux | Mac | Notes | +|--------|---------|-------|-----|-------| +| Dark | Y | | | | +| Light | Y | | | | +| System | Y | | | | ## NSIS Installer @@ -216,31 +217,31 @@ Built-in plugin support: | Plugin | Windows | Linux | Mac | Notes | |-----------------|---------|-------|-----|-------| -| Browser | | | ✅ | | -| KV Store | | | ✅ | | -| Log | | | ✅ | | -| Single Instance | | | ✅ | | -| SQLite | | | ✅ | | -| Start at login | | | ✅ | | +| Browser | | | Y | | +| KV Store | | | Y | | +| Log | | | Y | | +| Single Instance | | | Y | | +| SQLite | | | Y | | +| Start at login | | | Y | | | Server | | | | | ## Packaging | | Windows | Linux | Mac | Notes | |-----------------|---------|-------|-----|-------| -| Icon Generation | | | ✅ | | -| Icon Embedding | | | ✅ | | -| Info.plist | | | ✅ | | +| Icon Generation | | | Y | | +| Icon Embedding | | | Y | | +| Info.plist | | | Y | | | NSIS Installer | | | | | -| Mac bundle | | | ✅ | | +| Mac bundle | | | Y | | | Windows exe | | | | | ## Frameless Windows | Feature | Windows | Linux | Mac | Notes | -|---------|---------|-------|----|-------| -| Resize | | | | | -| Drag | | | | | +|---------|---------|-------|-----|-------| +| Resize | | | | | +| Drag | | | | | ## Mac Specific @@ -248,4 +249,7 @@ Built-in plugin support: ## Windows Specific +- [x] Translucency +- [x] Custom Themes + ## Linux Specific diff --git a/v3/pkg/application/webview_window.go b/v3/pkg/application/webview_window.go index 3b22e111d..638613b2d 100644 --- a/v3/pkg/application/webview_window.go +++ b/v3/pkg/application/webview_window.go @@ -22,7 +22,6 @@ type ( setMinSize(width, height int) setMaxSize(width, height int) execJS(js string) - restore() setBackgroundColour(color RGBA) run() center() @@ -53,6 +52,7 @@ type ( isMinimised() bool isMaximised() bool isFullscreen() bool + isNormal() bool disableSizeConstraints() setFullscreenButtonEnabled(enabled bool) show() @@ -102,6 +102,7 @@ func (w *WebviewWindow) onApplicationEvent(eventType events.ApplicationEventType w.addCancellationFunction(cancelFn) } +// NewWindow creates a new window with the given options func NewWindow(options *WebviewWindowOptions) *WebviewWindow { if options.Width == 0 { options.Width = 800 @@ -129,6 +130,7 @@ func (w *WebviewWindow) addCancellationFunction(canceller func()) { w.cancellers = append(w.cancellers, canceller) } +// SetTitle sets the title of the window func (w *WebviewWindow) SetTitle(title string) *WebviewWindow { w.implLock.RLock() defer w.implLock.RUnlock() @@ -139,10 +141,12 @@ func (w *WebviewWindow) SetTitle(title string) *WebviewWindow { return w } +// Name returns the name of the window func (w *WebviewWindow) Name() string { return w.options.Name } +// SetSize sets the size of the window func (w *WebviewWindow) SetSize(width, height int) *WebviewWindow { // Don't set size if fullscreen if w.IsFullscreen() { @@ -193,6 +197,7 @@ func (w *WebviewWindow) run() { w.impl.run() } +// SetAlwaysOnTop sets the window to be always on top. func (w *WebviewWindow) SetAlwaysOnTop(b bool) *WebviewWindow { w.options.AlwaysOnTop = b if w.impl != nil { @@ -201,6 +206,7 @@ func (w *WebviewWindow) SetAlwaysOnTop(b bool) *WebviewWindow { return w } +// Show shows the window. func (w *WebviewWindow) Show() *WebviewWindow { if globalApplication.impl == nil { return w @@ -212,6 +218,8 @@ func (w *WebviewWindow) Show() *WebviewWindow { w.impl.show() return w } + +// Hide hides the window. func (w *WebviewWindow) Hide() *WebviewWindow { w.options.Hidden = true if w.impl != nil { @@ -228,6 +236,7 @@ func (w *WebviewWindow) SetURL(s string) *WebviewWindow { return w } +// SetZoom sets the zoom level of the window. func (w *WebviewWindow) SetZoom(magnification float64) *WebviewWindow { w.options.Zoom = magnification if w.impl != nil { @@ -236,6 +245,7 @@ func (w *WebviewWindow) SetZoom(magnification float64) *WebviewWindow { return w } +// GetZoom returns the current zoom level of the window. func (w *WebviewWindow) GetZoom() float64 { if w.impl != nil { return w.impl.getZoom() @@ -243,6 +253,7 @@ func (w *WebviewWindow) GetZoom() float64 { return 1 } +// SetResizable sets whether the window is resizable. func (w *WebviewWindow) SetResizable(b bool) *WebviewWindow { w.options.DisableResize = !b if w.impl != nil { @@ -251,10 +262,12 @@ func (w *WebviewWindow) SetResizable(b bool) *WebviewWindow { return w } +// Resizable returns true if the window is resizable. func (w *WebviewWindow) Resizable() bool { return !w.options.DisableResize } +// SetMinSize sets the minimum size of the window. func (w *WebviewWindow) SetMinSize(minWidth, minHeight int) *WebviewWindow { w.options.MinWidth = minWidth w.options.MinHeight = minHeight @@ -282,6 +295,7 @@ func (w *WebviewWindow) SetMinSize(minWidth, minHeight int) *WebviewWindow { return w } +// SetMaxSize sets the maximum size of the window. func (w *WebviewWindow) SetMaxSize(maxWidth, maxHeight int) *WebviewWindow { w.options.MaxWidth = maxWidth w.options.MaxHeight = maxHeight @@ -309,6 +323,7 @@ func (w *WebviewWindow) SetMaxSize(maxWidth, maxHeight int) *WebviewWindow { return w } +// ExecJS executes the given javascript in the context of the window. func (w *WebviewWindow) ExecJS(js string) { if w.impl == nil { return @@ -316,6 +331,7 @@ func (w *WebviewWindow) ExecJS(js string) { w.impl.execJS(js) } +// Fullscreen sets the window to fullscreen mode. Min/Max size constraints are disabled. func (w *WebviewWindow) Fullscreen() *WebviewWindow { if w.impl == nil { w.options.StartState = WindowStateFullscreen @@ -370,6 +386,7 @@ func (w *WebviewWindow) IsFullscreen() bool { return w.impl.isFullscreen() } +// SetBackgroundColour sets the background colour of the window func (w *WebviewWindow) SetBackgroundColour(colour RGBA) *WebviewWindow { w.options.BackgroundColour = colour if w.impl != nil { @@ -388,6 +405,7 @@ func (w *WebviewWindow) handleMessage(message string) { } +// Center centers the window on the screen func (w *WebviewWindow) Center() { if w.impl == nil { return @@ -395,6 +413,7 @@ func (w *WebviewWindow) Center() { w.impl.center() } +// On registers a callback for the given window event func (w *WebviewWindow) On(eventType events.WindowEventType, callback func(ctx *WindowEventContext)) func() { eventID := uint(eventType) w.eventListenersLock.Lock() @@ -423,6 +442,7 @@ func (w *WebviewWindow) handleWindowEvent(id uint) { w.eventListenersLock.RUnlock() } +// Width returns the width of the window func (w *WebviewWindow) Width() int { if w.impl == nil { return 0 @@ -430,6 +450,7 @@ func (w *WebviewWindow) Width() int { return w.impl.width() } +// Height returns the height of the window func (w *WebviewWindow) Height() int { if w.impl == nil { return 0 @@ -437,6 +458,7 @@ func (w *WebviewWindow) Height() int { return w.impl.height() } +// Position returns the position of the window func (w *WebviewWindow) Position() (int, int) { w.implLock.RLock() defer w.implLock.RUnlock() @@ -457,6 +479,7 @@ func (w *WebviewWindow) Destroy() { w.impl.destroy() } +// Reload reloads the page assets func (w *WebviewWindow) Reload() { if w.impl == nil { return @@ -464,6 +487,7 @@ func (w *WebviewWindow) Reload() { w.impl.reload() } +// ForceReload forces the window to reload the page assets func (w *WebviewWindow) ForceReload() { if w.impl == nil { return @@ -471,6 +495,7 @@ func (w *WebviewWindow) ForceReload() { w.impl.forceReload() } +// ToggleFullscreen toggles the window between fullscreen and normal func (w *WebviewWindow) ToggleFullscreen() { if w.impl == nil { return @@ -489,6 +514,7 @@ func (w *WebviewWindow) ToggleDevTools() { w.impl.toggleDevTools() } +// ZoomReset resets the zoom level of the webview content to 100% func (w *WebviewWindow) ZoomReset() *WebviewWindow { if w.impl != nil { w.impl.zoomReset() @@ -497,6 +523,7 @@ func (w *WebviewWindow) ZoomReset() *WebviewWindow { } +// ZoomIn increases the zoom level of the webview content func (w *WebviewWindow) ZoomIn() { if w.impl == nil { return @@ -504,6 +531,7 @@ func (w *WebviewWindow) ZoomIn() { w.impl.zoomIn() } +// ZoomOut decreases the zoom level of the webview content func (w *WebviewWindow) ZoomOut() { if w.impl == nil { return @@ -511,6 +539,7 @@ func (w *WebviewWindow) ZoomOut() { w.impl.zoomOut() } +// Close closes the window func (w *WebviewWindow) Close() { if w.impl == nil { return @@ -518,13 +547,6 @@ func (w *WebviewWindow) Close() { w.impl.close() } -func (w *WebviewWindow) Minimize() { - if w.impl == nil { - return - } - w.impl.minimise() -} - func (w *WebviewWindow) Zoom() { if w.impl == nil { return @@ -532,6 +554,7 @@ func (w *WebviewWindow) Zoom() { w.impl.zoom() } +// SetHTML sets the HTML of the window to the given html string. func (w *WebviewWindow) SetHTML(html string) *WebviewWindow { w.options.HTML = html if w.impl != nil { @@ -540,6 +563,7 @@ func (w *WebviewWindow) SetHTML(html string) *WebviewWindow { return w } +// SetPosition sets the position of the window. func (w *WebviewWindow) SetPosition(x, y int) *WebviewWindow { w.options.X = x w.options.Y = y @@ -549,6 +573,7 @@ func (w *WebviewWindow) SetPosition(x, y int) *WebviewWindow { return w } +// Minimise minimises the window. func (w *WebviewWindow) Minimise() *WebviewWindow { if w.impl == nil { w.options.StartState = WindowStateMinimised @@ -560,6 +585,7 @@ func (w *WebviewWindow) Minimise() *WebviewWindow { return w } +// Maximise maximises the window. Min/Max size constraints are disabled. func (w *WebviewWindow) Maximise() *WebviewWindow { if w.impl == nil { w.options.StartState = WindowStateMaximised @@ -572,29 +598,39 @@ func (w *WebviewWindow) Maximise() *WebviewWindow { return w } +// UnMinimise un-minimises the window. Min/Max size constraints are re-enabled. func (w *WebviewWindow) UnMinimise() { if w.impl == nil { return } - w.impl.unminimise() + if w.IsMinimised() { + w.impl.unminimise() + } } +// UnMaximise un-maximises the window. func (w *WebviewWindow) UnMaximise() { if w.impl == nil { return } - w.enableSizeConstraints() - w.impl.unmaximise() + if w.IsMaximised() { + w.enableSizeConstraints() + w.impl.unmaximise() + } } +// UnFullscreen un-fullscreens the window. func (w *WebviewWindow) UnFullscreen() { if w.impl == nil { return } - w.enableSizeConstraints() - w.impl.unfullscreen() + if w.IsFullscreen() { + w.enableSizeConstraints() + w.impl.unfullscreen() + } } +// Restore restores the window to its previous state if it was previously minimised, maximised or fullscreen. func (w *WebviewWindow) Restore() { if w.impl == nil { return @@ -612,18 +648,27 @@ func (w *WebviewWindow) disableSizeConstraints() { if w.impl == nil { return } - w.impl.setMinSize(0, 0) - w.impl.setMaxSize(0, 0) + if w.options.MinWidth > 0 && w.options.MinHeight > 0 { + w.impl.setMinSize(0, 0) + } + if w.options.MaxWidth > 0 && w.options.MaxHeight > 0 { + w.impl.setMaxSize(0, 0) + } } func (w *WebviewWindow) enableSizeConstraints() { if w.impl == nil { return } - w.SetMinSize(w.options.MinWidth, w.options.MinHeight) - w.SetMaxSize(w.options.MaxWidth, w.options.MaxHeight) + if w.options.MinWidth > 0 && w.options.MinHeight > 0 { + w.SetMinSize(w.options.MinWidth, w.options.MinHeight) + } + if w.options.MaxWidth > 0 && w.options.MaxHeight > 0 { + w.SetMaxSize(w.options.MaxWidth, w.options.MaxHeight) + } } +// GetScreen returns the screen that the window is on func (w *WebviewWindow) GetScreen() (*Screen, error) { if w.impl == nil { return nil, nil @@ -631,6 +676,7 @@ func (w *WebviewWindow) GetScreen() (*Screen, error) { return w.impl.getScreen() } +// SetFrameless removes the window frame and title bar func (w *WebviewWindow) SetFrameless(frameless bool) *WebviewWindow { w.options.Frameless = frameless if w.impl != nil { @@ -690,12 +736,14 @@ func (w *WebviewWindow) openContextMenu(data *ContextMenuData) { w.impl.openContextMenu(menu, data) } +// RegisterContextMenu registers a context menu and assigns it the given name. func (w *WebviewWindow) RegisterContextMenu(name string, menu *Menu) { w.contextMenusLock.Lock() defer w.contextMenusLock.Unlock() w.contextMenus[name] = menu } +// NativeWindowHandle returns the platform native window handle for the window. func (w *WebviewWindow) NativeWindowHandle() (uintptr, error) { if w.impl == nil { return 0, errors.New("native handle unavailable as window is not running") diff --git a/v3/pkg/application/webview_window_windows.go b/v3/pkg/application/webview_window_windows.go index 2a471eb3f..f86bbdd06 100644 --- a/v3/pkg/application/webview_window_windows.go +++ b/v3/pkg/application/webview_window_windows.go @@ -26,12 +26,12 @@ func (w *windowsWebviewWindow) nativeWindowHandle() uintptr { } func (w *windowsWebviewWindow) setTitle(title string) { - //TODO implement me - panic("implement me") + w32.SetWindowText(w.hwnd, title) } func (w *windowsWebviewWindow) setSize(width, height int) { x, y := w.position() + // TODO: Take scaling/DPI into consideration w32.MoveWindow(w.hwnd, x, y, width, height, true) } @@ -71,11 +71,6 @@ func (w *windowsWebviewWindow) execJS(js string) { panic("implement me") } -func (w *windowsWebviewWindow) restore() { - //TODO implement me - panic("implement me") -} - func (w *windowsWebviewWindow) setBackgroundColour(color RGBA) { w32.SetBackgroundColour(w.hwnd, color.Red, color.Green, color.Blue) } @@ -161,8 +156,7 @@ func (w *windowsWebviewWindow) _run() { } func (w *windowsWebviewWindow) center() { - //TODO implement me - panic("implement me") + w32.CenterWindow(w.hwnd) } func (w *windowsWebviewWindow) size() (int, int) { @@ -264,23 +258,29 @@ func (w *windowsWebviewWindow) on(eventID uint) { } func (w *windowsWebviewWindow) minimise() { - //TODO implement me - panic("implement me") + globalApplication.dispatchOnMainThread(func() { + w32.ShowWindow(w.hwnd, w32.SW_MINIMIZE) + }) } func (w *windowsWebviewWindow) unminimise() { - //TODO implement me - panic("implement me") + w.restore() } func (w *windowsWebviewWindow) maximise() { - //TODO implement me - panic("implement me") + globalApplication.dispatchOnMainThread(func() { + w32.ShowWindow(w.hwnd, w32.SW_MAXIMIZE) + }) } func (w *windowsWebviewWindow) unmaximise() { - //TODO implement me - panic("implement me") + w.restore() +} + +func (w *windowsWebviewWindow) restore() { + globalApplication.dispatchOnMainThread(func() { + w32.ShowWindow(w.hwnd, w32.SW_RESTORE) + }) } func (w *windowsWebviewWindow) fullscreen() { @@ -294,13 +294,13 @@ func (w *windowsWebviewWindow) unfullscreen() { } func (w *windowsWebviewWindow) isMinimised() bool { - //TODO implement me - panic("implement me") + style := uint32(w32.GetWindowLong(w.hwnd, w32.GWL_STYLE)) + return style&w32.WS_MINIMIZE != 0 } func (w *windowsWebviewWindow) isMaximised() bool { - //TODO implement me - panic("implement me") + style := uint32(w32.GetWindowLong(w.hwnd, w32.GWL_STYLE)) + return style&w32.WS_MAXIMIZE != 0 } func (w *windowsWebviewWindow) isFullscreen() bool { @@ -308,6 +308,10 @@ func (w *windowsWebviewWindow) isFullscreen() bool { panic("implement me") } +func (w *windowsWebviewWindow) isNormal() bool { + return !w.isMinimised() && !w.isMaximised() && !w.isFullscreen() +} + func (w *windowsWebviewWindow) disableSizeConstraints() { //TODO implement me panic("implement me") @@ -319,12 +323,15 @@ func (w *windowsWebviewWindow) setFullscreenButtonEnabled(enabled bool) { } func (w *windowsWebviewWindow) show() { - w32.ShowWindow(w.hwnd, w32.SW_SHOW) + globalApplication.dispatchOnMainThread(func() { + w32.ShowWindow(w.hwnd, w32.SW_SHOW) + }) } func (w *windowsWebviewWindow) hide() { - //TODO implement me - panic("implement me") + globalApplication.dispatchOnMainThread(func() { + w32.ShowWindow(w.hwnd, w32.SW_HIDE) + }) } func (w *windowsWebviewWindow) getScreen() (*Screen, error) { @@ -404,7 +411,6 @@ func (w *windowsWebviewWindow) setIcon(icon w32.HICON) { func (w *windowsWebviewWindow) disableIcon() { // TODO: If frameless, return - exStyle := w32.GetWindowLong(w.hwnd, w32.GWL_EXSTYLE) w32.SetWindowLong(w.hwnd, w32.GWL_EXSTYLE, uint32(exStyle|w32.WS_EX_DLGMODALFRAME)) w32.SetWindowPos(w.hwnd, 0, 0, 0, 0, 0, diff --git a/v3/pkg/w32/window.go b/v3/pkg/w32/window.go index 67e20f017..22cdb0411 100644 --- a/v3/pkg/w32/window.go +++ b/v3/pkg/w32/window.go @@ -135,3 +135,39 @@ func MustUTF16FromString(input string) []uint16 { } return ret } + +func CenterWindow(hwnd HWND) { + windowInfo := getWindowInfo(hwnd) + frameless := windowInfo.IsPopup() + + info := getMonitorInfo(hwnd) + workRect := info.RcWork + screenMiddleW := workRect.Left + (workRect.Right-workRect.Left)/2 + screenMiddleH := workRect.Top + (workRect.Bottom-workRect.Top)/2 + var winRect *RECT + if !frameless { + winRect = GetWindowRect(hwnd) + } else { + winRect = GetClientRect(hwnd) + } + winWidth := winRect.Right - winRect.Left + winHeight := winRect.Bottom - winRect.Top + windowX := screenMiddleW - (winWidth / 2) + windowY := screenMiddleH - (winHeight / 2) + SetWindowPos(hwnd, HWND_TOP, int(windowX), int(windowY), int(winWidth), int(winHeight), SWP_NOSIZE) +} + +func getWindowInfo(hwnd HWND) *WINDOWINFO { + var info WINDOWINFO + info.CbSize = uint32(unsafe.Sizeof(info)) + GetWindowInfo(hwnd, &info) + return &info +} + +func getMonitorInfo(hwnd HWND) *MONITORINFO { + currentMonitor := MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST) + var info MONITORINFO + info.CbSize = uint32(unsafe.Sizeof(info)) + GetMonitorInfo(currentMonitor, &info) + return &info +} From cb8eb755a73dcb8657e121e0df91b838a31631d9 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Mon, 1 May 2023 10:52:46 +1000 Subject: [PATCH 16/28] [v3 Windows] Support setMin/MaxSize, setPosition --- v3/STATUS.md | 97 +++++++------- v3/pkg/application/mainthread_windows.go | 5 +- v3/pkg/application/messageprocessor_window.go | 2 +- v3/pkg/application/webview_window_windows.go | 102 ++++++++++++--- v3/pkg/w32/screen.go | 118 ++++++++++++++++++ v3/pkg/w32/window.go | 24 ++-- 6 files changed, 263 insertions(+), 85 deletions(-) create mode 100644 v3/pkg/w32/screen.go diff --git a/v3/STATUS.md b/v3/STATUS.md index e84e0e58a..c7c6b40d1 100644 --- a/v3/STATUS.md +++ b/v3/STATUS.md @@ -26,55 +26,54 @@ Application interface methods Webview Window Interface Methods -| Method | Windows | Linux | Mac | Notes | -|----------------------------------------------------|---------|-------|-----|-------| -| setTitle(title string) | Y | | Y | | -| setSize(width, height int) | Y | | Y | | -| setAlwaysOnTop(alwaysOnTop bool) | Y | | Y | | -| setURL(url string) | | | Y | | -| setResizable(resizable bool) | Y | | Y | | -| setMinSize(width, height int) | | | Y | | -| setMaxSize(width, height int) | | | Y | | -| execJS(js string) | | | Y | | -| restore() | | | Y | | -| setBackgroundColour(color RGBA) | Y | | Y | | -| run() | Y | | Y | | -| center() | Y | | Y | | -| size() (int, int) | | | Y | | -| width() int | Y | | Y | | -| height() int | Y | | Y | | -| position() (int, int) | Y | | Y | | -| destroy() | | | Y | | -| reload() | | | Y | | -| forceReload() | | | Y | | -| toggleDevTools() | | | Y | | -| zoomReset() | | | Y | | -| zoomIn() | | | Y | | -| zoomOut() | | | Y | | -| getZoom() float64 | | | Y | | -| setZoom(zoom float64) | | | Y | | -| close() | | | Y | | -| zoom() | | | Y | | -| setHTML(html string) | | | Y | | -| setPosition(x int, y int) | | | Y | | -| on(eventID uint) | | | Y | | -| minimise() | Y | | Y | | -| unminimise() | Y | | Y | | -| maximise() | Y | | Y | | -| unmaximise() | Y | | Y | | -| fullscreen() | | | Y | | -| unfullscreen() | | | Y | | -| isMinimised() bool | Y | | Y | | -| isMaximised() bool | Y | | Y | | -| isFullscreen() bool | | | Y | | -| disableSizeConstraints() | | | Y | | -| setFullscreenButtonEnabled(enabled bool) | | | Y | | -| show() | Y | | Y | | -| hide() | Y | | Y | | -| getScreen() (*Screen, error) | | | Y | | -| setFrameless(bool) | | | Y | | -| openContextMenu(menu *Menu, data *ContextMenuData) | | | Y | | -| nativeWindowHandle() (uintptr, error) | Y | | | | +| Method | Windows | Linux | Mac | Notes | +|----------------------------------------------------|---------|-------|-----|------------------------------------------| +| center() | Y | | Y | | +| close() | | | Y | | +| destroy() | | | Y | | +| disableSizeConstraints() | | | Y | | +| execJS(js string) | | | Y | | +| forceReload() | | | Y | | +| fullscreen() | | | Y | | +| getScreen() (*Screen, error) | | | Y | | +| getZoom() float64 | | | Y | | +| height() int | Y | | Y | | +| hide() | Y | | Y | | +| isFullscreen() bool | | | Y | | +| isMaximised() bool | Y | | Y | | +| isMinimised() bool | Y | | Y | | +| maximise() | Y | | Y | | +| minimise() | Y | | Y | | +| nativeWindowHandle() (uintptr, error) | Y | | | | +| on(eventID uint) | | | Y | | +| openContextMenu(menu *Menu, data *ContextMenuData) | | | Y | | +| position() (int, int) | Y | | Y | | +| reload() | | | Y | | +| run() | Y | | Y | | +| setAlwaysOnTop(alwaysOnTop bool) | Y | | Y | | +| setBackgroundColour(color RGBA) | Y | | Y | | +| setFrameless(bool) | | | Y | | +| setFullscreenButtonEnabled(enabled bool) | X | | Y | There is no fullscreen button in Windows | +| setHTML(html string) | | | Y | | +| setMaxSize(width, height int) | Y | | Y | | +| setMinSize(width, height int) | Y | | Y | | +| setPosition(x int, y int) | Y | | Y | | +| setResizable(resizable bool) | Y | | Y | | +| setSize(width, height int) | Y | | Y | | +| setTitle(title string) | Y | | Y | | +| setURL(url string) | | | Y | | +| setZoom(zoom float64) | | | Y | | +| show() | Y | | Y | | +| size() (int, int) | | | Y | | +| toggleDevTools() | | | Y | | +| unfullscreen() | | | Y | | +| unmaximise() | Y | | Y | | +| unminimise() | Y | | Y | | +| width() int | Y | | Y | | +| zoom() | | | Y | | +| zoomIn() | | | Y | | +| zoomOut() | | | Y | | +| zoomReset() | | | Y | | ## Runtime diff --git a/v3/pkg/application/mainthread_windows.go b/v3/pkg/application/mainthread_windows.go index 80967ccab..f2f03454c 100644 --- a/v3/pkg/application/mainthread_windows.go +++ b/v3/pkg/application/mainthread_windows.go @@ -6,10 +6,7 @@ import ( "github.com/wailsapp/wails/v3/pkg/w32" "runtime" "sort" - "syscall" "unsafe" - - "github.com/samber/lo" ) var ( @@ -37,7 +34,7 @@ func (m *windowsApp) initMainLoop() { m.mainThreadWindowHWND = w32.CreateWindowEx( 0, windowClassName, - lo.Must(syscall.UTF16PtrFromString("__wails_hidden_mainthread")), + w32.MustStringToUTF16Ptr("__wails_hidden_mainthread"), w32.WS_DISABLED, w32.CW_USEDEFAULT, w32.CW_USEDEFAULT, diff --git a/v3/pkg/application/messageprocessor_window.go b/v3/pkg/application/messageprocessor_window.go index ab4507073..7789cad7c 100644 --- a/v3/pkg/application/messageprocessor_window.go +++ b/v3/pkg/application/messageprocessor_window.go @@ -46,7 +46,7 @@ func (m *MessageProcessor) processWindowMethod(method string, rw http.ResponseWr window.UnFullscreen() m.ok(rw) case "Minimise": - window.Minimize() + window.Minimise() m.ok(rw) case "UnMinimise": window.UnMinimise() diff --git a/v3/pkg/application/webview_window_windows.go b/v3/pkg/application/webview_window_windows.go index f86bbdd06..7e0bc76e6 100644 --- a/v3/pkg/application/webview_window_windows.go +++ b/v3/pkg/application/webview_window_windows.go @@ -7,10 +7,7 @@ import ( "fmt" "github.com/wailsapp/wails/v3/pkg/events" "github.com/wailsapp/wails/v3/pkg/w32" - "syscall" "unsafe" - - "github.com/samber/lo" ) var showDevTools = func(window unsafe.Pointer) {} @@ -19,6 +16,10 @@ type windowsWebviewWindow struct { windowImpl unsafe.Pointer parent *WebviewWindow hwnd w32.HWND + + // Size Restrictions + minWidth, minHeight int + maxWidth, maxHeight int } func (w *windowsWebviewWindow) nativeWindowHandle() uintptr { @@ -57,13 +58,13 @@ func (w *windowsWebviewWindow) setResizable(resizable bool) { } func (w *windowsWebviewWindow) setMinSize(width, height int) { - //TODO implement me - panic("implement me") + w.minWidth = width + w.minHeight = height } func (w *windowsWebviewWindow) setMaxSize(width, height int) { - //TODO implement me - panic("implement me") + w.maxWidth = width + w.maxHeight = height } func (w *windowsWebviewWindow) execJS(js string) { @@ -80,8 +81,15 @@ func (w *windowsWebviewWindow) run() { } func (w *windowsWebviewWindow) _run() { - var exStyle uint + + // Copy options options := w.parent.options + w.minWidth = options.MinWidth + w.minHeight = options.MinHeight + w.maxWidth = options.MaxWidth + w.maxHeight = options.MaxHeight + + var exStyle uint exStyle = w32.WS_EX_CONTROLPARENT | w32.WS_EX_APPWINDOW if options.BackgroundType != BackgroundTypeSolid { exStyle |= w32.WS_EX_NOREDIRECTIONBITMAP @@ -92,7 +100,7 @@ func (w *windowsWebviewWindow) _run() { w.hwnd = w32.CreateWindowEx( exStyle, windowClassName, - lo.Must(syscall.UTF16PtrFromString(options.Title)), + w32.MustStringToUTF16Ptr(options.Title), w32.WS_OVERLAPPEDWINDOW, w32.CW_USEDEFAULT, w32.CW_USEDEFAULT, @@ -139,7 +147,6 @@ func (w *windowsWebviewWindow) _run() { switch options.Windows.Theme { case SystemDefault: w.updateTheme(w32.IsCurrentlyDarkMode()) - // Setup a listener to respond to theme changes w.parent.onApplicationEvent(events.Windows.SystemThemeChanged, func() { w.updateTheme(w32.IsCurrentlyDarkMode()) }) @@ -248,8 +255,9 @@ func (w *windowsWebviewWindow) setHTML(html string) { } func (w *windowsWebviewWindow) setPosition(x int, y int) { - //TODO implement me - panic("implement me") + info := w32.GetMonitorInfoForWindow(w.hwnd) + workRect := info.RcWork + w32.SetWindowPos(w.hwnd, w32.HWND_TOP, int(workRect.Left)+x, int(workRect.Top)+y, 0, 0, w32.SWP_NOSIZE) } func (w *windowsWebviewWindow) on(eventID uint) { @@ -476,9 +484,75 @@ func (w *windowsWebviewWindow) WndProc(msg uint32, wparam, lparam uintptr) uintp windowsApp := globalApplication.impl.(*windowsApp) windowsApp.unregisterWindow(w) return 0 - default: - return w32.DefWindowProc(w.hwnd, msg, wparam, lparam) + case w32.WM_GETMINMAXINFO: + mmi := (*w32.MINMAXINFO)(unsafe.Pointer(lparam)) + hasConstraints := false + if w.minWidth > 0 || w.minHeight > 0 { + hasConstraints = true + + width, height := w.scaleWithWindowDPI(w.minWidth, w.minHeight) + if width > 0 { + mmi.PtMinTrackSize.X = int32(width) + } + if height > 0 { + mmi.PtMinTrackSize.Y = int32(height) + } + } + if w.maxWidth > 0 || w.maxHeight > 0 { + hasConstraints = true + + width, height := w.scaleWithWindowDPI(w.maxWidth, w.maxHeight) + if width > 0 { + mmi.PtMaxTrackSize.X = int32(width) + } + if height > 0 { + mmi.PtMaxTrackSize.Y = int32(height) + } + } + if hasConstraints { + return 0 + } } + return w32.DefWindowProc(w.hwnd, msg, wparam, lparam) +} + +func (w *windowsWebviewWindow) DPI() (w32.UINT, w32.UINT) { + if w32.HasGetDpiForWindowFunc() { + // GetDpiForWindow is supported beginning with Windows 10, 1607 and is the most accureate + // one, especially it is consistent with the WM_DPICHANGED event. + dpi := w32.GetDpiForWindow(w.hwnd) + return dpi, dpi + } + + if w32.HasGetDPIForMonitorFunc() { + // GetDpiForWindow is supported beginning with Windows 8.1 + monitor := w32.MonitorFromWindow(w.hwnd, w32.MONITOR_DEFAULTTONEAREST) + if monitor == 0 { + return 0, 0 + } + var dpiX, dpiY w32.UINT + w32.GetDPIForMonitor(monitor, w32.MDT_EFFECTIVE_DPI, &dpiX, &dpiY) + return dpiX, dpiY + } + + // If none of the above is supported fallback to the System DPI. + screen := w32.GetDC(0) + x := w32.GetDeviceCaps(screen, w32.LOGPIXELSX) + y := w32.GetDeviceCaps(screen, w32.LOGPIXELSY) + w32.ReleaseDC(0, screen) + return w32.UINT(x), w32.UINT(y) +} + +func (w *windowsWebviewWindow) scaleWithWindowDPI(width, height int) (int, int) { + dpix, dpiy := w.DPI() + scaledWidth := ScaleWithDPI(width, dpix) + scaledHeight := ScaleWithDPI(height, dpiy) + + return scaledWidth, scaledHeight +} + +func ScaleWithDPI(pixels int, dpi uint) int { + return (pixels * int(dpi)) / 96 } func NewIconFromResource(instance w32.HINSTANCE, resId uint16) (w32.HICON, error) { diff --git a/v3/pkg/w32/screen.go b/v3/pkg/w32/screen.go new file mode 100644 index 000000000..7f43beb2b --- /dev/null +++ b/v3/pkg/w32/screen.go @@ -0,0 +1,118 @@ +//go:build windows + +package w32 + +import ( + "fmt" + "syscall" + "unsafe" +) + +func MonitorsEqual(first MONITORINFO, second MONITORINFO) bool { + // Checks to make sure all the fields are the same. + // A cleaner way would be to check identity of devices. but I couldn't find a way of doing that using the win32 API + return first.DwFlags == second.DwFlags && + first.RcMonitor.Top == second.RcMonitor.Top && + first.RcMonitor.Bottom == second.RcMonitor.Bottom && + first.RcMonitor.Right == second.RcMonitor.Right && + first.RcMonitor.Left == second.RcMonitor.Left && + first.RcWork.Top == second.RcWork.Top && + first.RcWork.Bottom == second.RcWork.Bottom && + first.RcWork.Right == second.RcWork.Right && + first.RcWork.Left == second.RcWork.Left +} + +func GetMonitorInformation(hMonitor HMONITOR) (*MONITORINFO, error) { + // Adapted from winc.utils.getMonitorInfo + // See docs for + //https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getmonitorinfoa + + var info MONITORINFO + info.CbSize = uint32(unsafe.Sizeof(info)) + succeeded := GetMonitorInfo(hMonitor, &info) + if !succeeded { + return &info, fmt.Errorf("Windows call to getMonitorInfo failed") + } + return &info, nil +} + +type Screen struct { + IsCurrent bool + IsPrimary bool + Width int + Height int +} + +func EnumProc(hMonitor HMONITOR, hdcMonitor HDC, lprcMonitor *RECT, screenContainer *ScreenContainer) uintptr { + // adapted from https://stackoverflow.com/a/23492886/4188138 + + // see docs for the following pages to better understand this function + // https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-enumdisplaymonitors + // https://docs.microsoft.com/en-us/windows/win32/api/winuser/nc-winuser-monitorenumproc + // https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-monitorinfo + // https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-monitorfromwindow + + ourMonitorData := Screen{} + currentMonHndl := MonitorFromWindow(screenContainer.mainWinHandle, MONITOR_DEFAULTTONEAREST) + currentMonInfo, currErr := GetMonitorInformation(currentMonHndl) + + if currErr != nil { + screenContainer.errors = append(screenContainer.errors, currErr) + screenContainer.monitors = append(screenContainer.monitors, Screen{}) + // not sure what the consequences of returning false are, so let's just return true and handle it ourselves + return TRUE + } + + monInfo, err := GetMonitorInformation(hMonitor) + if err != nil { + screenContainer.errors = append(screenContainer.errors, err) + screenContainer.monitors = append(screenContainer.monitors, Screen{}) + return TRUE + } + + height := lprcMonitor.Right - lprcMonitor.Left + width := lprcMonitor.Bottom - lprcMonitor.Top + ourMonitorData.IsPrimary = monInfo.DwFlags&MONITORINFOF_PRIMARY == 1 + ourMonitorData.Height = int(width) + ourMonitorData.Width = int(height) + ourMonitorData.IsCurrent = MonitorsEqual(*currentMonInfo, *monInfo) + + // the reason we need a container is that we have don't know how many times this function will be called + // this "append" call could potentially do an allocation and rewrite the pointer to monitors. So we save the pointer in screenContainer.monitors + // and retrieve the values after all EnumProc calls + // If EnumProc is multi-threaded, this could be problematic. Although, I don't think it is. + screenContainer.monitors = append(screenContainer.monitors, ourMonitorData) + // let's keep screenContainer.errors the same size as screenContainer.monitors in case we want to match them up later if necessary + screenContainer.errors = append(screenContainer.errors, nil) + return TRUE +} + +type ScreenContainer struct { + monitors []Screen + errors []error + mainWinHandle HWND +} + +func GetAllScreens(mainWinHandle HWND) ([]Screen, error) { + // TODO fix hack of container sharing by having a proper data sharing mechanism between windows and the runtime + monitorContainer := ScreenContainer{mainWinHandle: mainWinHandle} + returnErr := error(nil) + var errorStrings []string + + dc := GetDC(0) + defer ReleaseDC(0, dc) + succeeded := EnumDisplayMonitors(dc, nil, syscall.NewCallback(EnumProc), unsafe.Pointer(&monitorContainer)) + if !succeeded { + return monitorContainer.monitors, fmt.Errorf("Windows call to EnumDisplayMonitors failed") + } + for idx, err := range monitorContainer.errors { + if err != nil { + errorStrings = append(errorStrings, fmt.Sprintf("Error from monitor #%v, %v", idx+1, err)) + } + } + + if len(errorStrings) > 0 { + returnErr = fmt.Errorf("%v errors encountered: %v", len(errorStrings), errorStrings) + } + return monitorContainer.monitors, returnErr +} diff --git a/v3/pkg/w32/window.go b/v3/pkg/w32/window.go index 22cdb0411..3f626228b 100644 --- a/v3/pkg/w32/window.go +++ b/v3/pkg/w32/window.go @@ -2,6 +2,7 @@ package w32 import ( "fmt" + "github.com/samber/lo" "log" "strconv" "syscall" @@ -113,34 +114,23 @@ func showWindow(hwnd uintptr, cmdshow int) bool { } func MustStringToUTF16Ptr(input string) *uint16 { - ret, err := syscall.UTF16PtrFromString(input) - if err != nil { - panic(err) - } - return ret + return lo.Must(syscall.UTF16PtrFromString(input)) } func MustStringToUTF16uintptr(input string) uintptr { - ret, err := syscall.UTF16PtrFromString(input) - if err != nil { - panic(err) - } + ret := lo.Must(syscall.UTF16PtrFromString(input)) return uintptr(unsafe.Pointer(ret)) } -func MustUTF16FromString(input string) []uint16 { - ret, err := syscall.UTF16FromString(input) - if err != nil { - panic(err) - } - return ret +func MustStringToUTF16(input string) []uint16 { + return lo.Must(syscall.UTF16FromString(input)) } func CenterWindow(hwnd HWND) { windowInfo := getWindowInfo(hwnd) frameless := windowInfo.IsPopup() - info := getMonitorInfo(hwnd) + info := GetMonitorInfoForWindow(hwnd) workRect := info.RcWork screenMiddleW := workRect.Left + (workRect.Right-workRect.Left)/2 screenMiddleH := workRect.Top + (workRect.Bottom-workRect.Top)/2 @@ -164,7 +154,7 @@ func getWindowInfo(hwnd HWND) *WINDOWINFO { return &info } -func getMonitorInfo(hwnd HWND) *MONITORINFO { +func GetMonitorInfoForWindow(hwnd HWND) *MONITORINFO { currentMonitor := MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST) var info MONITORINFO info.CbSize = uint32(unsafe.Sizeof(info)) From 29a58086a375445d4faabbb801c9d1f05feec716 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Mon, 1 May 2023 11:34:06 +1000 Subject: [PATCH 17/28] [v3 Windows] Support application hide/show. Add `WebviewWindow.IsVisible()`. --- v3/STATUS.md | 4 ++-- v3/pkg/application/application_windows.go | 24 ++++++++++++++++++++ v3/pkg/application/webview_window.go | 10 +++++++- v3/pkg/application/webview_window_windows.go | 12 +++++----- v3/pkg/w32/constants.go | 10 ++++++++ v3/pkg/w32/user32.go | 9 ++++++++ 6 files changed, 60 insertions(+), 9 deletions(-) diff --git a/v3/STATUS.md b/v3/STATUS.md index c7c6b40d1..9313ef233 100644 --- a/v3/STATUS.md +++ b/v3/STATUS.md @@ -82,8 +82,8 @@ Webview Window Interface Methods | Feature | Windows | Linux | Mac | Notes | |---------|---------|-------|-----|-------| | Quit | | | Y | | -| Hide | | | Y | | -| Show | | | Y | | +| Hide | Y | | Y | | +| Show | Y | | Y | | ### Dialogs diff --git a/v3/pkg/application/application_windows.go b/v3/pkg/application/application_windows.go index 3f9225673..b85db6e4f 100644 --- a/v3/pkg/application/application_windows.go +++ b/v3/pkg/application/application_windows.go @@ -23,6 +23,10 @@ type windowsApp struct { mainThreadID w32.HANDLE mainThreadWindowHWND w32.HWND + // Windows hidden by application.Hide() + hiddenWindows []*windowsWebviewWindow + focusedWindow w32.HWND + // system theme isDarkMode bool } @@ -38,9 +42,29 @@ func (m *windowsApp) getScreens() ([]*Screen, error) { } func (m *windowsApp) hide() { + // Get the current focussed window + m.focusedWindow = w32.GetForegroundWindow() + + // Iterate over all windows and hide them if they aren't already hidden + for _, window := range m.windowMap { + if window.isVisible() { + // Add to hidden windows + m.hiddenWindows = append(m.hiddenWindows, window) + window.hide() + } + } + // Switch focus to the next application + hwndNext := w32.GetWindow(m.mainThreadWindowHWND, w32.GW_HWNDNEXT) + w32.SetForegroundWindow(hwndNext) } func (m *windowsApp) show() { + // Iterate over all windows and show them if they were previously hidden + for _, window := range m.hiddenWindows { + window.show() + } + // Show the foreground window + w32.SetForegroundWindow(m.focusedWindow) } func (m *windowsApp) on(eventID uint) { diff --git a/v3/pkg/application/webview_window.go b/v3/pkg/application/webview_window.go index 638613b2d..423a9301a 100644 --- a/v3/pkg/application/webview_window.go +++ b/v3/pkg/application/webview_window.go @@ -53,7 +53,7 @@ type ( isMaximised() bool isFullscreen() bool isNormal() bool - disableSizeConstraints() + isVisible() bool setFullscreenButtonEnabled(enabled bool) show() hide() @@ -360,6 +360,14 @@ func (w *WebviewWindow) IsMinimised() bool { return w.impl.isMinimised() } +// IsVisible returns true if the window is visible +func (w *WebviewWindow) IsVisible() bool { + if w.impl == nil { + return false + } + return w.impl.isVisible() +} + // IsMaximised returns true if the window is maximised func (w *WebviewWindow) IsMaximised() bool { if w.impl == nil { diff --git a/v3/pkg/application/webview_window_windows.go b/v3/pkg/application/webview_window_windows.go index 7e0bc76e6..9fcece222 100644 --- a/v3/pkg/application/webview_window_windows.go +++ b/v3/pkg/application/webview_window_windows.go @@ -260,6 +260,7 @@ func (w *windowsWebviewWindow) setPosition(x int, y int) { w32.SetWindowPos(w.hwnd, w32.HWND_TOP, int(workRect.Left)+x, int(workRect.Top)+y, 0, 0, w32.SWP_NOSIZE) } +// on is used to indicate that a particular event should be listened for func (w *windowsWebviewWindow) on(eventID uint) { //TODO implement me panic("implement me") @@ -320,14 +321,13 @@ func (w *windowsWebviewWindow) isNormal() bool { return !w.isMinimised() && !w.isMaximised() && !w.isFullscreen() } -func (w *windowsWebviewWindow) disableSizeConstraints() { - //TODO implement me - panic("implement me") +func (w *windowsWebviewWindow) isVisible() bool { + style := uint32(w32.GetWindowLong(w.hwnd, w32.GWL_STYLE)) + return style&w32.WS_VISIBLE != 0 } -func (w *windowsWebviewWindow) setFullscreenButtonEnabled(enabled bool) { - //TODO implement me - panic("implement me") +func (w *windowsWebviewWindow) setFullscreenButtonEnabled(_ bool) { + // Unused in Windows } func (w *windowsWebviewWindow) show() { diff --git a/v3/pkg/w32/constants.go b/v3/pkg/w32/constants.go index 8105b1195..1b200046d 100644 --- a/v3/pkg/w32/constants.go +++ b/v3/pkg/w32/constants.go @@ -276,6 +276,16 @@ const ( GWLP_USERDATA = -21 ) +const ( + GW_HWNDFIRST = 0 + GW_HWNDLAST = 1 + GW_HWNDNEXT = 2 + GW_HWNDPREV = 3 + GW_OWNER = 4 + GW_CHILD = 5 + GW_ENABLEDPOPUP = 6 +) + // Window style constants const ( WS_OVERLAPPED = 0x00000000 diff --git a/v3/pkg/w32/user32.go b/v3/pkg/w32/user32.go index d337a6145..9357d2586 100644 --- a/v3/pkg/w32/user32.go +++ b/v3/pkg/w32/user32.go @@ -41,6 +41,7 @@ var ( procGetWindowText = moduser32.NewProc("GetWindowTextW") procGetWindowRect = moduser32.NewProc("GetWindowRect") procGetWindowInfo = moduser32.NewProc("GetWindowInfo") + procGetWindow = moduser32.NewProc("GetWindow") procSetWindowCompositionAttribute = moduser32.NewProc("SetWindowCompositionAttribute") procMoveWindow = moduser32.NewProc("MoveWindow") procScreenToClient = moduser32.NewProc("ScreenToClient") @@ -415,6 +416,14 @@ func GetWindowInfo(hwnd HWND, info *WINDOWINFO) int { return int(ret) } +func GetWindow(hwnd HWND, cmd uint32) HWND { + ret, _, _ := procGetWindow.Call( + hwnd, + uintptr(cmd), + ) + return HWND(ret) +} + func GetWindowText(hwnd HWND) string { textLen := GetWindowTextLength(hwnd) + 1 From dac281ac321f0633cd39661b5bace04812c18c48 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Mon, 1 May 2023 18:20:28 +1000 Subject: [PATCH 18/28] [v3] Change `WebviewWindow` options to be a value, not a pointer. Support Un/Fullscreen. Remove main thread switching. Use parent options instead of local variables. --- v3/STATUS.md | 4 +- .../templates/_base/default/main.go.tmpl | 2 +- v3/internal/templates/lit-ts/main.go.tmpl | 2 +- v3/internal/templates/lit/main.go.tmpl | 2 +- v3/internal/templates/preact-ts/main.go.tmpl | 2 +- v3/internal/templates/preact/main.go.tmpl | 2 +- .../templates/react-swc-ts/main.go.tmpl | 2 +- v3/internal/templates/react-swc/main.go.tmpl | 2 +- v3/internal/templates/react-ts/main.go.tmpl | 2 +- v3/internal/templates/react/main.go.tmpl | 2 +- v3/internal/templates/svelte-ts/main.go.tmpl | 2 +- v3/internal/templates/svelte/main.go.tmpl | 2 +- v3/internal/templates/vanilla-ts/main.go.tmpl | 2 +- v3/internal/templates/vanilla/main.go.tmpl | 2 +- v3/internal/templates/vue-ts/main.go.tmpl | 2 +- v3/internal/templates/vue/main.go.tmpl | 2 +- v3/pkg/application/application.go | 8 +- v3/pkg/application/options_win.go | 4 + v3/pkg/application/webview_window.go | 4 +- v3/pkg/application/webview_window_windows.go | 153 ++++++++++++------ 20 files changed, 127 insertions(+), 76 deletions(-) diff --git a/v3/STATUS.md b/v3/STATUS.md index 9313ef233..0a0a9d687 100644 --- a/v3/STATUS.md +++ b/v3/STATUS.md @@ -17,8 +17,8 @@ Application interface methods | setIcon(icon []byte) | | | Y | | | on(id uint) | | | Y | | | dispatchOnMainThread(fn func()) | Y | | Y | | -| hide() | | | Y | | -| show() | | | Y | | +| hide() | Y | | Y | | +| show() | Y | | Y | | | getPrimaryScreen() (*Screen, error) | | | Y | | | getScreens() ([]*Screen, error) | | | Y | | diff --git a/v3/internal/templates/_base/default/main.go.tmpl b/v3/internal/templates/_base/default/main.go.tmpl index 1bc6a4868..16f808e8a 100644 --- a/v3/internal/templates/_base/default/main.go.tmpl +++ b/v3/internal/templates/_base/default/main.go.tmpl @@ -20,7 +20,7 @@ func main() { }, }) // Create window - app.NewWebviewWindowWithOptions(&application.WebviewWindowOptions{ + app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ Title: "Plain Bundle", CSS: `body { background-color: rgba(255, 255, 255, 0); } .main { color: white; margin: 20%; }`, Mac: application.MacWindow{ diff --git a/v3/internal/templates/lit-ts/main.go.tmpl b/v3/internal/templates/lit-ts/main.go.tmpl index 1bc6a4868..16f808e8a 100644 --- a/v3/internal/templates/lit-ts/main.go.tmpl +++ b/v3/internal/templates/lit-ts/main.go.tmpl @@ -20,7 +20,7 @@ func main() { }, }) // Create window - app.NewWebviewWindowWithOptions(&application.WebviewWindowOptions{ + app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ Title: "Plain Bundle", CSS: `body { background-color: rgba(255, 255, 255, 0); } .main { color: white; margin: 20%; }`, Mac: application.MacWindow{ diff --git a/v3/internal/templates/lit/main.go.tmpl b/v3/internal/templates/lit/main.go.tmpl index 1bc6a4868..16f808e8a 100644 --- a/v3/internal/templates/lit/main.go.tmpl +++ b/v3/internal/templates/lit/main.go.tmpl @@ -20,7 +20,7 @@ func main() { }, }) // Create window - app.NewWebviewWindowWithOptions(&application.WebviewWindowOptions{ + app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ Title: "Plain Bundle", CSS: `body { background-color: rgba(255, 255, 255, 0); } .main { color: white; margin: 20%; }`, Mac: application.MacWindow{ diff --git a/v3/internal/templates/preact-ts/main.go.tmpl b/v3/internal/templates/preact-ts/main.go.tmpl index 1bc6a4868..16f808e8a 100644 --- a/v3/internal/templates/preact-ts/main.go.tmpl +++ b/v3/internal/templates/preact-ts/main.go.tmpl @@ -20,7 +20,7 @@ func main() { }, }) // Create window - app.NewWebviewWindowWithOptions(&application.WebviewWindowOptions{ + app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ Title: "Plain Bundle", CSS: `body { background-color: rgba(255, 255, 255, 0); } .main { color: white; margin: 20%; }`, Mac: application.MacWindow{ diff --git a/v3/internal/templates/preact/main.go.tmpl b/v3/internal/templates/preact/main.go.tmpl index 1bc6a4868..16f808e8a 100644 --- a/v3/internal/templates/preact/main.go.tmpl +++ b/v3/internal/templates/preact/main.go.tmpl @@ -20,7 +20,7 @@ func main() { }, }) // Create window - app.NewWebviewWindowWithOptions(&application.WebviewWindowOptions{ + app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ Title: "Plain Bundle", CSS: `body { background-color: rgba(255, 255, 255, 0); } .main { color: white; margin: 20%; }`, Mac: application.MacWindow{ diff --git a/v3/internal/templates/react-swc-ts/main.go.tmpl b/v3/internal/templates/react-swc-ts/main.go.tmpl index 1bc6a4868..16f808e8a 100644 --- a/v3/internal/templates/react-swc-ts/main.go.tmpl +++ b/v3/internal/templates/react-swc-ts/main.go.tmpl @@ -20,7 +20,7 @@ func main() { }, }) // Create window - app.NewWebviewWindowWithOptions(&application.WebviewWindowOptions{ + app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ Title: "Plain Bundle", CSS: `body { background-color: rgba(255, 255, 255, 0); } .main { color: white; margin: 20%; }`, Mac: application.MacWindow{ diff --git a/v3/internal/templates/react-swc/main.go.tmpl b/v3/internal/templates/react-swc/main.go.tmpl index 1bc6a4868..16f808e8a 100644 --- a/v3/internal/templates/react-swc/main.go.tmpl +++ b/v3/internal/templates/react-swc/main.go.tmpl @@ -20,7 +20,7 @@ func main() { }, }) // Create window - app.NewWebviewWindowWithOptions(&application.WebviewWindowOptions{ + app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ Title: "Plain Bundle", CSS: `body { background-color: rgba(255, 255, 255, 0); } .main { color: white; margin: 20%; }`, Mac: application.MacWindow{ diff --git a/v3/internal/templates/react-ts/main.go.tmpl b/v3/internal/templates/react-ts/main.go.tmpl index 1bc6a4868..16f808e8a 100644 --- a/v3/internal/templates/react-ts/main.go.tmpl +++ b/v3/internal/templates/react-ts/main.go.tmpl @@ -20,7 +20,7 @@ func main() { }, }) // Create window - app.NewWebviewWindowWithOptions(&application.WebviewWindowOptions{ + app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ Title: "Plain Bundle", CSS: `body { background-color: rgba(255, 255, 255, 0); } .main { color: white; margin: 20%; }`, Mac: application.MacWindow{ diff --git a/v3/internal/templates/react/main.go.tmpl b/v3/internal/templates/react/main.go.tmpl index 1bc6a4868..16f808e8a 100644 --- a/v3/internal/templates/react/main.go.tmpl +++ b/v3/internal/templates/react/main.go.tmpl @@ -20,7 +20,7 @@ func main() { }, }) // Create window - app.NewWebviewWindowWithOptions(&application.WebviewWindowOptions{ + app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ Title: "Plain Bundle", CSS: `body { background-color: rgba(255, 255, 255, 0); } .main { color: white; margin: 20%; }`, Mac: application.MacWindow{ diff --git a/v3/internal/templates/svelte-ts/main.go.tmpl b/v3/internal/templates/svelte-ts/main.go.tmpl index 1bc6a4868..16f808e8a 100644 --- a/v3/internal/templates/svelte-ts/main.go.tmpl +++ b/v3/internal/templates/svelte-ts/main.go.tmpl @@ -20,7 +20,7 @@ func main() { }, }) // Create window - app.NewWebviewWindowWithOptions(&application.WebviewWindowOptions{ + app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ Title: "Plain Bundle", CSS: `body { background-color: rgba(255, 255, 255, 0); } .main { color: white; margin: 20%; }`, Mac: application.MacWindow{ diff --git a/v3/internal/templates/svelte/main.go.tmpl b/v3/internal/templates/svelte/main.go.tmpl index 1bc6a4868..16f808e8a 100644 --- a/v3/internal/templates/svelte/main.go.tmpl +++ b/v3/internal/templates/svelte/main.go.tmpl @@ -20,7 +20,7 @@ func main() { }, }) // Create window - app.NewWebviewWindowWithOptions(&application.WebviewWindowOptions{ + app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ Title: "Plain Bundle", CSS: `body { background-color: rgba(255, 255, 255, 0); } .main { color: white; margin: 20%; }`, Mac: application.MacWindow{ diff --git a/v3/internal/templates/vanilla-ts/main.go.tmpl b/v3/internal/templates/vanilla-ts/main.go.tmpl index 1bc6a4868..16f808e8a 100644 --- a/v3/internal/templates/vanilla-ts/main.go.tmpl +++ b/v3/internal/templates/vanilla-ts/main.go.tmpl @@ -20,7 +20,7 @@ func main() { }, }) // Create window - app.NewWebviewWindowWithOptions(&application.WebviewWindowOptions{ + app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ Title: "Plain Bundle", CSS: `body { background-color: rgba(255, 255, 255, 0); } .main { color: white; margin: 20%; }`, Mac: application.MacWindow{ diff --git a/v3/internal/templates/vanilla/main.go.tmpl b/v3/internal/templates/vanilla/main.go.tmpl index 1bc6a4868..16f808e8a 100644 --- a/v3/internal/templates/vanilla/main.go.tmpl +++ b/v3/internal/templates/vanilla/main.go.tmpl @@ -20,7 +20,7 @@ func main() { }, }) // Create window - app.NewWebviewWindowWithOptions(&application.WebviewWindowOptions{ + app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ Title: "Plain Bundle", CSS: `body { background-color: rgba(255, 255, 255, 0); } .main { color: white; margin: 20%; }`, Mac: application.MacWindow{ diff --git a/v3/internal/templates/vue-ts/main.go.tmpl b/v3/internal/templates/vue-ts/main.go.tmpl index 1bc6a4868..16f808e8a 100644 --- a/v3/internal/templates/vue-ts/main.go.tmpl +++ b/v3/internal/templates/vue-ts/main.go.tmpl @@ -20,7 +20,7 @@ func main() { }, }) // Create window - app.NewWebviewWindowWithOptions(&application.WebviewWindowOptions{ + app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ Title: "Plain Bundle", CSS: `body { background-color: rgba(255, 255, 255, 0); } .main { color: white; margin: 20%; }`, Mac: application.MacWindow{ diff --git a/v3/internal/templates/vue/main.go.tmpl b/v3/internal/templates/vue/main.go.tmpl index 1bc6a4868..16f808e8a 100644 --- a/v3/internal/templates/vue/main.go.tmpl +++ b/v3/internal/templates/vue/main.go.tmpl @@ -20,7 +20,7 @@ func main() { }, }) // Create window - app.NewWebviewWindowWithOptions(&application.WebviewWindowOptions{ + app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ Title: "Plain Bundle", CSS: `body { background-color: rgba(255, 255, 255, 0); } .main { color: white; margin: 20%; }`, Mac: application.MacWindow{ diff --git a/v3/pkg/application/application.go b/v3/pkg/application/application.go index 9cc7bae08..08f52aaf5 100644 --- a/v3/pkg/application/application.go +++ b/v3/pkg/application/application.go @@ -242,7 +242,7 @@ func (a *App) On(eventType events.ApplicationEventType, callback func()) func() } } func (a *App) NewWebviewWindow() *WebviewWindow { - return a.NewWebviewWindowWithOptions(&WebviewWindowOptions{}) + return a.NewWebviewWindowWithOptions(WebviewWindowOptions{}) } func (a *App) GetPID() int { @@ -283,11 +283,7 @@ func (a *App) error(message string, args ...any) { }) } -func (a *App) NewWebviewWindowWithOptions(windowOptions *WebviewWindowOptions) *WebviewWindow { - // Ensure we have sane defaults - if windowOptions == nil { - windowOptions = WebviewWindowDefaults - } +func (a *App) NewWebviewWindowWithOptions(windowOptions WebviewWindowOptions) *WebviewWindow { newWindow := NewWindow(windowOptions) id := newWindow.id if a.windows == nil { diff --git a/v3/pkg/application/options_win.go b/v3/pkg/application/options_win.go index e060d9e9c..7e58cf9af 100644 --- a/v3/pkg/application/options_win.go +++ b/v3/pkg/application/options_win.go @@ -27,6 +27,10 @@ type WindowsWindow struct { Theme Theme // Custom colours for dark/light mode CustomTheme *ThemeSettings + + // Disable all window decorations in Frameless mode, which means no "Aero Shadow" and no "Rounded Corner" will be shown. + // "Rounded Corners" are only available on Windows 11. + DisableFramelessWindowDecorations bool } type Theme int diff --git a/v3/pkg/application/webview_window.go b/v3/pkg/application/webview_window.go index 423a9301a..cd7f874e4 100644 --- a/v3/pkg/application/webview_window.go +++ b/v3/pkg/application/webview_window.go @@ -69,7 +69,7 @@ type WindowEventListener struct { } type WebviewWindow struct { - options *WebviewWindowOptions + options WebviewWindowOptions impl webviewWindowImpl implLock sync.RWMutex id uint @@ -103,7 +103,7 @@ func (w *WebviewWindow) onApplicationEvent(eventType events.ApplicationEventType } // NewWindow creates a new window with the given options -func NewWindow(options *WebviewWindowOptions) *WebviewWindow { +func NewWindow(options WebviewWindowOptions) *WebviewWindow { if options.Width == 0 { options.Width = 800 } diff --git a/v3/pkg/application/webview_window_windows.go b/v3/pkg/application/webview_window_windows.go index 9fcece222..671c3d4e5 100644 --- a/v3/pkg/application/webview_window_windows.go +++ b/v3/pkg/application/webview_window_windows.go @@ -17,9 +17,11 @@ type windowsWebviewWindow struct { parent *WebviewWindow hwnd w32.HWND - // Size Restrictions - minWidth, minHeight int - maxWidth, maxHeight int + // Fullscreen flags + isCurrentlyFullscreen bool + previousWindowStyle uint32 + previousWindowExStyle uint32 + previousWindowPlacement w32.WINDOWPLACEMENT } func (w *windowsWebviewWindow) nativeWindowHandle() uintptr { @@ -37,13 +39,11 @@ func (w *windowsWebviewWindow) setSize(width, height int) { } func (w *windowsWebviewWindow) setAlwaysOnTop(alwaysOnTop bool) { - globalApplication.dispatchOnMainThread(func() { - position := w32.HWND_NOTOPMOST - if alwaysOnTop { - position = w32.HWND_TOPMOST - } - w32.SetWindowPos(w.hwnd, position, 0, 0, 0, 0, uint(w32.SWP_NOMOVE|w32.SWP_NOSIZE)) - }) + position := w32.HWND_NOTOPMOST + if alwaysOnTop { + position = w32.HWND_TOPMOST + } + w32.SetWindowPos(w.hwnd, position, 0, 0, 0, 0, uint(w32.SWP_NOMOVE|w32.SWP_NOSIZE)) } func (w *windowsWebviewWindow) setURL(url string) { @@ -52,19 +52,17 @@ func (w *windowsWebviewWindow) setURL(url string) { } func (w *windowsWebviewWindow) setResizable(resizable bool) { - globalApplication.dispatchOnMainThread(func() { - w.setStyle(resizable, w32.WS_THICKFRAME) - }) + w.setStyle(resizable, w32.WS_THICKFRAME) } func (w *windowsWebviewWindow) setMinSize(width, height int) { - w.minWidth = width - w.minHeight = height + w.parent.options.MinWidth = width + w.parent.options.MinHeight = height } func (w *windowsWebviewWindow) setMaxSize(width, height int) { - w.maxWidth = width - w.maxHeight = height + w.parent.options.MaxWidth = width + w.parent.options.MaxHeight = height } func (w *windowsWebviewWindow) execJS(js string) { @@ -80,14 +78,13 @@ func (w *windowsWebviewWindow) run() { globalApplication.dispatchOnMainThread(w._run) } +func (w *windowsWebviewWindow) framelessWithDecorations() bool { + return w.parent.options.Frameless && !w.parent.options.Windows.DisableFramelessWindowDecorations +} + func (w *windowsWebviewWindow) _run() { - // Copy options options := w.parent.options - w.minWidth = options.MinWidth - w.minHeight = options.MinHeight - w.maxWidth = options.MaxWidth - w.maxHeight = options.MaxHeight var exStyle uint exStyle = w32.WS_EX_CONTROLPARENT | w32.WS_EX_APPWINDOW @@ -119,9 +116,7 @@ func (w *windowsWebviewWindow) _run() { windowsApp := globalApplication.impl.(*windowsApp) windowsApp.registerWindow(w) - if options.DisableResize { - w.setResizable(false) - } + w.setResizable(!options.DisableResize) // Icon if !options.Windows.DisableIcon { @@ -141,7 +136,6 @@ func (w *windowsWebviewWindow) _run() { case BackgroundTypeTranslucent: w.setBackdropType(options.Windows.BackdropType) } - w.setForeground() // Process the theme switch options.Windows.Theme { @@ -156,6 +150,20 @@ func (w *windowsWebviewWindow) _run() { w.updateTheme(true) } + // Process StartState + switch options.StartState { + case WindowStateMaximised: + if w.parent.Resizable() { + w.maximise() + } + case WindowStateMinimised: + w.minimise() + case WindowStateFullscreen: + w.fullscreen() + } + + w.setForeground() + if !options.Hidden { w.show() w.update() @@ -166,6 +174,21 @@ func (w *windowsWebviewWindow) center() { w32.CenterWindow(w.hwnd) } +func (w *windowsWebviewWindow) disableSizeConstraints() { + w.setMaxSize(0, 0) + w.setMinSize(0, 0) +} + +func (w *windowsWebviewWindow) enableSizeConstraints() { + options := w.parent.options + if options.MinWidth > 0 || options.MinHeight > 0 { + w.setMinSize(options.MinWidth, options.MinHeight) + } + if options.MaxWidth > 0 || options.MaxHeight > 0 { + w.setMaxSize(options.MaxWidth, options.MaxHeight) + } +} + func (w *windowsWebviewWindow) size() (int, int) { //TODO implement me panic("implement me") @@ -267,9 +290,7 @@ func (w *windowsWebviewWindow) on(eventID uint) { } func (w *windowsWebviewWindow) minimise() { - globalApplication.dispatchOnMainThread(func() { - w32.ShowWindow(w.hwnd, w32.SW_MINIMIZE) - }) + w32.ShowWindow(w.hwnd, w32.SW_MINIMIZE) } func (w *windowsWebviewWindow) unminimise() { @@ -277,9 +298,7 @@ func (w *windowsWebviewWindow) unminimise() { } func (w *windowsWebviewWindow) maximise() { - globalApplication.dispatchOnMainThread(func() { - w32.ShowWindow(w.hwnd, w32.SW_MAXIMIZE) - }) + w32.ShowWindow(w.hwnd, w32.SW_MAXIMIZE) } func (w *windowsWebviewWindow) unmaximise() { @@ -287,19 +306,54 @@ func (w *windowsWebviewWindow) unmaximise() { } func (w *windowsWebviewWindow) restore() { - globalApplication.dispatchOnMainThread(func() { - w32.ShowWindow(w.hwnd, w32.SW_RESTORE) - }) + w32.ShowWindow(w.hwnd, w32.SW_RESTORE) } func (w *windowsWebviewWindow) fullscreen() { - //TODO implement me - panic("implement me") + if w.isFullscreen() { + return + } + if w.framelessWithDecorations() { + w32.ExtendFrameIntoClientArea(w.hwnd, false) + } + w.disableSizeConstraints() + w.previousWindowStyle = uint32(w32.GetWindowLongPtr(w.hwnd, w32.GWL_STYLE)) + w.previousWindowExStyle = uint32(w32.GetWindowLong(w.hwnd, w32.GWL_EXSTYLE)) + monitor := w32.MonitorFromWindow(w.hwnd, w32.MONITOR_DEFAULTTOPRIMARY) + var monitorInfo w32.MONITORINFO + monitorInfo.CbSize = uint32(unsafe.Sizeof(monitorInfo)) + if !w32.GetMonitorInfo(monitor, &monitorInfo) { + return + } + if !w32.GetWindowPlacement(w.hwnd, &w.previousWindowPlacement) { + return + } + // According to https://devblogs.microsoft.com/oldnewthing/20050505-04/?p=35703 one should use w32.WS_POPUP | w32.WS_VISIBLE + w32.SetWindowLong(w.hwnd, w32.GWL_STYLE, w.previousWindowStyle & ^uint32(w32.WS_OVERLAPPEDWINDOW) | (w32.WS_POPUP|w32.WS_VISIBLE)) + w32.SetWindowLong(w.hwnd, w32.GWL_EXSTYLE, w.previousWindowExStyle & ^uint32(w32.WS_EX_DLGMODALFRAME)) + w32.SetWindowPos(w.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) + w.isCurrentlyFullscreen = true } func (w *windowsWebviewWindow) unfullscreen() { - //TODO implement me - panic("implement me") + if !w.isFullscreen() { + return + } + if w.framelessWithDecorations() { + w32.ExtendFrameIntoClientArea(w.hwnd, true) + } + w32.SetWindowLong(w.hwnd, w32.GWL_STYLE, w.previousWindowStyle) + w32.SetWindowLong(w.hwnd, w32.GWL_EXSTYLE, w.previousWindowExStyle) + w32.SetWindowPlacement(w.hwnd, &w.previousWindowPlacement) + w32.SetWindowPos(w.hwnd, 0, 0, 0, 0, 0, + w32.SWP_NOMOVE|w32.SWP_NOSIZE|w32.SWP_NOZORDER|w32.SWP_NOOWNERZORDER|w32.SWP_FRAMECHANGED) + w.enableSizeConstraints() + w.isCurrentlyFullscreen = false } func (w *windowsWebviewWindow) isMinimised() bool { @@ -313,8 +367,8 @@ func (w *windowsWebviewWindow) isMaximised() bool { } func (w *windowsWebviewWindow) isFullscreen() bool { - //TODO implement me - panic("implement me") + // TODO: Actually calculate this based on size of window against screen size + return w.isCurrentlyFullscreen } func (w *windowsWebviewWindow) isNormal() bool { @@ -331,15 +385,11 @@ func (w *windowsWebviewWindow) setFullscreenButtonEnabled(_ bool) { } func (w *windowsWebviewWindow) show() { - globalApplication.dispatchOnMainThread(func() { - w32.ShowWindow(w.hwnd, w32.SW_SHOW) - }) + w32.ShowWindow(w.hwnd, w32.SW_SHOW) } func (w *windowsWebviewWindow) hide() { - globalApplication.dispatchOnMainThread(func() { - w32.ShowWindow(w.hwnd, w32.SW_HIDE) - }) + w32.ShowWindow(w.hwnd, w32.SW_HIDE) } func (w *windowsWebviewWindow) getScreen() (*Screen, error) { @@ -487,10 +537,11 @@ func (w *windowsWebviewWindow) WndProc(msg uint32, wparam, lparam uintptr) uintp case w32.WM_GETMINMAXINFO: mmi := (*w32.MINMAXINFO)(unsafe.Pointer(lparam)) hasConstraints := false - if w.minWidth > 0 || w.minHeight > 0 { + options := w.parent.options + if options.MinWidth > 0 || options.MinHeight > 0 { hasConstraints = true - width, height := w.scaleWithWindowDPI(w.minWidth, w.minHeight) + width, height := w.scaleWithWindowDPI(options.MinWidth, options.MinHeight) if width > 0 { mmi.PtMinTrackSize.X = int32(width) } @@ -498,10 +549,10 @@ func (w *windowsWebviewWindow) WndProc(msg uint32, wparam, lparam uintptr) uintp mmi.PtMinTrackSize.Y = int32(height) } } - if w.maxWidth > 0 || w.maxHeight > 0 { + if options.MaxWidth > 0 || options.MaxHeight > 0 { hasConstraints = true - width, height := w.scaleWithWindowDPI(w.maxWidth, w.maxHeight) + width, height := w.scaleWithWindowDPI(options.MaxWidth, options.MaxHeight) if width > 0 { mmi.PtMaxTrackSize.X = int32(width) } From 9d1f86c410de2dd09e7d78ad2919f13b504310c5 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Mon, 1 May 2023 18:21:22 +1000 Subject: [PATCH 19/28] [v3] Update examples to use correct options. --- v3/examples/binding/main.go | 2 +- v3/examples/build/main.go | 6 +++--- v3/examples/contextmenus/main.go | 4 ++-- v3/examples/drag-n-drop/main.go | 2 +- v3/examples/events/main.go | 4 ++-- v3/examples/kitchensink/main.go | 4 ++-- v3/examples/plain/main.go | 4 ++-- v3/examples/screen/main.go | 2 +- v3/examples/window/main.go | 10 +++++----- v3/examples/windowjs/main.go | 2 +- v3/examples/wml/main.go | 2 +- 11 files changed, 21 insertions(+), 21 deletions(-) diff --git a/v3/examples/binding/main.go b/v3/examples/binding/main.go index ed0bd6331..b442c4fb2 100644 --- a/v3/examples/binding/main.go +++ b/v3/examples/binding/main.go @@ -21,7 +21,7 @@ func main() { }, }) - app.NewWebviewWindowWithOptions(&application.WebviewWindowOptions{ + app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ Assets: application.AssetOptions{ FS: assets, }, diff --git a/v3/examples/build/main.go b/v3/examples/build/main.go index 48ba24088..5bb3f0df1 100755 --- a/v3/examples/build/main.go +++ b/v3/examples/build/main.go @@ -67,7 +67,7 @@ func main() { if runtime.GOOS == "darwin" { myMenu.Add("New WebviewWindow (MacTitleBarHiddenInset)"). OnClick(func(ctx *application.Context) { - app.NewWebviewWindowWithOptions(&application.WebviewWindowOptions{ + app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ Mac: application.MacWindow{ TitleBar: application.MacTitleBarHiddenInset, InvisibleTitleBarHeight: 25, @@ -81,7 +81,7 @@ func main() { }) myMenu.Add("New WebviewWindow (MacTitleBarHiddenInsetUnified)"). OnClick(func(ctx *application.Context) { - app.NewWebviewWindowWithOptions(&application.WebviewWindowOptions{ + app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ Mac: application.MacWindow{ TitleBar: application.MacTitleBarHiddenInsetUnified, InvisibleTitleBarHeight: 50, @@ -95,7 +95,7 @@ func main() { }) myMenu.Add("New WebviewWindow (MacTitleBarHidden)"). OnClick(func(ctx *application.Context) { - app.NewWebviewWindowWithOptions(&application.WebviewWindowOptions{ + app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ Mac: application.MacWindow{ TitleBar: application.MacTitleBarHidden, InvisibleTitleBarHeight: 25, diff --git a/v3/examples/contextmenus/main.go b/v3/examples/contextmenus/main.go index a94b9d340..ad428e091 100644 --- a/v3/examples/contextmenus/main.go +++ b/v3/examples/contextmenus/main.go @@ -25,7 +25,7 @@ func main() { }, }) - mainWindow := app.NewWebviewWindowWithOptions(&application.WebviewWindowOptions{ + mainWindow := app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ Title: "Context Menu Demo", Mac: application.MacWindow{ Backdrop: application.MacBackdropTranslucent, @@ -34,7 +34,7 @@ func main() { }, }) - app.NewWebviewWindowWithOptions(&application.WebviewWindowOptions{ + app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ Title: "Context Menu Demo", Mac: application.MacWindow{ Backdrop: application.MacBackdropTranslucent, diff --git a/v3/examples/drag-n-drop/main.go b/v3/examples/drag-n-drop/main.go index 1346a2bac..7558ce55d 100644 --- a/v3/examples/drag-n-drop/main.go +++ b/v3/examples/drag-n-drop/main.go @@ -25,7 +25,7 @@ func main() { }, }) - window := app.NewWebviewWindowWithOptions(&application.WebviewWindowOptions{ + window := app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ Title: "Drag-n-drop Demo", Mac: application.MacWindow{ Backdrop: application.MacBackdropTranslucent, diff --git a/v3/examples/events/main.go b/v3/examples/events/main.go index 7f0c23653..dcf142437 100644 --- a/v3/examples/events/main.go +++ b/v3/examples/events/main.go @@ -41,7 +41,7 @@ func main() { } }) - app.NewWebviewWindowWithOptions(&application.WebviewWindowOptions{ + app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ Title: "Events Demo", Mac: application.MacWindow{ Backdrop: application.MacBackdropTranslucent, @@ -49,7 +49,7 @@ func main() { InvisibleTitleBarHeight: 50, }, }) - app.NewWebviewWindowWithOptions(&application.WebviewWindowOptions{ + app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ Title: "Events Demo", Mac: application.MacWindow{ Backdrop: application.MacBackdropTranslucent, diff --git a/v3/examples/kitchensink/main.go b/v3/examples/kitchensink/main.go index 509da3415..c7dade717 100644 --- a/v3/examples/kitchensink/main.go +++ b/v3/examples/kitchensink/main.go @@ -109,7 +109,7 @@ func main() { mySystray.SetMenu(myMenu) mySystray.SetIconPosition(application.NSImageLeading) - myWindow := app.NewWebviewWindowWithOptions(&application.WebviewWindowOptions{ + myWindow := app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ Title: "Kitchen Sink", Width: 600, Height: 400, @@ -184,7 +184,7 @@ func main() { */ var myWindow2 *application.WebviewWindow var myWindow2Lock sync.RWMutex - myWindow2 = app.NewWebviewWindowWithOptions(&application.WebviewWindowOptions{ + myWindow2 = app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ Title: "#2", Width: 1024, Height: 768, diff --git a/v3/examples/plain/main.go b/v3/examples/plain/main.go index 63ba8d88b..83cfdea11 100644 --- a/v3/examples/plain/main.go +++ b/v3/examples/plain/main.go @@ -24,7 +24,7 @@ func main() { }, }) // Create window - app.NewWebviewWindowWithOptions(&application.WebviewWindowOptions{ + app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ Title: "Plain Bundle", CSS: `body { background-color: rgba(255, 255, 255, 0); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; user-select: none; -ms-user-select: none; -webkit-user-select: none; } .main { color: white; margin: 20%; }`, Mac: application.MacWindow{ @@ -42,7 +42,7 @@ func main() { go func() { time.Sleep(5 * time.Second) - app.NewWebviewWindowWithOptions(&application.WebviewWindowOptions{ + app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ Title: "Plain Bundle new Window from GoRoutine", Width: 500, Height: 500, diff --git a/v3/examples/screen/main.go b/v3/examples/screen/main.go index e71f5c4be..566dca2cf 100644 --- a/v3/examples/screen/main.go +++ b/v3/examples/screen/main.go @@ -24,7 +24,7 @@ func main() { }, }) - app.NewWebviewWindowWithOptions(&application.WebviewWindowOptions{ + app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ Title: "Screen Demo", Width: 800, Height: 600, diff --git a/v3/examples/window/main.go b/v3/examples/window/main.go index 7a6e174c5..c428a92fd 100644 --- a/v3/examples/window/main.go +++ b/v3/examples/window/main.go @@ -56,7 +56,7 @@ func main() { myMenu.Add("New WebviewWindow (Hide on Close"). SetAccelerator("CmdOrCtrl+H"). OnClick(func(ctx *application.Context) { - app.NewWebviewWindowWithOptions(&application.WebviewWindowOptions{HideOnClose: true}). + app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{HideOnClose: true}). SetTitle("WebviewWindow "+strconv.Itoa(windowCounter)). SetPosition(rand.Intn(1000), rand.Intn(800)). SetURL("https://wails.io"). @@ -66,7 +66,7 @@ func main() { myMenu.Add("New Frameless WebviewWindow"). SetAccelerator("CmdOrCtrl+F"). OnClick(func(ctx *application.Context) { - app.NewWebviewWindowWithOptions(&application.WebviewWindowOptions{ + app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ X: rand.Intn(1000), Y: rand.Intn(800), Frameless: true, @@ -79,7 +79,7 @@ func main() { if runtime.GOOS == "darwin" { myMenu.Add("New WebviewWindow (MacTitleBarHiddenInset)"). OnClick(func(ctx *application.Context) { - app.NewWebviewWindowWithOptions(&application.WebviewWindowOptions{ + app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ Mac: application.MacWindow{ TitleBar: application.MacTitleBarHiddenInset, InvisibleTitleBarHeight: 25, @@ -93,7 +93,7 @@ func main() { }) myMenu.Add("New WebviewWindow (MacTitleBarHiddenInsetUnified)"). OnClick(func(ctx *application.Context) { - app.NewWebviewWindowWithOptions(&application.WebviewWindowOptions{ + app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ Mac: application.MacWindow{ TitleBar: application.MacTitleBarHiddenInsetUnified, InvisibleTitleBarHeight: 50, @@ -107,7 +107,7 @@ func main() { }) myMenu.Add("New WebviewWindow (MacTitleBarHidden)"). OnClick(func(ctx *application.Context) { - app.NewWebviewWindowWithOptions(&application.WebviewWindowOptions{ + app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ Mac: application.MacWindow{ TitleBar: application.MacTitleBarHidden, InvisibleTitleBarHeight: 25, diff --git a/v3/examples/windowjs/main.go b/v3/examples/windowjs/main.go index ff7f61cd7..d1c20642e 100644 --- a/v3/examples/windowjs/main.go +++ b/v3/examples/windowjs/main.go @@ -34,7 +34,7 @@ func main() { newWindow := func() { windowName := "WebviewWindow " + strconv.Itoa(windowCounter) - app.NewWebviewWindowWithOptions(&application.WebviewWindowOptions{ + app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ Name: windowName, }). SetTitle(windowName). diff --git a/v3/examples/wml/main.go b/v3/examples/wml/main.go index 1a9f4723b..d615e0dfc 100644 --- a/v3/examples/wml/main.go +++ b/v3/examples/wml/main.go @@ -24,7 +24,7 @@ func main() { }, }) - app.NewWebviewWindowWithOptions(&application.WebviewWindowOptions{ + app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ Title: "Wails ML Demo", Width: 800, Height: 600, From f682e4436751205220a36131480340547605823b Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Mon, 1 May 2023 18:24:24 +1000 Subject: [PATCH 20/28] [v3] Fix examples --- v3/examples/binding/go.mod | 1 + v3/examples/binding/go.sum | 2 ++ v3/examples/binding/main.go | 7 ++++--- v3/examples/kitchensink/main.go | 2 +- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/v3/examples/binding/go.mod b/v3/examples/binding/go.mod index affecaa9f..3dbff5f92 100644 --- a/v3/examples/binding/go.mod +++ b/v3/examples/binding/go.mod @@ -14,6 +14,7 @@ require ( github.com/wailsapp/wails/v2 v2.3.2-0.20230117193915-45c3a501d9e6 // indirect golang.org/x/exp v0.0.0-20220930202632-ec3f01382ef9 // indirect golang.org/x/net v0.7.0 // indirect + golang.org/x/sys v0.7.0 // indirect ) replace github.com/wailsapp/wails/v3 => ../.. diff --git a/v3/examples/binding/go.sum b/v3/examples/binding/go.sum index c06e0dbc6..5266584f2 100644 --- a/v3/examples/binding/go.sum +++ b/v3/examples/binding/go.sum @@ -27,6 +27,8 @@ golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/v3/examples/binding/main.go b/v3/examples/binding/main.go index b442c4fb2..24b148fb9 100644 --- a/v3/examples/binding/main.go +++ b/v3/examples/binding/main.go @@ -19,14 +19,15 @@ func main() { Mac: application.MacOptions{ ApplicationShouldTerminateAfterLastWindowClosed: true, }, - }) - - app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ Assets: application.AssetOptions{ FS: assets, }, }) + app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ + URL: "/", + }) + err := app.Run() if err != nil { diff --git a/v3/examples/kitchensink/main.go b/v3/examples/kitchensink/main.go index c7dade717..7c8151b37 100644 --- a/v3/examples/kitchensink/main.go +++ b/v3/examples/kitchensink/main.go @@ -115,7 +115,7 @@ func main() { Height: 400, AlwaysOnTop: true, DisableResize: false, - BackgroundColour: &application.RGBA{ + BackgroundColour: application.RGBA{ Red: 255, Green: 255, Blue: 255, From cf7b4e2458e2ab4089c4faf95489835b16cae569 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Mon, 1 May 2023 20:28:46 +1000 Subject: [PATCH 21/28] [v3] Ensure impl calls from WebvieWindow are on the main thread. Support size. --- v3/STATUS.md | 9 +- v3/pkg/application/application.go | 32 ++++ v3/pkg/application/webview_window.go | 188 ++++++++++++------- v3/pkg/application/webview_window_windows.go | 4 +- 4 files changed, 156 insertions(+), 77 deletions(-) diff --git a/v3/STATUS.md b/v3/STATUS.md index 0a0a9d687..5ed7c2dba 100644 --- a/v3/STATUS.md +++ b/v3/STATUS.md @@ -31,15 +31,14 @@ Webview Window Interface Methods | center() | Y | | Y | | | close() | | | Y | | | destroy() | | | Y | | -| disableSizeConstraints() | | | Y | | | execJS(js string) | | | Y | | | forceReload() | | | Y | | -| fullscreen() | | | Y | | +| fullscreen() | Y | | Y | | | getScreen() (*Screen, error) | | | Y | | | getZoom() float64 | | | Y | | | height() int | Y | | Y | | | hide() | Y | | Y | | -| isFullscreen() bool | | | Y | | +| isFullscreen() bool | Y | | Y | | | isMaximised() bool | Y | | Y | | | isMinimised() bool | Y | | Y | | | maximise() | Y | | Y | | @@ -64,9 +63,9 @@ Webview Window Interface Methods | setURL(url string) | | | Y | | | setZoom(zoom float64) | | | Y | | | show() | Y | | Y | | -| size() (int, int) | | | Y | | +| size() (int, int) | Y | | Y | | | toggleDevTools() | | | Y | | -| unfullscreen() | | | Y | | +| unfullscreen() | Y | | Y | | | unmaximise() | Y | | Y | | | unminimise() | Y | | Y | | | width() int | Y | | Y | | diff --git a/v3/pkg/application/application.go b/v3/pkg/application/application.go index 08f52aaf5..8fb8152ed 100644 --- a/v3/pkg/application/application.go +++ b/v3/pkg/application/application.go @@ -614,3 +614,35 @@ func (a *App) GetWindowByName(name string) *WebviewWindow { } return nil } + +func invokeSync(fn func()) { + var wg sync.WaitGroup + wg.Add(1) + globalApplication.dispatchOnMainThread(func() { + fn() + wg.Done() + }) + wg.Wait() +} + +func invokeSyncWithResult[T any](fn func() T) (res T) { + var wg sync.WaitGroup + wg.Add(1) + globalApplication.dispatchOnMainThread(func() { + res = fn() + wg.Done() + }) + wg.Wait() + return res +} + +func invokeSyncWithResultAndError[T any](fn func() (T, error)) (res T, err error) { + var wg sync.WaitGroup + wg.Add(1) + globalApplication.dispatchOnMainThread(func() { + res, err = fn() + wg.Done() + }) + wg.Wait() + return res, err +} diff --git a/v3/pkg/application/webview_window.go b/v3/pkg/application/webview_window.go index cd7f874e4..1537cd8b3 100644 --- a/v3/pkg/application/webview_window.go +++ b/v3/pkg/application/webview_window.go @@ -136,7 +136,9 @@ func (w *WebviewWindow) SetTitle(title string) *WebviewWindow { defer w.implLock.RUnlock() w.options.Title = title if w.impl != nil { - w.impl.setTitle(title) + invokeSync(func() { + w.impl.setTitle(title) + }) } return w } @@ -182,7 +184,9 @@ func (w *WebviewWindow) SetSize(width, height int) *WebviewWindow { } if w.impl != nil { - w.impl.setSize(width, height) + invokeSync(func() { + w.impl.setSize(width, height) + }) } return w } @@ -194,14 +198,16 @@ func (w *WebviewWindow) run() { w.implLock.Lock() w.impl = newWindowImpl(w) w.implLock.Unlock() - w.impl.run() + invokeSync(w.impl.run) } // SetAlwaysOnTop sets the window to be always on top. func (w *WebviewWindow) SetAlwaysOnTop(b bool) *WebviewWindow { w.options.AlwaysOnTop = b if w.impl != nil { - w.impl.setAlwaysOnTop(b) + invokeSync(func() { + w.impl.setAlwaysOnTop(b) + }) } return w } @@ -215,7 +221,7 @@ func (w *WebviewWindow) Show() *WebviewWindow { w.run() return w } - w.impl.show() + invokeSync(w.impl.show) return w } @@ -223,7 +229,7 @@ func (w *WebviewWindow) Show() *WebviewWindow { func (w *WebviewWindow) Hide() *WebviewWindow { w.options.Hidden = true if w.impl != nil { - w.impl.hide() + invokeSync(w.impl.hide) } return w } @@ -231,7 +237,9 @@ func (w *WebviewWindow) Hide() *WebviewWindow { func (w *WebviewWindow) SetURL(s string) *WebviewWindow { w.options.URL = s if w.impl != nil { - w.impl.setURL(s) + invokeSync(func() { + w.impl.setURL(s) + }) } return w } @@ -240,7 +248,9 @@ func (w *WebviewWindow) SetURL(s string) *WebviewWindow { func (w *WebviewWindow) SetZoom(magnification float64) *WebviewWindow { w.options.Zoom = magnification if w.impl != nil { - w.impl.setZoom(magnification) + invokeSync(func() { + w.impl.setZoom(magnification) + }) } return w } @@ -248,7 +258,7 @@ func (w *WebviewWindow) SetZoom(magnification float64) *WebviewWindow { // GetZoom returns the current zoom level of the window. func (w *WebviewWindow) GetZoom() float64 { if w.impl != nil { - return w.impl.getZoom() + return invokeSyncWithResult(w.impl.getZoom) } return 1 } @@ -257,7 +267,9 @@ func (w *WebviewWindow) GetZoom() float64 { func (w *WebviewWindow) SetResizable(b bool) *WebviewWindow { w.options.DisableResize = !b if w.impl != nil { - w.impl.setResizable(b) + invokeSync(func() { + w.impl.setResizable(b) + }) } return w } @@ -288,9 +300,13 @@ func (w *WebviewWindow) SetMinSize(minWidth, minHeight int) *WebviewWindow { } if w.impl != nil { if newSize { - w.impl.setSize(newWidth, newHeight) + invokeSync(func() { + w.impl.setSize(newWidth, newHeight) + }) } - w.impl.setMinSize(minWidth, minHeight) + invokeSync(func() { + w.impl.setMinSize(minWidth, minHeight) + }) } return w } @@ -316,9 +332,13 @@ func (w *WebviewWindow) SetMaxSize(maxWidth, maxHeight int) *WebviewWindow { } if w.impl != nil { if newSize { - w.impl.setSize(newWidth, newHeight) + invokeSync(func() { + w.impl.setSize(newWidth, newHeight) + }) } - w.impl.setMaxSize(maxWidth, maxHeight) + invokeSync(func() { + w.impl.setMaxSize(maxWidth, maxHeight) + }) } return w } @@ -339,7 +359,7 @@ func (w *WebviewWindow) Fullscreen() *WebviewWindow { } if !w.IsFullscreen() { w.disableSizeConstraints() - w.impl.fullscreen() + invokeSync(w.impl.fullscreen) } return w } @@ -347,7 +367,9 @@ func (w *WebviewWindow) Fullscreen() *WebviewWindow { func (w *WebviewWindow) SetFullscreenButtonEnabled(enabled bool) *WebviewWindow { w.options.FullscreenButtonEnabled = enabled if w.impl != nil { - w.impl.setFullscreenButtonEnabled(enabled) + invokeSync(func() { + w.impl.setFullscreenButtonEnabled(enabled) + }) } return w } @@ -357,7 +379,7 @@ func (w *WebviewWindow) IsMinimised() bool { if w.impl == nil { return false } - return w.impl.isMinimised() + return invokeSyncWithResult(w.impl.isMinimised) } // IsVisible returns true if the window is visible @@ -365,7 +387,7 @@ func (w *WebviewWindow) IsVisible() bool { if w.impl == nil { return false } - return w.impl.isVisible() + return invokeSyncWithResult(w.impl.isVisible) } // IsMaximised returns true if the window is maximised @@ -373,15 +395,19 @@ func (w *WebviewWindow) IsMaximised() bool { if w.impl == nil { return false } - return w.impl.isMaximised() + return invokeSyncWithResult(w.impl.isMaximised) } // Size returns the size of the window -func (w *WebviewWindow) Size() (width int, height int) { +func (w *WebviewWindow) Size() (int, int) { if w.impl == nil { return 0, 0 } - return w.impl.size() + var width, height int + invokeSync(func() { + width, height = w.impl.size() + }) + return width, height } // IsFullscreen returns true if the window is fullscreen @@ -391,14 +417,16 @@ func (w *WebviewWindow) IsFullscreen() bool { if w.impl == nil { return false } - return w.impl.isFullscreen() + return invokeSyncWithResult(w.impl.isFullscreen) } // SetBackgroundColour sets the background colour of the window func (w *WebviewWindow) SetBackgroundColour(colour RGBA) *WebviewWindow { w.options.BackgroundColour = colour if w.impl != nil { - w.impl.setBackgroundColour(colour) + invokeSync(func() { + w.impl.setBackgroundColour(colour) + }) } return w } @@ -407,7 +435,9 @@ func (w *WebviewWindow) handleMessage(message string) { w.info(message) // Check for special messages if message == "test" { - w.SetTitle("Hello World") + invokeSync(func() { + w.SetTitle("Hello World") + }) } w.info("ProcessMessage from front end:", message) @@ -418,7 +448,7 @@ func (w *WebviewWindow) Center() { if w.impl == nil { return } - w.impl.center() + invokeSync(w.impl.center) } // On registers a callback for the given window event @@ -455,7 +485,7 @@ func (w *WebviewWindow) Width() int { if w.impl == nil { return 0 } - return w.impl.width() + return invokeSyncWithResult(w.impl.width) } // Height returns the height of the window @@ -463,7 +493,7 @@ func (w *WebviewWindow) Height() int { if w.impl == nil { return 0 } - return w.impl.height() + return invokeSyncWithResult(w.impl.height) } // Position returns the position of the window @@ -473,7 +503,11 @@ func (w *WebviewWindow) Position() (int, int) { if w.impl == nil { return 0, 0 } - return w.impl.position() + var x, y int + invokeSync(func() { + x, y = w.impl.position() + }) + return x, y } func (w *WebviewWindow) Destroy() { @@ -484,7 +518,7 @@ func (w *WebviewWindow) Destroy() { for _, cancelFunc := range w.cancellers { cancelFunc() } - w.impl.destroy() + invokeSync(w.impl.destroy) } // Reload reloads the page assets @@ -492,7 +526,7 @@ func (w *WebviewWindow) Reload() { if w.impl == nil { return } - w.impl.reload() + invokeSync(w.impl.reload) } // ForceReload forces the window to reload the page assets @@ -500,7 +534,7 @@ func (w *WebviewWindow) ForceReload() { if w.impl == nil { return } - w.impl.forceReload() + invokeSync(w.impl.forceReload) } // ToggleFullscreen toggles the window between fullscreen and normal @@ -508,24 +542,26 @@ func (w *WebviewWindow) ToggleFullscreen() { if w.impl == nil { return } - if w.IsFullscreen() { - w.UnFullscreen() - } else { - w.Fullscreen() - } + invokeSync(func() { + if w.IsFullscreen() { + w.UnFullscreen() + } else { + w.Fullscreen() + } + }) } func (w *WebviewWindow) ToggleDevTools() { if w.impl == nil { return } - w.impl.toggleDevTools() + invokeSync(w.impl.toggleDevTools) } // ZoomReset resets the zoom level of the webview content to 100% func (w *WebviewWindow) ZoomReset() *WebviewWindow { if w.impl != nil { - w.impl.zoomReset() + invokeSync(w.impl.zoomReset) } return w @@ -536,7 +572,7 @@ func (w *WebviewWindow) ZoomIn() { if w.impl == nil { return } - w.impl.zoomIn() + invokeSync(w.impl.zoomIn) } // ZoomOut decreases the zoom level of the webview content @@ -544,7 +580,7 @@ func (w *WebviewWindow) ZoomOut() { if w.impl == nil { return } - w.impl.zoomOut() + invokeSync(w.impl.zoomOut) } // Close closes the window @@ -552,21 +588,23 @@ func (w *WebviewWindow) Close() { if w.impl == nil { return } - w.impl.close() + invokeSync(w.impl.close) } func (w *WebviewWindow) Zoom() { if w.impl == nil { return } - w.impl.zoom() + invokeSync(w.impl.zoom) } // SetHTML sets the HTML of the window to the given html string. func (w *WebviewWindow) SetHTML(html string) *WebviewWindow { w.options.HTML = html if w.impl != nil { - w.impl.setHTML(html) + invokeSync(func() { + w.impl.setHTML(html) + }) } return w } @@ -576,7 +614,9 @@ func (w *WebviewWindow) SetPosition(x, y int) *WebviewWindow { w.options.X = x w.options.Y = y if w.impl != nil { - w.impl.setPosition(x, y) + invokeSync(func() { + w.impl.setPosition(x, y) + }) } return w } @@ -588,7 +628,7 @@ func (w *WebviewWindow) Minimise() *WebviewWindow { return w } if !w.IsMinimised() { - w.impl.minimise() + invokeSync(w.impl.minimise) } return w } @@ -601,7 +641,7 @@ func (w *WebviewWindow) Maximise() *WebviewWindow { } if !w.IsMaximised() { w.disableSizeConstraints() - w.impl.maximise() + invokeSync(w.impl.maximise) } return w } @@ -612,7 +652,7 @@ func (w *WebviewWindow) UnMinimise() { return } if w.IsMinimised() { - w.impl.unminimise() + invokeSync(w.impl.unminimise) } } @@ -623,7 +663,7 @@ func (w *WebviewWindow) UnMaximise() { } if w.IsMaximised() { w.enableSizeConstraints() - w.impl.unmaximise() + invokeSync(w.impl.unmaximise) } } @@ -634,7 +674,7 @@ func (w *WebviewWindow) UnFullscreen() { } if w.IsFullscreen() { w.enableSizeConstraints() - w.impl.unfullscreen() + invokeSync(w.impl.unfullscreen) } } @@ -643,37 +683,43 @@ func (w *WebviewWindow) Restore() { if w.impl == nil { return } - if w.IsMinimised() { - w.UnMinimise() - } else if w.IsMaximised() { - w.UnMaximise() - } else if w.IsFullscreen() { - w.UnFullscreen() - } + invokeSync(func() { + if w.IsMinimised() { + w.UnMinimise() + } else if w.IsMaximised() { + w.UnMaximise() + } else if w.IsFullscreen() { + w.UnFullscreen() + } + }) } func (w *WebviewWindow) disableSizeConstraints() { if w.impl == nil { return } - if w.options.MinWidth > 0 && w.options.MinHeight > 0 { - w.impl.setMinSize(0, 0) - } - if w.options.MaxWidth > 0 && w.options.MaxHeight > 0 { - w.impl.setMaxSize(0, 0) - } + invokeSync(func() { + if w.options.MinWidth > 0 && w.options.MinHeight > 0 { + w.impl.setMinSize(0, 0) + } + if w.options.MaxWidth > 0 && w.options.MaxHeight > 0 { + w.impl.setMaxSize(0, 0) + } + }) } func (w *WebviewWindow) enableSizeConstraints() { if w.impl == nil { return } - if w.options.MinWidth > 0 && w.options.MinHeight > 0 { - w.SetMinSize(w.options.MinWidth, w.options.MinHeight) - } - if w.options.MaxWidth > 0 && w.options.MaxHeight > 0 { - w.SetMaxSize(w.options.MaxWidth, w.options.MaxHeight) - } + invokeSync(func() { + if w.options.MinWidth > 0 && w.options.MinHeight > 0 { + w.SetMinSize(w.options.MinWidth, w.options.MinHeight) + } + if w.options.MaxWidth > 0 && w.options.MaxHeight > 0 { + w.SetMaxSize(w.options.MaxWidth, w.options.MaxHeight) + } + }) } // GetScreen returns the screen that the window is on @@ -681,14 +727,16 @@ func (w *WebviewWindow) GetScreen() (*Screen, error) { if w.impl == nil { return nil, nil } - return w.impl.getScreen() + return invokeSyncWithResultAndError(w.impl.getScreen) } // SetFrameless removes the window frame and title bar func (w *WebviewWindow) SetFrameless(frameless bool) *WebviewWindow { w.options.Frameless = frameless if w.impl != nil { - w.impl.setFrameless(frameless) + invokeSync(func() { + w.impl.setFrameless(frameless) + }) } return w } diff --git a/v3/pkg/application/webview_window_windows.go b/v3/pkg/application/webview_window_windows.go index 671c3d4e5..b820abe9a 100644 --- a/v3/pkg/application/webview_window_windows.go +++ b/v3/pkg/application/webview_window_windows.go @@ -190,8 +190,8 @@ func (w *windowsWebviewWindow) enableSizeConstraints() { } func (w *windowsWebviewWindow) size() (int, int) { - //TODO implement me - panic("implement me") + rect := w32.GetWindowRect(w.hwnd) + return int(rect.Right - rect.Left), int(rect.Bottom - rect.Top) } func (w *windowsWebviewWindow) setForeground() { From 00c6f0dfdbd7f34b5a6bcaeae21fa1c37cd1da6b Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Mon, 1 May 2023 21:11:40 +1000 Subject: [PATCH 22/28] [v3 windows] Implement `getScreen` --- v3/pkg/application/webview_window_windows.go | 60 +++++++++++++++++++- v3/pkg/w32/user32.go | 8 +++ 2 files changed, 66 insertions(+), 2 deletions(-) diff --git a/v3/pkg/application/webview_window_windows.go b/v3/pkg/application/webview_window_windows.go index b820abe9a..aacc1e993 100644 --- a/v3/pkg/application/webview_window_windows.go +++ b/v3/pkg/application/webview_window_windows.go @@ -7,6 +7,8 @@ import ( "fmt" "github.com/wailsapp/wails/v3/pkg/events" "github.com/wailsapp/wails/v3/pkg/w32" + "strconv" + "unicode/utf16" "unsafe" ) @@ -392,9 +394,63 @@ func (w *windowsWebviewWindow) hide() { w32.ShowWindow(w.hwnd, w32.SW_HIDE) } +// Get the screen for the current window func (w *windowsWebviewWindow) getScreen() (*Screen, error) { - //TODO implement me - panic("implement me") + hMonitor := w32.MonitorFromWindow(w.hwnd, w32.MONITOR_DEFAULTTONEAREST) + + var mi w32.MONITORINFOEX + mi.CbSize = uint32(unsafe.Sizeof(mi)) + w32.GetMonitorInfoEx(hMonitor, &mi) + var thisScreen Screen + thisScreen.X = int(mi.RcMonitor.Left) + thisScreen.Y = int(mi.RcMonitor.Top) + thisScreen.Size = Size{ + Width: int(mi.RcMonitor.Right - mi.RcMonitor.Left), + Height: int(mi.RcMonitor.Bottom - mi.RcMonitor.Top), + } + thisScreen.Bounds = Rect{ + X: int(mi.RcMonitor.Left), + Y: int(mi.RcMonitor.Top), + Width: int(mi.RcMonitor.Right - mi.RcMonitor.Left), + Height: int(mi.RcMonitor.Bottom - mi.RcMonitor.Top), + } + thisScreen.WorkArea = Rect{ + X: int(mi.RcWork.Left), + Y: int(mi.RcWork.Top), + Width: int(mi.RcWork.Right - mi.RcWork.Left), + Height: int(mi.RcWork.Bottom - mi.RcWork.Top), + } + thisScreen.ID = strconv.Itoa(int(hMonitor)) + thisScreen.Name = string(utf16.Decode(mi.SzDevice[:])) + var xdpi, ydpi w32.UINT + w32.GetDPIForMonitor(hMonitor, w32.MDT_EFFECTIVE_DPI, &xdpi, &ydpi) + thisScreen.Scale = float32(xdpi) / 96.0 + thisScreen.IsPrimary = mi.DwFlags&w32.MONITORINFOF_PRIMARY != 0 + + // TODO: Get screen rotation + // https://docs.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-devmodea + + //// get display settings for monitor + //var dm w32.DEVMODE + //dm.DmSize = uint16(unsafe.Sizeof(dm)) + //dm.DmDriverExtra = 0 + //w32.EnumDisplaySettingsEx(&mi.SzDevice[0], w32.ENUM_CURRENT_SETTINGS, &dm, 0) + // + //// check display settings for rotation + //rotationAngle := dm.DmDi + //if rotationAngle == DMDO_0 { + // printf("Monitor is not rotated\n") + //} else if rotationAngle == DMDO_90 { + // printf("Monitor is rotated 90 degrees\n") + //} else if rotationAngle == DMDO_180 { + // printf("Monitor is rotated 180 degrees\n") + //} else if rotationAngle == DMDO_270 { + // printf("Monitor is rotated 270 degrees\n") + //} else { + // printf("Monitor is rotated at an unknown angle\n") + //} + + return &thisScreen, nil } func (w *windowsWebviewWindow) setFrameless(b bool) { diff --git a/v3/pkg/w32/user32.go b/v3/pkg/w32/user32.go index 9357d2586..caac6fa39 100644 --- a/v3/pkg/w32/user32.go +++ b/v3/pkg/w32/user32.go @@ -1151,6 +1151,14 @@ func GetMonitorInfo(hMonitor HMONITOR, lmpi *MONITORINFO) bool { return ret != 0 } +func GetMonitorInfoEx(hMonitor HMONITOR, lmpi *MONITORINFOEX) bool { + ret, _, _ := procGetMonitorInfo.Call( + uintptr(hMonitor), + uintptr(unsafe.Pointer(lmpi)), + ) + return ret != 0 +} + func EnumDisplayMonitors(hdc HDC, clip *RECT, fnEnum uintptr, dwData unsafe.Pointer) bool { ret, _, _ := procEnumDisplayMonitors.Call( hdc, From fc3725d3f4ccd2239cc951c775b1d6f435682965 Mon Sep 17 00:00:00 2001 From: stffabi Date: Tue, 2 May 2023 09:11:13 +0200 Subject: [PATCH 23/28] [v3 windows] Add frameless support --- v3/pkg/application/webview_window_windows.go | 103 +++++++++++++++++-- 1 file changed, 94 insertions(+), 9 deletions(-) diff --git a/v3/pkg/application/webview_window_windows.go b/v3/pkg/application/webview_window_windows.go index aacc1e993..7f72caea5 100644 --- a/v3/pkg/application/webview_window_windows.go +++ b/v3/pkg/application/webview_window_windows.go @@ -5,11 +5,12 @@ package application import ( "errors" "fmt" - "github.com/wailsapp/wails/v3/pkg/events" - "github.com/wailsapp/wails/v3/pkg/w32" "strconv" "unicode/utf16" "unsafe" + + "github.com/wailsapp/wails/v3/pkg/events" + "github.com/wailsapp/wails/v3/pkg/w32" ) var showDevTools = func(window unsafe.Pointer) {} @@ -76,15 +77,11 @@ func (w *windowsWebviewWindow) setBackgroundColour(color RGBA) { w32.SetBackgroundColour(w.hwnd, color.Red, color.Green, color.Blue) } -func (w *windowsWebviewWindow) run() { - globalApplication.dispatchOnMainThread(w._run) -} - func (w *windowsWebviewWindow) framelessWithDecorations() bool { return w.parent.options.Frameless && !w.parent.options.Windows.DisableFramelessWindowDecorations } -func (w *windowsWebviewWindow) _run() { +func (w *windowsWebviewWindow) run() { options := w.parent.options @@ -120,6 +117,22 @@ func (w *windowsWebviewWindow) _run() { w.setResizable(!options.DisableResize) + if options.Frameless { + // Inform the application of the frame change this is needed to trigger the WM_NCCALCSIZE event. + // => https://learn.microsoft.com/en-us/windows/win32/dwm/customframe#removing-the-standard-frame + // This is normally done in WM_CREATE but we can't handle that there because that is emitted during CreateWindowEx + // and at that time we can't yet register the window for calling our WndProc method. + // This must be called after setResizable above! + rcClient := w32.GetWindowRect(w.hwnd) + w32.SetWindowPos(w.hwnd, + 0, + int(rcClient.Left), + int(rcClient.Top), + int(rcClient.Right-rcClient.Left), + int(rcClient.Bottom-rcClient.Top), + w32.SWP_FRAMECHANGED) + } + // Icon if !options.Windows.DisableIcon { // App icon ID is 3 @@ -333,13 +346,13 @@ func (w *windowsWebviewWindow) fullscreen() { // According to https://devblogs.microsoft.com/oldnewthing/20050505-04/?p=35703 one should use w32.WS_POPUP | w32.WS_VISIBLE w32.SetWindowLong(w.hwnd, w32.GWL_STYLE, w.previousWindowStyle & ^uint32(w32.WS_OVERLAPPEDWINDOW) | (w32.WS_POPUP|w32.WS_VISIBLE)) w32.SetWindowLong(w.hwnd, w32.GWL_EXSTYLE, w.previousWindowExStyle & ^uint32(w32.WS_EX_DLGMODALFRAME)) + w.isCurrentlyFullscreen = true w32.SetWindowPos(w.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) - w.isCurrentlyFullscreen = true } func (w *windowsWebviewWindow) unfullscreen() { @@ -352,10 +365,10 @@ func (w *windowsWebviewWindow) unfullscreen() { w32.SetWindowLong(w.hwnd, w32.GWL_STYLE, w.previousWindowStyle) w32.SetWindowLong(w.hwnd, w32.GWL_EXSTYLE, w.previousWindowExStyle) w32.SetWindowPlacement(w.hwnd, &w.previousWindowPlacement) + w.isCurrentlyFullscreen = false w32.SetWindowPos(w.hwnd, 0, 0, 0, 0, 0, w32.SWP_NOMOVE|w32.SWP_NOSIZE|w32.SWP_NOZORDER|w32.SWP_NOOWNERZORDER|w32.SWP_FRAMECHANGED) w.enableSizeConstraints() - w.isCurrentlyFullscreen = false } func (w *windowsWebviewWindow) isMinimised() bool { @@ -370,6 +383,9 @@ func (w *windowsWebviewWindow) isMaximised() bool { func (w *windowsWebviewWindow) isFullscreen() bool { // TODO: Actually calculate this based on size of window against screen size + // => stffabi: This flag is essential since it indicates that we are in fullscreen mode even before the native properties + // reflect this, e.g. when needing to know if we are in fullscreen during a wndproc message. + // That's also why this flag is set before SetWindowPos in v2 in fullscreen/unfullscreen. return w.isCurrentlyFullscreen } @@ -620,6 +636,75 @@ func (w *windowsWebviewWindow) WndProc(msg uint32, wparam, lparam uintptr) uintp return 0 } } + + if options := w.parent.options; options.Frameless { + switch msg { + case w32.WM_ACTIVATE: + // If we want to have a frameless window but with the default frame decorations, extend the DWM client area. + // This Option is not affected by returning 0 in WM_NCCALCSIZE. + // As a result we have hidden the titlebar but still have the default window frame styling. + // See: https://docs.microsoft.com/en-us/windows/win32/api/dwmapi/nf-dwmapi-dwmextendframeintoclientarea#remarks + if w.framelessWithDecorations() { + w32.ExtendFrameIntoClientArea(w.hwnd, true) + } + case w32.WM_NCCALCSIZE: + // Disable the standard frame by allowing the client area to take the full + // window size. + // See: https://docs.microsoft.com/en-us/windows/win32/winmsg/wm-nccalcsize#remarks + // This hides the titlebar and also disables the resizing from user interaction because the standard frame is not + // shown. We still need the WS_THICKFRAME style to enable resizing from the frontend. + if wparam != 0 { + rgrc := (*w32.RECT)(unsafe.Pointer(lparam)) + if w.isCurrentlyFullscreen { + // In Full-Screen mode we don't need to adjust anything + // It essential we have the flag here, that is set before SetWindowPos in fullscreen/unfullscreen + // because the native size might not yet reflect we are in fullscreen during this event! + // TODO: w.chromium.SetPadding(edge.Rect{}) + } else if w.isMaximised() { + // If the window is maximized we must adjust the client area to the work area of the monitor. Otherwise + // some content goes beyond the visible part of the monitor. + // Make sure to use the provided RECT to get the monitor, because during maximizig there might be + // a wrong monitor returned in multi screen mode when using MonitorFromWindow. + // See: https://github.com/MicrosoftEdge/WebView2Feedback/issues/2549 + monitor := w32.MonitorFromRect(rgrc, w32.MONITOR_DEFAULTTONULL) + + var monitorInfo w32.MONITORINFO + monitorInfo.CbSize = uint32(unsafe.Sizeof(monitorInfo)) + if monitor != 0 && w32.GetMonitorInfo(monitor, &monitorInfo) { + *rgrc = monitorInfo.RcWork + + maxWidth := options.MaxWidth + maxHeight := options.MaxHeight + if maxWidth > 0 || maxHeight > 0 { + var dpiX, dpiY uint + w32.GetDPIForMonitor(monitor, w32.MDT_EFFECTIVE_DPI, &dpiX, &dpiY) + + maxWidth := int32(ScaleWithDPI(maxWidth, dpiX)) + if maxWidth > 0 && rgrc.Right-rgrc.Left > maxWidth { + rgrc.Right = rgrc.Left + maxWidth + } + + maxHeight := int32(ScaleWithDPI(maxHeight, dpiY)) + if maxHeight > 0 && rgrc.Bottom-rgrc.Top > maxHeight { + rgrc.Bottom = rgrc.Top + maxHeight + } + } + } + // TODO: w.chromium.SetPadding(edge.Rect{}) + } else { + // This is needed to workaround the resize flickering in frameless mode with WindowDecorations + // See: https://stackoverflow.com/a/6558508 + // The workaround originally suggests to decrese the bottom 1px, but that seems to bring up a thin + // white line on some Windows-Versions, due to DrawBackground using also this reduces ClientSize. + // Increasing the bottom also worksaround the flickering but we would loose 1px of the WebView content + // therefore let's pad the content with 1px at the bottom. + rgrc.Bottom += 1 + // TODO: w.chromium.SetPadding(edge.Rect{Bottom: 1}) + } + return 0 + } + } + } return w32.DefWindowProc(w.hwnd, msg, wparam, lparam) } From 6f246eed4a2167832cb4a294136f1acc57eaa2ff Mon Sep 17 00:00:00 2001 From: stffabi Date: Tue, 2 May 2023 09:39:13 +0200 Subject: [PATCH 24/28] [v3 windows] Add HiDPI awareness --- v3/pkg/application/application.go | 10 ++++- v3/pkg/application/webview_window_windows.go | 45 ++++++++++++++++---- v3/pkg/w32/constants.go | 1 + v3/pkg/w32/user32.go | 9 ++++ 4 files changed, 55 insertions(+), 10 deletions(-) diff --git a/v3/pkg/application/application.go b/v3/pkg/application/application.go index 8fb8152ed..b31347b76 100644 --- a/v3/pkg/application/application.go +++ b/v3/pkg/application/application.go @@ -1,7 +1,6 @@ package application import ( - "github.com/samber/lo" "log" "net/http" "os" @@ -9,6 +8,8 @@ import ( "strconv" "sync" + "github.com/samber/lo" + "github.com/wailsapp/wails/v2/pkg/assetserver" "github.com/wailsapp/wails/v2/pkg/assetserver/webview" assetserveroptions "github.com/wailsapp/wails/v2/pkg/options/assetserver" @@ -16,6 +17,7 @@ import ( wailsruntime "github.com/wailsapp/wails/v3/internal/runtime" "github.com/wailsapp/wails/v3/pkg/events" "github.com/wailsapp/wails/v3/pkg/logger" + "github.com/wailsapp/wails/v3/pkg/w32" ) var globalApplication *App @@ -33,6 +35,12 @@ func New(appOptions Options) *App { return globalApplication } + err := w32.SetProcessDPIAware() + if err != nil { + println("Fatal error in application initialisation: ", err.Error()) + os.Exit(1) + } + mergeApplicationDefaults(&appOptions) result := &App{ diff --git a/v3/pkg/application/webview_window_windows.go b/v3/pkg/application/webview_window_windows.go index 7f72caea5..90a05014c 100644 --- a/v3/pkg/application/webview_window_windows.go +++ b/v3/pkg/application/webview_window_windows.go @@ -36,9 +36,9 @@ func (w *windowsWebviewWindow) setTitle(title string) { } func (w *windowsWebviewWindow) setSize(width, height int) { - x, y := w.position() - // TODO: Take scaling/DPI into consideration - w32.MoveWindow(w.hwnd, x, y, width, height, true) + rect := w32.GetWindowRect(w.hwnd) + width, height = w.scaleWithWindowDPI(width, height) + w32.MoveWindow(w.hwnd, int(rect.Left), int(rect.Top), width, height, true) } func (w *windowsWebviewWindow) setAlwaysOnTop(alwaysOnTop bool) { @@ -206,7 +206,10 @@ func (w *windowsWebviewWindow) enableSizeConstraints() { func (w *windowsWebviewWindow) size() (int, int) { rect := w32.GetWindowRect(w.hwnd) - return int(rect.Right - rect.Left), int(rect.Bottom - rect.Top) + width := int(rect.Right - rect.Left) + height := int(rect.Bottom - rect.Top) + width, height = w.scaleToDefaultDPI(width, height) + return width, height } func (w *windowsWebviewWindow) setForeground() { @@ -218,18 +221,19 @@ func (w *windowsWebviewWindow) update() { } func (w *windowsWebviewWindow) width() int { - rect := w32.GetWindowRect(w.hwnd) - return int(rect.Right - rect.Left) + width, _ := w.size() + return width } func (w *windowsWebviewWindow) height() int { - rect := w32.GetWindowRect(w.hwnd) - return int(rect.Bottom - rect.Top) + _, height := w.size() + return height } func (w *windowsWebviewWindow) position() (int, int) { rect := w32.GetWindowRect(w.hwnd) - return int(rect.Left), int(rect.Right) + left, right := w.scaleToDefaultDPI(int(rect.Left), int(rect.Right)) + return left, right } func (w *windowsWebviewWindow) destroy() { @@ -293,6 +297,7 @@ func (w *windowsWebviewWindow) setHTML(html string) { } func (w *windowsWebviewWindow) setPosition(x int, y int) { + x, y = w.scaleWithWindowDPI(x, y) info := w32.GetMonitorInfoForWindow(w.hwnd) workRect := info.RcWork w32.SetWindowPos(w.hwnd, w32.HWND_TOP, int(workRect.Left)+x, int(workRect.Top)+y, 0, 0, w32.SWP_NOSIZE) @@ -635,6 +640,16 @@ func (w *windowsWebviewWindow) WndProc(msg uint32, wparam, lparam uintptr) uintp if hasConstraints { return 0 } + case w32.WM_DPICHANGED: + newWindowSize := (*w32.RECT)(unsafe.Pointer(lparam)) + w32.SetWindowPos(w.hwnd, + uintptr(0), + int(newWindowSize.Left), + int(newWindowSize.Top), + int(newWindowSize.Right-newWindowSize.Left), + int(newWindowSize.Bottom-newWindowSize.Top), + w32.SWP_NOZORDER|w32.SWP_NOACTIVATE) + } if options := w.parent.options; options.Frameless { @@ -743,10 +758,22 @@ func (w *windowsWebviewWindow) scaleWithWindowDPI(width, height int) (int, int) return scaledWidth, scaledHeight } +func (w *windowsWebviewWindow) scaleToDefaultDPI(width, height int) (int, int) { + dpix, dpiy := w.DPI() + scaledWidth := ScaleToDefaultDPI(width, dpix) + scaledHeight := ScaleToDefaultDPI(height, dpiy) + + return scaledWidth, scaledHeight +} + func ScaleWithDPI(pixels int, dpi uint) int { return (pixels * int(dpi)) / 96 } +func ScaleToDefaultDPI(pixels int, dpi uint) int { + return (pixels * 96) / int(dpi) +} + func NewIconFromResource(instance w32.HINSTANCE, resId uint16) (w32.HICON, error) { var err error var result w32.HICON diff --git a/v3/pkg/w32/constants.go b/v3/pkg/w32/constants.go index 1b200046d..a06db4fda 100644 --- a/v3/pkg/w32/constants.go +++ b/v3/pkg/w32/constants.go @@ -552,6 +552,7 @@ const ( WM_MOUSEHOVER = 0x2A1 WM_MOUSELEAVE = 0x2A3 WM_CLIPBOARDUPDATE = 0x031D + WM_DPICHANGED = 0x02E0 ) // WM_ACTIVATE diff --git a/v3/pkg/w32/user32.go b/v3/pkg/w32/user32.go index caac6fa39..002836c1f 100644 --- a/v3/pkg/w32/user32.go +++ b/v3/pkg/w32/user32.go @@ -130,6 +130,7 @@ var ( procGetMonitorInfo = moduser32.NewProc("GetMonitorInfoW") procGetDpiForSystem = moduser32.NewProc("GetDpiForSystem") procGetDpiForWindow = moduser32.NewProc("GetDpiForWindow") + procSetProcessDPIAware = moduser32.NewProc("SetProcessDPIAware") procEnumDisplayMonitors = moduser32.NewProc("EnumDisplayMonitors") procEnumDisplaySettingsEx = moduser32.NewProc("EnumDisplaySettingsExW") procChangeDisplaySettingsEx = moduser32.NewProc("ChangeDisplaySettingsExW") @@ -303,6 +304,14 @@ func GetDpiForWindow(hwnd HWND) UINT { return uint(dpi) } +func SetProcessDPIAware() error { + status, r, err := procSetProcessDPIAware.Call() + if status == 0 { + return fmt.Errorf("SetProcessDPIAware failed %d: %v %v", status, r, err) + } + return nil +} + func GetForegroundWindow() HWND { ret, _, _ := procGetForegroundWindow.Call() return HWND(ret) From 6758580be914e770389ae35ecc92792c3b350077 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Tue, 2 May 2023 23:18:22 +1000 Subject: [PATCH 25/28] [v3 windows] Add frameless resize --- v3/STATUS.md | 44 ++++++++++++++++-- v3/pkg/application/options_webview_window.go | 3 +- v3/pkg/application/webview_window_windows.go | 47 ++++++++++++++++++++ 3 files changed, 90 insertions(+), 4 deletions(-) diff --git a/v3/STATUS.md b/v3/STATUS.md index 5ed7c2dba..0bdd58d3f 100644 --- a/v3/STATUS.md +++ b/v3/STATUS.md @@ -52,7 +52,7 @@ Webview Window Interface Methods | setAlwaysOnTop(alwaysOnTop bool) | Y | | Y | | | setBackgroundColour(color RGBA) | Y | | Y | | | setFrameless(bool) | | | Y | | -| setFullscreenButtonEnabled(enabled bool) | X | | Y | There is no fullscreen button in Windows | +| setFullscreenButtonEnabled(enabled bool) | - | | Y | There is no fullscreen button in Windows | | setHTML(html string) | | | Y | | | setMaxSize(width, height int) | Y | | Y | | | setMinSize(width, height int) | Y | | Y | | @@ -148,6 +148,44 @@ Webview Window Interface Methods | SetZoom | | | Y | Set view scale | | Screen | | | Y | Get screen for window | + +### Window Options + +A 'Y' in the table below indicates that the option has been tested and is applied when the window is created. +An 'X' indicates that the option is not supported by the platform. + + +| Feature | Windows | Linux | Mac | Notes | +|---------------------------------|---------|-------|-----|--------------------------------------------| +| Name | | | | | +| Title | Y | | | | +| Width | Y | | | | +| Height | Y | | | | +| AlwaysOnTop | Y | | | | +| URL | | | | | +| DisableResize | Y | | | | +| Frameless | | | | | +| MinWidth | Y | | | | +| MinHeight | Y | | | | +| MaxWidth | Y | | | | +| MaxHeight | Y | | | | +| StartState | Y | | | | +| Mac | - | - | | | +| BackgroundType | | | | Acrylic seems to work but the others don't | +| BackgroundColour | Y | | | | +| HTML | | | | | +| JS | | | | | +| CSS | | | | | +| X | | | | | +| Y | | | | | +| HideOnClose | | | | | +| FullscreenButtonEnabled | | | | | +| Hidden | | | | | +| EnableFraudulentWebsiteWarnings | | | | | +| Zoom | | | | | +| EnableDragAndDrop | | | | | +| Windows | | - | - | | + ### Log To log or not to log? System logger vs custom logger. @@ -230,9 +268,9 @@ Built-in plugin support: | Icon Generation | | | Y | | | Icon Embedding | | | Y | | | Info.plist | | | Y | | -| NSIS Installer | | | | | +| NSIS Installer | | | - | | | Mac bundle | | | Y | | -| Windows exe | | | | | +| Windows exe | | | - | | ## Frameless Windows diff --git a/v3/pkg/application/options_webview_window.go b/v3/pkg/application/options_webview_window.go index 367ac2ce4..be0537947 100644 --- a/v3/pkg/application/options_webview_window.go +++ b/v3/pkg/application/options_webview_window.go @@ -12,7 +12,8 @@ const ( type WebviewWindowOptions struct { Name string Title string - Width, Height int + Width int + Height int AlwaysOnTop bool URL string DisableResize bool diff --git a/v3/pkg/application/webview_window_windows.go b/v3/pkg/application/webview_window_windows.go index 90a05014c..6d51a3f72 100644 --- a/v3/pkg/application/webview_window_windows.go +++ b/v3/pkg/application/webview_window_windows.go @@ -662,6 +662,53 @@ func (w *windowsWebviewWindow) WndProc(msg uint32, wparam, lparam uintptr) uintp if w.framelessWithDecorations() { w32.ExtendFrameIntoClientArea(w.hwnd, true) } + case w32.WM_NCHITTEST: + // Get the cursor position + x := int32(w32.LOWORD(uint32(lparam))) + y := int32(w32.HIWORD(uint32(lparam))) + ptCursor := w32.POINT{X: x, Y: y} + + // Get the window rectangle + rcWindow := w32.GetWindowRect(w.hwnd) + + // Determine if the cursor is in a resize area + bOnResizeBorder := false + resizeBorderWidth := int32(5) // change this to adjust the resize border width + if ptCursor.X >= rcWindow.Right-resizeBorderWidth { + bOnResizeBorder = true // right edge + } + if ptCursor.Y >= rcWindow.Bottom-resizeBorderWidth { + bOnResizeBorder = true // bottom edge + } + if ptCursor.X <= rcWindow.Left+resizeBorderWidth { + bOnResizeBorder = true // left edge + } + if ptCursor.Y <= rcWindow.Top+resizeBorderWidth { + bOnResizeBorder = true // top edge + } + + // Return the appropriate value + if bOnResizeBorder { + if ptCursor.X >= rcWindow.Right-resizeBorderWidth && ptCursor.Y >= rcWindow.Bottom-resizeBorderWidth { + return w32.HTBOTTOMRIGHT + } else if ptCursor.X <= rcWindow.Left+resizeBorderWidth && ptCursor.Y >= rcWindow.Bottom-resizeBorderWidth { + return w32.HTBOTTOMLEFT + } else if ptCursor.X >= rcWindow.Right-resizeBorderWidth && ptCursor.Y <= rcWindow.Top+resizeBorderWidth { + return w32.HTTOPRIGHT + } else if ptCursor.X <= rcWindow.Left+resizeBorderWidth && ptCursor.Y <= rcWindow.Top+resizeBorderWidth { + return w32.HTTOPLEFT + } else if ptCursor.X >= rcWindow.Right-resizeBorderWidth { + return w32.HTRIGHT + } else if ptCursor.Y >= rcWindow.Bottom-resizeBorderWidth { + return w32.HTBOTTOM + } else if ptCursor.X <= rcWindow.Left+resizeBorderWidth { + return w32.HTLEFT + } else if ptCursor.Y <= rcWindow.Top+resizeBorderWidth { + return w32.HTTOP + } + } + return w32.HTCLIENT + case w32.WM_NCCALCSIZE: // Disable the standard frame by allowing the client area to take the full // window size. From 792c5e2d9540bd2a02a622a069970064c9d3be0a Mon Sep 17 00:00:00 2001 From: Travis McLane Date: Tue, 2 May 2023 10:52:09 -0500 Subject: [PATCH 26/28] [w32] add missing build constraint --- v3/pkg/w32/window.go | 1 + 1 file changed, 1 insertion(+) diff --git a/v3/pkg/w32/window.go b/v3/pkg/w32/window.go index 3f626228b..fec225cfe 100644 --- a/v3/pkg/w32/window.go +++ b/v3/pkg/w32/window.go @@ -1,3 +1,4 @@ +//go:build windows package w32 import ( From 86a1de678805e56f651771250d70e9c6760d5b7f Mon Sep 17 00:00:00 2001 From: Travis McLane Date: Tue, 2 May 2023 10:52:21 -0500 Subject: [PATCH 27/28] [w32] move windows specific code to impl file --- v3/pkg/application/application.go | 7 ------- v3/pkg/application/application_windows.go | 7 +++++++ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/v3/pkg/application/application.go b/v3/pkg/application/application.go index b31347b76..8a75cfa9a 100644 --- a/v3/pkg/application/application.go +++ b/v3/pkg/application/application.go @@ -17,7 +17,6 @@ import ( wailsruntime "github.com/wailsapp/wails/v3/internal/runtime" "github.com/wailsapp/wails/v3/pkg/events" "github.com/wailsapp/wails/v3/pkg/logger" - "github.com/wailsapp/wails/v3/pkg/w32" ) var globalApplication *App @@ -35,12 +34,6 @@ func New(appOptions Options) *App { return globalApplication } - err := w32.SetProcessDPIAware() - if err != nil { - println("Fatal error in application initialisation: ", err.Error()) - os.Exit(1) - } - mergeApplicationDefaults(&appOptions) result := &App{ diff --git a/v3/pkg/application/application_windows.go b/v3/pkg/application/application_windows.go index b85db6e4f..8e6e23b13 100644 --- a/v3/pkg/application/application_windows.go +++ b/v3/pkg/application/application_windows.go @@ -211,6 +211,13 @@ func (m *windowsApp) unregisterWindow(w *windowsWebviewWindow) { } func newPlatformApp(app *App) *windowsApp { + err := w32.SetProcessDPIAware() + if err != nil { + println("Fatal error in application initialisation: ", err.Error()) + os.Exit(1) + } + + result := &windowsApp{ parent: app, instance: w32.GetModuleHandle(""), From f4749db8b3a010ed6d66cbb5fd499c92a626abb0 Mon Sep 17 00:00:00 2001 From: stffabi Date: Tue, 2 May 2023 21:54:56 +0200 Subject: [PATCH 28/28] [v3] Add some missing methods for darwin and windows --- v3/pkg/application/application_windows.go | 7 ++++--- v3/pkg/application/menuitem.go | 2 ++ v3/pkg/application/menuitem_darwin.go | 12 ++++++++++- v3/pkg/application/menuitem_windows.go | 4 ++++ v3/pkg/application/webview_window_darwin.go | 22 ++++++++++++++++++--- 5 files changed, 40 insertions(+), 7 deletions(-) diff --git a/v3/pkg/application/application_windows.go b/v3/pkg/application/application_windows.go index 8e6e23b13..2cf49bc80 100644 --- a/v3/pkg/application/application_windows.go +++ b/v3/pkg/application/application_windows.go @@ -3,11 +3,13 @@ package application import ( - "github.com/wailsapp/wails/v3/pkg/events" - "github.com/wailsapp/wails/v3/pkg/w32" + "os" "syscall" "unsafe" + "github.com/wailsapp/wails/v3/pkg/events" + "github.com/wailsapp/wails/v3/pkg/w32" + "github.com/samber/lo" ) @@ -217,7 +219,6 @@ func newPlatformApp(app *App) *windowsApp { os.Exit(1) } - result := &windowsApp{ parent: app, instance: w32.GetModuleHandle(""), diff --git a/v3/pkg/application/menuitem.go b/v3/pkg/application/menuitem.go index 9b0ff3724..ed7143e29 100644 --- a/v3/pkg/application/menuitem.go +++ b/v3/pkg/application/menuitem.go @@ -173,6 +173,8 @@ func newRole(role Role) *MenuItem { return newMinimizeMenuItem() case Zoom: return newZoomMenuItem() + case FullScreen: + return newFullScreenMenuItem() default: println("No support for role:", role) diff --git a/v3/pkg/application/menuitem_darwin.go b/v3/pkg/application/menuitem_darwin.go index c918c2ee3..eb252abf1 100644 --- a/v3/pkg/application/menuitem_darwin.go +++ b/v3/pkg/application/menuitem_darwin.go @@ -606,7 +606,7 @@ func newMinimizeMenuItem() *MenuItem { OnClick(func(ctx *Context) { currentWindow := globalApplication.CurrentWindow() if currentWindow != nil { - currentWindow.Minimize() + currentWindow.Minimise() } }) } @@ -620,3 +620,13 @@ func newZoomMenuItem() *MenuItem { } }) } + +func newFullScreenMenuItem() *MenuItem { + return newMenuItem("Fullscreen"). + OnClick(func(ctx *Context) { + currentWindow := globalApplication.CurrentWindow() + if currentWindow != nil { + currentWindow.Fullscreen() + } + }) +} diff --git a/v3/pkg/application/menuitem_windows.go b/v3/pkg/application/menuitem_windows.go index c8974c26f..caf07b850 100644 --- a/v3/pkg/application/menuitem_windows.go +++ b/v3/pkg/application/menuitem_windows.go @@ -177,3 +177,7 @@ func newMinimizeMenuItem() *MenuItem { func newZoomMenuItem() *MenuItem { panic("implement me") } + +func newFullScreenMenuItem() *MenuItem { + panic("implement me") +} diff --git a/v3/pkg/application/webview_window_darwin.go b/v3/pkg/application/webview_window_darwin.go index 5be173fea..60305c49a 100644 --- a/v3/pkg/application/webview_window_darwin.go +++ b/v3/pkg/application/webview_window_darwin.go @@ -703,6 +703,12 @@ static bool isFullScreen(void *window) { return (mask & NSWindowStyleMaskFullScreen) == NSWindowStyleMaskFullScreen; } +static bool isVisible(void *window) { + // get main window + WebviewWindow* nsWindow = (WebviewWindow*)window; + return (nsWindow.occlusionState & NSWindowOcclusionStateVisible) == NSWindowOcclusionStateVisible; +} + // windowSetFullScreen static void windowSetFullScreen(void *window, bool fullscreen) { if (isFullScreen(window)) { @@ -942,6 +948,14 @@ func (w *macosWebviewWindow) isFullscreen() bool { }) } +func (w *macosWebviewWindow) isNormal() bool { + return !w.isMinimised() && !w.isMaximised() && !w.isFullscreen() +} + +func (w *macosWebviewWindow) isVisible() bool { + return bool(C.isVisible(w.nsWindow)) +} + func (w *macosWebviewWindow) syncMainThreadReturningBool(fn func() bool) bool { var wg sync.WaitGroup wg.Add(1) @@ -1147,10 +1161,12 @@ func (w *macosWebviewWindow) run() { }) } +func (w *macosWebviewWindow) nativeWindowHandle() uintptr { + return uintptr(w.nsWindow) +} + func (w *macosWebviewWindow) setBackgroundColour(colour RGBA) { - if colour == nil { - return - } + C.windowSetBackgroundColour(w.nsWindow, C.int(colour.Red), C.int(colour.Green), C.int(colour.Blue), C.int(colour.Alpha)) }