5
0
mirror of https://github.com/wailsapp/wails.git synced 2025-05-02 13:51:10 +08:00
wails/v2/internal/ffenestri/ffenestri_windows.go
2021-09-15 20:30:14 +10:00

199 lines
4.5 KiB
Go

package ffenestri
import "C"
/*
#cgo windows CXXFLAGS: -std=c++11
#cgo windows,amd64 LDFLAGS: -lgdi32 -lole32 -lShlwapi -luser32 -loleaut32 -ldwmapi
#include "ffenestri.h"
extern void DisableWindowIcon(struct Application* app);
*/
import "C"
import (
"github.com/ztrue/tracerr"
"os"
"github.com/wailsapp/wails/v2/pkg/menu"
)
// Setup the global caches
var globalCheckboxCache = NewCheckboxCache()
var globalRadioGroupCache = NewRadioGroupCache()
var globalRadioGroupMap = NewRadioGroupMap()
var globalApplicationMenu *Menu
type menuType string
const (
appMenuType menuType = "ApplicationMenu"
contextMenuType
trayMenuType
)
func (a *Application) processPlatformSettings() error {
menuManager = a.menuManager
config := a.config.Windows
if config == nil {
return nil
}
// Check if the webview should be transparent
if config.WebviewIsTransparent {
C.WebviewIsTransparent(a.app)
}
if config.WindowIsTranslucent {
C.WindowIsTranslucent(a.app)
}
if config.DisableWindowIcon {
C.DisableWindowIcon(a.app)
}
// Unfortunately, we need to store this in the package variable so the C callback can see it
applicationMenu = a.menuManager.GetProcessedApplicationMenu()
//
//// Process tray
//trays, err := a.menuManager.GetTrayMenus()
//if err != nil {
// return err
//}
//if trays != nil {
// for _, tray := range trays {
// C.AddTrayMenu(a.app, a.string2CString(tray))
// }
//}
//
//// Process context menus
//contextMenus, err := a.menuManager.GetContextMenus()
//if err != nil {
// return err
//}
//if contextMenus != nil {
// for _, contextMenu := range contextMenus {
// C.AddContextMenu(a.app, a.string2CString(contextMenu))
// }
//}
//
//// Process URL Handlers
//if a.config.Mac.URLHandlers != nil {
// C.HasURLHandlers(a.app)
//}
return nil
}
func (c *Client) updateApplicationMenu() {
applicationMenu = c.app.menuManager.GetProcessedApplicationMenu()
createApplicationMenu(uintptr(C.GetWindowHandle(c.app.app)))
}
/* ---------------------------------------------------------------------------------
Application Menu
----------------
There's only 1 application menu and this is where we create it. This method
is called from C after the window is created and the WM_CREATE message has
been sent.
*/
func checkFatal(err error) {
if err != nil {
tracerr.PrintSourceColor(err)
globalRadioGroupCache.Dump()
globalRadioGroupMap.Dump()
os.Exit(1)
}
}
//export createApplicationMenu
func createApplicationMenu(hwnd uintptr) {
if applicationMenu == nil {
return
}
var err error
window := win32Window(hwnd)
if globalApplicationMenu != nil {
checkFatal(globalApplicationMenu.Destroy())
}
globalApplicationMenu, err = createMenu(applicationMenu, appMenuType)
checkFatal(err)
err = setWindowMenu(window, globalApplicationMenu.menu)
checkFatal(err)
}
//export handleKeypressInGo
func handleKeypressInGo(keycode uint16, modifiers uint8) {
//fmt.Printf("Key code: %#x\n", keycode)
menuID, menuType := getCallbackForKeyPress(keycode, modifiers)
if menuID == "" {
return
}
err := menuManager.ProcessClick(menuID, "", string(menuType), "")
if err != nil {
println(err.Error())
}
}
/*
This method is called by C when a menu item is pressed
*/
//export menuClicked
func menuClicked(id uint32) {
win32MenuID := win32MenuItemID(id)
//println("Got click from menu id", win32MenuID)
// Get the menu from the cache
menuItemDetails := getMenuCacheEntry(win32MenuID)
wailsMenuID := wailsMenuItemID(menuItemDetails.item.ID)
//println("Got click from menu id", win32MenuID, "- wails menu ID", wailsMenuID)
//spew.Dump(menuItemDetails)
switch menuItemDetails.item.Type {
case menu.CheckboxType:
// Determine if the menu is set or not
res, _, err := win32GetMenuState.Call(uintptr(menuItemDetails.parent), uintptr(id), uintptr(MF_BYCOMMAND))
if int(res) == -1 {
checkFatal(err)
}
flag := MF_CHECKED
if uint32(res) == MF_CHECKED {
flag = MF_UNCHECKED
}
for _, menuid := range globalCheckboxCache.win32MenuIDsForWailsMenuID(wailsMenuID) {
//println("setting menuid", menuid, "with flag", flag)
menuItemDetails := getMenuCacheEntry(menuid)
res, _, err = win32CheckMenuItem.Call(uintptr(menuItemDetails.parent), uintptr(menuid), uintptr(flag))
if int(res) == -1 {
checkFatal(err)
}
}
case menu.RadioType:
err := selectRadioItemFromWailsMenuID(wailsMenuID, win32MenuID)
checkFatal(err)
}
// Print the click error - it's not fatal
err := menuManager.ProcessClick(menuItemDetails.item.ID, "", string(menuItemDetails.menuType), "")
if err != nil {
println(err.Error())
}
}