Added a lot of the stuff needed to create a simple window. Not done yet...

This commit is contained in:
Pietro Gagliardi 2014-02-08 23:51:11 -05:00
parent 35e8a028f5
commit ecc00bd1f5
7 changed files with 342 additions and 1 deletions

View File

@ -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)
}

41
cursors.go Normal file
View File

@ -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
}

35
icons.go Normal file
View File

@ -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
}

104
windows.go Normal file
View File

@ -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
}

59
winmain.go Normal file
View File

@ -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
}

64
wndclass.go Normal file
View File

@ -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
}

24
wndproc.go Normal file
View File

@ -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)
}