1 Star 0 Fork 0

程序员锡哥/walk

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
dialog.go 4.91 KB
一键复制 编辑 原始数据 按行查看 历史
// Copyright 2010 The Walk Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build windows
package walk
import (
"syscall"
"unsafe"
)
import (
"github.com/lxn/win"
)
const (
DlgCmdNone = 0
DlgCmdOK = win.IDOK
DlgCmdCancel = win.IDCANCEL
DlgCmdAbort = win.IDABORT
DlgCmdRetry = win.IDRETRY
DlgCmdIgnore = win.IDIGNORE
DlgCmdYes = win.IDYES
DlgCmdNo = win.IDNO
DlgCmdClose = win.IDCLOSE
DlgCmdHelp = win.IDHELP
DlgCmdTryAgain = win.IDTRYAGAIN
DlgCmdContinue = win.IDCONTINUE
DlgCmdTimeout = win.IDTIMEOUT
)
const dialogWindowClass = `\o/ Walk_Dialog_Class \o/`
func init() {
MustRegisterWindowClass(dialogWindowClass)
}
type dialogish interface {
DefaultButton() *PushButton
CancelButton() *PushButton
}
type Dialog struct {
FormBase
result int
defaultButton *PushButton
cancelButton *PushButton
centerInOwnerWhenRun bool
}
func NewDialog(owner Form) (*Dialog, error) {
return newDialogWithStyle(owner, win.WS_THICKFRAME)
}
func NewDialogWithFixedSize(owner Form) (*Dialog, error) {
return newDialogWithStyle(owner, 0)
}
func newDialogWithStyle(owner Form, style uint32) (*Dialog, error) {
dlg := &Dialog{
FormBase: FormBase{
owner: owner,
},
}
if err := InitWindow(
dlg,
owner,
dialogWindowClass,
win.WS_CAPTION|win.WS_SYSMENU|style,
0); err != nil {
return nil, err
}
succeeded := false
defer func() {
if !succeeded {
dlg.Dispose()
}
}()
dlg.centerInOwnerWhenRun = owner != nil
// This forces display of focus rectangles, as soon as the user starts to type.
dlg.SendMessage(win.WM_CHANGEUISTATE, win.UIS_INITIALIZE, 0)
dlg.result = DlgCmdNone
succeeded = true
return dlg, nil
}
func (dlg *Dialog) DefaultButton() *PushButton {
return dlg.defaultButton
}
func (dlg *Dialog) SetDefaultButton(button *PushButton) error {
if button != nil && !win.IsChild(dlg.hWnd, button.hWnd) {
return newError("not a descendant of the dialog")
}
succeeded := false
if dlg.defaultButton != nil {
if err := dlg.defaultButton.setAndClearStyleBits(win.BS_PUSHBUTTON, win.BS_DEFPUSHBUTTON); err != nil {
return err
}
defer func() {
if !succeeded {
dlg.defaultButton.setAndClearStyleBits(win.BS_DEFPUSHBUTTON, win.BS_PUSHBUTTON)
}
}()
}
if button != nil {
if err := button.setAndClearStyleBits(win.BS_DEFPUSHBUTTON, win.BS_PUSHBUTTON); err != nil {
return err
}
}
dlg.defaultButton = button
succeeded = true
return nil
}
func (dlg *Dialog) CancelButton() *PushButton {
return dlg.cancelButton
}
func (dlg *Dialog) SetCancelButton(button *PushButton) error {
if button != nil && !win.IsChild(dlg.hWnd, button.hWnd) {
return newError("not a descendant of the dialog")
}
dlg.cancelButton = button
return nil
}
func (dlg *Dialog) Result() int {
return dlg.result
}
func (dlg *Dialog) Accept() {
dlg.Close(DlgCmdOK)
}
func (dlg *Dialog) Cancel() {
dlg.Close(DlgCmdCancel)
}
func (dlg *Dialog) Close(result int) {
dlg.result = result
dlg.FormBase.Close()
}
func firstFocusableDescendantCallback(hwnd win.HWND, lParam uintptr) uintptr {
widget := windowFromHandle(hwnd)
if widget == nil || !widget.Visible() || !widget.Enabled() {
return 1
}
style := uint(win.GetWindowLong(hwnd, win.GWL_STYLE))
// FIXME: Ugly workaround for NumberEdit
_, isTextSelectable := widget.(textSelectable)
if style&win.WS_TABSTOP > 0 || isTextSelectable {
hwndPtr := (*win.HWND)(unsafe.Pointer(lParam))
*hwndPtr = hwnd
return 0
}
return 1
}
var firstFocusableDescendantCallbackPtr = syscall.NewCallback(firstFocusableDescendantCallback)
func firstFocusableDescendant(container Container) Window {
var hwnd win.HWND
win.EnumChildWindows(container.Handle(), firstFocusableDescendantCallbackPtr, uintptr(unsafe.Pointer(&hwnd)))
return windowFromHandle(hwnd)
}
type textSelectable interface {
SetTextSelection(start, end int)
}
func (dlg *Dialog) focusFirstCandidateDescendant() {
window := firstFocusableDescendant(dlg)
if window == nil {
return
}
if err := window.SetFocus(); err != nil {
return
}
if textSel, ok := window.(textSelectable); ok {
textSel.SetTextSelection(0, -1)
}
}
func (dlg *Dialog) Show() {
if dlg.owner != nil {
var size Size
if layout := dlg.Layout(); layout != nil {
size = layout.MinSize()
min := dlg.MinSize()
size.Width = maxi(size.Width, min.Width)
size.Height = maxi(size.Height, min.Height)
} else {
size = dlg.Size()
}
ob := dlg.owner.Bounds()
if dlg.centerInOwnerWhenRun {
dlg.SetBounds(Rectangle{
ob.X + (ob.Width-size.Width)/2,
ob.Y + (ob.Height-size.Height)/2,
size.Width,
size.Height,
})
}
} else {
dlg.SetBounds(dlg.Bounds())
}
dlg.FormBase.Show()
dlg.focusFirstCandidateDescendant()
}
func (dlg *Dialog) Run() int {
dlg.Show()
if dlg.owner != nil {
dlg.owner.SetEnabled(false)
}
dlg.FormBase.Run()
return dlg.result
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/msgy/walk.git
git@gitee.com:msgy/walk.git
msgy
walk
walk
master

搜索帮助

0d507c66 1850385 C8b1a773 1850385