课前准备
win32
Windows使用dwm管理窗口,可以使用user32.dll
来做嵌入窗口
涉及到
user32.EnumWindows
遍历窗口
user32.IsWindow
user32.IsWindowVisible
user32.IsWindowEnabled
筛选窗口
user32.SetParent
设置父窗口
python
可以用ctypes
调用系统API
ctypes.windll
Win系统独有,调用系统dll(即API)
如ctypes.windll.user32
ctypes.windll.kernel32
为什么不用win32gui?
太大了。好像whl都有40MB,如果只需要这么一个常用功能,那么可以单独写一个API
正文
导入
import ctypes
u32 = ctypes.windll.user32 #获取dll
获取所有窗口
_all_hwnds=[] #未处理的
_all_handles=[]#已处理的
TITLE_MAX=25 #最长标题字符数
@ctypes.CFUNCTYPE(None,ctypes.c_int)
def enum(hwnd):
"C函数"
_all_hwnds.append(int(hwnd))
def update_hwnd():
global _all_hwnds,_all_handles
_all_hwnds=[]
_all_handles=[]
u32.EnumWindows(enum) #更新,传入C函数
for hwnd in _all_hwnds:#已更新
if u32.IsWindow(hwnd) and u32.IsWindowVisible(hwnd) and u32.IsWindowEnabled(hwnd):#筛选出合适的窗口
titlelist = (ctypes.c_char*(TITLE_MAX+1))()#C字节串,中文是GBK编码
u32.GetWindowTextA(hwnd,titlelist,TITLE_MAX+1)#GBK编码的串,传入hwnd,空字节串和最大长度(需+1)
try:
title=b""
for w in titlelist:
if w!=b"\00":#\00是空
title+=w
continue
break
title=title.decode("gbk")#需解码
except:title=""
k = {"hwnd": hwnd,"title": title}#hwnd是必要的,title用来判断窗口
_all_handles.append(k)
嵌入
def into(title,parent):
for h in _all_handles:
hwnd=h["hwnd"]
t=h["title"]
if t==title:
u32.SetParent(hwnd,parent)
return
利用tkinter测试
import tkinter
import random as r
def new_subwin(parent,title=""):
t="TOP#%d"%r.randint(1000,9999)
new=tk.Toplevel()
new.title(t)
new.update()
update_hwnd()
into(t,parent)
if title:new.title(title)
return new
完整代码
import ctypes
import random as r
import tkinter as tk
u32=ctypes.windll.user32
_all_hwnds=[]
_all_handles=[]
TITLE_MAX=25
@ctypes.CFUNCTYPE(None,ctypes.c_int)
def enum(hwnd):
_all_hwnds.append(int(hwnd))
def update_hwnd():
global _all_hwnds,_all_handles
_all_hwnds=[]
_all_handles=[]
u32.EnumWindows(enum)
for hwnd in _all_hwnds:
if u32.IsWindow(hwnd) and u32.IsWindowVisible(hwnd) and u32.IsWindowEnabled(hwnd):
titlelist = (ctypes.c_char*(TITLE_MAX+1))()
u32.GetWindowTextA(hwnd,titlelist,TITLE_MAX+1)
try:
title=b""
for w in titlelist:
if w!=b"\00":
title+=w
continue
break
title=title.decode("gbk")
except:title=""
k = {"hwnd": hwnd,"title": title}
_all_handles.append(k)
def into(title,parent):
for h in _all_handles:
hwnd=h["hwnd"]
t=h["title"]
if t==title:
u32.SetParent(hwnd,parent)
return
def into_func(func,parent):
for h in _all_handles:
hwnd=h["hwnd"]
t=h["title"]
if func(t):
u32.SetParent(hwnd,parent)
return
def into_startswith(title,parent):
into_func(title.startswith,parent)
def into_endswith(title,parent):
into_func(title.endswith,parent)
def into_intitle(title,parent):
into_func(lambda t:t in title,parent)
def new_subwin(parent,title=""):
t="TOP#%d"%r.randint(1000,9999)
new=tk.Toplevel()
new.title(t)
new.update()
update_hwnd()
into(t,parent)
if title:new.title(title)
return new
if __name__ == '__main__':
root=tk.Tk()
root.geometry("400x400")
winid=root.winfo_id()
new=new_subwin(winid,"2")
new.geometry("200x200+0+0")
new_subwin(new.winfo_id(),"3").geometry("+0+0")
root.deiconify()
root.mainloop()
结尾
本文章在2021/12/12 10:54发布于CSDN
不要吝啬你的赞!