2014-07-17 17:04:51 -05:00
|
|
|
// 25 february 2014
|
|
|
|
|
|
|
|
package ui
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"io/ioutil"
|
|
|
|
"syscall"
|
|
|
|
"unsafe"
|
|
|
|
)
|
|
|
|
|
2014-07-17 23:22:21 -05:00
|
|
|
// #include "winapi_windows.h"
|
|
|
|
import "C"
|
|
|
|
|
2014-07-17 17:04:51 -05:00
|
|
|
// pretty much every constant here except _WM_USER is from commctrl.h, except where noted
|
|
|
|
|
|
|
|
/*
|
|
|
|
Windows requires a manifest file to enable Common Controls version 6.
|
|
|
|
The only way to not require an external manifest is to synthesize the manifest ourselves.
|
|
|
|
We can use the activation context API to load it at runtime.
|
|
|
|
References:
|
|
|
|
- http://stackoverflow.com/questions/4308503/how-to-enable-visual-styles-without-a-manifest
|
|
|
|
- http://support.microsoft.com/kb/830033
|
2014-07-17 19:05:47 -05:00
|
|
|
The activation context code itself is in comctl32_windows.c.
|
2014-07-17 17:04:51 -05:00
|
|
|
*/
|
2014-07-17 19:05:47 -05:00
|
|
|
func initCommonControls() (err error) {
|
2014-07-17 17:04:51 -05:00
|
|
|
manifestfile, err := ioutil.TempFile("", "gouicomctl32v6manifest")
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("error creating synthesized manifest file: %v", err)
|
|
|
|
}
|
|
|
|
_, err = manifestfile.Write(manifest)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("error writing synthesized manifest file: %v", err)
|
|
|
|
}
|
|
|
|
filename := manifestfile.Name()
|
|
|
|
// we now have to close the file, otherwise ActivateActCtx() will complain that it's in use by another program
|
|
|
|
// if ioutil.TempFile() ever changes so that the file is deleted when it is closed, this will need to change
|
|
|
|
manifestfile.Close()
|
|
|
|
|
2014-07-17 19:05:47 -05:00
|
|
|
var errmsg *C.char
|
2014-07-17 17:04:51 -05:00
|
|
|
|
2014-07-17 19:05:47 -05:00
|
|
|
errcode := C.initCommonControls(C.LPCWSTR(unsafe.Pointer(syscall.StringToUTF16Ptr(filename))), &errmsg)
|
|
|
|
if errcode != 0 || errmsg != nil {
|
|
|
|
return fmt.Errorf("error actually initializing comctl32.dll: %s: %v", C.GoString(errmsg), syscall.Errno(errcode))
|
2014-07-17 17:04:51 -05:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Common Controls class names.
|
|
|
|
const (
|
|
|
|
// x (lowercase) prefix to avoid being caught by the constants generator
|
|
|
|
x_PROGRESS_CLASS = "msctls_progress32"
|
|
|
|
)
|
|
|
|
|
|
|
|
var manifest = []byte(`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
|
|
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
|
|
|
<assemblyIdentity
|
|
|
|
version="1.0.0.0"
|
|
|
|
processorArchitecture="*"
|
|
|
|
name="CompanyName.ProductName.YourApplication"
|
|
|
|
type="win32"
|
|
|
|
/>
|
|
|
|
<description>Your application description here.</description>
|
|
|
|
<dependency>
|
|
|
|
<dependentAssembly>
|
|
|
|
<assemblyIdentity
|
|
|
|
type="win32"
|
|
|
|
name="Microsoft.Windows.Common-Controls"
|
|
|
|
version="6.0.0.0"
|
|
|
|
processorArchitecture="*"
|
|
|
|
publicKeyToken="6595b64144ccf1df"
|
|
|
|
language="*"
|
|
|
|
/>
|
|
|
|
</dependentAssembly>
|
|
|
|
</dependency>
|
|
|
|
</assembly>
|
|
|
|
`)
|