Skip to content
This repository
tree: 06c8b6c89a
Fetching contributors…

Cannot retrieve contributors at this time

file 165 lines (126 sloc) 3.067 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
// 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.

package walk

import (
"syscall"
"unsafe"
)

import . "github.com/lxn/go-winapi"

type Menu struct {
hMenu HMENU
hWnd HWND
actions *ActionList
}

func newMenuBar() (*Menu, error) {
hMenu := CreateMenu()
if hMenu == 0 {
return nil, lastError("CreateMenu")
}

m := &Menu{hMenu: hMenu}
m.actions = newActionList(m)

return m, nil
}

func NewMenu() (*Menu, error) {
hMenu := CreatePopupMenu()
if hMenu == 0 {
return nil, lastError("CreatePopupMenu")
}

var mi MENUINFO
mi.CbSize = uint32(unsafe.Sizeof(mi))

if !GetMenuInfo(hMenu, &mi) {
return nil, lastError("GetMenuInfo")
}

mi.FMask |= MIM_STYLE
mi.DwStyle = MNS_CHECKORBMP

if !SetMenuInfo(hMenu, &mi) {
return nil, lastError("SetMenuInfo")
}

m := &Menu{hMenu: hMenu}
m.actions = newActionList(m)

return m, nil
}

func (m *Menu) Dispose() {
if m.hMenu != 0 {
DestroyMenu(m.hMenu)
m.hMenu = 0
}
}

func (m *Menu) IsDisposed() bool {
return m.hMenu == 0
}

func (m *Menu) Actions() *ActionList {
return m.actions
}

func (m *Menu) initMenuItemInfoFromAction(mii *MENUITEMINFO, action *Action) {
mii.CbSize = uint32(unsafe.Sizeof(*mii))
mii.FMask = MIIM_FTYPE | MIIM_ID | MIIM_STATE | MIIM_STRING
if action.image != nil {
mii.FMask |= MIIM_BITMAP
mii.HbmpItem = action.image.handle()
}
if action.text == "-" {
mii.FType = MFT_SEPARATOR
} else {
mii.FType = MFT_STRING
mii.DwTypeData = syscall.StringToUTF16Ptr(action.text)
mii.Cch = uint32(len([]rune(action.text)))
}
mii.WID = uint32(action.id)

if action.Enabled() {
mii.FState &^= MFS_DISABLED
} else {
mii.FState |= MFS_DISABLED
}

menu := action.menu
if menu != nil {
mii.FMask |= MIIM_SUBMENU
mii.HSubMenu = menu.hMenu
}
}

func (m *Menu) onActionChanged(action *Action) error {
var mii MENUITEMINFO

m.initMenuItemInfoFromAction(&mii, action)

if !SetMenuItemInfo(m.hMenu, uint32(m.actions.Index(action)), true, &mii) {
return newError("SetMenuItemInfo failed")
}

return nil
}

func (m *Menu) onInsertingAction(index int, action *Action) error {
var mii MENUITEMINFO

m.initMenuItemInfoFromAction(&mii, action)

if !InsertMenuItem(m.hMenu, uint32(index), true, &mii) {
return newError("InsertMenuItem failed")
}

action.addChangedHandler(m)

menu := action.menu
if menu != nil {
menu.hWnd = m.hWnd
}

if m.hWnd != 0 {
DrawMenuBar(m.hWnd)
}

return nil
}

func (m *Menu) onRemovingAction(index int, action *Action) error {
if !RemoveMenu(m.hMenu, uint32(index), MF_BYPOSITION) {
return lastError("RemoveMenu")
}

action.removeChangedHandler(m)

if m.hWnd != 0 {
DrawMenuBar(m.hWnd)
}

return nil
}

func (m *Menu) onClearingActions() error {
for i := m.actions.Len() - 1; i >= 0; i-- {
if !RemoveMenu(m.hMenu, uint32(i), MF_BYPOSITION) {
return lastError("RemoveMenu")
}

m.actions.At(i).removeChangedHandler(m)
}

if m.hWnd != 0 {
DrawMenuBar(m.hWnd)
}

return nil
}
Something went wrong with that request. Please try again.