mirror of
https://gitee.com/energye/energy.git
synced 2024-12-03 12:17:44 +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() //启用标题栏帮助
|
||||
NewTray() ITray //创建LCL的系统托盘
|
||||
SetRoundRectRgn(rgn int) //窗口无边框时圆角设置
|
||||
FramelessForLine() //无边框四边一条细线样式
|
||||
Frameless() //无边框
|
||||
ChromiumCreate(config *TCefChromiumConfig, defaultUrl string) //chromium实例为空时创建 chromium
|
||||
BroderDirectionAdjustments() 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 窗口组件
|
||||
type LCLBrowserWindow struct {
|
||||
*lcl.TForm //window form
|
||||
isFormCreate bool //是否创建完成 WindowForm
|
||||
chromiumBrowser ICEFChromiumBrowser //浏览器
|
||||
windowProperty *WindowProperty //窗口属性
|
||||
windowId int32 //窗口ID
|
||||
windowType consts.WINDOW_TYPE //窗口类型
|
||||
isClosing bool //
|
||||
canClose bool //
|
||||
onResize []TNotifyEvent //扩展事件 向后链试循环调用
|
||||
windowResize TNotifyEvent //扩展事件
|
||||
onActivate TNotifyEvent //扩展事件
|
||||
onShow []TNotifyEvent //扩展事件 向后链试循环调用
|
||||
onClose []TCloseEvent //扩展事件 向后链试循环调用
|
||||
onCloseQuery TCloseQueryEvent //扩展事件
|
||||
onActivateAfter lcl.TNotifyEvent //扩展事件
|
||||
*lcl.TForm //window form
|
||||
isFormCreate bool //是否创建完成 WindowForm
|
||||
chromiumBrowser ICEFChromiumBrowser //浏览器
|
||||
windowProperty *WindowProperty //窗口属性
|
||||
windowId int32 //窗口ID
|
||||
windowType consts.WINDOW_TYPE //窗口类型
|
||||
isClosing bool //
|
||||
canClose bool //
|
||||
onResize []TNotifyEvent //扩展事件 向后链试循环调用
|
||||
windowResize TNotifyEvent //扩展事件
|
||||
onActivate TNotifyEvent //扩展事件
|
||||
onShow []TNotifyEvent //扩展事件 向后链试循环调用
|
||||
onClose []TCloseEvent //扩展事件 向后链试循环调用
|
||||
onCloseQuery TCloseQueryEvent //扩展事件
|
||||
onActivateAfter lcl.TNotifyEvent //扩展事件
|
||||
onDestroy lcl.TNotifyEvent
|
||||
onWndProc []lcl.TWndProcEvent //扩展事件 向后链试循环调用
|
||||
onPaint []lcl.TNotifyEvent //扩展事件 向后链试循环调用
|
||||
auxTools IAuxTools //辅助工具
|
||||
@ -65,6 +66,7 @@ type LCLBrowserWindow struct {
|
||||
wmWindowPosChangedMessage wmWindowPosChanged //
|
||||
screen IScreen //屏幕
|
||||
rgn int //窗口四边圆角
|
||||
oldWndPrc uintptr
|
||||
}
|
||||
|
||||
// NewLCLBrowserWindow 创建一个 LCL 带有 chromium 窗口
|
||||
@ -194,7 +196,7 @@ func (m *LCLBrowserWindow) SetProperty() {
|
||||
m.SetFormStyle(types.FsSystemStayOnTop)
|
||||
}
|
||||
if wp.EnableHideCaption {
|
||||
m.HideTitle()
|
||||
//m.HideTitle()
|
||||
} else {
|
||||
if !wp.EnableMinimize {
|
||||
m.DisableMinimize()
|
||||
@ -615,16 +617,17 @@ func (m *LCLBrowserWindow) FormCreate() {
|
||||
m.isFormCreate = true
|
||||
m.SetName(fmt.Sprintf("energy_window_name_%d", time.Now().UnixNano()/1e6))
|
||||
m.onFormMessages()
|
||||
m.taskMenu()
|
||||
}
|
||||
|
||||
// defaultWindowEvent 默认窗口活动/关闭处理事件
|
||||
func (m *LCLBrowserWindow) defaultWindowEvent() {
|
||||
m._HookWndProcMessage()
|
||||
if m.WindowType() != consts.WT_DEV_TOOLS {
|
||||
m.TForm.SetOnActivate(m.activate)
|
||||
}
|
||||
m.TForm.SetOnResize(m.resize)
|
||||
m.TForm.SetOnShow(m.show)
|
||||
m.TForm.SetOnDestroy(m.destroy)
|
||||
}
|
||||
|
||||
// defaultWindowCloseEvent 默认的窗口关闭事件
|
||||
@ -803,6 +806,7 @@ func (m *LCLBrowserWindow) IsLCL() bool {
|
||||
|
||||
// show 内部调用
|
||||
func (m *LCLBrowserWindow) show(sender lcl.IObject) {
|
||||
m.SetBoundsRect(m.BoundsRect()) // trigger WM_NCCALCSIZE hook msg
|
||||
if m.onShow != nil {
|
||||
for _, fn := range m.onShow {
|
||||
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
|
||||
//
|
||||
// 设置 Chromium 创建浏览器时设置的扩展信息
|
||||
@ -1178,6 +1189,10 @@ func (m *LCLBrowserWindow) SetOnWMWindowPosChanged(fn wmWindowPosChanged) {
|
||||
m.wmWindowPosChangedMessage = fn
|
||||
}
|
||||
|
||||
func (m *LCLBrowserWindow) SetOnDestroy(fn lcl.TNotifyEvent) {
|
||||
m.onDestroy = fn
|
||||
}
|
||||
|
||||
func init() {
|
||||
lcl.RegisterExtEventCallback(func(fn interface{}, getVal func(idx int) uintptr) bool {
|
||||
getPtr := func(i int) unsafe.Pointer {
|
||||
|
@ -41,18 +41,11 @@ const (
|
||||
// ShowTitle 显示标题栏
|
||||
func (m *LCLBrowserWindow) ShowTitle() {
|
||||
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 隐藏标题栏 无边框样式
|
||||
func (m *LCLBrowserWindow) HideTitle() {
|
||||
m.WindowProperty().EnableHideCaption = true
|
||||
m.SetBorderStyle(types.BsNone)
|
||||
//m.Frameless()
|
||||
}
|
||||
|
||||
// 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
|
||||
//
|
||||
// 在窗口 (Visible = true) 显示之后设置窗口焦点
|
||||
@ -114,7 +69,7 @@ func (m *LCLBrowserWindow) taskMenu() {
|
||||
func (m *LCLBrowserWindow) SetFocus() {
|
||||
if m.TForm != nil {
|
||||
m.Visible()
|
||||
//窗口\激活在Z序中的下个顶层窗口
|
||||
//窗口激活在Z序中的下个顶层窗口
|
||||
m.Minimize()
|
||||
//激活窗口出现在前景
|
||||
m.Restore()
|
||||
@ -198,47 +153,6 @@ func (m *LCLBrowserWindow) doOnRenderCompMsg(chromiumBrowser ICEFChromiumBrowser
|
||||
|
||||
handled := m.cwcap.onCanBorder(chromiumBrowser, x, y, &rect)
|
||||
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)
|
||||
*aHandled = true
|
||||
|
Loading…
Reference in New Issue
Block a user