创建窗口的应用程序

通过前面的基础知识的学习,已经对ctypes库的基本功能学会了使用,为了加强这种知识训练,以及运用刚学习的知识的快乐,我们来创建一个稍稍复杂一点的应用程序。这个应用程序是所有后面应用程序的基础,只有学会这个程序的基本原理,才可以更进一步学习WIN32的API程序开发。更何况后面所有程序都会在这个程序上修改而成,这个就相当你的爬向高楼顶层的第一个台阶。在所有工程技术里,都会从一个小小的演示程序开始,逐渐地增加功能,慢慢地变成一个强大的应用程序。如果发现这些API函数不清楚,可以参考我写的另外一本书《Windows API一日一练》,在那本书里有完整的介绍和例子,不过这些例子使用C++来编写的。

下面就来开始浏览整个程序的功能吧,第一步是先把ctypes库导入,这样才可以使用它的功能,并且还导入ctypes.wintypes,它有对应WIN32的类型,这样使用起来更方便,比如消息结构MSG。这段代码如下:

#windows应用程序

from ctypes import *

from ctypes.wintypes import *

接着下来定义一个Windows的窗口回调函数的原型,因为Windows指定了每个窗口都需要有一个窗口消息函数来处理窗口所有发生的事件消息,这样你写的应用程序才有机会去响应窗口所发生的事件或操作。这行代码如下:

WNDPROCTYPE = WINFUNCTYPE(c_int, HWND, c_uint, WPARAM, LPARAM)

由于WIN32的定义常量全部是在C语言的头文件里定义,要想在Python中直接使用是不行的。目前只有两种方法,一个是使用一个转换程序,把所有SDK里提供的头文件进行转换为Python定义的形式的模块文件;另外一个就是自己使用到那些,就定义那些常量。本例子里,采用的是最后一种方法,使用到那些就定义就定义那些常量,这样做是为了这个例子保持简单,这些常量定义如下:

WS_EX_APPWINDOW = 0x40000

WS_OVERLAPPEDWINDOW = 0xcf0000

WS_CAPTION = 0xc00000

SW_SHOWNORMAL = 1

SW_SHOW = 5

CS_HREDRAW = 2

CS_VREDRAW = 1

CW_USEDEFAULT = 0x80000000

WM_DESTROY = 2

WHITE_BRUSH = 0

在这些常量主要是窗口的格式、样式、以及显示方式,还有一个消息定义和画笔。由于每个新创建的窗口都需要在Windows里注册唯一的名称,以便创建时从系统内存里找到相应的窗口类,所有其它窗口可以以这个窗口为基本模板,复制N个相同的出来。每个窗口还有一个主题名称,又叫做窗口名称,这两个定义常量如下:

#窗口类的名称

wclassName = u'ShenzhenCai'

wname = u'Hello World'

第一个常量窗口类名称,第二个常量是窗口显示的标题。

窗口的格式、样式通过定义一个结构的方式传递给WIN32的API函数,在这里定义窗口类的结构体如下:

#定义窗口类结构

class WNDCLASSEX(Structure):

_fields_ = [("cbSize", c_uint),

("style", c_uint),

("lpfnWndProc", WNDPROCTYPE),

("cbClsExtra", c_int),

("cbWndExtra", c_int),

("hInstance", HANDLE),

("hIcon", HANDLE),

("hCursor", HANDLE),

("hBrush", HANDLE),

("lpszMenuName", LPCWSTR),

("lpszClassName", LPCWSTR),

("hIconSm", HANDLE)]

这个窗口类的结构体与C语言里描述的结构体是一样的,通过这样定义,就可以给窗口说明窗口的类型了。具体每项的值,请参考《Windows API一日一练》。接着下来,查看窗口回调函数,这里定义了处理窗口收到消息。主要处理了当窗口关闭(WM_DESTROY)时就退出程序。调用API函数PostQuitMessage发送消息给主程序循环,需要结束应用程序了。其它的消息都是调用API函数DefWindowProcW来做默认的处理。

#窗口消息处理回调函数

def PyWndProc(hWnd, Msg, wParam, lParam):

if Msg == WM_DESTROY:

windll.user32.PostQuitMessage(0)

else:

return windll.user32.DefWindowProcW(hWnd, Msg, wParam, lParam)

return 0

接着下来是设置窗口类的属性,注册窗口的类型,以便后面可以创建这个窗口,这里主要是调用函数RegisterClassExW来实现。同时这里把前面的回调函数WndProc、程序实例句柄hInst、窗口类名称wclassName组合一起了。

#初始化主窗口

def initwinclass(hInst, WndProc):

wndClass = WNDCLASSEX()

wndClass.cbSize = sizeof(WNDCLASSEX)

wndClass.style = CS_HREDRAW | CS_VREDRAW

wndClass.lpfnWndProc = WndProc

wndClass.cbClsExtra = 0

wndClass.cbWndExtra = 0

wndClass.hInstance = hInst

wndClass.hIcon = 0

wndClass.hCursor = 0

wndClass.hBrush = windll.gdi32.GetStockObject(WHITE_BRUSH)

wndClass.lpszMenuName = 0

wndClass.lpszClassName = wclassName

wndClass.hIconSm = 0

return windll.user32.RegisterClassExW(byref(wndClass))

窗口的回调函数已经定义,窗口类型又已经注册,接着下来就是创建窗口,并把窗口显示出来了,代码如下:

#主函数入口

def main():

hInst = windll.kernel32.GetModuleHandleW(None)

WndProc = WNDPROCTYPE(PyWndProc)

if initwinclass(hInst, WndProc) <= 0:

return False

hWnd = windll.user32.CreateWindowExW(

0, wclassName, wname,

WS_OVERLAPPEDWINDOW | WS_CAPTION,

CW_USEDEFAULT, CW_USEDEFAULT,

800, 600, 0, 0, hInst, 0)

if not hWnd:

print('Failed to create window')

exit(0)

windll.user32.ShowWindow(hWnd, SW_SHOW)

windll.user32.UpdateWindow(hWnd)

msg = MSG()

lpmsg = pointer(msg)

print('Entering message loop')

while windll.user32.GetMessageW(lpmsg, 0, 0, 0) != 0:

windll.user32.TranslateMessage(lpmsg)

windll.user32.DispatchMessageW(lpmsg)

print('done.')

在这个主函数里,融合前面介绍内容。如果对前面介绍都比较了解,那么在这里就很容易理解它,如果还是不懂,请再查看前面的内容,多练习一下。GetModuleHandleW函数是用来获取当前进程的实例句柄,WNDPROCTYPE是用来转换回调函数,initwinclass函数是用来初始化窗口类型并注册,CreateWindowExW函数是用来创建窗口,ShowWindow函数是用来显示窗口出来,UpdateWindow是用来刷新窗口的显示客户区,pointer函数是用来转换消息指针,GetMessageW函数是获取窗口的消息,TranslateMessage函数是用来转换消息,DispatchMessageW函数是把转换后的消息发送到消息队列。通过创建窗口、显示窗口及更新窗口这三步曲,就完成窗口的显示。后面通过消息循环处理,响应了窗口所有的事件处理。最后还差一个触发这个主函数main的方式,它的实现如下:

if __name__ == "__main__":

print( "Win32 Application in python" )

main()

这里使用了Python的一个特性,当本文件最先运行加载时,就会设置当前文件运行的名称为__main__属性,这样就会调用main函数运行了。当你运行这个例子时,最激动人心的时刻到来了,它运行的结果如下:

编程已经是目前的主流方向,正在学习编程的小伙伴们努力、加油吧。

http://www.dengb.com/Javabc/866195.htmlwww.dengb.comtruehttp://www.dengb.com/Javabc/866195.htmlTechArticle创建窗口的应用程序 通过前面的基础知识的学习,已经对ctypes库的基本功能学会了使用,为了加强这种知识训练,以及运用刚学习的知识的...

用java创建窗口程序,创建窗口的应用程序相关推荐

  1. 【OpenGL】七、桌面窗口搭建 ( 导入头文件 | 桌面程序入口函数 | 注册窗口 | 创建窗口 | 显示窗口 )

    文章目录 一.导入头文件 二.桌面程序入口函数 三.注册窗口 四.创建窗口 五.显示窗口 六.完整代码示例 七.相关资源 基于 [OpenGL]一.Visual Studio 2019 创建 Wind ...

  2. 如何在其他程序的窗口上创建按钮并使之能响应

    如何在其他程序的窗口上创建按钮并使之能响应 源代码下载 环境:Windows NT/2000 实现方法:采用将动态连接库注入到其他进程中的方法来实现. 为了便于选择窗口,我借用了另一个程序" ...

  3. Delphi非应用程序主窗口创建MDI

    对Delphi很熟悉的人,都知道MDI窗口的创建方式,是将主窗口的formstyle设置成MDIForm,然后将各个要设置成MDI的窗口的FormStyle都设置成MDIChild,运行就可以看到效果 ...

  4. VS创建 Win32 应用程序(实现窗口的创建)

    VS创建 Win32 应用程序(实现窗口的创建)(二) 程序框架如下: 一.VS演示流程 打开VS----文件----新建----项目----Windows 桌面应用程序 二.生成代码:(大部分函数在 ...

  5. win32程序窗口的创建

    尽管Windows应用程序千变万化,令人眼花缭乱,但,消息机制和窗口过程却始终它们的基础,掌握了这两项技术,也就相当于把握住了问题的关键. 如果你以前是C程序员或是MFC的忠实用户,只要你学习过C语言 ...

  6. mysql怎么创建窗口应用程序,Win32子窗口及其创建应用

    简介: 所谓的子窗口就是一个父窗口里的一个窗口,父窗口也叫主窗口.子窗口也是窗口,它有自己的回调函数.自己的窗口类.自己的创建.它位于主窗口里的一个区域,我们可以设置子窗口的大小和位置以及相关属性.子 ...

  7. d3d程序创建窗口失败的原因

    是用HWND窗口句柄创建窗口时,是用CreateWindow()函数,其中第一个参数对应你之前的 WNDCLASS类的类名,即 .lpszClassName=L"--"  L与_T ...

  8. QT 基础知识一(QT安装、创建项目、常用窗口控件使用、信号与槽机制讲解)

    QT概念 Qt:Qt是一个跨平台的C++框架(C++库),Qt除了支持界面设计(GUI编程),还封装了与网络编程.多线程.数据库连接.视频音频等相关的功能. ctrl 撤销(返回上一步) 市面常见的G ...

  9. 按键精灵通过句柄获取窗口坐标_使用visual studio 2019 创建简单的Windows窗口「Win32」...

    今天Bili发现网上好多MFC代码都不能用,给大家分享一个简单的MFC窗口语言: 学的不仅仅是技术,更是梦想 学的不仅仅是技术,更是梦想 学的不仅仅是技术,更是梦想 学的不仅仅是技术,更是梦想 复制代 ...

最新文章

  1. 计算机科学与虚拟技术,虚拟现实与可视化技术
  2. 2017年热度最高的十大技术类技能
  3. [BZOJ 2844] albus就是要第一个出场
  4. 房贷断供会有什么严重后果?
  5. Cesium颜色调整
  6. 给你自己的博客加个 Markdown
  7. 偏微分方程数值解的matlab 实现,偏微分方程数值解的Matlab 实现
  8. linux系统 浏览器安装包下载,Linux版360浏览器安装包非常大的原因
  9. Vue框架Element UI教程
  10. 使用ConfuserEx加密混淆程序以及如何脱壳反编译
  11. 关于尼德霍夫VS塔勒布: 今年赚钱最多的,居然是个牧羊人(作者:老喻)
  12. bridging the gap between anchor-based and anchor-free detection via adaptive training sample select
  13. instant-ngp
  14. android 实现果冻动画效果,手把手教你绘制Android粘性果冻动画组件
  15. linux调节伽马值软件,四个 Linux 下的“护眼”软件
  16. Java fx 变速播放音乐_QVE音频剪辑如何调整音频播放速度?音乐变速方法说明
  17. 【CXY】JAVA基础 之 语法基础
  18. Python_静态方法
  19. matlab结束外循环,求单源最短路径的BellmanFord算法的matlab实现及其优化
  20. 用计算机算四分位数间距,数据不满足正态分布——如何计算中位数(四分位数间距)...

热门文章

  1. 新年快乐轮播特效html,基于owl-carousel的卡片水平轮播展示特效
  2. 嵌入式Linux初始化硬件RTC,嵌入式Linux系统中的快速启动技术研究
  3. catia怎么将特征参数化_VSLAM中特征点的参数化表示
  4. 离散数学和组合数学什么关系_关系类型| 离散数学
  5. 相同布局在不同手机上显示不同_不懂响应式,不同尺寸屏幕下的页面很难达到最佳效果...
  6. ajax 跨站返回值,jquery ajax 跨域问题
  7. jsp 嵌入java_关于JSP里的Java语句嵌入问题
  8. 字符串大写转小写库函数_PHP程序无需使用库函数即可将字符串转换为大写
  9. 面试突击第 3 期 | Redis 如何实现查询附近的人?视频实战版
  10. nodejs+nginx获取真实ip