func (this *Canvas) DrawRect(rect *Rect, pen *Pen, brush *Brush) { w32Rect := rect.GetW32Rect() previousPen := w32.SelectObject(this.hdc, w32.HGDIOBJ(pen.GetHPEN())) defer w32.SelectObject(this.hdc, previousPen) previousBrush := w32.SelectObject(this.hdc, w32.HGDIOBJ(brush.GetHBRUSH())) defer w32.SelectObject(this.hdc, previousBrush) w32.Rectangle(this.hdc, int(w32Rect.Left), int(w32Rect.Top), int(w32Rect.Right), int(w32Rect.Bottom)) }
func (this *Canvas) DrawBitmap(bmp *Bitmap, x, y int) { cdc := w32.CreateCompatibleDC(0) defer w32.DeleteDC(cdc) hbmpOld := w32.SelectObject(cdc, w32.HGDIOBJ(bmp.GetHBITMAP())) defer w32.SelectObject(cdc, w32.HGDIOBJ(hbmpOld)) w, h := bmp.Size() w32.BitBlt(this.hdc, x, y, w, h, cdc, 0, 0, w32.SRCCOPY) }
// Refer win32 DrawText document for uFormat. func (this *Canvas) DrawText(text string, rect *Rect, format uint, font *Font, textColor Color) { previousFont := w32.SelectObject(this.hdc, w32.HGDIOBJ(font.GetHFONT())) defer w32.SelectObject(this.hdc, w32.HGDIOBJ(previousFont)) previousBkMode := w32.SetBkMode(this.hdc, w32.TRANSPARENT) defer w32.SetBkMode(this.hdc, previousBkMode) previousTextColor := w32.SetTextColor(this.hdc, w32.COLORREF(textColor)) defer w32.SetTextColor(this.hdc, previousTextColor) w32.DrawText(this.hdc, text, len(text), rect.GetW32Rect(), format) }
func (this *Canvas) DrawStretchedBitmap(bmp *Bitmap, rect *Rect) { cdc := w32.CreateCompatibleDC(0) defer w32.DeleteDC(cdc) hbmpOld := w32.SelectObject(cdc, w32.HGDIOBJ(bmp.GetHBITMAP())) defer w32.SelectObject(cdc, w32.HGDIOBJ(hbmpOld)) w, h := bmp.Size() rc := rect.GetW32Rect() w32.StretchBlt(this.hdc, int(rc.Left), int(rc.Top), int(rc.Right), int(rc.Bottom), cdc, 0, 0, w, h, w32.SRCCOPY) }
// SetColor sets the drawing color of the window. func (win *window) SetColor(p sparta.Property, c color.RGBA) { if (p != sparta.Background) && (p != sparta.Foreground) { return } if win.dc == 0 { return } b := getBrush(c) if p == sparta.Foreground { w32.SelectObject(win.dc, w32.HGDIOBJ(b.brush)) w32.SelectObject(win.dc, w32.HGDIOBJ(b.pen)) w32.SetTextColor(win.dc, b.color) win.curr = b } else { w32.SetBkColor(win.dc, b.color) } }
// Draw sets the drawing mode of the window. func (win *window) Draw(mode bool) { if win.isPaint { return } if mode { if win.dc != 0 { return } win.dc = w32.GetDC(win.id) w32.SetBkMode(win.dc, w32.TRANSPARENT) w32.SetBkColor(win.dc, win.back.color) w32.SelectObject(win.dc, w32.HGDIOBJ(win.fore.brush)) w32.SelectObject(win.dc, w32.HGDIOBJ(win.fore.pen)) w32.SelectObject(win.dc, w32.HGDIOBJ(winFont)) w32.SetTextColor(win.dc, win.fore.color) win.curr = win.fore return } if win.dc == 0 { return } w32.ReleaseDC(win.id, win.dc) win.dc = 0 }
// WinEvent proccess a win32 event. func winEvent(id w32.HWND, event uint32, wParam, lParam uintptr) uintptr { w, ok := widgetTable[id] if !ok { return w32.DefWindowProc(id, event, wParam, lParam) } switch event { case w32.WM_CHAR: r := utf16.Decode([]uint16{uint16(loWord(uint32(wParam)))}) if len(r) == 0 { break } key := r[0] if key == 0 { break } if (key == '\b') || (key == '\t') || (key == '\n') || (key == '\r') { break } ev := sparta.KeyEvent{ Key: sparta.Key(key), State: getState(), } x, y, _ := w32.GetCursorPos() ev.Loc.X, ev.Loc.Y, _ = w32.ScreenToClient(id, x, y) w.OnEvent(ev) case w32.WM_CLOSE: if w.Property(sparta.Parent) != nil { break } w.OnEvent(sparta.CloseEvent{}) case w32.WM_KEYDOWN: key := getKeyValue(wParam) if key == 0 { break } if (key & sparta.KeyNoChar) == 0 { break } ev := sparta.KeyEvent{ Key: key, State: getState(), } x, y, _ := w32.GetCursorPos() ev.Loc.X, ev.Loc.Y, _ = w32.ScreenToClient(id, x, y) w.OnEvent(ev) case w32.WM_KEYUP: key := getKeyValue(wParam) if key == 0 { break } ev := sparta.KeyEvent{ Key: -key, State: getState(), } x, y, _ := w32.GetCursorPos() ev.Loc.X, ev.Loc.Y, _ = w32.ScreenToClient(id, x, y) w.OnEvent(ev) case w32.WM_LBUTTONDOWN, w32.WM_RBUTTONDOWN, w32.WM_MBUTTONDOWN: ev := sparta.MouseEvent{ Button: getButton(event), State: getState(), Loc: image.Pt(getXLParam(lParam), getYLParam(lParam)), } w.OnEvent(ev) w.Focus() case w32.WM_LBUTTONUP, w32.WM_RBUTTONUP, w32.WM_MBUTTONUP: ev := sparta.MouseEvent{ Button: -getButton(event), State: getState(), Loc: image.Pt(getXLParam(lParam), getYLParam(lParam)), } w.OnEvent(ev) case w32.WM_MOUSEMOVE: ev := sparta.MouseEvent{ Loc: image.Pt(getXLParam(lParam), getYLParam(lParam)), } w.OnEvent(ev) case w32.WM_MOUSEWHEEL: ev := sparta.MouseEvent{ Button: sparta.MouseWheel, } if getWheelDeltaWParam(wParam) < 0 { ev.Button = -sparta.MouseWheel } ev.Loc.X, ev.Loc.Y, _ = w32.ScreenToClient(id, getXLParam(lParam), getYLParam(lParam)) w = propagateWheel(w, ev.Loc) w.OnEvent(ev) case w32.WM_MOVE: win := w.Window().(*window) win.pos.X, win.pos.Y = int(loWord(uint32(lParam))), int(hiWord(uint32(lParam))) case w32.WM_PAINT: win := w.Window().(*window) ps := &w32.PAINTSTRUCT{} win.dc = w32.BeginPaint(id, ps) win.isPaint = true w32.SetBkMode(win.dc, w32.TRANSPARENT) w32.SetBkColor(win.dc, win.back.color) // "clear" the area w32.SelectObject(win.dc, w32.HGDIOBJ(win.back.brush)) w32.SelectObject(win.dc, w32.HGDIOBJ(win.back.pen)) w32.Rectangle(win.dc, int(ps.RcPaint.Left), int(ps.RcPaint.Top), int(ps.RcPaint.Right), int(ps.RcPaint.Bottom)) w32.SelectObject(win.dc, w32.HGDIOBJ(win.fore.brush)) w32.SelectObject(win.dc, w32.HGDIOBJ(win.fore.pen)) w32.SelectObject(win.dc, w32.HGDIOBJ(winFont)) w32.SetTextColor(win.dc, win.fore.color) win.curr = win.fore ev := sparta.ExposeEvent{image.Rect(int(ps.RcPaint.Left), int(ps.RcPaint.Top), int(ps.RcPaint.Right), int(ps.RcPaint.Bottom))} w.OnEvent(ev) w32.EndPaint(id, ps) win.isPaint = false win.dc = 0 case w32.WM_SIZE: win := w.Window().(*window) ev := sparta.ConfigureEvent{image.Rect(win.pos.X, win.pos.Y, win.pos.X+int(loWord(uint32(lParam))), win.pos.Y+int(hiWord(uint32(lParam))))} w.OnEvent(ev) case w32.WM_USER: src, ok := widgetTable[w32.HWND(wParam)] if !ok { src = nil } ev := sparta.CommandEvent{ Source: src, Value: int(int32(lParam)), } w.OnEvent(ev) default: return w32.DefWindowProc(id, event, wParam, lParam) } return 0 }
func CaptureRect(rect image.Rectangle) (*image.RGBA, error) { hDC := w32.GetDC(0) if hDC == 0 { return nil, fmt.Errorf("Could not Get primary display err:%d.\n", w32.GetLastError()) } defer w32.ReleaseDC(0, hDC) m_hDC := w32.CreateCompatibleDC(hDC) if m_hDC == 0 { return nil, fmt.Errorf("Could not Create Compatible DC err:%d.\n", w32.GetLastError()) } defer w32.DeleteDC(m_hDC) x, y := rect.Dx(), rect.Dy() bt := w32.BITMAPINFO{} bt.BmiHeader.BiSize = uint(reflect.TypeOf(bt.BmiHeader).Size()) bt.BmiHeader.BiWidth = x bt.BmiHeader.BiHeight = -y bt.BmiHeader.BiPlanes = 1 bt.BmiHeader.BiBitCount = 32 bt.BmiHeader.BiCompression = w32.BI_RGB ptr := unsafe.Pointer(uintptr(0)) m_hBmp := w32.CreateDIBSection(m_hDC, &bt, w32.DIB_RGB_COLORS, &ptr, 0, 0) if m_hBmp == 0 { return nil, fmt.Errorf("Could not Create DIB Section err:%d.\n", w32.GetLastError()) } if m_hBmp == w32.InvalidParameter { return nil, fmt.Errorf("One or more of the input parameters is invalid while calling CreateDIBSection.\n") } defer w32.DeleteObject(w32.HGDIOBJ(m_hBmp)) obj := w32.SelectObject(m_hDC, w32.HGDIOBJ(m_hBmp)) if obj == 0 { return nil, fmt.Errorf("error occurred and the selected object is not a region err:%d.\n", w32.GetLastError()) } if obj == 0xffffffff { //GDI_ERROR return nil, fmt.Errorf("GDI_ERROR while calling SelectObject err:%d.\n", w32.GetLastError()) } defer w32.DeleteObject(obj) //Note:BitBlt contains bad error handling, we will just assume it works and if it doesn't it will panic :x w32.BitBlt(m_hDC, 0, 0, x, y, hDC, rect.Min.X, rect.Min.Y, w32.SRCCOPY) var slice []byte hdrp := (*reflect.SliceHeader)(unsafe.Pointer(&slice)) hdrp.Data = uintptr(ptr) hdrp.Len = x * y * 4 hdrp.Cap = x * y * 4 imageBytes := make([]byte, len(slice)) for i := 0; i < len(imageBytes); i += 4 { imageBytes[i], imageBytes[i+2], imageBytes[i+1], imageBytes[i+3] = slice[i+2], slice[i], slice[i+1], slice[i+3] } img := &image.RGBA{imageBytes, 4 * x, image.Rect(0, 0, x, y)} return img, nil }