python getmenu不到菜单句柄_如何利用Python和win32编程避免重复性体力劳动(二)——菜单操作:GetMenu,GetSubMenu,GetMenuItemID以及wParam的H...

本文介绍了如何使用Python的win32gui模块进行菜单操作,包括GetMenu、GetSubMenu和GetMenuItemID函数的用法,以及如何通过PostMessage发送WM_COMMAND消息触发菜单项命令。示例中展示了打开和保存文件的菜单操作。
摘要由CSDN通过智能技术生成

请移步至这里以获得更加的排版和阅读体验,谢谢您

Part 2:菜单操作

有了句柄,我们就可以操作FaceGen了!嗯,要先打开文件,File→Open,然后再File→Save Image(很悲剧,Save Image没有快捷键,所以不得不进行菜单操作)。现在我们有了FindWindow和FindWindowEx,要怎么操作菜单呢?

哦,抱歉,靠他俩还做不到。

窗口的菜单就像窗口的标题栏一样,是窗口自身的一部分,不是其他窗体控件,也就没有办法用FindWindow和FindWindowEx返回句柄。所以要对菜单进行操作的话,我们需要新的函数,也就是GetMenu,GetSubMenu和GetMenuItemID,它们也都属于win32gui模块。怎么用呢,结合下图来说:

GetMenu(hwnd)

描述:获取窗口的菜单句柄。

参数:

hwnd:整型,需要获取菜单的窗口的句柄。

说明:获取的是插图中黄色的部分。

GetSubMenu(hMenu, nPos)

描述:获取菜单的下拉菜单或者子菜单。

参数:

hMenu:整型,菜单的句柄,从GetMenu获得。

nPos:整型,下拉菜单或子菜单的的索引,从0算起。

说明:这个可以获取插图中蓝色的部分z;如描述所述,这个不仅可以获取本例中的下拉菜单,还可以获取子菜单。

GetMenuItemID(hMenu, nPos)

描述:获取菜单中特定项目的标识符。

参数:

hMenu:整型,包含所需菜单项的菜单句柄,从GetSubMenu获得。

nPos:整型,菜单项的索引,从0算起。

说明:这个获取的就是红色区域中的项目啦,注意,分隔符是被编入索引的,所以Open的索引是2而非1,而Exit的索引是9而非6。

找到这个菜单项的标识符有什么用呢?找到以后我们就可以告诉应用程序:我们要执行这个菜单项的命令!怎么告诉呢?这就要涉及消息机制了,我们要给应用程序发个消息,让它执行所需菜单项的命令。假设之前获取的Open的标识符是open_ID,那么只需要这样:

win32gui.PostMessage(self.Mhandle, win32con.WM_COMMAND, open_ID, 0)

就会有一个打开文件的对话框出现啦。

解释一下:

PostMessage(hWnd, Msg, wParam, lParam)

描述:在消息队列中加入为指定的窗体加入一条消息,并马上返回,不等待线程对消息的处理。

参数:

hWnd:整型,接收消息的窗体句柄

Msg:整型,要发送的消息,这些消息都是windows预先定义好的,可以参见系统定义消息(System-Defined Messages))

wParam:整型,消息的wParam参数

lParam:整型,消息的lParam参数

说明:简单说,就是给指定程序发一个消息,这些消息都用整型编好号,作为windows的常量可以查询的。在这里,我们用的就是win32con这个库里定义的WM_COMMAND这个消息,具体的wParam和lParam是根据消息的不同而不同的。具体请根据MSDN查阅。

关于wParam的low word和high word:

查阅MSDN的消息时,会发现有的wParam定义了low word和high word,这是什么呢?wParam的定义是32位整型,high word就是他的31至16位,low word是它的15至0位,如图。当参数超过两个,wParam和lParam不够用时,可以将wParam就给拆成两个int16来使用。这种时候在python里记得用把HIWORD的常数向左移16位,再加LOWORD,即wParam = HIWORD<<16+LOWORD。

更新一下我们定义的类,把菜单添加进去:

class FaceGenWindow(object):

def __init__(self, fgFilePath=None):

self.Mhandle = win32gui.FindWindow("FaceGenMainWinClass", None)

self.menu = win32gui.GetMenu(self.Mhandle)

self.menu = win32gui.GetSubMenu(self.menu, 0)

print "FaceGen initialization compeleted"

# 然后定义一个菜单操作的方法:

def menu_command(self, command):

"""

菜单操作

返回弹出的打开或保存的对话框的句柄 dig_handle

返回确定按钮的句柄 confBTN_handle

"""

command_dict = {  # [目录的编号, 打开的窗口名]

"open": [2, u"打开"],

"save_to_image": [5, u"另存为"],

}

cmd_ID = win32gui.GetMenuItemID(self.menu, command_dict[command][0])

win32gui.PostMessage(self.Mhandle, win32con.WM_COMMAND, cmd_ID, 0)

for i in range(10):

if win32gui.FindWindow(None, command_dict[command][1]):

break # 如果找到了打开或者另存为的对话框,就跳出循环

else:

win32api.Sleep(200) # 利用这个函数等待200ms,就不需要再额外导入time模块了

dig_handle = win32gui.FindWindow(None, command_dict[command][1])

confBTN_handle = win32gui.FindWindowEx(dig_handle, 0, "Button", None)

return dig_handle, confBTN_handle

在这里顺便返回了弹出来的对话框的句柄和确定按钮的句柄,后面操作会用到。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值