栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

[win32&ctypes]不一样的嵌入窗口

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

[win32&ctypes]不一样的嵌入窗口

文章目录
  • 课前准备
    • win32
    • python
    • 为什么不用win32gui?
  • 正文
    • 导入
    • 获取所有窗口
    • 嵌入
    • 利用tkinter测试
  • 完整代码
  • 结尾

课前准备 win32

Windows使用dwm管理窗口,可以使用user32.dll来做嵌入窗口
涉及到
user32.EnumWindows遍历窗口
user32.IsWindow user32.IsWindowVisible user32.IsWindowEnabled筛选窗口
user32.SetParent设置父窗口

python

可以用ctypes调用系统API
ctypes.windllWin系统独有,调用系统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"0":#0是空
                        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"0":
                        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
不要吝啬你的赞!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/656186.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号