目前手上有一个发送手机短信的程序,可以正常发送短信,但是不提供任何可编辑的接口及文档。
无奈之下,想到了将整个程序的窗口操作过程用脚本的形式封装起来。 从而实际调用函数,自动操控
短信程序的窗口,完成发信任务。
QXT_CTRL.py
其中用到了另一个自定义的模块 SendKeys2.py 请参考 : python-sendkeys 模拟键盘事件的模块
熟悉 VB 或 .net 里的 SendKeys 函数的话,看本程序就很简单了。 基本就是通过发送 Tab , Enter 等键实现操作窗口.
1 #!/usr/bin/python 2 # -*- coding: gbk -*- 3 4 # QXT_CTRL.py 5 # 6 # Copyright (C) 2012 - xulong <fangkailove@gmail.com> 7 # 8 import sys 9 from ctypes import * 10 import time 11 import win32con 12 import win32api 13 import win32ui 14 import win32clipboard as w 15 from SendKeys2 import * 16 17 #将文本复制到粘贴板 18 def SetText(aString): 19 w.OpenClipboard() 20 w.EmptyClipboard() 21 w.SetClipboardData(win32con.CF_TEXT,aString) 22 w.CloseClipboard() 23 24 def FillText(aString): #将文本从粘贴板贴到当前光标下 25 SetText(aString) 26 win32api.Sleep(5) 27 KeyDown(win32con.VK_CONTROL) 28 SendString('v') 29 win32api.Sleep(10) 30 KeyUp(win32con.VK_CONTROL) 31 32 33 34 35 def QXT_Send(phones,msg): 36 hWnd = None 37 try: 38 hWnd = win32ui.FindWindow(u"TMainForm", u"xxxxxx") 39 hWnd.ShowWindow(win32con.SW_NORMAL) 40 except win32ui.error,e: 41 print u'xxxxxxxxxxxxxxxxxxxx' ,e 42 astr="" 43 aStr= raw_input() 44 exit() 45 46 47 try: 48 hCWnd = win32ui.FindWindow(u"TNewMsgForm", u"MsgForm") 49 hCWnd.SendMessage(win32con.WM_CLOSE,0,0) 50 except win32ui.error,e: 51 #print u'child window:' ,e 52 pass 53 54 55 if hWnd != None: 56 57 #按 shift+F6 调出MsgForm窗口 58 KeyPress(win32con.VK_F6,True) 59 win32api.Sleep(300) 60 61 KeyPress(win32con.VK_TAB,False) 62 KeyPress(win32con.VK_TAB,False) 63 KeyPress(win32con.VK_TAB,False) 64 KeyPress(win32con.VK_TAB,False) 65 66 win32api.Sleep(200) 67 FillText(phones) 68 win32api.Sleep(300) 69 70 KeyPress(win32con.VK_TAB,False) 71 KeyPress(win32con.VK_TAB,False) 72 KeyPress(win32con.VK_TAB,False) 73 74 win32api.Sleep(1000) 75 76 FillText(msg) 77 78 win32api.Sleep(2000) 79 80 KeyPress(win32con.VK_TAB,False) 81 82 KeyPress(win32con.VK_SPACE,False) 83 84 win32api.Sleep(3000) 85 KeyPress(win32con.VK_ESCAPE,False) 86 KeyPress(win32con.VK_ESCAPE,False) 87 88 89 if __name__ == '__main__': 90 #单元测试 91 QXT_Send('1231','tet')
上述已基本能控制发信窗口按要求发出短信,但是不幸的是,此方法偶有失灵,键盘消息有时丢失,不能完整控制窗口发信。 而且当操作系统处于屏保或锁定状态时,键盘模拟没法操作不在当前显示的窗口。
基于此原因,我又重新设计了一下. 完全用 windows 窗口消息来实现,这样即使窗口本身不在激活状态或不在当前桌面(操作系统锁定或注消),也能正常以接收窗口消息而被操控。
QXT_CTRL.py
1 #!/usr/bin/python 2 # -*- coding: gbk -*- 3 4 # QXT_CTRL.py 5 # 6 # Copyright (C) 2012 - xulong <fangkailove@gmail.com> 7 # 8 import sys 9 from ctypes import * 10 import time 11 import win32con 12 import win32api 13 import win32ui 14 15 16 17 18 def QXT_Send(phones,msg): 19 mainform = None 20 try: 21 mainform = win32ui.FindWindow(u"TMainForm", u"窗口标题") 22 #hWnd.ShowWindow(win32con.SW_NORMAL) 23 except win32ui.error,e: 24 print u'没有找到相应窗口的提示' ,e 25 astr="" 26 aStr= raw_input() 27 exit() 28 29 30 #关掉以前打开的未退出的 MsgForm 窗口. 31 try: 32 msgform = win32ui.FindWindow(u"TNewMsgForm", u"窗口标题") 33 msgform.SendMessage(win32con.WM_CLOSE,0,0) 34 except win32ui.error,e: 35 #print u'child window:' ,e 36 pass 37 38 #通过WM_COMMAND消息,模拟菜单命令,打开 MsgForm 窗口 39 mainform.PostMessage(win32con.WM_COMMAND,65,0) 40 time.sleep(1) 41 msgform = win32ui.FindWindow('TNewMsgForm',None) 42 43 44 #MsgForm已打开,以下是填充MsgForm中的栏位,及点击其 "发送" 按钮 45 if msgform != None: 46 47 panel1 = win32ui.FindWindowEx(msgform,None,'TPanel',None) 48 49 50 #查找到了手机号所在栏位,并填充号码进去. 51 combobox = win32ui.FindWindowEx(panel1,None,'TCombobox',None) 52 combobox.SendMessage(win32con.WM_SETTEXT,phones) 53 54 #找到了发送按钮 55 sendbutton = win32ui.FindWindowEx(panel1,None,'TBitBtn','\xb7\xa2\xcb\xcd') 56 57 panel2 = win32ui.FindWindowEx(panel1,None,'TPanel',None) 58 panel3 = win32ui.FindWindowEx(panel2,None,'TPanel',None) 59 60 #找到了短信文本框,并将信息填充进去 61 memo = win32ui.FindWindowEx(panel3,None,'TMemo',None) 62 memo.SendMessage(win32con.WM_SETTEXT,msg+'--') 63 64 #print msg 65 66 #模拟单击 "发送" 按钮 67 sendbutton.SendMessage(win32con.WM_LBUTTONDOWN,0) 68 sendbutton.SendMessage(win32con.WM_LBUTTONUP,0) 69 #msgform.SendMessage(win32con.WM_CLOSE,0,0) 70 71 if __name__ == '__main__': 72 #单元测试 73 for x in range(1,100): 74 QXT_Send('122','test ,test')