记录今日将C语言的Windows程序更改为python语言Windows程序,实现子窗口控制,类似微信程序框架最简单的原型

基本思路 为什么要选择python制作Windows应用程序,主要就是源代码直接展示,发现问题随时修改,同时可以不断增加新的功能方便。  由于C语言的Windows程序中结构类型在python中不能使用, 因此我们按照ctypes模块指导意见继承structure为类来创建使用,但是我也使用python中的命名元组方式来使用C语言的结构类型,所以对于同样的C语言结构类型我们可以自己解释为python不同的类型 ,只要自己使用时知道如何使用C语言结构的各个域字段就可以。同时C语言在switch case语句只有python3.10及以后版本支持对应的语句 match case  所以注意python版本,安装支持库pywin32, 我的在Windows10下测试运行通过,我会给出实际代码,最后显示运行效果图 供初学者参考。

例如  C语言的结构

typedef struct tagRECT

     { LONG left;

      LONG top;

     LONG right;

     LONG bottom; } RECT

在python中 我们定义为

LONG = ctypes.c_long
class RECT(ctypes.Structure):_fields_ = [("left", LONG),("top", LONG),("right", LONG),("bottom", LONG)]

我同样可以定义为命名元组 ,不过按官方建议最好按上面的定义。

但是我知道如何解释 所以我也涉及到元组定义,例如

ButtonTuple=collections.namedtuple("ButtonTuple","iStyle szText chinese")

该程序主要涉及几个文件,我通常文件命名后面加个数字1,其内容非常简单,以示区别,定义多个文件主要目的是让自己的程序看起来不太臃肿 。展示一种编程风格而已 一定要遵循这种原则、 以后自己的其他程序可以重复利用

1、主程序文件                                                                main.py

2、涉及C语言结构 Windows类型定义的文件                 structureType1.py

3、宏定义文件                                                                microDefine1.py

4、按钮类型常数文件                                                     ButtonTypeConst1.py

1、main.py  代码

import collections
import ButtonTypeConst1
from structureType1 import *
import ctypes
from micro1 import *
import win32con
import win32gui
import sys
user32=ctypes.windll.user32
gdi32=ctypes.windll.gdi32
clib=ctypes.cdll.msvcrt
printf=ctypes.windll.LoadLibrary("msvcrt.dll")
#给元组元素起名称 然后可以使用名称来引用数据
#我能创建一个以ButtonTuple为名称的元组 就如C语言的数据结构一样 给每个域起个有意义的名字 而我们不必
#关心数据的类型 自己在初始化的时候自己检查  增加编程的灵活性
ButtonTuple=collections.namedtuple("ButtonTuple","iStyle szText chinese")
buttonList=[]buttonList.append(ButtonTuple(ButtonTypeConst1.BS_PUSHBUTTON,"pushButton","普通按钮"))
buttonList.append(ButtonTuple(ButtonTypeConst1.BS_DEFPUSHBUTTON,"DEFPUSHBUTTON","下压按钮"))
buttonList.append(ButtonTuple(ButtonTypeConst1.BS_CHECKBOX,"CHECKBOX","复选框"))
buttonList.append(ButtonTuple(ButtonTypeConst1.BS_AUTOCHECKBOX,"AUTOCHECKBOX","自动复选框"))
buttonList.append(ButtonTuple(ButtonTypeConst1.BS_RADIOBUTTON,"RADIOBUTTON","自动选项按钮"))
buttonList.append(ButtonTuple(ButtonTypeConst1.BS_3STATE,"3STATE","三态按钮"))
buttonList.append(ButtonTuple(ButtonTypeConst1.BS_AUTO3STATE,"AUTO3STATE","自动三态按钮"))
buttonList.append(ButtonTuple(ButtonTypeConst1.BS_GROUPBOX,"GROUPBOX","分组框"))
buttonList.append(ButtonTuple(ButtonTypeConst1.BS_AUTORADIOBUTTON,"AUTORADIOBUTTON","自动选项按钮"))
buttonList.append(ButtonTuple(ButtonTypeConst1.BS_OWNERDRAW,"OWNERDRAW","拥有者绘制按钮"))NUM=len(buttonList)
szAppName="ButtonLock"
hwndButtons=[]   #C语言中数组  python对应列表
rect=RECT()
szTop="message         wParam           lParam                中文"
szUnd="_______         ______           ______               ______"
szFormat="%-16s%04X-%04X     %08X-%08x       %s "
szbuffer=ctypes.create_string_buffer(b"0", 150)
cxChar=0
cyChar=0
ps=PAINTSTRUCT()
msg = MSG()
hInstance=win32gui.GetModuleHandle(None)
def windowProc(hwnd, msg, wParam, lParam):# global hwndButtonglobal cxCharglobal cyCharglobal NUMmatch msg:case win32con.WM_CREATE:   #相当于初始化cxChar=LOWORD(user32.GetDialogBaseUnits())cyChar=HIWORD(user32.GetDialogBaseUnits())for i in range(NUM):hwndButtons.append(win32gui.CreateWindow("button",  #预定义类名buttonList[i].szText,  #按钮标题win32con.WS_CHILD | win32con.WS_VISIBLE | buttonList[i].iStyle,  #按钮风格cxChar,cyChar*(1+2*i), #按钮坐标20*cxChar,7*cyChar//4, #按钮宽 高hwnd,i,   #父窗口句柄 按钮IDhInstance,None))  #实例句柄return 0case win32con.WM_SIZE:rect.left = 24 * cxCharrect.top = 2 *cyCharrect.right=LOWORD(lParam)rect.bottom=HIWORD(lParam)return 0case win32con.WM_PAINT:user32.InvalidateRect(hwnd,ctypes.byref(rect),True)hdc=user32.BeginPaint(hwnd,ctypes.byref(ps))gdi32.SelectObject(hdc,gdi32.GetStockObject(win32con.SYSTEM_FIXED_FONT))gdi32.SetBkMode(hdc,win32con.TRANSPARENT)gdi32.TextOutW(hdc,24*cxChar,cyChar,szTop,len(szTop))gdi32.TextOutW(hdc,12*cyChar,cyChar,szUnd,len(szUnd))user32.EndPaint(hwnd,ctypes.byref(ps))return 0case win32con.WM_DRAWITEM :passcase win32con.WM_COMMAND:user32.ScrollWindow(hwnd,0,-cyChar,ctypes.byref(rect),ctypes.byref(rect))hdc=user32.GetDC(hwnd)gdi32.SelectObject(hdc,gdi32.GetStockObject(win32con.SYSTEM_FIXED_FONT))#wparam高位字节为按钮风格index=LOWORD(wParam)print("按钮的索引",index)gdi32.TextOutW(hdc,24*cxChar,cyChar*(rect.bottom//cyChar-1),szbuffer,user32.wsprintfW(szbuffer,szFormat,"WM_DRAWITEM" if msg==win32con.WM_DRAWITEM  else "WM_COMMAND",HIWORD(wParam),LOWORD(wParam),HIWORD(lParam),LOWORD(lParam),buttonList[index].chinese))user32.ReleaseDC(hwnd,hdc)user32.ValidateRect(hwnd,ctypes.byref(rect))case win32con.WM_DESTROY:user32.PostQuitMessage(0)return 0return win32gui.DefWindowProc(hwnd,msg,wParam,lParam)#---------第一步   初始化类结构-python版本和C语言版本有一定的不同 某些域没有cbClsExtra-----------------------------------------
#---------窗口类的作用就是定义窗口的一般性特征 或者通用特征
wndClass = win32gui.WNDCLASS()
wndClass.cbWndExtra=0
wndClass.style = win32con.CS_HREDRAW | win32con.CS_VREDRAW | win32con.CS_DBLCLKS  #每当窗口水平方向或垂直方向尺寸发生改变后 要完全刷新窗口
wndClass.lpfnWndProc = windowProc                           #这个过程要处理基于这个窗口类创建的所有窗口的全部消息  使用函数名 实际引用提供指向函数的指针
wndClass.hInstance = win32gui.GetModuleHandle(None)         #程序的实例句柄
wndClass.hCursor = win32gui.LoadCursor(None, win32con.IDC_ARROW)    #使用预定义图标 第一个参数为None  使用自定义图片 第一个参数为程序的实例句柄
wndClass.hbrBackground =  win32con.COLOR_WINDOW     #win32gui.GetStockObject(win32con.WHITE_BRUSH) 或者获取图像对象#将窗口客户区边界设置为指定颜色
wndClass.lpszClassName = szAppName#--------第二步  注册类---------------------------------------------
wndClassAtom = win32gui.RegisterClass(wndClass)   #因为python中变量名就是结构体的地址 无须像C语言使用取地址运算符&if(wndClassAtom==0):print("注册失败")sys.exit(0)
# print("注册结果",wndClassAtom)
#-------第三步  创建程序主窗口-------------------------------------------------
#窗口具有垂直和水平滚动条win32con.WS_HSCROLL=0x00100000  in32con.WS_VSCROLL=0x00200000L
hwnd = win32gui.CreateWindow(szAppName, "我的窗口buttonlock", win32con.WS_OVERLAPPEDWINDOW | 0x00100000 |0x00200000,100, 100, 500, 500, None, None, win32gui.GetModuleHandle(None), None)#---------第四步 显示并更新窗口
user32.ShowWindow(hwnd, win32con.SW_SHOW) #产生一个WM_SIZE消息
user32.UpdateWindow(hwnd)  #产生一个WM_PAINT消息#-------第五步 创建消息结构体并建立消息循环 -------------------------------
# msg = ctypes.wintypes.MSG()wParam=None
lparam=None
#手动调用一次回调函数 python调试时中不自动执行创建初始化
# windowProc(hwnd,win32con.WM_CREATE,0,0)#-------自己使用函数调用---------------------------
user32.SendMessageA(hwnd,win32con.WM_CREATE,wParam)
hdc=user32.GetDC(hwnd)
testString="测试文字\n又是一个"
#注意 参数涉及字符串的函数可能都有ASCII版本和Unicode版本
gdi32.TextOutW(hdc,0,0,testString,len(testString))user32.ReleaseDC(hwnd,hdc)#第六步 自动执行消息队列  msg由操作系统自动生成 传递给你的程序
while user32.GetMessageW(ctypes.byref(msg), None, wParam, lparam) != 0:user32.TranslateMessage(ctypes.byref(msg))user32.DispatchMessageW(ctypes.byref(msg))2、 structureType1.py  代码
import ctypesHANDLE = ctypes.c_void_pHDC = HANDLE
DWORD = ctypes.c_ulong
HWND=ctypes.c_void_p
LONG = ctypes.c_long
BOOL = ctypes.c_long
BYTE = ctypes.c_byte
WCHAR = ctypes.c_wchar
UINT = ctypes.c_uint
INT=ctypes.c_int
if ctypes.sizeof(ctypes.c_long) == ctypes.sizeof(ctypes.c_void_p):WPARAM = ctypes.c_ulongLPARAM = ctypes.c_long
elif ctypes.sizeof(ctypes.c_longlong) == ctypes.sizeof(ctypes.c_void_p):WPARAM = ctypes.c_ulonglongLPARAM = ctypes.c_longlongclass RECT(ctypes.Structure):_fields_ = [("left", LONG),("top", LONG),("right", LONG),("bottom", LONG)]
tagRECT = _RECTL = RECTL = RECTclass PAINTSTRUCT(ctypes.Structure):_fields_=[("hdc",HDC),("fErase",BOOL),("rcPaint",RECT),("fRestore",BOOL),("fIncUpdate",BOOL),("rgbReserved",BYTE * 32)]
tagPAINTSTRUCT=PAINTSTRUCTclass TEXTMETRIC(ctypes.Structure):_fields_=[("tmHeight",LONG),("tmAscent",LONG),('tmDescent',LONG),('tmInternalLeading', LONG),('tmExternalLeading',LONG ),('tmAveCharWidth',LONG ),('tmMaxCharWidth',LONG ),('tmWeight',LONG ),('tmOverhang',LONG ),('tmDigitizedAspectX',LONG ),('tmDigitizedAspectY',LONG),('tmFirstChar',WCHAR),('tmLastChar',WCHAR),('tmDefaultChar', WCHAR),('tmBreakChar',WCHAR ),('tmItalic',BYTE ),('tmUnderlined',BYTE ),('tmStruckOut', BYTE ),('tmPitchAndFamily',BYTE),('tmCharSet',BYTE)]
TEXTMETRICW=PTEXTMETRICW=NPTEXTMETRICW=LPTEXTMETRICW=TEXTMETRICclass SCROLLINFO(ctypes.Structure):_fields_=[('cbSize',UINT),   #set to sizeof(SCROLLINFO)('fMask',UINT),    #value to set or get('nMin',INT),      #minimum range value('nMax',INT),      #maximum range value('nPage',UINT),    #page size('nPos',INT),      #current position('nTrackPos',INT)  #current track position]
tagSCROLLINFO=PSCROLLINFO=SCROLLINFOclass WNDPROC(ctypes.Structure):_fields_=[("unnamedParam1",HWND),("namedParam2",UINT),("unnamedParam3",WPARAM),("unnamedParam4",LPARAM)]HINSTANCE=HANDLE
HICON=HANDLE
HCURSOR=HANDLE
HBRUSH=HANDLE
LPCWSTR=HANDLE
class WNDCLASS(ctypes.Structure):_fields_=[("style",UINT),("lpfnWndProc",WNDPROC),("cbClsExtra",ctypes.c_int),("cbWndExtra",ctypes.c_int),("hInstance",HINSTANCE),("hIcon",HICON),("hCursor",HCURSOR),('hbrBackground',HBRUSH),('lpszMenuName',LPCWSTR),('lpszClassName',LPCWSTR)]class POINT(ctypes.Structure):_fields_ = [("x", LONG),("y", LONG)]tagPOINT = _POINTL = POINTL = POINT#演示 验证初始化后是否正确打印每个域的值
p=PAINTSTRUCT(1111,1)class MSG(ctypes.Structure):_fields_ = [("hWnd", HWND),("message", UINT),("wParam", WPARAM),("lParam", LPARAM),("time", DWORD),("pt", POINT)]
tagMSG = MSGCOLORREF=ctypes.c_uint32
class LOGPEN(ctypes.Structure):_fields_=[('lopnStyle',UINT),('lopnWidth',POINT),('lopnColor',COLORREF)]
PLOGPEN=NPLOGPEN=LPLOGPEN=LOGPENprint(p.hdc,p.fErase)
print(ctypes.sizeof(SCROLLINFO))class pythonArrayD2():def __init__(self,rows,columns):assert isinstance(rows,int),"参数必须是正整数"assert isinstance(rows, int), "参数必须是正整数"self.rows=rowsself.columns=columnsself.Values={}self.Values=self.initValues()def initValues(self):for i in range(self.rows):for j in range(self.columns):self.Values[str(i)+','+str(j)]=0return self.Values

3、microDefine1.py 代码

def LOWORD(x):return x & 0xffff
def HIWORD(x):return (x>>16) & 0xffff
def MAX(a,b):if a>b:return aelse:return b
def MIN(a,b):if a<b:return aelse:return b
def RGB(red,green,blue):assert isinstance(red,(int,float)),"必须输入整数"assert isinstance(green, (int, float)), "必须输入整数"assert isinstance(green, (int, float)), "必须输入整数"red=int(red)green=int(green)blue=int(blue)if red>255:red=min(red,255)if red<0:red=max(0,red)if green>255:green=min(green,255)if green<0:green=max(0,green)if blue>255:blue=min(blue,255)if blue<0:blue=max(0,blue)return blue*(1<<16)+green*(1<<8)+red

4、ButtonTypeConst1.py    代码

BS_PUSHBUTTON=0
BS_DEFPUSHBUTTON=1
BS_CHECKBOX=2
BS_AUTOCHECKBOX=3
BS_RADIOBUTTON=4
BS_3STATE=5
BS_AUTO3STATE=6
BS_GROUPBOX=7
BS_AUTORADIOBUTTON=8
BS_OWNERDRAW=9

运行效果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/223077.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Verilog自学还是报班?

FPGA作为国内领先的芯片产品&#xff0c;和传统芯片相比并不局限于单纯的研究和设计芯片&#xff0c;而是针对多种领域的产品通过特定的芯片模型进行优化设计。FPGA本身也构成了典型的半定制电路&#xff0c;涵盖了数字管理模块、输入、输出等单元。 FPGA最大的特点是可以在同…

Unity_C#中使用protobuf

Unity_C#中使用protobuf 下载官方protobuf地址&#xff1a; https://github.com/protocolbuffers/protobuf/releaseshttps://links.jianshu.com/go?tohttps%3A%2F%2Fgithub.com%2Fprotocolbuffers%2Fprotobuf%2Freleases protobuf-c#源码生成dll&#xff0c;导入unity 1.…

双向无线功率传输系统MATLAB仿真

微❤关注“电气仔推送”获得资料&#xff08;专享优惠&#xff09; 模型简介&#xff1a; 初级侧转换器通过双向 AC/DC 转换器从电网获取电力&#xff0c;并由直流线电压 Vin 供电&#xff0c;而拾波侧被视为连接到 EV&#xff0c;并由连接到任一存储的单独直流源 Vout 表示或…

N26:构建无缝体验的平台工程之路-Part 2

​ 在第一​​​​​​部分&#xff0c;我们介绍了 N26 团队为达成 “在 Day 1 实现轻松部署” 的目标而设定的战略规划和开发人员体验图&#xff0c;在这一部分&#xff0c;我们将带您了解该团队如何构建最简可行平台以及该平台如何运作。 01 计划构建最简可行平台 我们通…

高通开发系列 - 功耗问题之添加CPU Idle和Hotplug的功能

By: fulinux E-mail: fulinux@sina.com Blog: https://blog.csdn.net/fulinus 喜欢的盆友欢迎点赞和订阅! 你的喜欢就是我写作的动力! 返回:专栏总目录 目录 概述CPU IdleCPU TopologyCPU Idle DriverCPU Idle GovernorCPU的hotplug函数

TCP/UDP 协议

目录 一.TCP协议 1.介绍 2.报文格式 ​编辑 确认号 控制位 窗口大小 3.TCP特性 二.TCP协议的三次握手 1.tcp 三次握手的过程 三.四次挥手 2.有限状态机 四.tcp协议和udp协议的区别 五.udp协议 UDP特性 六.telnet协议 一.TCP协议 1.介绍 TCP&#xff08;Transm…

DBCA创建RAC的过程截图

以下错误是由于配置的内存较大&#xff0c;而大页&#xff08;HugePage&#xff09;配置较小导致&#xff0c;调整大页后就好了。

Kafka基础理论与常用命令详解(超详细)

文章目录 前言一、Kafka概述1. Kafka简介2. Kafka架构2.1 Broker&#xff08;代理服务器&#xff09;2.2 Topic&#xff08;主题&#xff09;2.3 Producer&#xff08;生产者&#xff09;2.4 Consumer&#xff08;消费者&#xff09;2.5 Consumer Group&#xff08;消费者组&am…

Centos硬盘操作合集

一、硬盘命令说明 lsblk 列出系统上的所有磁盘列表 查看磁盘列表 参数意义 blkid 列出硬盘UUID [rootzs ~]# blkid /dev/sda1: UUID"77dcd110-dad6-45b8-97d4-fa592dc56d07" TYPE"xfs" /dev/sda2: UUID"oDT0oD-LCIJ-Xh7r-lBfd-axLD-DRiN-Twa…

Mybatis详解

MyBatis是什么 MyBatis是一个持久层框架&#xff0c;用于简化数据库操作的开发。它通过将SQL语句和Java方法进行映射&#xff0c;实现了数据库操作的解耦和简化。以下是MyBatis的优点和缺点&#xff1a; 优点&#xff1a; 1. 灵活性&#xff1a;MyBatis允许开发人员编写原生的…

如何正确使用缓存来提升系统性能

文章目录 引言什么时候适合加缓存&#xff1f;示例1示例2&#xff1a;示例3&#xff1a; 缓存应该怎么配置&#xff1f;数据分布**缓存容量大小&#xff1a;**数据淘汰策略 缓存的副作用总结 引言 在上一篇文章IO密集型服务提升性能的三种方法中&#xff0c;我们提到了三种优化…

Kafka-Kafka基本原理与集群快速搭建

一、Kafka介绍 ​ ChatGPT对于Apache Kafka的介绍&#xff1a; Apache Kafka是一个分布式流处理平台&#xff0c;最初由LinkedIn开发并于2011年开源。它主要用于解决大规模数据的实时流式处理和数据管道问题。 Kafka是一个分布式的发布-订阅消息系统&#xff0c;可以快速地处理…

【基础篇】一,认识STM32

一&#xff0c;什么是STM32&#xff1f; STM32是一款由意法半导体公司开发的32位微控制器&#xff1b;其中ST指意法半导体&#xff1b;M指MCU或MPU&#xff0c;32指32 位。 STM32覆盖了Cortex-M的多种系列&#xff0c;包括M0、M0、M3、M7等。在分类上&#xff0c;STM32有很多…

MyBatisPlus基础入门笔记

MyBatisPlus基础入门笔记&#xff0c;源码可见下载链接 大家阅读时可善用目录功能&#xff0c;可以提高大家的阅读效率 下载地址&#xff1a;MyBatisPlus源码笔记 初识MyBatisPlus 入门案例 SpringBoot整合MyBatis&#xff08;复习&#xff09; 创建SpringBoot工程勾选使用的…

56.windows docker 安装ES、Go操作ES(github.com/olivere/elastic/v7库)

文章目录 一、环境准备1、 docker安装ES2、启动容器3、图像化客户端工具ElasticSearch-Head 二、Go ES连接与认证1、 连接ES2、配置ES认证 三、索引的增删改查四、文档的增删改创建单个文档根据文档id删除文档批量删除文档批量创建文档 五、文档查询列表查询精确匹配模糊匹配嵌…

五、Microsoft群集服务(MSCS)环境的搭建

一、【目的】 学会利用Windows Server布置群集环境。 二、【设备】 FreeNAS11.2&#xff0c;Windows Server 2019 三、【要求】 学会利用Windows Server布置群集环境&#xff0c;掌握处理问题的能力。 配置表&#xff1a; 节点公网IP(public)内网IP(private)群集IP(clust…

linux磁盘空间清理

查看磁盘使用情况 查看磁盘分区上可以使用的磁盘空间 $ df -h若要查看文件类型和block&#xff0c;使用下面的命令 $ df -T查看每个文件和目录的磁盘使用空间&#xff0c;也就是文件的大小。 $ sudo du -sh /* $ sudo du -h --max-depth1 /清理旧的 Snap 包版本以释放磁盘空…

华为OD试题六(数据最节约的备份方法、TLV解码)

1. 数据最节约的备份方法 题目描述&#xff1a; 有若干个文件&#xff0c;使用刻录光盘的方式进行备份&#xff0c;假设每张光盘的容量是500MB&#xff0c;求 使用光盘最少的文件分布方式 所有文件的大小都是整数的MB&#xff0c;且不超过500MB&#xff1b;文件不能分割、分卷…

centos-LAMP搭建与配置(论坛网站)

文章目录 LAMP简介搭建LAMP环境安装apache&#xff08;httpd&#xff09;安装mysql安装PHP安装php-mysql安装phpwind LAMP简介 LAMP是指一组通常一起使用来运行动态网站或者服务器的自由软件名称首字母缩写&#xff1a;Linux操作系统&#xff0c;网页服务器Apache&#xff0c;…