XP系统下的菜单是不使用主题的,所以不在讨论范围。在VISTA\WIN7下的菜单使用了系统主题文件,所以只有使用了这样的系统的朋友才有测试环境。现在有无数疑问如下:
1、系统默认菜单的单个菜单项的高度怎么获得?
我在WIN7下测试,用tHeight = GetSystemMetrics(SM_CYMENU)获得的高度比实际的小。
用GetThemePartSize hTheme, 0, MENU_POPUPITEM, MBI_NORMAL, lpRect, TS_TRUE, lpSize2,然后取tHeight = lpSize2.CY,失败,值为0.2、WIN7默认主题菜单背景似乎是使用了背景图,我用
DrawThemeBackground hTheme, MeDIS.hdc, MENU_POPUPBACKGROUND, MBI_NORMAL, MeDIS.rcItem, MeDIS.rcItem
并没有绘制出菜单背景来。3、(该问题可能无解)假设我有一下拉菜单,其中一部分菜单是自绘风格,另外一些不是自绘的。此时,系统在对付这些不是自绘的这部分菜单的时候,也没有按照主题绘制,而是类似XP的样式。希望各位踊跃发言、讨论。若解决,可另开贴送分。谢谢

解决方案 »

  1.   

    如果类 MENU 在主题中没有定义,那么 OpenThemeData() 就不成功,肯定无法调用 GetThemePartSize()了。
    SM_CYMENU 是菜单栏的高度,单个菜单没有统一高度(比如分割线和普通菜单项高度就不一样),用 GetMenuItemRect() 取。可以用下面的工具检查一下当前主题是否有相应类的定义。
    http://www.vbaccelerator.com/home/VB/Code/Libraries/XP_Visual_Styles/Drawing_with_XP_Visual_Styles/article.asp
      

  2.   

    对于字汇菜单,WM_MEASUREITEM的时候是可以设置菜单宽度和高度的。现在的问题就是普通菜单或分割线对应的高度是多少。
      

  3.   

    我下载了一个XP下的仿Vista界面,自带Vista的小工具,非常漂亮,菜单的背景图是可以替换的。不知道是否使用了主题?
      

  4.   

    无论在什么操作系统下,OpenThemeData(0,strptr("menu"))返回非零的话,就是使用主题的了。我在XP默认主题是返回0的。
      

  5.   

    不一定,我现在的 XP 使用非默认主题,OpenThemeData() 就是返回 0。
      

  6.   

    恩,是我表达错了。在VBGOOD上看到一个帖子说,XP中的菜单是不使用主题的。OpenThemeData() 就是返回 0就是失败,而在VISTA、WIN7下OpenThemeData是会成功的。但就是遇到了这几个难题
      

  7.   

    所以你用我2楼给的程序,看看在 Win7 下是否可以绘出菜单。
      

  8.   

    我测试过这个代码,的确没绘制出来。但是,http://www.vbgood.com/viewthread.php?tid=90424&extra=&page=3
    这里的21楼的代码是可以绘制的,这个代码是vbaccelerator的改进版本。我自己做的时候,用
    DrawThemeBackground hTheme, MeDIS.hdc, MENU_POPUPITEM, MBI_HOT, MeDIS.rcItem, MeDIS.rcItem这样的代码是可以绘制出菜单选中状态的。说明已经部分成功了,但就是还存在一些问题
      

  9.   

    学习
    UPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUP
      

  10.   

    没有 Win7,无法测。
    回头再看改进的代码。
      

  11.   

    Hook 产生效果的前提是 DrawThemeBackground 发生了调用,XP 下是没法试的。DrawThemeBackground hTheme, MeDIS.hdc, MENU_POPUPITEM, MBI_HOT, MeDIS.rcItem, MeDIS.rcItem
    对应实现在
    'IUxThemeHook.cls
    Private Sub IAPIHook_OnHook(...)
      ...
      Case hTheme_Menu
        ...
        Case 14    'vista:menu item
    附近检查一下,是否你调用有问题的没有相应的实现?
      

  12.   

    是的,这个代码只是演示了DrawThemeBackground的效果。从左侧列表的menu部分也可看到各个部分的绘制效果,但仍然存在上述问题。
    即菜单高度,还包括图标区域的宽度等在OpenThemeData成功的前提下,GetThemePartSize和GetThemeInt都失败了……,这样一来,就无法继续下去了
      

  13.   

    创建菜单后用 GetMenuItemRect() 取高度啊。
    你就当作每个菜单项的高度都不同。
      

  14.   

    对于一个MFT_OWNERDRAW风格的菜单,在显示前,容器窗口将会接收到一个WM_MEASUREITEM 消息,此时是需要指定宽度和高度的。GetMenuItemRect只针对已经创建好(或者说显示出来)的菜单。如果不处理WM_MEASUREITEM 消息,菜单尺寸是不会自动调整的。
      

  15.   

    a)已经用了 Hook 进行自绘,就不需要定义 OwnerDraw 风格了。
    b)反过来说,既然 OwnerDraw,样式(高度)自己决定。
      

  16.   

    对啊对啊,“反过来说,既然 OwnerDraw,样式(高度)自己决定。”,现在的问题之一就是设置多高才合适(这个合适的意思是指与系统默认菜单的高度一致)
      

  17.   

    这个非 常规 的方法我也想过……做一样高的菜单这个需求也算正常的吧。且从字面看来GetThemePartSize就是干这个事情的,只是不知道为什么失败了。
      

  18.   

    这个问题我也想过,比如修改了系统字体大小。那么我想到一个比较折中的方法,获取窗体的系统菜单,然后GetMenuItemRect,不过还没实验……至少在目前看来,高度是可以曲线解决了。那么菜单的图标部分(比如复选菜单那个勾),就是菜单左侧部分,这部分的宽度怎么获得呢?为什么会有这么多问题?目的只有一个,就是绘制和系统的菜单尽可能一样的菜单。而菜单的模样由主题决定
      

  19.   

    一点都不矛盾。VB自带的菜单是不支持图标的(是图标,不是位图),要做有图标的菜单,唯有自绘。但自绘成什么样子呢?系统默认的样子。看看IE的收藏夹菜单吧,无论什么系统什么主题,都是那么和谐统一……
      

  20.   

    没有 Win7 无法体验所谓的河蟹。
    www.vbaccelerator.com 有绘制图形菜单的,可以在 Win7 下试试。