Added a lot of the stuff needed to create a simple window. Not done yet...
This commit is contained in:
parent
35e8a028f5
commit
ecc00bd1f5
16
common.go
16
common.go
|
@ -7,11 +7,25 @@ import (
|
||||||
|
|
||||||
var (
|
var (
|
||||||
user32 = syscall.NewLazyDLL("user32.dll")
|
user32 = syscall.NewLazyDLL("user32.dll")
|
||||||
|
kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||||
)
|
)
|
||||||
|
|
||||||
type HWND uintptr
|
type HANDLE uintptr
|
||||||
|
type HWND HANDLE
|
||||||
|
type HBRUSH HANDLE
|
||||||
|
|
||||||
const (
|
const (
|
||||||
NULL = 0
|
NULL = 0
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type ATOM uint16
|
||||||
|
|
||||||
|
// TODO pull the thanks for these three from the old wingo source
|
||||||
|
type WPARAM uintptr
|
||||||
|
type LPARAM uintptr
|
||||||
|
type LRESULT uintptr
|
||||||
|
|
||||||
|
// microsoft's header files do this
|
||||||
|
func MAKEINTRESOURCE(what uint16) uintptr {
|
||||||
|
return uintptr(what)
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
// 8 february 2014
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
// "syscall"
|
||||||
|
// "unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Predefined cursor resource IDs.
|
||||||
|
const (
|
||||||
|
IDC_APPSTARTING = 32650
|
||||||
|
IDC_ARROW = 32512
|
||||||
|
IDC_CROSS = 32515
|
||||||
|
IDC_HAND = 32649
|
||||||
|
IDC_HELP = 32651
|
||||||
|
IDC_IBEAM = 32513
|
||||||
|
// IDC_ICON = 32641 // [Obsolete for applications marked version 4.0 or later.]
|
||||||
|
IDC_NO = 32648
|
||||||
|
// IDC_SIZE = 32640 // [Obsolete for applications marked version 4.0 or later. Use IDC_SIZEALL.]
|
||||||
|
IDC_SIZEALL = 32646
|
||||||
|
IDC_SIZENESW = 32643
|
||||||
|
IDC_SIZENS = 32645
|
||||||
|
IDC_SIZENWSE = 32642
|
||||||
|
IDC_SIZEWE = 32644
|
||||||
|
IDC_UPARROW = 32516
|
||||||
|
IDC_WAIT = 32514
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
loadCursor = user32.NewProc("LoadCursorW")
|
||||||
|
)
|
||||||
|
|
||||||
|
func LoadCursor_ResourceID(hInstance HANDLE, lpCursorName uint16) (cursor HANDLE, err error) {
|
||||||
|
r1, _, err := loadCursor.Call(
|
||||||
|
uintptr(hInstance),
|
||||||
|
MAKEINTRESOURCE(lpCursorName))
|
||||||
|
if r1 == 0 { // failure
|
||||||
|
return NULL, err
|
||||||
|
}
|
||||||
|
return HANDLE(r1), nil
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
// 8 february 2014
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
// "syscall"
|
||||||
|
// "unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Predefined icon resource IDs.
|
||||||
|
const (
|
||||||
|
IDI_APPLICATION = 32512
|
||||||
|
IDI_ASTERISK = 32516
|
||||||
|
IDI_ERROR = 32513
|
||||||
|
IDI_EXCLAMATION = 32515
|
||||||
|
IDI_HAND = 32513
|
||||||
|
IDI_INFORMATION = 32516
|
||||||
|
IDI_QUESTION = 32514
|
||||||
|
IDI_SHIELD = 32518
|
||||||
|
IDI_WARNING = 32515
|
||||||
|
IDI_WINLOGO = 32517
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
loadIcon = user32.NewProc("LoadIconW")
|
||||||
|
)
|
||||||
|
|
||||||
|
func LoadIcon_ResourceID(hInstance HANDLE, lpIconName uint16) (icon HANDLE, err error) {
|
||||||
|
r1, _, err := loadIcon.Call(
|
||||||
|
uintptr(hInstance),
|
||||||
|
MAKEINTRESOURCE(lpIconName))
|
||||||
|
if r1 == 0 { // failure
|
||||||
|
return NULL, err
|
||||||
|
}
|
||||||
|
return HANDLE(r1), nil
|
||||||
|
}
|
|
@ -0,0 +1,104 @@
|
||||||
|
// 8 february 2014
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Extended window styles.
|
||||||
|
const (
|
||||||
|
WS_EX_ACCEPTFILES = 0x00000010
|
||||||
|
WS_EX_APPWINDOW = 0x00040000
|
||||||
|
WS_EX_CLIENTEDGE = 0x00000200
|
||||||
|
// WS_EX_COMPOSITED = 0x02000000 // [Windows 2000:This style is not supported.]
|
||||||
|
WS_EX_CONTEXTHELP = 0x00000400
|
||||||
|
WS_EX_CONTROLPARENT = 0x00010000
|
||||||
|
WS_EX_DLGMODALFRAME = 0x00000001
|
||||||
|
WS_EX_LAYERED = 0x00080000
|
||||||
|
WS_EX_LAYOUTRTL = 0x00400000
|
||||||
|
WS_EX_LEFT = 0x00000000
|
||||||
|
WS_EX_LEFTSCROLLBAR = 0x00004000
|
||||||
|
WS_EX_LTRREADING = 0x00000000
|
||||||
|
WS_EX_MDICHILD = 0x00000040
|
||||||
|
WS_EX_NOACTIVATE = 0x08000000
|
||||||
|
WS_EX_NOINHERITLAYOUT = 0x00100000
|
||||||
|
WS_EX_NOPARENTNOTIFY = 0x00000004
|
||||||
|
WS_EX_OVERLAPPEDWINDOW = (WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE)
|
||||||
|
WS_EX_PALETTEWINDOW = (WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST)
|
||||||
|
WS_EX_RIGHT = 0x00001000
|
||||||
|
WS_EX_RIGHTSCROLLBAR = 0x00000000
|
||||||
|
WS_EX_RTLREADING = 0x00002000
|
||||||
|
WS_EX_STATICEDGE = 0x00020000
|
||||||
|
WS_EX_TOOLWINDOW = 0x00000080
|
||||||
|
WS_EX_TOPMOST = 0x00000008
|
||||||
|
WS_EX_TRANSPARENT = 0x00000020
|
||||||
|
WS_EX_WINDOWEDGE = 0x00000100
|
||||||
|
)
|
||||||
|
|
||||||
|
// TODO CW_USEDEFAULT
|
||||||
|
|
||||||
|
// GetSysColor values. These can be cast to HBRUSH (after adding 1) for WNDCLASS as well.
|
||||||
|
const (
|
||||||
|
COLOR_3DDKSHADOW = 21
|
||||||
|
COLOR_3DFACE = 15
|
||||||
|
COLOR_3DHIGHLIGHT = 20
|
||||||
|
COLOR_3DHILIGHT = 20
|
||||||
|
COLOR_3DLIGHT = 22
|
||||||
|
COLOR_3DSHADOW = 16
|
||||||
|
COLOR_ACTIVEBORDER = 10
|
||||||
|
COLOR_ACTIVECAPTION = 2
|
||||||
|
COLOR_APPWORKSPACE = 12
|
||||||
|
COLOR_BACKGROUND = 1
|
||||||
|
COLOR_BTNFACE = 15
|
||||||
|
COLOR_BTNHIGHLIGHT = 20
|
||||||
|
COLOR_BTNHILIGHT = 20
|
||||||
|
COLOR_BTNSHADOW = 16
|
||||||
|
COLOR_BTNTEXT = 18
|
||||||
|
COLOR_CAPTIONTEXT = 9
|
||||||
|
COLOR_DESKTOP = 1
|
||||||
|
COLOR_GRADIENTACTIVECAPTION = 27
|
||||||
|
COLOR_GRADIENTINACTIVECAPTION = 28
|
||||||
|
COLOR_GRAYTEXT = 17
|
||||||
|
COLOR_HIGHLIGHT = 13
|
||||||
|
COLOR_HIGHLIGHTTEXT = 14
|
||||||
|
COLOR_HOTLIGHT = 26
|
||||||
|
COLOR_INACTIVEBORDER = 11
|
||||||
|
COLOR_INACTIVECAPTION = 3
|
||||||
|
COLOR_INACTIVECAPTIONTEXT = 19
|
||||||
|
COLOR_INFOBK = 24
|
||||||
|
COLOR_INFOTEXT = 23
|
||||||
|
COLOR_MENU = 4
|
||||||
|
// COLOR_MENUHILIGHT = 29 // [Windows 2000:This value is not supported.]
|
||||||
|
// COLOR_MENUBAR = 30 // [Windows 2000:This value is not supported.]
|
||||||
|
COLOR_MENUTEXT = 7
|
||||||
|
COLOR_SCROLLBAR = 0
|
||||||
|
COLOR_WINDOW = 5
|
||||||
|
COLOR_WINDOWFRAME = 6
|
||||||
|
COLOR_WINDOWTEXT = 8
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
createWindowEx = user32.NewProc("CreateWindowExW")
|
||||||
|
)
|
||||||
|
|
||||||
|
// TODO use lpParam
|
||||||
|
func CreateWindowEx(dwExStyle uint32, lpClassName string, lpWindowName string, dwStyle uint32, x int, y int, nWidth int, nHeight int, hwndParent HWND, hMenu HANDLE, hInstance HANDLE, lpParam interface{}) (hwnd HWND, err error) {
|
||||||
|
r1, _, err := createWindowEx.Call(
|
||||||
|
uintptr(dwExStyle),
|
||||||
|
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpClassName))),
|
||||||
|
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpWindowName))),
|
||||||
|
uintptr(dwStyle),
|
||||||
|
uintptr(x),
|
||||||
|
uintptr(y),
|
||||||
|
uintptr(nWidth),
|
||||||
|
uintptr(nHeight),
|
||||||
|
uintptr(hwndParent),
|
||||||
|
uintptr(hMenu),
|
||||||
|
uintptr(hInstance),
|
||||||
|
uintptr(0))
|
||||||
|
if r1 == 0 { // failure
|
||||||
|
return NULL, err
|
||||||
|
}
|
||||||
|
return HWND(r1), nil
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
// 8 february 2014
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
// "syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// this provides the hInstance and nCmdShow that are normally passed to WinMain()
|
||||||
|
|
||||||
|
const (
|
||||||
|
STARTF_USESHOWWINDOW = 0x00000001
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
getModuleHandle = kernel32.NewProc("GetModuleHandleW")
|
||||||
|
getStartupInfo = kernel32.NewProc("GetStartupInfoW")
|
||||||
|
)
|
||||||
|
|
||||||
|
// TODO is this trick documented in MSDN?
|
||||||
|
func getWinMainhInstance() (hInstance HANDLE, err error) {
|
||||||
|
r1, _, err := getModuleHandle.Call(uintptr(NULL))
|
||||||
|
if r1 == 0 {
|
||||||
|
return NULL, err
|
||||||
|
}
|
||||||
|
return HANDLE(r1), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO this is what MinGW-w64's crt (svn revision xxx) does; is it best? is any of this documented anywhere on MSDN?
|
||||||
|
// TODO I highly doubt Windows API functions ever not fail, so figure out what to do should an error actually occur
|
||||||
|
func getWinMainnCmdShow() (nCmdShow int, err error) {
|
||||||
|
var info struct {
|
||||||
|
cb uint32
|
||||||
|
lpReserved *uint16
|
||||||
|
lpDesktop *uint16
|
||||||
|
lpTitle *uint16
|
||||||
|
dwX uint32
|
||||||
|
dwY uint32
|
||||||
|
dwXSize uint32
|
||||||
|
dwYSzie uint32
|
||||||
|
dwXCountChars uint32
|
||||||
|
dwYCountChars uint32
|
||||||
|
dwFillAttribute uint32
|
||||||
|
dwFlags uint32
|
||||||
|
wShowWindow uint16
|
||||||
|
cbReserved2 uint16
|
||||||
|
lpReserved2 *byte
|
||||||
|
hStdInput HANDLE
|
||||||
|
hStdOutput HANDLE
|
||||||
|
hStdError HANDLE
|
||||||
|
}
|
||||||
|
|
||||||
|
// does not fail according to MSDN
|
||||||
|
getStartupInfo.Call(uintptr(unsafe.Pointer(&info)))
|
||||||
|
if info.dwFlags & STARTF_USESHOWWINDOW != 0 {
|
||||||
|
return int(info.wShowWindow), nil
|
||||||
|
}
|
||||||
|
return SW_SHOWDEFAULT, nil
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
// 8 february 2014
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
type WNDCLASS struct {
|
||||||
|
Style uint32
|
||||||
|
LpfnWndProc WNDPROC
|
||||||
|
CbClsExtra int // TODO exact Go type for C int? MSDN says C int
|
||||||
|
CbWndExtra int // TODO exact Go type for C int? MSDN says C int
|
||||||
|
HInstance HANDLE // actually HINSTANCE
|
||||||
|
HIcon HANDLE // actually HICON
|
||||||
|
HCursor HANDLE // actually HCURSOR
|
||||||
|
HbrBackground HBRUSH
|
||||||
|
LpszMenuName *string // TODO this should probably just be a regular string with "" indicating no name but MSDN doesn't say if that's legal or not
|
||||||
|
LpszClassName string
|
||||||
|
}
|
||||||
|
|
||||||
|
type _WNDCLASSW struct {
|
||||||
|
style uint32
|
||||||
|
lpfnWndProc WNDPROC
|
||||||
|
cbClsExtra int
|
||||||
|
cbWndExtra int
|
||||||
|
hInstance HANDLE
|
||||||
|
hIcon HANDLE
|
||||||
|
hCursor HANDLE
|
||||||
|
hbrBackground HBRUSH
|
||||||
|
lpszMenuName *uint16
|
||||||
|
lpszClassName *uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *WNDCLASS) toNative() *_WNDCLASSW {
|
||||||
|
menuName := (*uint16)(nil)
|
||||||
|
if w.LpszMenuName != nil {
|
||||||
|
menuName = syscall.StringToUTF16Ptr(*w.LpszMenuName)
|
||||||
|
}
|
||||||
|
return &_WNDCLASSW{
|
||||||
|
style: w.Style,
|
||||||
|
lpfnWndProc: w.LpfnWndProc,
|
||||||
|
cbClsExtra: w.CbClsExtra,
|
||||||
|
cbWndExtra: w.CbWndExtra,
|
||||||
|
hInstance: w.HInstance,
|
||||||
|
hIcon: w.HIcon,
|
||||||
|
hCursor: w.HCursor,
|
||||||
|
hbrBackground: w.HbrBackground,
|
||||||
|
lpszMenuName: menuName,
|
||||||
|
lpszClassName: syscall.StringToUTF16Ptr(w.LpszClassName),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
registerClass = user32.NewProc("RegisterClassW")
|
||||||
|
)
|
||||||
|
|
||||||
|
func RegisterClass(lpWndClass *WNDCLASS) (class ATOM, err error) {
|
||||||
|
r1, _, err := registerClass.Call(uintptr(unsafe.Pointer(lpWndClass.toNative())))
|
||||||
|
if r1 == 0 { // failure
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return ATOM(r1), nil
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
// 8 february 2014
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
// "syscall"
|
||||||
|
// "unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TODO error handling
|
||||||
|
type WNDPROC func(hwnd HWND, uMsg uint32, wParam WPARAM, lParam LPARAM) LRESULT
|
||||||
|
|
||||||
|
var (
|
||||||
|
defWindowProc = user32.NewProc("DefWindowProcW")
|
||||||
|
)
|
||||||
|
|
||||||
|
// TODO error handling
|
||||||
|
func DefWindowProc(hwnd HWND, uMsg uint32, wParam WPARAM, lParam LPARAM) LRESULT {
|
||||||
|
r1, _, _ := defWindowProc.Call(
|
||||||
|
uintptr(hwnd),
|
||||||
|
uintptr(uMsg),
|
||||||
|
uintptr(wParam),
|
||||||
|
uintptr(lParam))
|
||||||
|
return LRESULT(r1)
|
||||||
|
}
|
Loading…
Reference in New Issue