导航:  CWindow Class > Tutorial >

Visual style menus

上一页返回章节概述下一页

Windows Vista和后台Windows版本提供作为可视化架构一部分的菜单。 这些菜单使用可视化样式渲染,可以添加到现有应用程序中。 为现有代码添加新功能的代码必须仔细进行,以避免破坏现有的应用程序行为。 某些情况可能导致在应用程序中禁用视觉样式。 这些情况包括:

 

- 使用所有者绘制菜单项(MFT_OWNERDRAW)自定义菜单

- 使用菜单中断(MFT_MENUBREAK或MFT_MENUBARBREAK)

- 使用HBMMENU_CALLBACK来延迟位图渲染

- 使用销毁的菜单句柄

 

这些情况会阻止呈现视觉样式菜单。 所有者绘制菜单可以在Windows Vista和后台Windows版本中使用,但菜单不会被视觉设计。 Windows Vista和后Windows版本提供Alpha混合位图,可以显示菜单项,而不使用所有者绘制菜单项。

 

要求:

 

- 位图是一个32bpp DIB部分。

- DIB部分具有BI_RGB压缩。

- 该位图包含预乘法α像素。

- 位图存储在hbmpChecked,hbmpUnchecked或hbmpItem字段中。

 

注意:MFT_BITMAP项目不支持PARGB32位图。

 

AfxMenu.inc中包含的AfxAddIconToMenuItem函数允许在视觉样式菜单中使用字符图标。

 

DIM hSubMenu AS HMENU = GetSubMenu(hMenu, 1)

DIM hIcon AS HICON

hIcon = LoadImageW(NULL, "MyIcon.ico", IMAGE_ICON, 32, 32, LR_LOADFROMFILE)

IF hIcon THEN AfxAddIconToMenuItem(hSubMenu, 0, TRUE, hIcon)

 

可以使用PNG图标将其首先转换为带有AfxGdipImageFromFile的图标:

 

hIcon = AfxGdipImageFromFileEx("MyIcon.png")

IF hIcon THEN AfxAddIconToMenuItem(hSubMenu, 0, TRUE, hIcon)

 

但是,一般来说,我们更感兴趣的是从嵌入在应用程序中的资源文件加载图标。 我们可以使用AfxGdipIconFromRes函数来实现它。

 

DIM hSubMenu AS HMENU = GetSubMenu(hMenu, 0)

AfxAddIconToMenuItem(hSubMenu, 0, TRUE, AfxGdipIconFromRes(hInst, "IDI_ARROW_LEFT_48"))

 

以下代码使用与“在工具栏示例中使用PNG图标”相同的资源文件来演示我们只能为工具栏和菜单使用一组图标。

 

' ########################################################################################

' Microsoft Windows

' Contents: CWindow with a menu

' Compiler: FreeBasic 32 & 64 bit

' Copyright (c) 2016 José Roca. Freeware. Use at your own risk.

' THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER

' EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF

' MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.

' ########################################################################################

 

#define _WIN32_WINNT &h0602

#INCLUDE ONCE "windows.bi"

#INCLUDE ONCE "win/uxtheme.bi"

#INCLUDE ONCE "Afx/CWindow.inc"

#INCLUDE ONCE "Afx/AfxGdiplus.inc"

#INCLUDE ONCE "Afx/AfxMenu.inc"

using Afx

 

' // Menu identifiers

#define IDM_UNDO     1001   ' Undo

#define IDM_REDO     1002   ' Redo

#define IDM_HOME     1003   ' Home

#define IDM_SAVE     1004   ' Save file

#define IDM_EXIT     1005   ' Exit

 

DECLARE FUNCTION WinMain (BYVAL hInstance AS HINSTANCE, _

                        BYVAL hPrevInstance AS HINSTANCE, _

                        BYVAL szCmdLine AS ZSTRING PTR, _

                        BYVAL nCmdShow AS LONG) AS LONG

 

 END WinMain(GetModuleHandleW(NULL), NULL, COMMAND(), SW_NORMAL)

 

' ========================================================================================

' Build the menu

' ========================================================================================

FUNCTION BuildMenu () AS HMENU

 

 DIM hMenu AS HMENU

 DIM hPopUpMenu AS HMENU

 

 hMenu = CreateMenu

 hPopUpMenu = CreatePopUpMenu

    AppendMenuW hMenu, MF_POPUP OR MF_ENABLED, CAST(UINT_PTR, hPopUpMenu), "&File"

       AppendMenuW hPopUpMenu, MF_ENABLED, IDM_UNDO, "&Undo" & CHR(9) & "Ctrl+U"

       AppendMenuW hPopUpMenu, MF_ENABLED, IDM_REDO, "&Redo" & CHR(9) & "Ctrl+R"

       AppendMenuW hPopUpMenu, MF_ENABLED, IDM_HOME, "&Home" & CHR(9) & "Ctrl+H"

       AppendMenuW hPopUpMenu, MF_ENABLED, IDM_SAVE, "&Save" & CHR(9) & "Ctrl+S"

       AppendMenuW hPopUpMenu, MF_ENABLED, IDM_EXIT, "E&xit" & CHR(9) & "Alt+F4"

 FUNCTION = hMenu

 

END FUNCTION

' ========================================================================================

 

' ========================================================================================

' 窗口处理程序

' ========================================================================================

FUNCTION WndProc (BYVAL hWnd AS HWND, BYVAL uMsg AS UINT, BYVAL wParam AS WPARAM, BYVAL lParam AS LPARAM) AS LRESULT

 

 SELECT CASE uMsg

 

    CASE WM_CREATE

       EXIT FUNCTION

 

    CASE WM_COMMAND

       SELECT CASE LOWORD(wParam)

          CASE IDCANCEL

             ' // If ESC key pressed, close the application sending an WM_CLOSE message

             IF HIWORD(wParam) = BN_CLICKED THEN

                SendMessageW hwnd, WM_CLOSE, 0, 0

                EXIT FUNCTION

             END IF

          CASE IDM_UNDO

             MessageBox hwnd, "Undo option clicked", "Menu", MB_OK

             EXIT FUNCTION

          CASE IDM_REDO

             MessageBox hwnd, "Redo option clicked", "Menu", MB_OK

             EXIT FUNCTION

          CASE IDM_HOME

             MessageBox hwnd, "Home option clicked", "Menu", MB_OK

             EXIT FUNCTION

          CASE IDM_SAVE

             MessageBox hwnd, "Save option clicked", "Menu", MB_OK

             EXIT FUNCTION

       END SELECT

 

         CASE WM_DESTROY

       PostQuitMessage(0)

       EXIT FUNCTION

 

 END SELECT

 

 FUNCTION = DefWindowProcW(hWnd, uMsg, wParam, lParam)

 

END FUNCTION

' ========================================================================================

 

' ========================================================================================

' Main

' ========================================================================================

FUNCTION WinMain (BYVAL hInstance AS HINSTANCE, _

                BYVAL hPrevInstance AS HINSTANCE, _

                BYVAL szCmdLine AS ZSTRING PTR, _

                BYVAL nCmdShow AS LONG) AS LONG

 

 ' // 设置处理DPI感知

 AfxSetProcessDPIAware

 

 DIM pWindow AS CWindow

 pWindow.Create(NULL, "CWindow with a menu", @WndProc)

 pWindow.SetClientSize(400, 250)

 pWindow.Center

 

 ' // Add a button

 pWindow.AddControl("Button", pWindow.hWindow, IDCANCEL, "&Close", 280, 180, 75, 23)

 

 ' // Module instance handle

 DIM hInst AS HINSTANCE = GetModuleHandle(NULL)

 

 ' // Create the menu

 DIM hMenu AS HMENU = BuildMenu

 SetMenu pWindow.hWindow, hMenu

 

 ' // Add icons to the items of the File menu

 DIM hSubMenu AS HMENU = GetSubMenu(hMenu, 0)

 AfxAddIconToMenuItem(hSubMenu, 0, TRUE, AfxGdipIconFromRes(hInst, "IDI_ARROW_LEFT_48"))

 AfxAddIconToMenuItem(hSubMenu, 1, TRUE, AfxGdipIconFromRes(hInst, "IDI_ARROW_RIGHT_48"))

 AfxAddIconToMenuItem(hSubMenu, 2, TRUE, AfxGdipIconFromRes(hInst, "IDI_HOME_48"))

 AfxAddIconToMenuItem(hSubMenu, 3, TRUE, AfxGdipIconFromRes(hInst, "IDI_SAVE_48"))

 

 ' // Process Windows messages

 FUNCTION = pWindow.DoEvents(nCmdShow)

 

END FUNCTION

' ========================================================================================