draw2d/wingui/wintestgdi/wintestgdi.go

249 lines
6.2 KiB
Go
Raw Normal View History

2012-04-19 14:49:55 +00:00
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
2011-04-27 08:06:14 +00:00
package main
import (
"fmt"
"image"
2012-04-19 14:49:55 +00:00
"image/color"
2015-04-16 09:51:13 +00:00
"io/ioutil"
2012-04-19 14:49:55 +00:00
"os"
2015-04-16 09:51:13 +00:00
"strings"
2012-01-13 09:14:12 +00:00
"syscall"
2011-04-27 08:06:14 +00:00
"time"
2012-01-13 09:14:12 +00:00
"unsafe"
2015-04-16 09:51:13 +00:00
"github.com/llgcode/draw2d/draw2d"
"github.com/llgcode/draw2d/wingui"
"github.com/llgcode/ps"
2011-04-27 08:06:14 +00:00
)
2012-04-19 14:49:55 +00:00
// some help functions
2011-04-27 08:06:14 +00:00
func abortf(format string, a ...interface{}) {
fmt.Fprintf(os.Stdout, format, a...)
os.Exit(1)
}
2012-04-19 14:49:55 +00:00
func abortErrNo(funcname string, err error) {
abortf("%s failed: %d %s\n", funcname, err, err)
2011-04-27 08:06:14 +00:00
}
2012-04-19 14:49:55 +00:00
// global vars
2011-04-27 08:06:14 +00:00
func TestDrawCubicCurve(gc draw2d.GraphicContext) {
2012-04-19 14:49:55 +00:00
// draw a cubic curve
2011-04-27 08:06:14 +00:00
x, y := 25.6, 128.0
x1, y1 := 102.4, 230.4
x2, y2 := 153.6, 25.6
x3, y3 := 230.4, 128.0
2012-04-19 14:49:55 +00:00
gc.SetStrokeColor(color.NRGBA{0, 0, 0, 0xFF})
2011-04-27 08:06:14 +00:00
gc.SetLineWidth(10)
gc.MoveTo(x, y)
gc.CubicCurveTo(x1, y1, x2, y2, x3, y3)
gc.Stroke()
2012-04-19 14:49:55 +00:00
gc.SetStrokeColor(color.NRGBA{0xFF, 0, 0, 0xFF})
2011-04-27 08:06:14 +00:00
gc.SetLineWidth(6)
2012-04-19 14:49:55 +00:00
// draw segment of curve
2011-04-27 08:06:14 +00:00
gc.MoveTo(x, y)
gc.LineTo(x1, y1)
gc.LineTo(x2, y2)
gc.LineTo(x3, y3)
gc.Stroke()
}
2015-04-16 09:51:13 +00:00
func DrawTiger(gc draw2d.GraphicContext) {
2012-04-19 14:49:55 +00:00
if postscriptContent == "" {
src, err := os.OpenFile("../../../ps/samples/tiger.ps", 0, 0)
2012-04-19 14:49:55 +00:00
if err != nil {
fmt.Println("can't find postscript file.")
return
}
defer src.Close()
bytes, err := ioutil.ReadAll(src)
postscriptContent = string(bytes)
}
interpreter := ps.NewInterpreter(gc)
2012-04-19 14:49:55 +00:00
reader := strings.NewReader(postscriptContent)
interpreter.Execute(reader)
}
2011-04-27 08:06:14 +00:00
var (
2015-04-16 09:51:13 +00:00
mh syscall.Handle
hdcWndBuffer syscall.Handle
wndBufferHeader syscall.Handle
2011-04-27 08:06:14 +00:00
wndBuffer wingui.BITMAP
2015-04-16 09:51:13 +00:00
ppvBits *uint8
backBuffer *image.RGBA
2011-04-27 08:06:14 +00:00
postscriptContent string
)
2012-04-19 14:49:55 +00:00
// WinProc called by windows to notify us of all windows events we might be interested in.
func WndProc(hwnd syscall.Handle, msg uint32, wparam, lparam uintptr) (rc uintptr) {
_ = make([]int, 100000)
2011-04-27 08:06:14 +00:00
switch msg {
case wingui.WM_CREATE:
hdc := wingui.GetDC(hwnd)
hdcWndBuffer = wingui.CreateCompatibleDC(hdc)
wndBufferHeader = wingui.CreateCompatibleBitmap(hdc, 600, 800)
wingui.GetObject(wndBufferHeader, unsafe.Sizeof(wndBuffer), uintptr(unsafe.Pointer(&wndBuffer)))
wingui.SelectObject(hdcWndBuffer, wndBufferHeader)
var bmp_header wingui.BITMAPINFOHEADER
bmp_header.Size = uint32(unsafe.Sizeof(bmp_header))
bmp_header.Width = 600
bmp_header.Height = 800
2012-04-19 14:49:55 +00:00
bmp_header.SizeImage = 0 // the api says this must be 0 for BI_RGB images
2011-04-27 08:06:14 +00:00
bmp_header.Compression = wingui.BI_RGB
bmp_header.BitCount = 32
bmp_header.Planes = 1
bmp_header.XPelsPerMeter = 0
bmp_header.YPelsPerMeter = 0
bmp_header.ClrUsed = 0
bmp_header.ClrImportant = 0
2012-04-19 14:49:55 +00:00
//bitmap info
2011-04-27 08:06:14 +00:00
var bmpinfo wingui.BITMAPINFO
bmpinfo.Colors[0].Blue = 0
bmpinfo.Colors[0].Green = 0
bmpinfo.Colors[0].Red = 0
bmpinfo.Colors[0].Reserved = 0
bmpinfo.Header = bmp_header
wndBufferHeader = wingui.CreateDIBSection(hdc, &bmpinfo, wingui.DIB_RGB_COLORS, uintptr(unsafe.Pointer(&ppvBits)), 0, 0)
wingui.GetObject(wndBufferHeader, unsafe.Sizeof(wndBufferHeader), uintptr(unsafe.Pointer(&wndBuffer)))
hdcWndBuffer = wingui.CreateCompatibleDC(hdc)
wingui.SelectObject(hdcWndBuffer, wndBufferHeader)
2012-04-19 14:49:55 +00:00
pixel := (*[600 * 800 * 4]uint8)(unsafe.Pointer(ppvBits))
2011-04-27 08:06:14 +00:00
pixelSlice := pixel[:]
2015-04-16 09:51:13 +00:00
backBuffer = &image.RGBA{pixelSlice, 4 * 600, image.Rect(0, 0, 600, 800)}
2011-04-27 08:06:14 +00:00
fmt.Println("Create windows")
rc = wingui.DefWindowProc(hwnd, msg, wparam, lparam)
case wingui.WM_COMMAND:
2012-04-19 14:49:55 +00:00
switch syscall.Handle(lparam) {
2011-04-27 08:06:14 +00:00
default:
rc = wingui.DefWindowProc(hwnd, msg, wparam, lparam)
}
case wingui.WM_PAINT:
var ps wingui.PAINTSTRUCT
hdc := wingui.BeginPaint(hwnd, &ps)
2012-04-19 14:49:55 +00:00
t := time.Now()
2011-04-27 08:06:14 +00:00
gc := draw2d.NewGraphicContext(backBuffer)
2012-04-19 14:49:55 +00:00
/*gc.SetFillColor(color.RGBA{0xFF, 0xFF, 0xFF, 0xFF})
gc.Clear()*/
2015-04-16 09:51:13 +00:00
for i := 0; i < len(backBuffer.Pix); i += 1 {
2012-04-19 14:49:55 +00:00
backBuffer.Pix[i] = 0xff
}
2011-04-27 08:06:14 +00:00
gc.Save()
2012-04-19 14:49:55 +00:00
//gc.Translate(0, -380)
DrawTiger(gc)
2011-04-27 08:06:14 +00:00
gc.Restore()
// back buf in
2012-04-19 14:49:55 +00:00
var tmp uint8
2015-04-16 09:51:13 +00:00
for i := 0; i < len(backBuffer.Pix); i += 4 {
2012-04-19 14:49:55 +00:00
tmp = backBuffer.Pix[i]
backBuffer.Pix[i] = backBuffer.Pix[i+2]
backBuffer.Pix[i+2] = tmp
}
2011-04-27 08:06:14 +00:00
wingui.BitBlt(hdc, 0, 0, int(wndBuffer.Width), int(wndBuffer.Height), hdcWndBuffer, 0, 0, wingui.SRCCOPY)
wingui.EndPaint(hwnd, &ps)
rc = wingui.DefWindowProc(hwnd, msg, wparam, lparam)
2012-04-19 14:49:55 +00:00
dt := time.Now().Sub(t)
2011-04-27 08:06:14 +00:00
fmt.Printf("Redraw in : %f ms\n", float64(dt)*1e-6)
case wingui.WM_CLOSE:
wingui.DestroyWindow(hwnd)
case wingui.WM_DESTROY:
wingui.PostQuitMessage(0)
default:
rc = wingui.DefWindowProc(hwnd, msg, wparam, lparam)
}
2012-04-19 14:49:55 +00:00
return
2011-04-27 08:06:14 +00:00
}
func rungui() int {
2012-04-19 14:49:55 +00:00
var e error
2011-04-27 08:06:14 +00:00
2012-04-19 14:49:55 +00:00
// GetModuleHandle
2011-04-27 08:06:14 +00:00
mh, e = wingui.GetModuleHandle(nil)
2012-04-19 14:49:55 +00:00
if e != nil {
2011-04-27 08:06:14 +00:00
abortErrNo("GetModuleHandle", e)
}
2012-04-19 14:49:55 +00:00
// Get icon we're going to use.
2011-04-27 08:06:14 +00:00
myicon, e := wingui.LoadIcon(0, wingui.IDI_APPLICATION)
2012-04-19 14:49:55 +00:00
if e != nil {
2011-04-27 08:06:14 +00:00
abortErrNo("LoadIcon", e)
}
2012-04-19 14:49:55 +00:00
// Get cursor we're going to use.
2011-04-27 08:06:14 +00:00
mycursor, e := wingui.LoadCursor(0, wingui.IDC_ARROW)
2012-04-19 14:49:55 +00:00
if e != nil {
2011-04-27 08:06:14 +00:00
abortErrNo("LoadCursor", e)
}
2012-04-19 14:49:55 +00:00
// Create callback
2011-04-27 08:06:14 +00:00
wproc := syscall.NewCallback(WndProc)
2012-04-19 14:49:55 +00:00
// RegisterClassEx
wcname := syscall.StringToUTF16Ptr("myWindowClass")
2011-04-27 08:06:14 +00:00
var wc wingui.Wndclassex
wc.Size = uint32(unsafe.Sizeof(wc))
wc.WndProc = wproc
wc.Instance = mh
wc.Icon = myicon
wc.Cursor = mycursor
2012-04-19 14:49:55 +00:00
wc.Background = wingui.COLOR_BTNFACE + 1
2011-04-27 08:06:14 +00:00
wc.MenuName = nil
wc.ClassName = wcname
wc.IconSm = myicon
2012-04-19 14:49:55 +00:00
if _, e := wingui.RegisterClassEx(&wc); e != nil {
2011-04-27 08:06:14 +00:00
abortErrNo("RegisterClassEx", e)
}
2012-04-19 14:49:55 +00:00
// CreateWindowEx
2011-04-27 08:06:14 +00:00
wh, e := wingui.CreateWindowEx(
wingui.WS_EX_CLIENTEDGE,
wcname,
syscall.StringToUTF16Ptr("My window"),
wingui.WS_OVERLAPPEDWINDOW,
wingui.CW_USEDEFAULT, wingui.CW_USEDEFAULT, 600, 800,
0, 0, mh, 0)
2012-04-19 14:49:55 +00:00
if e != nil {
2011-04-27 08:06:14 +00:00
abortErrNo("CreateWindowEx", e)
}
fmt.Printf("main window handle is %x\n", wh)
2012-04-19 14:49:55 +00:00
// ShowWindow
2011-04-27 08:06:14 +00:00
wingui.ShowWindow(wh, wingui.SW_SHOWDEFAULT)
2012-04-19 14:49:55 +00:00
// UpdateWindow
if e := wingui.UpdateWindow(wh); e != nil {
2011-04-27 08:06:14 +00:00
abortErrNo("UpdateWindow", e)
}
2012-04-19 14:49:55 +00:00
// Process all windows messages until WM_QUIT.
2011-04-27 08:06:14 +00:00
var m wingui.Msg
for {
r, e := wingui.GetMessage(&m, 0, 0, 0)
2012-04-19 14:49:55 +00:00
if e != nil {
2011-04-27 08:06:14 +00:00
abortErrNo("GetMessage", e)
}
if r == 0 {
2012-04-19 14:49:55 +00:00
// WM_QUIT received -> get out
2011-04-27 08:06:14 +00:00
break
}
wingui.TranslateMessage(&m)
wingui.DispatchMessage(&m)
}
return int(m.Wparam)
}
func main() {
rc := rungui()
os.Exit(rc)
}