mirror of
https://gitee.com/energye/energy.git
synced 2024-12-04 04:38:21 +08:00
U: frameless for windows LCL, Border style reflects,
R: function's, FramelessForLine, Frameless
This commit is contained in:
parent
f2e33dddab
commit
00fdcd0a8a
@ -161,8 +161,6 @@ type ILCLBrowserWindow interface {
|
|||||||
EnableHelp() //启用标题栏帮助
|
EnableHelp() //启用标题栏帮助
|
||||||
NewTray() ITray //创建LCL的系统托盘
|
NewTray() ITray //创建LCL的系统托盘
|
||||||
SetRoundRectRgn(rgn int) //窗口无边框时圆角设置
|
SetRoundRectRgn(rgn int) //窗口无边框时圆角设置
|
||||||
FramelessForLine() //无边框四边一条细线样式
|
|
||||||
Frameless() //无边框
|
|
||||||
ChromiumCreate(config *TCefChromiumConfig, defaultUrl string) //chromium实例为空时创建 chromium
|
ChromiumCreate(config *TCefChromiumConfig, defaultUrl string) //chromium实例为空时创建 chromium
|
||||||
BroderDirectionAdjustments() et.BroderDirectionAdjustments //返回可以调整窗口大小的边框方向, 默认所有方向
|
BroderDirectionAdjustments() et.BroderDirectionAdjustments //返回可以调整窗口大小的边框方向, 默认所有方向
|
||||||
SetBroderDirectionAdjustments(val et.BroderDirectionAdjustments) // 设置可以调整窗口大小的边框方向, 默认所有方向
|
SetBroderDirectionAdjustments(val et.BroderDirectionAdjustments) // 设置可以调整窗口大小的边框方向, 默认所有方向
|
||||||
|
20
cef/browser_window_hook_other.go
Normal file
20
cef/browser_window_hook_other.go
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
//----------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright © yanghy. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// Licensed under Apache License Version 2.0, January 2004
|
||||||
|
//
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
//----------------------------------------
|
||||||
|
|
||||||
|
//go:build !windows
|
||||||
|
// +build !windows
|
||||||
|
|
||||||
|
package cef
|
||||||
|
|
||||||
|
func (m *LCLBrowserWindow) _HookWndProcMessage() {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *LCLBrowserWindow) _RestoreWndProc() {
|
||||||
|
}
|
74
cef/browser_window_hook_windows.go
Normal file
74
cef/browser_window_hook_windows.go
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
//----------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright © yanghy. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// Licensed under Apache License Version 2.0, January 2004
|
||||||
|
//
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
//----------------------------------------
|
||||||
|
|
||||||
|
//go:build windows
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
package cef
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/energye/golcl/lcl/types"
|
||||||
|
"github.com/energye/golcl/lcl/types/messages"
|
||||||
|
"github.com/energye/golcl/lcl/win"
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
dwmAPI = syscall.NewLazyDLL("dwmapi.dll")
|
||||||
|
_DwmExtendFrameIntoClientArea = dwmAPI.NewProc("DwmExtendFrameIntoClientArea")
|
||||||
|
)
|
||||||
|
|
||||||
|
type margins struct {
|
||||||
|
CxLeftWidth, CxRightWidth, CyTopHeight, CyBottomHeight int32
|
||||||
|
}
|
||||||
|
|
||||||
|
func extendFrameIntoClientArea(hwnd uintptr, margins margins) {
|
||||||
|
_, _, _ = _DwmExtendFrameIntoClientArea.Call(hwnd, uintptr(unsafe.Pointer(&margins)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *LCLBrowserWindow) wndProc(hwnd types.HWND, message uint32, wParam, lParam uintptr) uintptr {
|
||||||
|
if m.WindowProperty().EnableHideCaption {
|
||||||
|
switch message {
|
||||||
|
case messages.WM_ACTIVATE:
|
||||||
|
// If we want to have a frameless window but with the default frame decorations, extend the DWM client area.
|
||||||
|
// This Option is not affected by returning 0 in WM_NCCALCSIZE.
|
||||||
|
// As a result we have hidden the titlebar but still have the default window frame styling.
|
||||||
|
// See: https://docs.microsoft.com/en-us/windows/win32/api/dwmapi/nf-dwmapi-dwmextendframeintoclientarea#remarks
|
||||||
|
extendFrameIntoClientArea(m.Handle(), margins{CxLeftWidth: 1, CxRightWidth: 1, CyTopHeight: 1, CyBottomHeight: 1})
|
||||||
|
case messages.WM_NCCALCSIZE:
|
||||||
|
// Disable the standard frame by allowing the client area to take the full
|
||||||
|
// window size.
|
||||||
|
// See: https://docs.microsoft.com/en-us/windows/win32/winmsg/wm-nccalcsize#remarks
|
||||||
|
// This hides the titlebar and also disables the resizing from user interaction because the standard frame is not
|
||||||
|
// shown. We still need the WS_THICKFRAME style to enable resizing from the frontend.
|
||||||
|
if wParam != 0 {
|
||||||
|
//cycaption := win.GetSystemMetrics(4)
|
||||||
|
//rect := (*types.TRect)(unsafe.Pointer(lParam))
|
||||||
|
//rect.Bottom += -1
|
||||||
|
//rect.Right += -1
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return win.CallWindowProc(m.oldWndPrc, hwnd, message, wParam, lParam)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *LCLBrowserWindow) _HookWndProcMessage() {
|
||||||
|
wndProcCallback := syscall.NewCallback(m.wndProc)
|
||||||
|
m.oldWndPrc = win.SetWindowLongPtr(m.Handle(), win.GWL_WNDPROC, wndProcCallback)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *LCLBrowserWindow) _RestoreWndProc() {
|
||||||
|
if m.oldWndPrc != 0 {
|
||||||
|
win.SetWindowLongPtr(m.Handle(), win.GWL_WNDPROC, m.oldWndPrc)
|
||||||
|
m.oldWndPrc = 0
|
||||||
|
}
|
||||||
|
}
|
@ -38,21 +38,22 @@ import (
|
|||||||
//
|
//
|
||||||
// 该窗口使用CEF和LCL组件实现,CEF<=1.106.xx版本 在windows、MacOSX可正常使用, Linux无法输入中文, CEF>=2.107.xx版本linux强制使用 ViewsFrameworkBrowserWindow 窗口组件
|
// 该窗口使用CEF和LCL组件实现,CEF<=1.106.xx版本 在windows、MacOSX可正常使用, Linux无法输入中文, CEF>=2.107.xx版本linux强制使用 ViewsFrameworkBrowserWindow 窗口组件
|
||||||
type LCLBrowserWindow struct {
|
type LCLBrowserWindow struct {
|
||||||
*lcl.TForm //window form
|
*lcl.TForm //window form
|
||||||
isFormCreate bool //是否创建完成 WindowForm
|
isFormCreate bool //是否创建完成 WindowForm
|
||||||
chromiumBrowser ICEFChromiumBrowser //浏览器
|
chromiumBrowser ICEFChromiumBrowser //浏览器
|
||||||
windowProperty *WindowProperty //窗口属性
|
windowProperty *WindowProperty //窗口属性
|
||||||
windowId int32 //窗口ID
|
windowId int32 //窗口ID
|
||||||
windowType consts.WINDOW_TYPE //窗口类型
|
windowType consts.WINDOW_TYPE //窗口类型
|
||||||
isClosing bool //
|
isClosing bool //
|
||||||
canClose bool //
|
canClose bool //
|
||||||
onResize []TNotifyEvent //扩展事件 向后链试循环调用
|
onResize []TNotifyEvent //扩展事件 向后链试循环调用
|
||||||
windowResize TNotifyEvent //扩展事件
|
windowResize TNotifyEvent //扩展事件
|
||||||
onActivate TNotifyEvent //扩展事件
|
onActivate TNotifyEvent //扩展事件
|
||||||
onShow []TNotifyEvent //扩展事件 向后链试循环调用
|
onShow []TNotifyEvent //扩展事件 向后链试循环调用
|
||||||
onClose []TCloseEvent //扩展事件 向后链试循环调用
|
onClose []TCloseEvent //扩展事件 向后链试循环调用
|
||||||
onCloseQuery TCloseQueryEvent //扩展事件
|
onCloseQuery TCloseQueryEvent //扩展事件
|
||||||
onActivateAfter lcl.TNotifyEvent //扩展事件
|
onActivateAfter lcl.TNotifyEvent //扩展事件
|
||||||
|
onDestroy lcl.TNotifyEvent
|
||||||
onWndProc []lcl.TWndProcEvent //扩展事件 向后链试循环调用
|
onWndProc []lcl.TWndProcEvent //扩展事件 向后链试循环调用
|
||||||
onPaint []lcl.TNotifyEvent //扩展事件 向后链试循环调用
|
onPaint []lcl.TNotifyEvent //扩展事件 向后链试循环调用
|
||||||
auxTools IAuxTools //辅助工具
|
auxTools IAuxTools //辅助工具
|
||||||
@ -65,6 +66,7 @@ type LCLBrowserWindow struct {
|
|||||||
wmWindowPosChangedMessage wmWindowPosChanged //
|
wmWindowPosChangedMessage wmWindowPosChanged //
|
||||||
screen IScreen //屏幕
|
screen IScreen //屏幕
|
||||||
rgn int //窗口四边圆角
|
rgn int //窗口四边圆角
|
||||||
|
oldWndPrc uintptr
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewLCLBrowserWindow 创建一个 LCL 带有 chromium 窗口
|
// NewLCLBrowserWindow 创建一个 LCL 带有 chromium 窗口
|
||||||
@ -194,7 +196,7 @@ func (m *LCLBrowserWindow) SetProperty() {
|
|||||||
m.SetFormStyle(types.FsSystemStayOnTop)
|
m.SetFormStyle(types.FsSystemStayOnTop)
|
||||||
}
|
}
|
||||||
if wp.EnableHideCaption {
|
if wp.EnableHideCaption {
|
||||||
m.HideTitle()
|
//m.HideTitle()
|
||||||
} else {
|
} else {
|
||||||
if !wp.EnableMinimize {
|
if !wp.EnableMinimize {
|
||||||
m.DisableMinimize()
|
m.DisableMinimize()
|
||||||
@ -615,16 +617,17 @@ func (m *LCLBrowserWindow) FormCreate() {
|
|||||||
m.isFormCreate = true
|
m.isFormCreate = true
|
||||||
m.SetName(fmt.Sprintf("energy_window_name_%d", time.Now().UnixNano()/1e6))
|
m.SetName(fmt.Sprintf("energy_window_name_%d", time.Now().UnixNano()/1e6))
|
||||||
m.onFormMessages()
|
m.onFormMessages()
|
||||||
m.taskMenu()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// defaultWindowEvent 默认窗口活动/关闭处理事件
|
// defaultWindowEvent 默认窗口活动/关闭处理事件
|
||||||
func (m *LCLBrowserWindow) defaultWindowEvent() {
|
func (m *LCLBrowserWindow) defaultWindowEvent() {
|
||||||
|
m._HookWndProcMessage()
|
||||||
if m.WindowType() != consts.WT_DEV_TOOLS {
|
if m.WindowType() != consts.WT_DEV_TOOLS {
|
||||||
m.TForm.SetOnActivate(m.activate)
|
m.TForm.SetOnActivate(m.activate)
|
||||||
}
|
}
|
||||||
m.TForm.SetOnResize(m.resize)
|
m.TForm.SetOnResize(m.resize)
|
||||||
m.TForm.SetOnShow(m.show)
|
m.TForm.SetOnShow(m.show)
|
||||||
|
m.TForm.SetOnDestroy(m.destroy)
|
||||||
}
|
}
|
||||||
|
|
||||||
// defaultWindowCloseEvent 默认的窗口关闭事件
|
// defaultWindowCloseEvent 默认的窗口关闭事件
|
||||||
@ -803,6 +806,7 @@ func (m *LCLBrowserWindow) IsLCL() bool {
|
|||||||
|
|
||||||
// show 内部调用
|
// show 内部调用
|
||||||
func (m *LCLBrowserWindow) show(sender lcl.IObject) {
|
func (m *LCLBrowserWindow) show(sender lcl.IObject) {
|
||||||
|
m.SetBoundsRect(m.BoundsRect()) // trigger WM_NCCALCSIZE hook msg
|
||||||
if m.onShow != nil {
|
if m.onShow != nil {
|
||||||
for _, fn := range m.onShow {
|
for _, fn := range m.onShow {
|
||||||
fn(sender)
|
fn(sender)
|
||||||
@ -810,6 +814,13 @@ func (m *LCLBrowserWindow) show(sender lcl.IObject) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *LCLBrowserWindow) destroy(sender lcl.IObject) {
|
||||||
|
m._RestoreWndProc()
|
||||||
|
if m.onDestroy != nil {
|
||||||
|
m.onDestroy(sender)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// SetCreateBrowserExtraInfo
|
// SetCreateBrowserExtraInfo
|
||||||
//
|
//
|
||||||
// 设置 Chromium 创建浏览器时设置的扩展信息
|
// 设置 Chromium 创建浏览器时设置的扩展信息
|
||||||
@ -1178,6 +1189,10 @@ func (m *LCLBrowserWindow) SetOnWMWindowPosChanged(fn wmWindowPosChanged) {
|
|||||||
m.wmWindowPosChangedMessage = fn
|
m.wmWindowPosChangedMessage = fn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *LCLBrowserWindow) SetOnDestroy(fn lcl.TNotifyEvent) {
|
||||||
|
m.onDestroy = fn
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
lcl.RegisterExtEventCallback(func(fn interface{}, getVal func(idx int) uintptr) bool {
|
lcl.RegisterExtEventCallback(func(fn interface{}, getVal func(idx int) uintptr) bool {
|
||||||
getPtr := func(i int) unsafe.Pointer {
|
getPtr := func(i int) unsafe.Pointer {
|
||||||
|
@ -41,18 +41,11 @@ const (
|
|||||||
// ShowTitle 显示标题栏
|
// ShowTitle 显示标题栏
|
||||||
func (m *LCLBrowserWindow) ShowTitle() {
|
func (m *LCLBrowserWindow) ShowTitle() {
|
||||||
m.WindowProperty().EnableHideCaption = false
|
m.WindowProperty().EnableHideCaption = false
|
||||||
//win.SetWindowLong(m.Handle(), win.GWL_STYLE, uintptr(win.GetWindowLong(m.Handle(), win.GWL_STYLE)|win.WS_CAPTION))
|
|
||||||
//win.SetWindowPos(m.Handle(), m.Handle(), 0, 0, 0, 0, win.SWP_NOSIZE|win.SWP_NOMOVE|win.SWP_NOZORDER|win.SWP_NOACTIVATE|win.SWP_FRAMECHANGED)
|
|
||||||
m.EnabledMaximize(m.WindowProperty().EnableMaximize)
|
|
||||||
m.EnabledMinimize(m.WindowProperty().EnableMinimize)
|
|
||||||
m.SetBorderStyle(types.BsSizeable)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// HideTitle 隐藏标题栏 无边框样式
|
// HideTitle 隐藏标题栏 无边框样式
|
||||||
func (m *LCLBrowserWindow) HideTitle() {
|
func (m *LCLBrowserWindow) HideTitle() {
|
||||||
m.WindowProperty().EnableHideCaption = true
|
m.WindowProperty().EnableHideCaption = true
|
||||||
m.SetBorderStyle(types.BsNone)
|
|
||||||
//m.Frameless()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetRoundRectRgn 窗口无边框时圆角设置
|
// SetRoundRectRgn 窗口无边框时圆角设置
|
||||||
@ -68,44 +61,6 @@ func (m *LCLBrowserWindow) SetRoundRectRgn(rgn int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FramelessForDefault 窗口四边框系统默认样式
|
|
||||||
//
|
|
||||||
// TODO 窗口顶部有条线,
|
|
||||||
func (m *LCLBrowserWindow) FramelessForDefault() {
|
|
||||||
gwlStyle := win.GetWindowLong(m.Handle(), win.GWL_STYLE)
|
|
||||||
win.SetWindowLong(m.Handle(), win.GWL_STYLE, uintptr(gwlStyle&^win.WS_CAPTION&^win.WS_BORDER|win.WS_THICKFRAME))
|
|
||||||
win.SetWindowPos(m.Handle(), 0, 0, 0, 0, 0, uint32(win.SWP_NOMOVE|win.SWP_NOSIZE|win.SWP_FRAMECHANGED))
|
|
||||||
|
|
||||||
//winapi.SetClassLongPtr(this.Handle, GCL_STYLE, GetClassLong(this.Handle, GCL_STYLE)|CS_DropSHADOW)
|
|
||||||
//gclStyle := winapi.GetClassLongPtr(et.HWND(m.Handle()), messages.GCL_STYLE)
|
|
||||||
//winapi.WinSetClassLongPtr().SetClassLongPtr(et.HWND(m.Handle()), messages.GCL_STYLE, gclStyle|messages.CS_DROPSHADOW)
|
|
||||||
}
|
|
||||||
|
|
||||||
// FramelessForLine 窗口四边框是一条细线
|
|
||||||
func (m *LCLBrowserWindow) FramelessForLine() {
|
|
||||||
gwlStyle := win.GetWindowLong(m.Handle(), win.GWL_STYLE)
|
|
||||||
win.SetWindowLong(m.Handle(), win.GWL_STYLE, uintptr(gwlStyle&^win.WS_CAPTION&^win.WS_THICKFRAME|win.WS_BORDER))
|
|
||||||
win.SetWindowPos(m.Handle(), 0, 0, 0, 0, 0, uint32(win.SWP_NOMOVE|win.SWP_NOSIZE|win.SWP_FRAMECHANGED))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Frameless 无边框
|
|
||||||
func (m *LCLBrowserWindow) Frameless() {
|
|
||||||
gwlStyle := win.GetWindowLong(m.Handle(), win.GWL_STYLE)
|
|
||||||
win.SetWindowLong(m.Handle(), win.GWL_STYLE, uintptr(gwlStyle&^win.WS_CAPTION&^win.WS_THICKFRAME))
|
|
||||||
win.SetWindowPos(m.Handle(), 0, 0, 0, 0, 0, uint32(win.SWP_NOMOVE|win.SWP_NOSIZE|win.SWP_FRAMECHANGED))
|
|
||||||
}
|
|
||||||
|
|
||||||
// windows无边框窗口任务栏处理
|
|
||||||
func (m *LCLBrowserWindow) taskMenu() {
|
|
||||||
m.SetOnShow(func(sender lcl.IObject) bool {
|
|
||||||
if m.WindowProperty().EnableHideCaption {
|
|
||||||
gwlStyle := win.GetWindowLong(m.Handle(), win.GWL_STYLE)
|
|
||||||
win.SetWindowLong(m.Handle(), win.GWL_STYLE, uintptr(gwlStyle|win.WS_SYSMENU|win.WS_MINIMIZEBOX))
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetFocus
|
// SetFocus
|
||||||
//
|
//
|
||||||
// 在窗口 (Visible = true) 显示之后设置窗口焦点
|
// 在窗口 (Visible = true) 显示之后设置窗口焦点
|
||||||
@ -114,7 +69,7 @@ func (m *LCLBrowserWindow) taskMenu() {
|
|||||||
func (m *LCLBrowserWindow) SetFocus() {
|
func (m *LCLBrowserWindow) SetFocus() {
|
||||||
if m.TForm != nil {
|
if m.TForm != nil {
|
||||||
m.Visible()
|
m.Visible()
|
||||||
//窗口\激活在Z序中的下个顶层窗口
|
//窗口激活在Z序中的下个顶层窗口
|
||||||
m.Minimize()
|
m.Minimize()
|
||||||
//激活窗口出现在前景
|
//激活窗口出现在前景
|
||||||
m.Restore()
|
m.Restore()
|
||||||
@ -198,47 +153,6 @@ func (m *LCLBrowserWindow) doOnRenderCompMsg(chromiumBrowser ICEFChromiumBrowser
|
|||||||
|
|
||||||
handled := m.cwcap.onCanBorder(chromiumBrowser, x, y, &rect)
|
handled := m.cwcap.onCanBorder(chromiumBrowser, x, y, &rect)
|
||||||
if handled {
|
if handled {
|
||||||
// 鼠标在边框范围
|
|
||||||
// 当是CEF组件消息,判断一次组件四边距离窗口四边间距,如果大于边框范围则取消操作
|
|
||||||
// TODO 暂时不使用
|
|
||||||
//if messageType == cmtCEF {
|
|
||||||
// windowRect := m.BoundsRect()
|
|
||||||
// switch m.cwcap.borderHT {
|
|
||||||
// case messages.HTTOP: // 上
|
|
||||||
// if rect.Top > borderRange {
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// case messages.HTBOTTOM: // 下
|
|
||||||
// if (windowRect.Height() - rect.Bottom) > borderRange {
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// case messages.HTLEFT: // 左
|
|
||||||
// if rect.Left > borderRange {
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// case messages.HTRIGHT: // 右
|
|
||||||
// if (windowRect.Width() - rect.Right) > borderRange {
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// case messages.HTTOPRIGHT: // 右上
|
|
||||||
// if (windowRect.Width()-rect.Right) > borderRange || rect.Top > borderRange {
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// case messages.HTBOTTOMRIGHT: // 右下
|
|
||||||
// if (windowRect.Width()-rect.Right) > borderRange || (windowRect.Height()-rect.Bottom) > borderRange {
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// case messages.HTTOPLEFT: // 左上
|
|
||||||
// if rect.Left > borderRange || rect.Top > borderRange {
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// case messages.HTBOTTOMLEFT: // 左下
|
|
||||||
// if rect.Left > borderRange || (windowRect.Height()-rect.Bottom) > borderRange {
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
// 鼠标在边框位置
|
// 鼠标在边框位置
|
||||||
*lResult = types.LRESULT(m.cwcap.borderHT)
|
*lResult = types.LRESULT(m.cwcap.borderHT)
|
||||||
*aHandled = true
|
*aHandled = true
|
||||||
|
Loading…
Reference in New Issue
Block a user