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 (
|
||||
user32 = syscall.NewLazyDLL("user32.dll")
|
||||
kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||
)
|
||||
|
||||
type HWND uintptr
|
||||
type HANDLE uintptr
|
||||
type HWND HANDLE
|
||||
type HBRUSH HANDLE
|
||||
|
||||
const (
|
||||
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