目录

  • 依赖的库的安装
  • 写入方式
  • 通过向记事本发送 WM_CHAR 消息
  • 发送ASCII码
  • 发送汉字
  • 错误的方式
  • 正确的方式
  • 用剪贴板向记事本里面复制字符串
  • 方法解析
  • python中的字符编码
  • 解决汉字的python3编码与windows api编码传递出现乱码的问题
  • 参考资料


依赖的库的安装

pip install pywin32==224 #适用于python的Windows API库

写入方式

在网上找了很多代码来实验,发现当粘贴的文字为中英文混合的时候不是粘贴出乱码就是粘贴不全。

自己研究了一下,目前发现在windows下用python3.0通过windows api往记事本里面写入字符串有两种方式:

通过向记事本发送 WM_CHAR 消息

发送ASCII码

#windows下用python3.0操作windows api向记事本里面写入字符--发送ASCII码
import win32gui,win32con
astring = b'abcdABCD' #必须采用字节串,采用字符串会出现乱码
#先手动打开一个记事本
#获取记事本中编辑控件的句柄
hWndText = win32gui.FindWindow("Notepad",None)
hWndEdit = win32gui.FindWindowEx(hWndText,None,"Edit",None)
#发送消息
for x in astring: #依次发送字节串中的每个字节
	win32gui.SendMessage(hWndEdit,win32con.WM_CHAR,x,0)

运行结果:

python win32编程 python win32api教程_python win32编程

发送汉字

错误的方式

采用上述方式发送汉字的话会出现乱码,例如:

#windows下用python3.0操作windows api向记事本里面写入字符--发送汉字-错误的方式
import win32gui, win32con
astring = u'你好!'
astr = astring.encode("gbk") #字符串编码为字节串
#先手动打开一个记事本
#获取记事本中编辑控件的句柄
hWndText = win32gui.FindWindow("Notepad",None)
hWndEdit = win32gui.FindWindowEx(hWndText,None,"Edit",None)
#发送消息
for x in astring: #依次发送字符串中的每个字符
	win32gui.SendMessage(hWndEdit,win32con.WM_CHAR,x, 0)
#发送回车键换行
win32gui.PostMessage(hWndEdit,win32con.WM_KEYDOWN, win32con.VK_RETURN, 0)
for x in astr: #依次发送字节串中的每个字节
	win32gui.SendMessage(hWndEdit,win32con.WM_CHAR,x, 0)

运行结果:

python win32编程 python win32api教程_剪贴板_02

正确的方式
#windows下用python3.0操作windows api向记事本里面写入字符--发送汉字--正确的方式
import win32gui, win32con
import binascii #导入python的进制转换模块
astring = u'Hello World! 你好!'
astrToint = [ord(c) for c in astring]  #将字符串转换为整数型列表
#先手动打开一个记事本
#获取记事本中编辑控件的句柄
hWndText = win32gui.FindWindow("Notepad",None)
hWndEdit = win32gui.FindWindowEx(hWndText,None,"Edit",None)
#发送消息
for x in astrToint: #依次发送列表中的每个数字所代表的的字符
	win32gui.SendMessage(hWndEdit,win32con.WM_CHAR,x, 0)

运行结果:

python win32编程 python win32api教程_字符串_03

用剪贴板向记事本里面复制字符串

#windows下用python3.0操作windows api通过剪贴板向记事本里面复制字符串
import win32clipboard as wcl #导入windows操作剪贴板的库
import win32con, win32gui

#从文件读取字符串
#file = open("test.txt")
#while True:
#    astring=f.readline()
#    if len(line)==0:
#        break

astring = u'Hello World! 你好!' #待写入字符串
wcl.OpenClipboard(None) #打开剪贴板并
wcl.EmptyClipboard() #清空剪贴板
wcl.SetClipboardData(win32con.CF_UNICODETEXT,astring) #向剪贴板中写入信息
wcl.CloseClipboard() #关闭剪贴板
#先手动打开一个记事本
#获取记事本中编辑控件的句柄
hWndText = win32gui.FindWindow("Notepad",None)
hWndEdit = win32gui.FindWindowEx(hWndText,None,"Edit",None)
#发送粘贴消息
win32gui.SendMessage(hWndEdit,win32con.WM_PASTE,0,0)
#读取剪贴板内容并显示
wcl.OpenClipboard(None)
hClipMem = wcl.GetClipboardData(win32con.CF_UNICODETEXT)
wcl.CloseClipboard()
print(hClipMem)

运行结果:

python win32编程 python win32api教程_字符串_04

方法解析

python中的字符编码

python中有两种字符编码形式

  • str字节串–container for bytes
  • Unicode字符串
    他们两者之间的关系如下:

decode

encode


str

Unicode

utf-8, gbk, gb18030 ...


在python3的版本中默认的编码形式是Unicode,在python2.X的版本中如果要采用Unicode编码就要在源文件的开头指定编码形式:

# encoding=utf-8

编码测试:

#编码测试
#测试一
print("test1..........")
bstring1 = b'ABCD'
print(bstring1)
print(type(bstring1))
ustring1 = bstring1.decode("utf-8")
print(ustring1)
print(type(ustring1))
#测试二
print("test2........")
ustring2 = u"Hello!你好!"
print(ustring2)
print(type(ustring2))
bstring2 = ustring2.encode("utf-8")
print(bstring2)
print(type(bstring2))

运行结果:

python win32编程 python win32api教程_字符串_05

解决汉字的python3编码与windows api编码传递出现乱码的问题

根据MSDN上对WM_CHAR的解释,WM_CHAR使用Unicode转换格式UTF-16。UTF-16以每2个字节为一个单元,每个字符由1-2个单元组成,所以每个字符可能是2个字节或者4个字节,包括最常见的英文字母都会编成两个字节。大部分汉字也是2个字节,少部分生僻字为4个字节。并且UTF-16一个单元中的两个字节的顺序不是唯一的。这就造成了从python中往windows api中传递汉字字符出现乱码,因为python中的Unicode是标准的,Unicode的每一个字符都对应一个整数,既然UTF-16会造成字节顺序混乱,那传入整数就避免了这种混乱,就会输出正确的汉字字符了。

参考资料

1.Python3中bytes和HexStr之间的转换 2.关于解决Python乱码问题的终极解决方案 (TL;DR) 3.Python2.x 字符编码终极指南