// Sorts 'count' child elements starting at index 'start'. Uses comparator to define the // order. Comparator should return -1, or 0, or 1 to indicate less, equal or greater func (e *Element) SortChildrenRange(start, count uint, comparator func(*Element, *Element) int) { end := start + count arg := uintptr(unsafe.Pointer(&comparator)) if ret := C.HTMLayoutSortElements(e.handle, C.UINT(start), C.UINT(end), (*[0]byte)(unsafe.Pointer(goElementComparator)), C.LPVOID(arg)); ret != HLDOM_OK { domPanic(ret, "Failed to sort elements") } }
func (this *Hotkeys) AddHotkey(ModKey, Vk uint, callback Callback) int { hotkey := new(Hotkey) hotkey.ModKey = C.UINT(ModKey) hotkey.Vk = C.UINT(Vk) hotkey.Callback = callback this.hotkeys[this.id] = hotkey oldId := this.id this.id++ return int(oldId) }
// Sets the specified flag to "on" or "off" according to the value of the provided boolean func (e *Element) SetState(flag uint32, on bool) { addBits := uint32(0) clearBits := uint32(0) if on { addBits = flag } else { clearBits = flag } shouldUpdate := C.BOOL(1) if ret := C.HTMLayoutSetElementState(e.handle, C.UINT(addBits), C.UINT(clearBits), shouldUpdate); ret != HLDOM_OK { domPanic(ret, "Failed to set element state flag") } }
func (e *Element) Child(index uint) *Element { var child C.HELEMENT if ret := C.HTMLayoutGetNthChild(e.handle, C.UINT(index), &child); ret != HLDOM_OK { domPanic(ret, "Failed to get child at index: ", index) } return NewElementFromHandle(HELEMENT(child)) }
// Let's find a suitable pixel format -- first try with antialiasing func BestwglChoosePixelFormatARB(procs *C.wglProcs, hdc C.HDC, bitsPerPixel uint, settings *ContextSettings) C.int { if settings.AntialiasingLevel <= 0 { return 0 } if procs.p_wglChoosePixelFormatARB == nil { return 0 } AttribIList := [...]C.int{ C.WGL_DRAW_TO_WINDOW_ARB, C.GL_TRUE, C.WGL_SUPPORT_OPENGL_ARB, C.GL_TRUE, C.WGL_ACCELERATION_ARB, C.WGL_FULL_ACCELERATION_ARB, C.WGL_DOUBLE_BUFFER_ARB, C.GL_TRUE, C.WGL_SAMPLE_BUFFERS_ARB, C.GL_TRUE, // turn on antialiasing C.WGL_SAMPLES_ARB, C.int(settings.AntialiasingLevel), 0, 0, } AttribFList := []C.FLOAT{0, 0} // Let's check how many formats are supporting our requirements const formats_size = 128 var formats [formats_size]C.int var nbFormats C.UINT for settings.AntialiasingLevel > 0 { if C.__wglChoosePixelFormatARB(procs, hdc, &AttribIList[0], &AttribFList[0], formats_size, &formats[0], &nbFormats) == C.TRUE && nbFormats > 0 { break } nbFormats = 0 // reset this // Decrease the antialiasing level until we find a valid one settings.AntialiasingLevel-- AttribIList[11]-- } bestScore := uint(1<<32 - 1) var bestFormat C.int for i := C.UINT(0); bestScore != 0 && i < nbFormats; i++ { // Get the current format's attributes attributes := C.PIXELFORMATDESCRIPTOR{ nSize: C.PIXELFORMATDESCRIPTOR_size, nVersion: 1, } if C.__DescribePixelFormat(hdc, formats[i], C.PIXELFORMATDESCRIPTOR_size, &attributes) == 0 { return 0 } // Evaluate the current configuration color := uint(attributes.cRedBits + attributes.cGreenBits + attributes.cBlueBits + attributes.cAlphaBits) score := EvaluateFormat(bitsPerPixel, *settings, color, uint(attributes.cDepthBits), uint(attributes.cStencilBits), settings.AntialiasingLevel) // Keep it if it's better than the current best if score < bestScore { bestScore = score bestFormat = formats[i] } } return bestFormat }
// For delivering programmatic events to this element. // Returns true if the event was handled, false otherwise func (e *Element) SendEvent(eventCode uint, source *Element, reason uint32) bool { var handled C.BOOL = 0 if ret := C.HTMLayoutSendEvent(e.handle, C.UINT(eventCode), source.handle, C.UINT_PTR(reason), &handled); ret != HLDOM_OK { domPanic(ret, "Failed to send event") } return handled != 0 }
func (e *Element) getRect(rectTypeFlags uint32) (left, top, right, bottom int) { r := Rect{} if ret := C.HTMLayoutGetElementLocation(e.handle, (C.LPRECT)(unsafe.Pointer(&r)), C.UINT(rectTypeFlags)); ret != HLDOM_OK { domPanic(ret, "Failed to get element rect") } return int(r.Left), int(r.Top), int(r.Right), int(r.Bottom) }
func virtualKeyCodeToSF(vkey C.WPARAM, flags C.LPARAM) Key { if key, ok := keyboard_vkeys_map[C.int(vkey)]; ok { return key } switch vkey { // Check the scancode to distinguish between left and right shift case C.VK_SHIFT: scancode := C.UINT((flags & (0xFF << 16)) >> 16) if scancode == lShift { return KeyLShift } return KeyRShift // Check the "extended" flag to distinguish between left and right alt case C.VK_MENU: if C.__HIWORD(C.DWORD(flags))&C.KF_EXTENDED != 0 { return KeyRAlt } return KeyLAlt // Check the "extended" flag to distinguish between left and right control case C.VK_CONTROL: if C.__HIWORD(C.DWORD(flags))&C.KF_EXTENDED != 0 { return KeyRControl } return KeyLControl } return KeyUnknown }
func (e *Element) AttrByIndex(index int) (string, string) { szValue := (*C.WCHAR)(nil) szName := (*C.CHAR)(nil) if ret := C.HTMLayoutGetNthAttribute(e.handle, C.UINT(index), (*C.LPCSTR)(&szName), (*C.LPCWSTR)(&szValue)); ret != HLDOM_OK { domPanic(ret, fmt.Sprintf("Failed to get attribute by index: %u", index)) } return C.GoString((*C.char)(szName)), utf16ToString((*uint16)(szValue)) }
// Load html contents into window func LoadHtml(hwnd uint32, data []byte, baseUrl string) error { if len(data) > 0 { if ok := C.HTMLayoutLoadHtmlEx(C.HWND(C.HANDLE(uintptr(hwnd))), (*C.BYTE)(&data[0]), C.UINT(len(data)), (*C.WCHAR)(stringToUtf16Ptr(baseUrl))); ok == 0 { return errors.New("HTMLayoutLoadHtmlEx failed") } } return nil }
func ProcND(hwnd win.HWND, msg uint, wParam uintptr, lParam uintptr) (ret int, handled bool) { var bHandled C.BOOL // ret = uintptr(syssciterProcND(HWND(hwnd), msg, wParam, lParam, &bHandled)) ret = int(C.SciterProcND(C.HWINDOW(unsafe.Pointer(hwnd)), C.UINT(msg), C.WPARAM(wParam), C.LPARAM(lParam), &bHandled)) if bHandled == 0 { handled = false } else { handled = true } return }
// Searches up the parent chain to find the first element that matches the given selector. // Includes the element in the search. Depth indicates how far the search should progress. // Depth = 1 means only consider this element. Depth = 0 means search all the way up to the // root. Any other positive value of depth limits the length of the search. func (e *Element) SelectParentLimit(selector string, depth int) *Element { szSelector := C.CString(selector) defer C.free(unsafe.Pointer(szSelector)) var parent C.HELEMENT if ret := C.HTMLayoutSelectParent(e.handle, (*C.CHAR)(szSelector), C.UINT(depth), &parent); ret != HLDOM_OK { domPanic(ret, "Failed to select parent dom elements, selector: '", selector, "'") } if parent != nil { return NewElementFromHandle(HELEMENT(parent)) } return nil }
// rect is the display area func CreateWindow(createFlags WindowCreationFlag, rect *Rect, delegate uintptr, delegateParam uintptr, parent C.HWINDOW) C.HWINDOW { // set default size if rect == nil { rect = DefaultRect } // create window hwnd := C.SciterCreateWindow( C.UINT(createFlags), (*C.RECT)(unsafe.Pointer(rect)), nil, (C.LPVOID)(delegateParam), parent) // in case of NULL if int(uintptr(unsafe.Pointer(hwnd))) == 0 { return BAD_HWINDOW } return hwnd }
func (e *Element) Update(restyle, restyleDeep, remeasure, remeasureDeep, render bool) { var flags uint32 if restyle { if restyleDeep { flags |= RESET_STYLE_DEEP } else { flags |= RESET_STYLE_THIS } } if remeasure { if remeasureDeep { flags |= MEASURE_DEEP } else { flags |= MEASURE_INPLACE } } if render { flags |= REDRAW_NOW } if ret := C.HTMLayoutUpdateElementEx(e.handle, C.UINT(flags)); ret != HLDOM_OK { domPanic(ret, "Failed to update element") } }
func (e *Element) AppendChild(child *Element) { count := e.ChildCount() if ret := C.HTMLayoutInsertElement(child.handle, e.handle, C.UINT(count)); ret != HLDOM_OK { domPanic(ret, "Failed to append child element") } }
func (e *Element) AttachHandler(handler *EventHandler) { attachedHandlers, hasAttachments := eventHandlers[e.handle] if hasAttachments { if _, exists := attachedHandlers[handler]; exists { // This exact event handler is already attached to this exact element. return } } // Don't let the caller disable ATTACH/DETACH events, otherwise we // won't know when to throw out our event handler object subscription := handler.Subscription() subscription &= ^uint32(DISABLE_INITIALIZATION & 0xffffffff) tag := uintptr(unsafe.Pointer(handler)) if subscription == HANDLE_ALL { if ret := C.HTMLayoutAttachEventHandler(e.handle, (*[0]byte)(unsafe.Pointer(goElementProc)), C.LPVOID(tag)); ret != HLDOM_OK { domPanic(ret, "Failed to attach event handler to element") } } else { if ret := C.HTMLayoutAttachEventHandlerEx(e.handle, (*[0]byte)(unsafe.Pointer(goElementProc)), C.LPVOID(tag), C.UINT(subscription)); ret != HLDOM_OK { domPanic(ret, "Failed to attach event handler to element") } } if !hasAttachments { eventHandlers[e.handle] = make(map[*EventHandler]bool, 8) } eventHandlers[e.handle][handler] = true }
// Main htmlayout wndproc func ProcNoDefault(hwnd, msg uint32, wparam, lparam uintptr) (uintptr, bool) { var handled C.BOOL = 0 var result C.LRESULT = C.HTMLayoutProcND(C.HWND(C.HANDLE(uintptr(hwnd))), C.UINT(msg), C.WPARAM(wparam), C.LPARAM(lparam), &handled) return uintptr(result), handled != 0 }
// Replaces the whole set of state flags with the specified value func (e *Element) SetStateFlags(flags uint32) { shouldUpdate := C.BOOL(1) if ret := C.HTMLayoutSetElementState(e.handle, C.UINT(flags), C.UINT(^flags), shouldUpdate); ret != HLDOM_OK { domPanic(ret, "Failed to set element state flags") } }
func (e *Element) SetText(text string) { szText := C.CString(text) defer C.free(unsafe.Pointer(szText)) if ret := C.HTMLayoutSetElementInnerText(e.handle, (*C.BYTE)(unsafe.Pointer(szText)), C.UINT(len(text))); ret != HLDOM_OK { domPanic(ret, "Failed to replace element's text") } }
func (e *Element) SetTimer(ms int) { if ret := C.HTMLayoutSetTimer(e.handle, C.UINT(ms)); ret != HLDOM_OK { domPanic(ret, "Failed to set timer") } }
// This is the same as AttachHandler, except that behaviors are singleton instances stored // in a master map. They may be shared among many elements since they have no state. // The only reason we keep a separate set of the behaviors is so that the event handler // dispatch method can tell if an event handler is a behavior or a regular handler. func (e *Element) attachBehavior(handler *EventHandler) { tag := uintptr(unsafe.Pointer(handler)) if subscription := handler.Subscription(); subscription == HANDLE_ALL { if ret := C.HTMLayoutAttachEventHandler(e.handle, (*[0]byte)(unsafe.Pointer(goElementProc)), C.LPVOID(tag)); ret != HLDOM_OK { domPanic(ret, "Failed to attach event handler to element") } } else { if ret := C.HTMLayoutAttachEventHandlerEx(e.handle, (*[0]byte)(unsafe.Pointer(goElementProc)), C.LPVOID(tag), C.UINT(subscription)); ret != HLDOM_OK { domPanic(ret, "Failed to attach event handler to element") } } }
func (s *ScnLoadData) SetData(data []byte) { s.outData = (C.LPCBYTE)(unsafe.Pointer((&data[0]))) s.outDataSize = C.UINT(len(data)) }
func AttachWindowEventHandler(hwnd uint32, handler *EventHandler) { key := uintptr(hwnd) tag := uintptr(unsafe.Pointer(handler)) if _, exists := windowEventHandlers[hwnd]; exists { if ret := C.HTMLayoutWindowDetachEventHandler(C.HWND(C.HANDLE(key)), (*[0]byte)(unsafe.Pointer(goElementProc)), C.LPVOID(tag)); ret != HLDOM_OK { domPanic(ret, "Failed to detach event handler from window before adding the new one") } } // Overwrite if it exists windowEventHandlers[hwnd] = handler // Don't let the caller disable ATTACH/DETACH events, otherwise we // won't know when to throw out our event handler object subscription := handler.Subscription() subscription &= ^uint32(DISABLE_INITIALIZATION & 0xffffffff) if ret := C.HTMLayoutWindowAttachEventHandler(C.HWND(C.HANDLE(key)), (*[0]byte)(unsafe.Pointer(goElementProc)), C.LPVOID(tag), C.UINT(subscription)); ret != HLDOM_OK { domPanic(ret, "Failed to attach event handler to window") } }
// For asynchronously delivering programmatic events to this element. func (e *Element) PostEvent(eventCode uint, source *Element, reason uint32) { if ret := C.HTMLayoutPostEvent(e.handle, C.UINT(eventCode), source.handle, C.UINT(reason)); ret != HLDOM_OK { domPanic(ret, "Failed to post event") } }
func MessageBox(text string, caption string, style int) int { cText := C.CString(text) cCaption := C.CString(caption) result := C.MessageBox(nil, (*C.CHAR)(unsafe.Pointer(cText)), (*C.CHAR)(unsafe.Pointer(cCaption)), C.UINT(style)) C.free(unsafe.Pointer(cText)) C.free(unsafe.Pointer(cCaption)) return int(result) }
func (e *Element) InsertChild(child *Element, index uint) { if ret := C.HTMLayoutInsertElement(child.handle, e.handle, C.UINT(index)); ret != HLDOM_OK { domPanic(ret, "Failed to insert child element at index: ", index) } }