win32编程基础

合集下载

WIN32编程入门指南资料

WIN32编程入门指南资料
第二部分 Win32 SDK编程
Windows程序与传统C程序区别
•传统的C程序是顺序的,所有的流程控制由程序员决 定
•Windows程序是交互式的、事件驱动的。事件是随 机的,事件发生后OS以消息的形式通知应用程序如 何动作。所有的Windows程序都要处理对鼠标键盘等 事件,对事件的不同处理方法是windows程序的构成 本质。
Windows消息模型
消息模型(一)
Windows程序设计的关键
Windows程序程序设计需要掌握Windows操作系统为 程序设计者提供的API( Application Programming Interface)。具体分两个方面: 1)某个具体事件发生后你需要OS为你做什么,如建 立窗口、输出文本、输出图形; 2)OS如何通知你发生了什么事件、事件的具体内容, 如鼠标的某个键被按下、某个键盘键被按下。
Win32 程序构成
WndProc( )函数负责完成消息的处理,该函数的编 写几乎是windows程序设计的全部工作。对不同的消 息进行不同的处理,如对键盘输入和鼠标输入的处理, 对窗口的重绘等。
消息类型(1)
WM_CREATE WM_CLOSE 窗口创建时发送 窗口关闭时发送
WM_DESTROY 窗口销毁是发送 WM_QUIT 退出程序值为0
Win32 程序构成
#include <windows.h> WinMain( )函数 WndProc( )窗口过程函数
见HelloWin32(没有窗口过程函数)与OnlyWindow例程
Win32 程序构成
WinMain( )函数负则完成: 窗口设计 ----- 搭积木 窗口注册 ----- 通知OS搭好了 窗口显示 ----- 让OSБайду номын сангаас窗口显示出来 建立消息循环 ----- 获取消息并分发消息到窗口过程

Win32 API编程入门

Win32 API编程入门

欢迎阅读theForger's Win32 API教程第二版(简体中文)作者:Brooks Miles译者:湛宗儒 本教程试图使用尽可能快和尽可能清晰的方法教你开始Win32 API开发.它是以一个整体来组织的,所以在你提问之前请从头到尾看一遍...你的大多数问题很可能在文字中已被回答.每个章节以之前的章节为基础.我也在附錄A中附上了一些常见的错误的解決方法.如果你问一些在教程中已被回答的问题的话,看起来就有点不聪明了.·下载完整的范例源代码,在整个教程都有对代码的引用.·或是下载整个教程( 包括源代码)至你自己的计算机上慢慢看.下到硬盘的版本可能不包括网络版本具有的一些如拼写更正之类的小规模修改. 如果你在一个別的站点上看此教程,请访问#winprog 站点看最新的官方版本. · ·目錄·基础1.开始 学习2.一个简单的窗口3.处理消息4.理解消息循环5.使用资源6.菜单和图标7.对话框 , 图形界面设计者的好朋友8.非模态 对话框9.标準控件: 按钮 , 编辑框 , 列表框 , 靜态 控件10.等等 , 我还想问 ...( 对话框常见问题)·创建一个简单应用1.应用第一部分 : 在运行时创建控件2.应用第二部分 : 使用文件与常用对话框3.应用第三部分 : 工具栏与状态栏4.应用第四部分 : 多文档界面·图形设备界面1.位图 , 设备上下文与BitBlt2.透明位图3.定时器与动画4.文本 , 字体与顏色·工具与文档1.推荐的书与参考2.免费的Visual C++ 命令行工具3.免费的Borland C++ 命令行工具·附表附表A:常见错误的解決方法附表B:为什要在学习MFC 编程之前学习API附表C:关于资源文件 我听某些读者说教材中的源代码在一些很旧的Netscape浏览器中不能正确地換行,如果你遇到此问题请参考zip打包下载的源代码.想做点什么?你可以绝对免费地使用此文档,但是把在它放在互联网上的确是有些费用..如果你感觉它对你有帮助,也想回馈一些,我将很感谢你能捐赠任何数目的款项来协助支撐此网站.此页面每月大約有15,000个点击,并且在一直增加:) 再说一次,你完全沒有义务支付,你也不会因为支付而得到除了在此处之外的任何东西,但是你想协助的话,是很好的...就点那个PayPal图片就行.但愿你能享受閱读,Brook 我想对如下几个人做出的贡献表示感谢:Yih Horng,Todd Troxell,T FrankZvovushe,Suzanne Lorrin, Seth McCarus,Crispina Chong,John Crutchfield,Scott Johnstone,Patrick Sears,Juan Demerutis,Richard Anthony,Alex Fox,Bob Rudis,Eric Wadsworth,Chris Blume.还有那些写信告诉我觉得此文档有用的那些读者.我很高兴!需要进一步的帮助? 一般地话我会免费回复求助邮件,或指出在哪里可以找到可供参考的资源. 现在我正忙于几个大项目,所沒有时间跟你写一些特定的范例或一定规模的软件项目.但是我愿意接项目:)尽管联系我 .Copyright © 1998-2003, Brook Miles (theForger). All rights reserved.开始学习这篇教程讲什么 这篇教程试图向你展现使用Win32 API写程序的一些基础知识(还有常见的扩展知识).使用C语言,大多数的C++工具也可以编译.事实上从大多数语言的介绍文章可知,大多数语言皆可调用API,包括Java,汇编语言以及Visual Basic.但是我将不会提到这些语言的代码例子,你想使用其它语言的话,请自己参考相关资料,不过有好几个使用过此教程的人都对我说用上面的这些语言都是可行的. 本教程不会教你C语言,也不会教你怎么使用你喜欢的编译器(Borland C++,Visual C ++,LCC-Win32,等等).但是我将在附表中就我对编译器的所知提供一些说明. 如果你不知道macro或typedef是什么,或switch()语句如何工作,那你要先回去找一本好的C语言的教程学习一下.重要说明 在此文档的某些部分我将指出某些地方很重要.因为很多人在不閱读它们情況下造成理解困难,你如果不閱读,你很可能也陷入困难. 第一个就是: 以zip打包的源代码范例不是可选可不选的!我沒有把所有的代码放在教程中,只放了那些与我正在讨论问题相关的.要想知道这里的代码怎么与其它部分配合,就必须去看zip文件中的源代码. 好!第二个: 把整个文档看完.如果你在读某章节遇到了问题,请耐心一点,很可能在后面一点就可以找到答案.如果你实在不能忍受这种无知的状态,请在到IRC频道上去提问或发出求助邮件之前至少跳过一点或在余下的文档中搜一下(是的,计算机可以搜索). 另外一点就是一个关于话题A的问题很可能在关于话题B或C的讨论中得到解答,也有可能是话题L.所以多看看,找一下. 好,东扯西拉暂时告一段落,我们来试些实际代码.最简单的Win32程序 如果你是一个完全的新手,就让我们来确认一下你可以编译一个基本的windows程序.把下面这些代码弄到你的编译器中去编译一下,如果一切正常你就得到有史以来最简易的程序之一. 记得以C来编译,不是以C++.可能沒有关系,但这里的代码都是C,在正确的轨道,行驶还是好些.大多数情況,你要做的就是把文件的扩展名写成.c而不是.cpp..如果这些话伤了你的脑筋的话,就把文件名写成test.c并用它就行了.#include <windows.h>int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow){MessageBox(NULL, "Goodbye, cruel world!", "Note", MB_OK);return 0;} 如果不行,首先閱读得到的任何错误提示,并在帮助文档或任何其它跟你编译器配套的文档中查找它们.确定你是以一个Win32 GUI(不是Console)的工程/makefile/目标来编译的.不幸的是,这一点上我也帮不了什么,对于不同的编译器(不同的人),解決方法不同. 你可能得到一些警告说你沒有使用WinMain()传递的那些参数.这沒关系.现在我们确定你能编译一个程序了,我们来看一下代码...int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow) WinMain()是Windows中与DOS或UNIX的main()的等价物.这是你的程开始执行的入口.参数如下:HINSTANCE hInstance程序可执行模块的句柄(內存中的.exe文件).HINSTANCE hPrevInstance在Win32程序中总是为NULL.LPSTR lpCmdLine命令行参数组成的一个单字符串.不包括程序名字.int nCmdShow一个将要传递给ShowWindow()的整数,我们在后面进行讨论. hInstance用作装入资源或其它的以模块为单位的任务.一个模块是一个装入到你程序的exe或dll.对于本教程的大多数部分(如果不是全部的话),我们只关心一种模块,就是exe 模块. hPrevInstance在Win16时代曾经用作你程序的前面已经运行的实例(如果有的话).现在已经不用了,在Win32中你忽略它就行了.调用规则 WINAPI指定调用规则并被定义为_stdcall.要是你不知道它是干什么用的,先不管它,在我们的这个教程中它对我们沒有影响.记住在这个位置我们需要它就是了.Win32数据类型 你会发现很多普通的关键字或类型在windows中有特定的定义.UINT是unsigned int,LPSTR是char*等等...你怎么用完全取決于你自己.你要是喜欢char*超过了LPSTR,那就用就是了.当然在你替換一个数据类型前你要确定你知道它是什么. 就记住一些容易记住的东西就夠了.LP前缀代表Long Pointer.在Win32中,Long这个部分已经是过时的概念,不要管它.要是不知道指针是什么的话,你可以1)去找一本好的C语言教程,或2)直接往下读,弄得头脑混乱.我是推荐第一种方案的,但很多人使用第二种(我也是:).到时候別说我沒有提醒你. 接下来,一个C接在LP后面表示是常量指针.LPCSTR表示一个指向不会也不能被修改的常量字符串的指针.LPSTR指向的就不是常量的,可以被修改. 你可能还会看到一个T混在里面.现在不要管它,除非你打算与Unicode打交道,它沒有其它的意义.Copyright © 1998-2003, Brook Miles (theForger). All rights reserved.一个简单的窗口范例:simple_window 有时候有人在IRC上问:”我怎么才实现一个窗口?”...我觉得不是一句两句能说得清楚.虽然一旦你搞清楚你要做什么后并不难,但是你的确需要做一些事情来使显示一个窗口;这些事情不是在聊天室中一下子说得清楚的.我总是喜欢先做一件事情然后来理解它...所以先给出一个简单窗口的代码稍后再做解释.#include <windows.h>const char g_szClassName[] = "myWindowClass";// Step 4: the Window ProcedureLRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){switch(msg){case WM_CLOSE:DestroyWindow(hwnd);break;case WM_DESTROY:PostQuitMessage(0);break;default:return DefWindowProc(hwnd, msg, wParam, lParam);}return 0;}int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow){WNDCLASSEX wc;HWND hwnd;MSG Msg;//Step 1: Registering the Window Classwc.cbSize = sizeof(WNDCLASSEX);wc.style = 0;wc.lpfnWndProc = WndProc;wc.cbClsExtra = 0;wc.cbWndExtra = 0;wc.hInstance = hInstance;wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);wc.hCursor = LoadCursor(NULL, IDC_ARROW);wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);wc.lpszMenuName = NULL;wc.lpszClassName = g_szClassName;wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);if(!RegisterClassEx(&wc)){MessageBox(NULL, "Window Registration Failed!", "Error!",MB_ICONEXCLAMATION | MB_OK);return 0;}// Step 2: Creating the Windowhwnd = CreateWindowEx(WS_EX_CLIENTEDGE,g_szClassName,"The title of my window",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,NULL, NULL, hInstance, NULL);if(hwnd == NULL){MessageBox(NULL, "Window Creation Failed!", "Error!",MB_ICONEXCLAMATION | MB_OK);return 0;}ShowWindow(hwnd, nCmdShow);UpdateWindow(hwnd);// Step 3: The Message Loopwhile(GetMessage(&Msg, NULL, 0, 0) > 0){TranslateMessage(&Msg);DispatchMessage(&Msg);}return Msg.wParam;} 简单来说这是你想创建一个窗口能写的最简单的程序,大致上70行左右的代码.如果第一个范例你通过了编译,这个也应该不成问题.第一步:注冊窗口类 一个窗口类存储关于一个窗口的消息,包括控制窗口的窗口过程,窗口的大小图标,以及背景顏色.用这种方式,你可以先注冊一个窗口类,然后从它创建任意数目的窗口,而不需要一次次的指定这些参数.如果需要,大多数属性能针对单个的窗口来攺变. 这里说的窗口类与C++中的类是完全不同的概念.const char g_szClassName[] = "myWindowClass"; 上面的变量存储了我们窗口类的名字,马上会用来向系统注冊窗口类. WNDCLASSEX wc;wc.cbSize = sizeof(WNDCLASSEX);wc.style = 0;wc.lpfnWndProc = WndProc;wc.cbClsExtra = 0;wc.cbWndExtra = 0;wc.hInstance = hInstance;wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);wc.hCursor = LoadCursor(NULL, IDC_ARROW);wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);wc.lpszMenuName = NULL;wc.lpszClassName = g_szClassName;wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);if(!RegisterClassEx(&wc)){MessageBox(NULL, "Window Registration Failed!", "Error!",MB_ICONEXCLAMATION | MB_OK);return 0;} 这是我们在WinMain()中注冊我们的窗口类的代码.我们填写一个WNDCLASSEX结构体的成员并调用RegisterClassEx(). 结构体的成员对窗口类的影响如下:cbSize 结构体的大小.style 类的式样(CS_*),不要跟窗口式样(WS_*)混淆了.这个一般设置为0.lpfnWndProc 指向这个窗口类的窗口过程的指针.cbClsExtra 配置给这个类的额外內存.一般为0.cbWndExtra 配置给这个类的每个窗口的额外內存.一般为0.hInstance 应用程序实例的句柄.(从WinMain()第一个参数传递来.)hIcon 当用戶按下Alt+Tab组合时候显示的大图标(一般为32*32).hCursor 在我们的窗口上显示的光标.hbrBackground 设置我们窗口背景顏色的背景刷子.lpszMenuName 这个类的窗口所用的菜单资源的名字.lpszClassName 类的名字.hIconSm 在任务栏和窗口的左上角显示的小图标(一般为16*16). 如果看得不很明白先不要担心,马上会有讲解.另外要记住的一件事情是不要试图去记下这些东西.我基本上不(从来不)记结构体或函数的参数,这样做是浪费精力和更重要的时间.如果你知道要调用的函数你就去花几秒钟在你的帮助文档中查一下.要是沒有帮助文档,就是想法弄到.沒有它们是很郁闷的.随著你使用多次后也许你会记住那些最常用的函数的参数. 然后我们调用RegisterClassEx()并检查是否成功,如果失败我们弹出一条提示消息并从WinMain()函数退出程序.第二步:创建窗口 一旦类注冊完,我们即可从它创建一个窗口.你应该去查一下CreateWindowEx()的参数列表(在你要用一个新API的时候你总是要这样做),但是我会在这里做个简单的介绍.HWND hwnd;hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,g_szClassName,"The title of my window",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,NULL, NULL, hInstance, NULL); 第一个参数(WS_EX_CLIENTEDGE)是扩展的窗口式样,这里我设置它想得到一个內部下陷的边框效果.你可以设成0看看效果.要习惯于试不同的值看效果. 接下来我设置了类的名字(g_szClassName),告诉系统我们要创建什么样的窗口.因为我们要从刚刚注冊的类创建窗口,我们使用了该类的名字.之后我们指定了我们窗口的名字或是标题,用来显示在我们窗口的外观或是标题栏上. 我们设置的WS_OVERLAPPEDWINDOW是一个窗口式样参数.这里有很多东西你可以查找并做试验.在下文中将详加说明. 接下来的四个参数(CW_USEDEFAULT,CW_USEDEFAULT,320,240)是我们窗口的左上角的X,Y坐标和其宽度和高度.我把X,Y坐标设为CW_USEDEFAULT来让系统自己选择在屏幕的哪个地方来放置窗口.记住屏幕的最左边的X坐标为0并向右加;屏幕的顶部的Y坐标为0并向底加.单位是像素,这是屏幕在特定的分辨率下能显示的最小单位. 再接下来的四个(NULL,NULL,g_hInst,NULL)分別是父窗口的句柄,菜单句柄,应用程序实例句柄,和窗口创建数据的指针.在windows系统中,你屏幕上的窗口是以分层次的父窗口,子窗口的形式来组织的.当你看到一个窗口中有一个按钮时候,按钮就是子窗口,包含它的窗口就是父窗口.我们的例子中,父窗口的句柄为NULL,因为这里沒有父窗口,这个是是我们的主窗口或是顶层窗口.菜单也是NULL,因为我们现在也沒有菜单.实例句柄设为我们从WinMain()得到的第一个参数.窗口的创建数据(我们几乎沒有使用)可以用来向创建的窗口发送额外数据在这里也设为NULL. 如果你想知道神奇的NULL是什么,它实际上被定义为0(零).而且在C中,它是被定义为((void*)0)的,因为是用来作指针用的.所以你有可能在把NULL当整数使用时会得到警告,跟你的编译器的警告级別设置有关.你可以忽略这个警告,也可以用0来代替. 不检查调用是否成功几乎是程序员为找不来程序究竟错在哪里而烦恼的最常发生的情況.CreateWindow()可能会调用失败,即使你是一个用经验的程序员,原因就是可能犯错误的地方实在太多了.除非你学会了如何快速查出错误,最少你应该给自己一个机会知道是哪里出了错,一定记住检查返回值!if(hwnd == NULL){MessageBox(NULL, "Window Creation Failed!", "Error!",MB_ICONEXCLAMATION | MB_OK);return 0;} 在我们创建了窗口并作检查以确定我们有一个正确的句柄后,我们使用WinMain()最后的参数来显示窗口,再更新它以确认它在屏幕上正确地重画了自己.ShowWindow(hwnd, nCmdShow);UpdateWindow(hwnd); nCmdShow是可选的参数,你可以简单地传递SW_SHOWNORMAL即可.但是用从WinMain()传来的参数可给予运行此程序的用戶选择以可视,最大化,最小化等选项...来引导程序的自由.你可以在windows快捷方式的属性中看到这些选项,参数由选项来決定.第三步:消息循环 这是整个程序的心臟,程序中几乎所有的控制都从这个点传递. while(GetMessage(&Msg, NULL, 0, 0) > 0){TranslateMessage(&Msg);DispatchMessage(&Msg);}return Msg.wParam; GetMessage()从你应用的消息队列中取一个消息.任何时候用戶移动鼠标,敲击键盘,点击你窗口的菜单,或做別的什么事,系统会产生消息并输入到你的程序的消息队列中去.调用GetMessage()时你请求将下一个可用的消息从队列中删除并返回给你来处理.如果队列为空,GetMessage()阻塞.如果你不熟悉这个术语,它意味著一直等待直到得到一个消息,才返回给你. TranslateMessage()为键盘事件做一些额外的处理,如随著WM_KEYDOWN消息产生WM_CHAR消息.最后DispatchMessage()将消息送到消息应该被送到的窗口. 可能是我们的主窗口或另外一个,或一个控件,有些情況下是一个被系统或其它程序创建的窗口.这不是你需要担心的,因为我们主要关心我们得到消息并送出,系统来做后面的事以确认它到达正确的窗口.第四步:窗口过程 如果说消息循环是程序的心臟,那个窗口过程就是程序的大脑.这里所有送到窗口的消息被处理.LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){switch(msg){case WM_CLOSE:DestroyWindow(hwnd);break;case WM_DESTROY:PostQuitMessage(0);break;default:return DefWindowProc(hwnd, msg, wParam, lParam);}return 0;} 窗口过程在每个消息到来时被调用一次,HWND参数是消息相应的窗口的句柄.这很重要因为你可能用相同的类创建了两个或多个窗口并且它们用相同的窗口过程(WndProc()).不同点就在不同的窗口有不同的hwnd参数.比如我们得到WM_CLOSE消息我们就要销毀那个窗口.我们使用了窗口句柄作为我们得到的第一个参数,其它的窗口都不会受影响,除了那个我们想要操作的之外. WM_CLOSE是在我们按下关闭按钮或按下Alt+F4组合时产生的.这默认会使窗口销毀,但我喜欢显式处理它,因为这是在程序退出之前做清除检查,或询问用戶是否保存文件等事情的绝佳的位置. 当我们调用DestoryWindow()系统向要销毀的窗口送出WM_DESTORY消息,这里是我们的窗口,并在从系统移除我们的窗口之前删除它剩下的所有的子窗口.因为这是我们的程序中唯一的窗口,我们準备好了并希望程序退出,所以我们调用了PostQuitMessage().这样会向消息循环发出WM_QUIT消息.我们不永远收不到这个消息,因为它使GetMessage()返回FALSE,而且你也可以看到我们的消息循环代码中,这时候我们停止处理消息并返回最终的结果码,我们传递给PostQuitMessage()的WM_QUIT中的wParam部分.这个返回值只有在你的编程为被別的程序调用并且你需要一个确定的返回值时候才有真正有用.第五步:沒有第五步Phew(喘一口气),到这先告一段落.如果上面还沒有解释清楚的话,还是先放下,也许我们在讲解更有用的程序时这些东西会变得清晰起来.Copyright © 1998-2003, Brook Miles (theForger). All rights reserved.处理消息范例:window_click 不错,我们有个窗口了,不过除了DefWindowProc()允许它做的,如拉抻,最大化等等之外沒有別的什的功能了,并不是很令人激动. 下一章节我将演示如何修改你已有的代码来加点新东西.现在我只来告诉你”处理这个消息,在这里处理...”你就知道我的意思,知道怎样做且不用看一整个例子.希望如此,所以注意看:P 对于初学者,请把我们最后那个窗口编译好并确信它能工作.然后你要么就在这个例子上修改要么拷到另外一个新工程中来修改. 我们準备加个使用戶点击我们的窗口时候能夠显示出我们程序的名称的功能.不是很酷,就是基本的一个消息的处理.让我们看看我们的WndProc()中有些什么:LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){switch(msg){case WM_CLOSE:DestroyWindow(hwnd);break;case WM_DESTROY:PostQuitMessage(0);break;default:return DefWindowProc(hwnd, msg, wParam, lParam);}return 0;} 如果我们想处理鼠标的点击,我们需要添加一个WM_LBUTTONDOWN的处理部分(对于右键与中间键,分別是WM_RBUTTONDOWN与WM_MBUTTONDOWN). 如果你听到我或其它人提到处理消息,就是说在窗口的类的WndProc()中加上如下代码:LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){switch(msg){case WM_LBUTTONDOWN: // <-// <- 这就是我们加的break; // <-case WM_CLOSE:DestroyWindow(hwnd);break;case WM_DESTROY:PostQuitMessage(0);break;default:return DefWindowProc(hwnd, msg, wParam, lParam);}return 0;} 不同消息处理的代码的顺序基本上沒有什么关系.要记住的是一定不要忘了在每个消息处理代码后写上break语句.你可以看到我们在我们的switch()中加了另外一个case.现在我们想要在我们的程序执行至此时发生点什么. 首先我们把我们要加的代码写出来(显示我们程序的文件名)然后整合到我们的程序中去.后面的章节中我将只写出代码让你自己整合到程序中去.对我来说不用打那么多字了,对你来说也更灵活,不只是这里的程序还可以加到任何程序中去.如果你不知道怎么办,请参考样例zip文档中对应此章的部分.GetModuleFileName(hInstance, szFileName, MAX_PATH);MessageBox(hwnd, szFileName, "This program is:", MB_OK | MB_ICONINFORMATION); 这段代码不是自解释的,你不能把它随便敲到你原来的代码中去.我们只想在用戶用鼠标点击的时候运行这段代码,所以我们把它加到我们的消息处理框架中去:LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){switch(msg){case WM_LBUTTONDOWN:// BEGIN NEW CODE{char szFileName[MAX_PATH];HINSTANCE hInstance = GetModuleHandle(NULL);GetModuleFileName(hInstance, szFileName, MAX_PATH);MessageBox(hwnd, szFileName, "This program is:", MB_OK |MB_ICONINFORMATION);}// END NEW CODEbreak;case WM_CLOSE:DestroyWindow(hwnd);break;case WM_DESTROY:PostQuitMessage(0);break;default:return DefWindowProc(hwnd, msg, wParam, lParam);}return 0;} 注意那对新的花括号{}.当你在switch()中定义变量时需要它.这本来是基础的C语言知识,但我认为我应该在此指出来,为那些理解有困难的读者著想. 如果你已经加进了代码,现在就编译它.如果正常的话,你点击窗口你就应该看到一个有.exe字样的对话框弹出来. 你可能已经注意到我们加了两个变量,hInstance与szFileName.查一下GetModuleFileName()你就会看到第一个参数是HINSTANCE.指向可执行文件(我们的程序,.exe文件).我们哪里得到这样一个东西?GetModuleHandle()给出了答案.GetModuleHandle()的说明指出传给它一个NULL会返回一个创建发出调用进程的文件句柄,正是我们刚刚提到的HINSTANCE,是我们需要的.把这些消息集中起来我们就会得到如下的定义:HINSTANCE hInstance = GetModuleHandle(NULL); 对于第二个参数,我们再次转向我们可以信赖的参考文档,我们看到它是”一个用来接收那个模块的文件名和路径的缓冲区的指针”而且数据类型是LPTSTR(要是你的文档是比较旧的话就是LPSTR).因为LPSTR等价于char*,我们就定义一个字符串:char szFileName[MAX_PATH]; MAX_PATH是在<windows.h>中定义的一个宏,用来定义Win32中文件名缓冲区的最大长度.我们也将MAX_PATH传给GetModuleFileName()以使它知道缓冲区的大小. GetModuleFileName()被调用后,szFileName将包括一个我们的.exe文件名的字符串,以null结尾.我们把它传递给MessageBox()以一个简单的方法向用戶显示. 所以如果你加了代码,编译了.如果正常,点击窗口你就会看到一个有.exe文件名的对话框弹出来. 如果不是这样,这里是完整的代码.跟你的比较一下,看错误在哪里.#include <windows.h>const char g_szClassName[] = "myWindowClass";LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){switch(msg){case WM_LBUTTONDOWN:{char szFileName[MAX_PATH];HINSTANCE hInstance = GetModuleHandle(NULL);GetModuleFileName(hInstance, szFileName, MAX_PATH);MessageBox(hwnd, szFileName, "This program is:", MB_OK |MB_ICONINFORMATION);}break;case WM_CLOSE:DestroyWindow(hwnd);break;case WM_DESTROY:PostQuitMessage(0);break;default:return DefWindowProc(hwnd, msg, wParam, lParam);}return 0;}int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){WNDCLASSEX wc;HWND hwnd;MSG Msg;wc.cbSize = sizeof(WNDCLASSEX);wc.style = 0;wc.lpfnWndProc = WndProc;wc.cbClsExtra = 0; wc.cbWndExtra = 0;wc.hInstance = hInstance;wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);wc.hCursor = LoadCursor(NULL, IDC_ARROW);wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);wc.lpszMenuName = NULL;wc.lpszClassName = g_szClassName;wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);if(!RegisterClassEx(&wc)){MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);return 0;}hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,g_szClassName,"The title of my window",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,NULL, NULL, hInstance, NULL); if(hwnd == NULL){MessageBox(NULL, "Window Creation Failed!", "Error!",MB_ICONEXCLAMATION | MB_OK);return 0;}ShowWindow(hwnd, nCmdShow);UpdateWindow(hwnd);while(GetMessage(&Msg, NULL, 0, 0) > 0){TranslateMessage(&Msg);DispatchMessage(&Msg);}return Msg.wParam;}Copyright © 1998-2003, Brook Miles (theForger). All rights reserved.理解消息循环 在写任何有实际价值的程序之前,都要理解整个消息循环和windows程序传递消息的结构.当前为止我们已经试了一些消息的处理,我还应该更进一步的看一下这个过程, 因为你如果不理解它们的话,后面的內容将会对你很难.什么是消息 一个消息就是一个整数.如果你到头文件中看一下(了解API的好地方)你就会发现这样的內容:#define WM_INITDIALOG 0x0110#define WM_COMMAND 0x0111#define WM_LBUTTONDOWN 0x0201...等等..消息用来进行windows系统中的所有通信,至少在基本方面是这样的.如果你想要你的窗口或是控件(其实就一种特別的窗口)做点什么你就给它发个消息. 如果另外一个窗口要你做点什么它也发给你一个消息..如果发生了用戶按动了键盘,移动了鼠标,点击了一个按钮之类的事件,系统就向相关的窗口发送消息.你要是就是那个被传至消息的窗口,你就要处理这些消息. 每个windows消息可能拥有至多两个参数,wParam和lParam.最初wParam是16bit,lParam是32bit,但在Win32平台下两者都是32bit.不是每个消息使用了这些参数,而且每个消息以不同的方式来使用.比如,WM_CLOSE不使用它们任一个,所以你应该忽略它们.WM_COMMAND消息两个都使用,wParam有两个部分,HIWORD(wParam)中含有提示消息(如果有的话),LOWORD(wParam)含有发送消息的控件或菜单的标识号.lParam含有发送消息的控件的HWND(窗口的句柄)或者为NULL,当消息不是由控件发送. HIWORD()和LOWORD()是windows定义的两个宏,用来从一个32bit值中分离出高字(0xffff0000)和低字(0x0000ffff)的两字节.在Win32中,一个WORD是16bit,所以一个DWORD为32bit. 可以用PostMessage()或SendMessage()来发送消息.PostMessage()把消息放入消息队列再立即返回.就是说你调用了PostMessage()后消息可能被处理了,也可能还沒有被处理. SendMessage()则真接把消息送往窗口并且在窗口沒有结束处理消息之前不返回.如果我们想关闭一个窗口我们可以发送一个WM_CLOSE消息:PostMessage(hwnd,WM_CLOSE,0,0);这跟我们点击窗口顶部的按钮一样的效果.注意wParam和lParam都为0.这是因为我们刚才说了WM_CLOSE并不用它们.对话框 一旦你开始使用对话框,你将需要向此控件发送消息以与它们通信.你可以先使用GetDlgItem()来用ID得到控件的句柄然后用SendMessage(),也可以直接用SendDlgItemMessage()这个一步到位的函数.你给它一个窗口的句柄和一个子窗口的ID,它就会得到字窗口的句柄并向它发送消息.SendDlgItemMessage()和类似的API,如。

轻松走进Win32汇编语言

轻松走进Win32汇编语言



P o D g i R T : i 皿 , D O I :W R) :W R) r c i  ̄ n P O O DI l o :W R) D O I D O I , ,
MⅡ L
语句放在数据段中,是一个 函数的定义,这个和 C 语言也无太 多区别 ,如果子程序 的定义语句在引用的后面 ,开发者就必
维普资讯
必需 l蹦 6 1 以上版本才能够汇编 Wn 2 i砒锄 6 1 只要 / ̄ i .1


Ⅱ 1 ou eae Old lX n
个 虬. X E E文 件就 可 以 了 T r o  ̄ M . ( A M)是 u b Kt j O T S S
须先进行定义,当然,这个定义是针对  ̄ v k 语句和其 noe 他带参数的调用的,如果开发者的子程序没有参数 ,开发者 就可以用 c ] 指令去调用它而不是用宏指令  ̄v k ,此 al no e 时 ,开发 者就 不必声 明此 函数 了。 接下来 的代码段包含 了子程序与主程序,在 p o r c后的
“ L DG
_
序上,汇编语言有其不可 取代的优越性。相信通过本文的阅读, 言的大致印象 好戏在后面, 本期专题 拭 目以待,别看花 了眼哦。
M I e u 语句 ,相 当于 C语言的  ̄ e i e A N q 1 d fn
D G L
_
M I 1 A N ,用来预 定义一些常量。
es le
… ex FL E a AS
rt e
ed f n i mv ex T E 。 a 刚
rt e
P0 Dg 1 c l h
s ̄ " t 2 t:
d p

ue s sr 语句表示其后的寄存器要编译器 自动插入保存及恢复

第四讲 WIN32编程入门(3)GDI

第四讲 WIN32编程入门(3)GDI

GDI简介--HDC
取得设备内容句柄的方法:
HDC hdc; hdc = BeginPaint(HWND hwnd, LPPAINTSTRUCT lpPaint); Do some drawing with hdc; EndPaint (HWND hwnd, CONST PAINTSTRUCT lpPaint); 以上只能用于WM_PAINT消息响应中; hdc = GetDC(HWND hwnd); Do some drawing with hdc; ReleaseDC(HWND hwnd, HDChdc); 以上用于非WM_PAINT消息响应中
ReleaseDC(hwnd,hdc);
return 0;
GDI简介--字体
字体参数:
For(i= 0; i< 10; i++) { TextOut(hdc,0,i * cyChar,students[i].stuOrder, strlen(students[i].stuOrder)); TextOut(hdc,cxChar * 10,i * cyChar,students[i].stuNo,strlen(students[i].stuNo)); SetTextAlign(hdc,TA_RIGHT);//设置对其方式 TextOut(hdc,cxChar * 30,i * cyChar,students[i].stuName,strlen(students[i].stuName));
GDI简介--字体
设置字体颜色: COLORREF SetTextColor( HDC hdc, // handle to device context COLORREF crColor // text color ); 设置背景色: COLORREF SetBkColor( HDC hdc, // handle of device context COLORREF crColor // background color value ); 设置对其方式: UINT SetTextAlign( HDC hdc, // handle to device context UINT fMode // text-alignment fl简称为「DC」):

第02课 - Win32编程基础知识

第02课 - Win32编程基础知识
27
C语言入口函数
Windows程序设计-基础教程
例如 dir /w /p c:\windows argc = 4 argv[0] = dir argv[1] = /w argv[2] = /p argv[3] = c:\windows
17
代码规范-函数头的注释模板
Windows程序设计-基础教程
每行字符不要超出80个字符(“/”加上“-” 的总长度是80个字符; “FUNC”为函数的名称; “IN”为输入的参数; “OUT”为在函数内部的输出信息内容,即函数 参数作为返回值的说明; “RETURN”函数的返回值(如:函数成功返 回TRUE,否则返回FALSE。); “AUTHOR”为作者信息,需要时间的写法; “NOTE”为函数功能的描述,其中包括:功 能描述、全局变量描述以及调用模块。
Windows 数据类型
C 数据类型
char * const char *
Windows 类型
LPSTR, PSTR LPCSTR, PCSTR
void
void *
VOID
LPVOID
22
Windows 新增数据类型:句柄类型 * *
Windows程序设计-基础教程
HINSTANCE HWND HANDLE HPEN HBRUSH HBITMAP HFONT HDC HRESOURCE HCURSOR ……
8
代码规范-函数命名
Windows程序设计-基础教程
第一个字母必须使用大写字母,要求用大小写字 母组合规范函数命名,必要时可用下划线间隔, 示例如下: int GetValue(); void* Word_GetApp();

win32汇编除法

win32汇编除法

win32汇编除法1. 简介win32汇编是一种低级编程语言,用于在Windows操作系统上编写应用程序。

在win32汇编中,除法操作是非常常见的,它允许将两个数相除并得到商和余数。

本文将介绍win32汇编中的除法操作,包括如何使用除法指令、处理异常和处理特殊情况。

2. 除法指令win32汇编提供了两个除法指令:div和idiv。

•div指令用于无符号整数的除法操作。

它使用eax寄存器作为除数,并将商存储在eax中,余数存储在edx中。

•idiv指令用于有符号整数的除法操作。

它使用eax寄存器作为除数,并将商存储在eax中,余数存储在edx中。

以下是一个示例程序,展示如何在win32汇编中使用除法指令:mov eax, 10 ; 设置除数mov ebx, 3 ; 设置被除数div ebx ; 无符号整数除法; 此时 eax = 3(商),edx = 1(余数)idiv ebx ; 有符号整数除法; 此时 eax = -3(商),edx = 1(余数)3. 处理异常在进行除法操作时,可能会出现一些异常情况,例如被除数为0或除数与被除数的符号不同。

为了处理这些异常,win32汇编提供了一些标志位。

•CF(Carry Flag)标志位用于指示除法操作是否溢出。

如果除数为0,则CF会被设置为1。

•ZF(Zero Flag)标志位用于指示商是否为0。

如果商为0,则ZF会被设置为1。

以下是一个处理除法异常的示例程序:mov eax, 10 ; 设置除数mov ebx, 0 ; 设置被除数为0div ebx ; 无符号整数除法jnc success ; 如果没有溢出,跳转到成功处理的标签; 处理除法异常的代码; ...success:; 处理除法成功的代码; ...4. 处理特殊情况除法操作还涉及一些特殊情况的处理。

例如,当进行除法操作时,如果商的结果无法放入指定的寄存器,会导致溢出。

为了处理这种情况,可以使用cwd指令将32位有符号整数转换为64位有符号整数。

第9章 Win32编程

第9章  Win32编程

第9章
Win32编程
9.1.1 Windows API的有关概念
Windows API都是以DLL输出函数的形式提供的, 大部分核心的API服务都在Kernel32.dll、GUI32.dll和 User32.dll三个文件内,它们位于Windows\System (Winnt\System32)目录内。还有许多重要的API函数在 Windows (Winnt)或Windows\System (Winnt\System32) 目录中的其它DLL文件内(本章第5节将介绍DLL)。这 些函数数量庞大,而且随着Windows版本的升级仍在 不断增加。对于普通程序员来说,不可能也没必要知 道每个API函数的用法,但应了解一些API的知识并且 能在需要时迅速查到自己感兴趣的API函数的资料。
GetActiveWindow、FindWindow等API函数取得其句柄。
第9章
Win32编程
下面一个例子是在当前Windows环境下查找一个标 题为“Hello”的窗口,如果查到该窗口,就将其标题 改为“How Are You”。 HWND hWnd ; if (hWnd = FindWindow (0, "Hello"))
判断一个窗口是否处于最小化状态
改变窗口的位置 改变窗口的位置和大小
第9章
Win32编程
BringWindowToTop FindWindow FlashWindow GetWindowText
将指定的窗口带到顶部 寻找符合某些条件的窗口 使指定的窗口闪烁显示 取窗口的标题或控件的内容
SetWindowText
运行外部应用程序 退出Windows并关闭或重新启动系统等 创建形状各异的窗口 打开剪贴板 清除剪贴板上的数据 关闭剪贴板

Windows程序设计-第02章-Win32编程基础知识

Windows程序设计-第02章-Win32编程基础知识
2.1
在C语言的世界里,所有的程序都是用函数来装配的,main称之为主函数,是所有程序运行的入口。main函数可以无参,也可以有参,但标准的C语言,main函数是有参函数,其形式如下所示:
int main(int argc, char* argv[])
{
printf("Hello World!\n");
第2章
Windows编程,大家也通常称为win32编程,或win32 SDK编程,其含义是针对32位Windows操作系统。本章节回顾了C语言的入口函数,再引入Win32入口函数,通过win32开发所需要的相关知识,巩固对Win32编程的理解。
Win32编程具体的功能是什么?它是为Windows系统编写应用程序的工具或手段,目的是为了服务于系统用户。当然,Win32程序就是所有可以在Windows系统下运行的程序的统称。因为Windows是由很多窗口组成,所以这里所指的Windows程序,即为窗口程序。
char *
LPSTR, PSTR
const char *
LPCSTR, PCSTR
void
VOID
void *
LPVOID
Win32的数据类型众多,有上百个,记忆时可以使用一些技巧,切勿死记硬背,拿“LPCSTR、PCSTR”为例:
“LP”与“P”代表同一含义,即指针;
“C”代表“const”;
“STR”则代表字符串。
2.2
C语言有入口函数,当然Win32编程也有入口函数,虽然它们的写法有所不同,但同为入口函数,基本功能是一样的。不一样的是Win32的入口函数相对来说更为复杂,它为窗口应用程序提供相应的参数。为了让大家更好的了解Win32入口函数的参数,先来了解一下C语言的一些参数,表2.1描述了常用的数据类型。

Win32多线程编程

Win32多线程编程

(2)CloseHandle,用于关闭对象,其函数原型为: BOOL CloseHandle(HANDLE hObject);
如果函数执行成功,则返回 TRUE;否则返回 FALSE,我们可以通过 GetLastError 函数进一步可以获 得错误原因。
C 运行时库 在 VC++6.0 中,有两种多线程编程方法:一是使用 C 运行时库及 WIN32 API 函数,另一种方法是使 用 MFC,MFC 对多线程开发有强大的支持。 标准 C 运行时库是 1970 年问世的,当时还没有多线程的概念。因此,C 运行时库早期的设计者们不可能考 虑到让其支持多线程应用程序。 Visual C++提供了两种版本的 C 运行时库,-个版本供单线程应用程序调用,另一个版本供多线程应用程序 调用。多线程运行时库与单线程运行时库有两个重大差别: (1)类似 errno 的全局变量,每个线程单独设置一个; 这样从每个线程中可以获取正确的错误信息。 (2)多线程库中的数据结构以同步机制加以保护。 这样可以避免访问时候的冲突。
通过下列代码就可以遍历系统中的进程,获得进程列表:
//获取当前进程总数 EnumProcesses(process_ids, sizeof(process_ids), &num_processes);
//遍历进程 for (int i = 0; i < num_processes; i++)
{ //根据进程 ID 获取句柄 process[i] = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, 0,
2、获取进程信息 在 WIN32 中,可使用在 PSAPI .DLL 中提供的 Process status Helper 函数帮助我们获取进程信息。 (1)EnumProcesses()函数可以获取进程的 ID,其原型为:

win32gui用法

win32gui用法

win32gui用法Win32 GUI编程是Windows平台下一种重要的开发方式,通过使用Win32 GUI库,我们可以创建具有图形用户界面(GUI)的应用程序。

其中,win32gui是Python中一个常用的GUI库,它提供了丰富的API,方便我们进行GUI开发。

一、win32gui库介绍win32gui库是Python中用于Windows平台下进行GUI开发的库,它提供了丰富的API,包括窗口、控件、消息、图标、位图等操作接口。

通过使用win32gui库,我们可以方便地进行窗口创建、消息处理、控件操作等GUI开发工作。

二、win32gui基本用法1. 导入win32gui库在使用win32gui库之前,需要先导入它。

在Python中,可以使用`import win32gui`语句来导入该库。

2. 创建窗口使用win32gui库创建窗口需要使用`win32gui.CreateWindow()`函数。

该函数需要传入窗口的类名、窗口的样式、窗口的父窗口等参数。

创建窗口后,可以通过调用其他函数来设置窗口的位置、大小、标题等信息。

示例代码:```pythonimport win32guiwindow_class = "MyWindowClass"window_style = win32con.WS_OVERLAPPEDWINDOW |win32con.WS_VISIBLEwindow_rect = (0, 0, 640, 480)window_proc = win32gui.WNDPROC()win32gui.RegisterClass(window_class)window = win32gui.CreateWindow(window_class, "My Window Title", window_style, window_rect, None, None, None, None, None)```3. 发送消息使用win32gui库可以发送各种消息到窗口中,例如WM_PAINT消息用于绘制窗口内容,WM_CLOSE消息用于关闭窗口等。

Windows平台Python编程必会模块之pywin32

Windows平台Python编程必会模块之pywin32

Windows平台Python编程必会模块之pywin32在Windows平台上,从原来使⽤C/C++编写原⽣EXE程序,到使⽤Python编写⼀些常⽤脚本程序,成熟的模块的使⽤使得编程效率⼤⼤提⾼了。

不过,python模块虽多,也不可能满⾜开发者的所有需求。

⽽且,模块为了便于使⽤,通常都封装过度,有些功能⽆法灵活使⽤,必须直接调⽤Windows API来实现。

要完成这⼀⽬标,有两种办法,⼀种是使⽤C编写Python扩展模块,或者就是编写普通的DLL通过python的ctypes来调⽤,但是这样就部分牺牲掉了Python的快速开发、免编译特性。

还好,有⼀个模块pywin32可以解决这个问题,它直接包装了⼏乎所有的Windows API,可以⽅便地从Python直接调⽤,该模块另⼀⼤主要功能是通过Python进⾏COM编程。

安装时可以直接使⽤pip执⾏“pip install pywin32”来安装它。

安装完毕后,在Python安装路径下的Lib\site-packages\win32可以看到所有的API⽀撑模块,Lib\site-packages\win32com下则是COM的⽀撑模块。

在Lib\site-packages下有⼀个PyWin32.CHM帮助⽂件,相信对Windows编程有⼀定基础的,看了这个帮助⽂件就能很快上⼿。

简单说,pywin32把Windows API按照功能分了⼀些⼤类,每⼀个⼤类作为⼀个模块。

以下是所有的模块:mmapfile odbc perfmon servicemanager timer win2kras win32api win32clipboard win32consolewin32cred win32crypt win32event win32evtlog win32file win32gui win32help win32inet win32jobwin32lz win32net win32pdh win32pipe win32print win32process win32profile win32ras win32securitywin32service win32trace win32transaction win32ts win32wnet winxpgui⽐如⽂件类API就在模块win32file中,进程类API在模块win32process中。

汇编语言第六章

汇编语言第六章

三.中断向量表
3. 设置或取出中断向量指令 (1) 设置中断向量指令 功能:把由AL指定的中断类型的中断向量DS:DX放入中
断向量表中。
(AH)= 25H
(AL)= 中断类型号
DS:DX = 中断向量 INT 21H
三.中断向量表
(2) 取出中断向量指令
功能:把AL中指定的中断类型的中断向量从中断
一、 WIN32编程基础
(2) 循环控制伪指令
格式:.WHILE 条件表达式 循环体 .ENDW 格式:.REPEAT 循环体 .UNTIL 条件表达式 格式:.CONTINUE 功能:终止本次循环, 开始下一次循环 格式:.BREAK 功能:退出当前循环
功能:实现循环结构
一、 WIN32编程基础
内中断的处理特点: ①中断类型号一般在指令中; ② 不受中断允许标志位IF的影响。
二、 中断源
2. 外中断 由外设控制器、协处理器等CPU以外的事件引起的中断, 称为外中断。 外中断的处理特点: ① 中断类型号由8259A提供,或由自制电路来提供;
② 受中断允许标志位IF的影响(IF=1,响应中断)。
个字节。
三.中断向量表
如:INT 4AH
中断向量地址 = 4AH*4 = 128H
DEBUG执行后, 用D命令查看: ―D0:0↙ … 执行INT 4AH时: IP=1805H CS=F000H IP F000: 1805 中断处理
0:128H
0:129H
05 18
0:12AH
0:12BH
00
F0 …
外设
二、 外设与主机传送的接口与信息
接口的组成:设备状态寄存器、设备控制寄存 器、数据寄存器。 I/O端口的地址空间:允许设置64K个8位端口 或32K个16位端口。 如:40H~43H时钟/定时器,60H~63H为 8255通讯芯片的接口。

罗云彬的Win32汇编教程

罗云彬的Win32汇编教程

罗云彬的Win32汇编教程之一Win32汇编的环境和基础1.32位环境简介在Dos下编汇编程序,我们可以管理系统的所有资源,我们可以改动系统中所有的内存,如自己改动内存控制块来分配内存,自己修改中断向量表来截获中断等,对其他操作也是如此,如我们对键盘端口直接操作就可以把键盘屏蔽掉,可以这样来描述Dos系统:系统只有一个特权级别,在编程上讲,任何程序和操作系统都是同级的,所以在Dos下,一个编得不好的程序会影响其他所有的程序,如一个程序把键盘口中断关掉了,所有程序就都不能从键盘获得键入的数据,直到任何一个程序重新打开键盘为止,一个程序陷入死循环,也没有其他程序可以把它终止掉。

Dos下的编程思路是“单任务”的,你只要认为你的程序会按照你的流程一步步的执行下去,不必考虑先后问题(当然程序可能会被中断打断,但你可以认为它们会把环境恢复,如果中断程序没有把环境恢复,那是他们的错)。

在内存管理方式上,Dos汇编和Win32汇编也有很多的不同:Dos工作在实模式下,我们可以寻址1M 的内存,寻址时通过段寄存器来制定段的初始地址,每个段的大小为64K,超过1M的部分,就只能把他作为XMS使用,也就是说,只能用作数据存放使用而无法在其中执行程序。

而Windows在保护模式下执行,这里所有的资源对应用程序来说都是被“保护”的:程序在执行中有级别之分,只有操作系统工作在最高级--0级中,所有应用程序都工作在3级中(Ring3),在Ring3中,你无法直接访问IO端口,无法访问其他程序运行的内存,连向程序自己的代码段写入数据都是非法的,会在Windows的屏幕上冒出一个熟悉的蓝屏幕来。

只有对Ring0的程序来说,系统才是全开放的。

在内存方面,Windows使用了处理器的分页机制,使得对应用程序来说,所有的内存都是“平坦”的,你不必用一个段寄存器去指定段的地址,因为在保护模式下,段寄存器的含义是不同的(可以参见80386手册方面的书籍),你可以直接指定一个32位的地址来寻址4GB的内存。

win32界面编程实例

win32界面编程实例

win32界面编程实例Win32 界面编程是使用 Microsoft Windows 的 Win32 API 进行应用程序开发的过程。

以下是一个简单的 Win32 应用程序示例,它创建一个窗口并在其中显示文本。

```c++include <>// 窗口过程函数的声明LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {// 注册窗口类WNDCLASS wc = {0};= WindowProcedure;= hInstance;= "SampleWindowClass";RegisterClass(&wc);// 创建窗口HWND hwnd = CreateWindow("SampleWindowClass", // 窗口类名"Hello, Win32!", // 窗口标题WS_OVERLAPPEDWINDOW, // 窗口风格CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, // 窗口位置和大小NULL, NULL, hInstance, NULL);if (hwnd == NULL) {return 0;}// 显示窗口ShowWindow(hwnd, nCmdShow);UpdateWindow(hwnd);// 消息循环MSG msg = {0};while (GetMessage(&msg, NULL, 0, 0)) {TranslateMessage(&msg);DispatchMessage(&msg);}return 0;}LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {switch (msg) {case WM_DESTROY:PostQuitMessage(0); // 退出消息循环break;default:return DefWindowProc(hwnd, msg, wParam, lParam); // 默认处理其他消息}return 0;}```这个程序首先注册一个窗口类,然后创建一个窗口,并显示它。

Win32汇编语言简明教程

Win32汇编语言简明教程

第一课基本概念我们先假设您已知道了如何使用MASM。

如果您还不知道的话,请下载win32asm.exe ,并请仔细研读其中所附带的文档资料。

好,如果您已准备就绪,我们这就开始吧!理论:WIN32 程序运行在保护模式下的,保护模式的历史可以追溯到 80286。

而今80286 已成为了历史。

所以我们将只把精力集中于 80386 及后续的X86 系列CPU。

Windows 把每一个 Win32 应用程序放到分开的虚拟地址空间中去运行,也就是说每一个应用程序都拥有其相互独立的 4GB 地址空间,当然这倒不是说它们都拥有 4GB 的物理地址空间,而只是说能够在 4GB 的范围内寻址。

操作系统将会在应用程序运行时完成 4GB 的虚拟地址和物理内存地址间的转换。

这就要求编写应用程序时必须格守 Windows 的规范,否则极易引起内存的保护模式错误。

而过去的 Win16 内存模式下,所有的应用程序都运行于同一个 4GB 地址空间,它们可以彼此"看"到别的程序的内容,这极易导致一个应用程序破坏另一个应用程序甚至是操作系统的数据或代码。

和 16 位 Windows 下的把代码分成 DATA,CODE 等段的内存模式不同,WIN32 只有一种内存模式,即 FLAT 模式,意思是"平坦"的内存模式,再没有 64K 的段大小限制,所有的 WIN32 的应用程序运行在一个连续、平坦、巨大的 4GB 的空间中。

这同时也意味着您无须和段寄存器打交道,您可以用任意的段寄存器寻址任意的地址空间,这对于程序员来说是非常方便的,这也使得用32位汇编语言和用C语言一样方便。

在Win32下编程,有许多重要的规则需要遵守。

有一条很重要的是:Windows 在内部频繁使用 ESI,EDI,EBP,EBX 寄存器,而且并不去检测这些寄存器的值是否被更改,这样当您要使用这些寄存器时必须先保存它们的值,待用完后再恢复它们,一个最显著的应用例子就是 Windows 的CallBack 函数中。

Windows编程基础新手入门

Windows编程基础新手入门

Windows编程基础基于Windows的编程方式有两种;一种是使用Windows的APIApplication Programming Interface,应用程序编程接口函数,通常用C/C++语言按相应的程序框架进行编程;这些程序框架往往就程序应用提供相应的文档、范例和软件开发工具包Software Development Kit,SDK,所以这种编程方式有时又称为SDK方式;另一种是使用“封装”方式,例如Visual C++的MFC方式,它是将SDK中的绝大多数函数、数据等按C++“类”的形式进行封装,并提供相应的应用程序框架和编程操作;事实上,无论是哪种编程方式,人们最关心的内容有三个:一是程序入口,二是窗口、资源等的创建和使用,三是键盘、鼠标等所产生的事件或消息的接收和处理;本章就来讨论这些内容;学习编程往往从简单的例子入手,例如一个C程序常有下列简单的框架代码:include <>int main{printf"Hello World\n"; / 输出 /return 0; / 指定返回值 /}事实上,该程序已包括C程序中最常用的include指令、必须的程序入口main函数、库函数printf调用和return语句;由于此程序是在早期的DOSDisk Operating System,磁盘操作系统环境的字符模型下运行的,因而printf函数所输出的都是字符流,也就是说,它在屏幕上输出一行文本“Hello World”;在Windows环境下,这里的屏幕就由控制台窗口来兼作,而基于Windows的上述C程序代码框架肯定是有所不同的;特别地,由于目前所在的Windows环境基本上都是32位,所以这里的Windows程序平台就是Win32,Windows编程可直接理解为是Win32编程;1.1.1 Windows等价程序等价的Windows程序可以写成:include <>int WINAPI WinMain HINSTANCE hInstance, HINSTANCE hPrevInstance,PSTR szCmdLine, int nCmdShow{MessageBox NULL, TEXT"Hello, World", TEXT"Hello", 0 ;return 0 ;}在深入剖析上述程序之前,先来看一看在Visual C++ 中的编辑、连接和运行的过程:①选择“开始”→“程序”→Microsoft Visual Studio →Microsoft Visual C++ ,运行Visual C++ ;第一次运行时,将显示如图所示的“每日提示”对话框;单击“下一条”按钮,可看到有关各种操作的提示;如果在“启动时显示提示”复选框中单击鼠标,去除复选框的选中标记“”,那么下一次运行Visual C++ ,将不再出现此对话框;单击“关闭”按钮关闭此对话框,进入Visual C++ 开发环境;②选择“文件”→“新建”菜单命令,打开应图“每日提示”对话框用程序向导,显示出“新建”对话框,如图所示;选择“工程”选项卡,从列表框中选中Win32 ApplicationWin32 应用程序项图中的标记1;③单击“位置”编辑框右侧的“浏览”按钮图中的标记2,从弹出的“选择目录”对话框指定项目所在的文件夹,如图所示图中的数字标记表示最经常的操作次序,下同;单击“确定”按钮,退出“选择目录”对话框,回到“新建”对话框中;需要说明的是,为了便于程序的管理和查找,本书所涉及的程序均放入Visual C++ 的工作文件夹“Visual C++程序”中,第1章程序放入子文件夹“第1章”中,第2章程序放入子文件夹“第2章”,依此类推;④在“新建”对话框的“工程名称”编辑框图中的标记3中,输入项目名称Ex_HelloMsg,保留“平台”下Win32复选框的默认“选中”状态,单击“确定”按钮进入下一步;⑤出现Win32 Application向导的“步骤1共1步”对话框,从中可选择要创建的应用程序类型:“一个空工程”、“一个简单的Win32程序”和“一个典型的"Hello World "程序”,如图所示;它们的区别在于:“一个空工程”仅创建Win32应用程序文件框架,不含任何代码;“一个简单的Win32程序”是在“一个空工程”基础上添加了程序框架有入口函数、include 指令等;“一个典型的‘Hello World’程序”在“一个简单的Win32程序”基础上增加了MessageBox函数调用,用来输出“Hello World”;图“新建”对话框“工程”选项卡图“选择目录”对话框⑥选中“一个空工程”,单击“完成”按钮,弹出“新建工程信息”对话框,如图所示;单击“确定”按钮,系统将按前面的选择自动创建此应用程序;图应用程序的向导对话框图“新建工程信息”对话框⑦再次选择“文件”→“新建”菜单命令,Visual C++将打开“新建”对话框并自动切换到“文件”选项卡,如图所示;在左侧的文件类型列表中选中C++ Source FileC++源文件,在右侧的“文件名”编辑框中输入“”或输入“”文件扩展名也可不输入,系统会自动添加cpp扩展名,cpp是C Plus Plus的缩写,是C++的意思;⑧单击“确定”按钮,系统将在创建的Win32项目工程Ex_HelloMsg中创建并添加一个新的文件,同时打开该文件窗口;现在可以在中输入前面例中的代码了;输完后,单击编译工具条上的“生成工具”按钮或直接按F7键,系统开始对Ex_HelloMsg项目工程中的文件进行编译、连接,同时在输出窗口中观察出现的内容,当出现errors, 0 warnings表示可执行文件已经正确无误地生成了;同时也可看到在文档窗口中所有代码的颜色都发生改变,这是Visual C++ 的文本编辑器所具有的语法颜色功能绿色表示注释,蓝色表示关键字等;⑨单击编译工具条上的“运行工具”按钮或直接按Ctrl+F5键,就可以运行刚刚生成的,结果如图所示;单击“确定”按钮,Hello对话框退出;图创建并添加程序文件图开发环境和运行结果1.1.2 头文件是一个include预处理指令开始,实际上在用C/C++编写的Windows应用程序的头部都可以看到这样的指令:include <>头文件是最主要的包含头文件,它还包含了其他一些Windows头文件; 例如:: 基本类型定义: 内核函数: 用户接口函数: 图形设备接口函数这些头文件定义了Windows的所有数据类型、函数调用、数据结构和符号常量,它们是Windows应用程序文档中的一个重要部分;1.1.3 程序入口函数在C/C++程序中,其入口函数都是main;但在Windows程序中,这个入口函数由WinMain 来代替;该函数是在中声明的,其原型如下:intWINAPIWinMainHINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd;可以看出,这个WinMain函数除了形参名、个数与main函数不同外,类型名也有了新的变化;下面就来分析:①WinMain函数被声明成为返回一个int值,同时WinMain函数名前还有WINAPI标识符的修饰;WINAPI是一种“调用约定”宏,它在中有如下定义:define WINAPI __stdcall所谓“调用约定”,就是指程序生成机器码后,函数调用的多个参数是按怎样的次序来传递,同时函数调用结束后堆栈由谁来恢复,以及编译器对函数名的修饰约定等的协议;函数调用约定“协议”有许多,其中由WINAPI宏指定的__stdcall是一个常见的协议,内容包括:参数从右向左压入堆栈;函数自身修改堆栈;机器码中的函数名前面自动加下划线,而函数后面接符号和参数的字节数;特别地,Visual C++的MFC方式却采用了__cdecl调用约定:参数从右向左压入堆栈;传递参数的内存栈由调用者来维护正因为如此可实现变参函数;机器码中的函数名只在前面自动加下划线;②WinMain函数的第一个和第二个参数都是HINSTANCE实例句柄类型;HINSTANCE中,H表示Handle,是“句柄”的意思;在Windows编程中,句柄是一个应用程序用来识别某些资源、状态、模块等的数字;由于句柄唯一标识着对应的资源、状态、模块等,因而使用句柄就是使调用相应的资源、状态、模块;当应用程序运行多次时,每一次都是应用程序的“实例”;由于同一个应用程序的所有实例都共享着应用程序的资源,因而程序通过检查hPrevInstance参数就可确定自身的其他实例是否正在运行;③WinMain函数的第三个参数lpCmdLine用来指定程序的命令行,其参数类型为LPSTR;但在中,却将其改为PSTR;这两种数据类型都是合法的,也都是指向字符串的指针类型;其中的STR是“STRING,字符串”的含义,是指以\0结尾的字符串,LP前缀表示“长指针”,在Win32中它与“P”前缀表示的“指针”含义相同;④WinMain函数的第四个参数nShowCmd用来指定程序最初显示的方式,它可以是正常、最大化或最小化来显示程序窗口;纵观上述参数和类型名可以发现它们的命名规则:●C/C++的类型名仍保留其小写,但新的类型都是用大写字母来命名;●参数名变量名都是采用“匈牙利表示法”的命名规则来定义的;它的主要方法是将变量名前后加上表示“类型”和“作用”的“前缀小写”,而变量名本身由“状态”、“属性”和“含义”等几个部分组成,每一个部分的名称可以是全称,也可以是缩写,但通常只有第一个字母是大写;例如,hPrevInstance则是由前缀h表示“句柄”类型+状态Prev表示“以前的”+属性Instance表示“实例”组成的;1.1.4 MessageBox函数MessageBox是一个Win32 API函数,用来弹出一个对话框窗口,显示短信息;该函数具有下列原型:int MessageBox HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType;其中,第一个参数hWnd用来指定父窗口句柄,即对话框所在的窗口句柄;第二、三个参数分别用来指定显示的消息内容lpText和对话框窗口的标题lpCaption,最后一个参数用来指定在对话框中显示的预定义的按钮和图标标识,它们是在定义的一组以MB_开始的常数组合;例如,下面是在中改变MessageBox的第四个参数;include <>int WINAPI WinMain HINSTANCE hInstance, HINSTANCE hPrevInstance,PSTR szCmdLine, int nCmdShow{MessageBox NULL, TEXT"Hello, World", TEXT"Hello",MB_ICONQUESTION | MB_ABORTRETRYIGNORE ;return 0 ;}程序运行后,结果如图所示;可见,MB_ICONQUESTION 用来指定在对话框中显示图标,而MB_ABORTRETRYIGNORE用来指定“终止”、“重试”和“忽略”按钮,类似这样的预定义标识还有很多,在以后讨论到MFC中的CWnd::MessageBox函数时还要讨论,故这里不再赘述;在程序中,调用MessageBox的实参中还涉及TEXT宏;在Windows编程中,TEXT宏是用来对UNICODE编码的字符串的支持;UNICODE是使用两个字节表示一个字符,这样单字节的ANSI字符和双字节的“汉字”的表示就统一起来了;在程序中使用图第四个参数的作用TEXT文本,无论在何Windows环境下均可显示正确的内容,而不会出现乱码的情形;另外,还有_TEXT 和_T宏等,在Visual C++中,它们的作用是等同的;窗口和消息MessageBox是通过创建的默认“窗口”来显示简单的信息:窗口标题、一行或多行文本、图标和按钮等;在Windows环境中,一个“窗口”就是屏幕上的一个矩形区域,它接收用户的输入,并以文本或图形方式来显示内容;事实上,“窗口”就是用户操作的区域界面,在编程中除创建等操作外,还要处理用户输入、窗口本身事件所产生的“消息”;1.2.1 程序框架代码为了能处理上述两个部分的内容:窗口创建和消息处理,Windows 提供了相应的程序框架,如下面的例子;include <>LRESULT CALLBACK WndProc HWND, UINT, WP ARAM, LP ARAM;客户区标题栏窗口边框其中,类名是已声明过的类的标识符,对象名可以有一个或多个,多个时要用逗号隔开;被定义的对象既可以是一个普通对象,也可以是一个数组对象或指针对象;例如:CStuscore one, Stu, Stus2;这时,one是类CStuscore的一个普通对象,Stu和Stus分别是该类的一个指针对象和对象数组;若对象是一个指针,则还可像指针变量那样进行初始化,例如:CStuscore two = &one;可见,在程序中,对象的使用和变量是一样的,只是对象还有成员的访问等手段;3.对象成员的访问一个对象的成员就是该对象的类所定义的数据成员和成员函数;访问对象的成员变量和成员函数与访问一般结构的变量的方法是一样的;对于普通对象,其访问格式如下:<对象名>.<成员变量><对象名>.<成员函数><参数表>例如,用来调用对象one中的成员函数getName,Stus0.getNo用来调用对象数组元素Stus0中的成员函数getNo;要注意,由于类的封装性,每个成员均有声明的访问属性,一个类对象只能访问该类的公有型成员,而对于私有型成员则不能访问,例如getName和getNo等公有成员可以由对象通过上述方式来访问,但strName、strStuNo、fScore等私有成员不能被对象来访问;若对象是一个指针,则对象的成员访问格式如下:<对象名>-><成员变量><对象名>-><成员函数><参数表>“->”是另一个表示成员的运算符,它与“.”运算符的区别是:“->”用来表示指向对象的指针的成员,而“.”用来表示一般对象的成员;需要说明的是,下面的两种表示是等价的对于成员函数也适用:<对象指针名>-><成员变量><对象指针名>.<成员变量>例如,two.getName与two->getName等价;可见,在C++中,类实际上是一种新的数据类型,它是对某一类对象的抽象;如同变量一样,用“类”也可定义一个对象,此时的对象称为类的实例;1.3.2 构造函数和析构函数事实上,一个类总有两种特殊的成员函数:构造函数和析构函数;构造函数的功能是在创建对象时,给数据成员赋初值,即给对象初始化;析构函数的功能是用来释放一个对象,在对象删除前,用它来做一些内存释放等清理工作,它与构造函数的功能正好相反;1.构造函数C++规定,在类的定义中是不能对数据成员进行初始化的;为了能给数据成员设置某些初值,这时就要使用类的特殊成员函数——构造函数;构造函数的最大特点是在对象建立时它会被自动执行,因此用于变量、对象的初始化代码一般放在构造函数中;C++规定,一个类的构造函数必须与相应的类同名,它可以带参数,也可以不带参数,与一般的成员函数定义相同,可以重载,也可以有默认的形参值;例如:include <>class CPerson{public:CPersonchar str, float h, float w // A:构造函数{strcpyname, str; height = h; weight = w;}CPersonchar str // B:构造函数{strcpyname, str;}CPersonfloat h, float w = 120; // C:构造函数public:void print{cout<<"姓名:"<<name<<"\t身高:"<<height<<"\t体重:"<<weight<<endl;}private:char name20; // 姓名float height; // 身高float weight; // 体重};CPerson::CPersonfloat h, float w{height = h; weight = w;}int main{CPerson one"DING";;CPerson two170, 130;;CPerson three"DING", 170, 130;;return 0;}include后面的是C++编译器自带的文件,称为C++库文件,它定义了标准输入/输出流的相关数据及其操作;cout表示标准输出流对象屏幕,“<<”是插入符,它将后面的内容插入到cout 中,即输出到屏幕上;程序运行的结果为:姓名:DING 身高:–+008 体重:–+008姓名:烫烫烫烫烫烫烫烫烫烫身高:170 体重:130姓名:DING 身高:170 体重:130分析和说明:①类CPerson定义了3个重载的构造函数程序中用A、B、C标明,这些构造函数的重载必须按其规定进行定义,要么参数个数不同,要么参数个数相同,但参数类型不相同;其中,构造函数CPersonfloat h, float w = 120,不仅设置了形参w的默认值,而且还将该构造函数的声明在类中进行,其定义在类体外实现;②在主函数main中,对象one的初始化等价于"DING",因而调用的是B构造函数,此时对象的私有数据成员name设定了初值“DING”,而height和weight初值没有指定,它们的初值取决于对象的存储类型,可能是默认值或无效值;③对象two的初始化等价于170, 130,因而调用的是C构造函数,此时对象的私有数据成员height和weight初值分别设定为170、130,而name初值没有指定,它可能是默认值或无效值;④对象three的初始化等价于"DING", 170, 130,因而调用的是A构造函数,此时对象的私有数据成员name、height和weight初值分别设定为"DING"、170和130;可见,构造函数提供了对象的初始化方式;若没有定义任何构造函数,则编译自动为类隐式生成一个不带任何参数的默认构造函数,由于函数体是空块,因此默认构造函数不进行任何操作,仅仅为了对象创建时的语法需要;例如,对于CPerson类来说,默认构造函数的形式如下:CPerson // 默认构造函数的形式{ }默认构造函数的目的是使下列对象定义形式合法:CPerson one; // 即: ; 会自动调用默认构造函数此时,由于对象one没指定任何初值,因而编译会自动调用类中隐式生成的默认构造函数对其初始化;若当类定义中指定了构造函数,则隐式的默认构造函数不再存在,因此,若对于前面定义的CPerson类来说,若有:C Person four; // 错误则因为找不到默认构造函数而出现编译错误;此时,在类中还要给出默认构造函数的具体定义,即定义一个不带任何参数的构造函数,称为显式的默认构造函数,这样才能对four进行定义并初始化;另外,构造函数的访问属性必须是公有型public,否则上述的类对象定义也是错误的;2.析构函数与构造函数相对应的是析构函数Destructor;析构函数是C++类中另一个特殊的成员函数,它只是在类名称前加上一个“~”符号逻辑非,以与构造函数功能相反;其格式如下:< ~类名>{ … }当对象的生存期结束后,或者当使用delete释放由new来分配动态内存的对象时,析构函数会被自动调用;这样,数据成员尤其是用new为其开辟的内存空间的释放代码就可放入析构函数的函数体中,以便对象消失后自动调用;需要说明的是:①每一个类最多只能有一个析构函数,且应为public,否则类实例化后无法自动调用析构函数进行释放,但不能被重载,没有任何参数,也不返回任何值,函数名前也不能有任何关键词包括void;例如:class CPerson{public:…~CPerson { }// 析构函数…};②与类的其他成员函数一样,析构函数的定义也可在类体外进行,但必须指明它所属的类,且在类体中还必须有析构函数的声明;例如:。

win32界面编程 实例

win32界面编程 实例

win32界面编程实例
Win32界面编程是指使用Win32 API来创建Windows应用程序
的用户界面。

下面我将从不同角度给出一些Win32界面编程的实例。

1. 创建窗口,使用Win32 API可以创建一个基本的窗口应用程序。

首先需要注册窗口类,然后创建窗口并处理窗口消息。

通过设
置窗口类的属性和消息处理函数,可以实现窗口的基本功能,比如
响应用户输入、绘制图形等。

2. 控件和布局,Win32 API提供了一系列控件,比如按钮、文
本框、列表框等,可以通过创建这些控件来构建丰富的用户界面。

同时,可以使用布局管理技术来控制控件的位置和大小,以实现界
面的美观和合理布局。

3. 图形绘制,Win32 API允许开发者直接操作图形设备接口(GDI),从而实现自定义的图形绘制功能。

通过GDI可以绘制各种
图形、文本和图像,实现丰富多彩的界面效果。

4. 用户交互,Win32界面编程可以实现丰富的用户交互功能,
比如鼠标点击、键盘输入、菜单操作等。

通过响应用户的交互行为,
可以让应用程序更加灵活和易用。

5. 窗口管理,Win32 API提供了丰富的窗口管理功能,比如最大化、最小化、关闭窗口等。

开发者可以通过这些功能来管理应用程序的窗口,提升用户体验。

总之,Win32界面编程可以实现丰富多彩的Windows应用程序界面。

开发者可以通过灵活运用Win32 API提供的功能,创建出符合自己需求的界面效果。

希望以上实例可以帮助你更好地理解
Win32界面编程。

c语言编写win32程序

c语言编写win32程序

c语言编写win32程序C语言是一种广泛应用于编程领域的高级程序设计语言,而Win32则是指在Windows操作系统中使用C语言编写的程序。

本文将详细介绍如何使用C语言编写Win32程序,并探讨其相关知识和技巧。

我们需要了解Win32编程的基础知识。

Win32是Windows操作系统的一套API(应用程序编程接口),它提供了一组函数和数据结构,用于实现图形界面、文件操作、网络通信等功能。

在Win32编程中,我们需要熟悉这些API并学会如何调用它们来实现所需的功能。

在开始编写Win32程序之前,我们需要安装一个编译器,例如微软的Visual Studio。

安装完成后,我们就可以创建一个新的Win32项目,并开始编写代码了。

在编写Win32程序时,我们首先需要定义一个窗口类。

窗口类是窗口的模板,用于定义窗口的属性和行为。

我们可以使用Win32 API 中的RegisterClass函数来注册窗口类,并指定窗口的样式、消息处理函数等。

注册完成后,我们就可以使用CreateWindow函数来创建窗口实例,并显示在屏幕上。

创建窗口后,我们还需要处理窗口的消息。

在Win32编程中,窗口和其他组件之间通过消息进行通信。

当窗口接收到消息时,会调用相应的消息处理函数来处理该消息。

我们可以在消息处理函数中编写逻辑代码,对不同的消息进行不同的处理。

例如,当用户点击窗口的关闭按钮时,窗口会接收到WM_CLOSE消息,我们可以在消息处理函数中编写代码来响应该消息,并执行相应的操作。

除了处理消息外,我们还可以在Win32程序中添加其他功能。

例如,我们可以使用GDI(图形设备接口)来绘制图形和文字,使用文件操作函数来读写文件,使用网络通信函数来实现网络功能等。

通过调用这些函数,我们可以实现各种各样的功能,使我们的Win32程序变得更加强大和实用。

在编写Win32程序时,我们需要注意一些常见的问题。

首先,我们需要遵循Win32编程的规范和约定,例如使用正确的数据类型、遵循消息处理函数的约定等。

Win32编程

Win32编程

Win32编程此资料为ITjob软件开发教程网提供,特此分享,互相学习!C/C++/VC/MFC技术交流群:95453496一、Win32编程基本概念1、消息驱动在介绍Windows消息驱动概念之前,我们首先来回顾面向过程的程序结构:main()程序有明显的开始、中间过程和结束点,程序是围绕这个过程编写好相关的子过程,再把这些子过程串联在一起。

程序编好以后,该过程也就确定了,程序必须按照规定好的顺序执行:是否需要用户的输入、输入什么、程序取得用户输入以后做什么处理,处理完毕将结果显示给用户。

该过程一旦确定,程序的执行过程也是固定的,用户不能干预。

而Windows编程所采用设计思想是:消息驱动,又叫做事件驱动。

在这种程序结构中,程序没有明显的开始、结束,程序流程的控制由各种随机发生、不确定、没有预先设定顺序的事件的发生来触发。

是一个不断产生消息和处理消息的过程。

也就是说程序一运行开始处于等待消息状态,取得消息以后,就对该消息做出相应的处理,完成处理以后又进入等待消息的状态。

这种程序结构与Windows操作系统结合非常紧密,最明显一点就是消息的管理是由操作系统完成的。

应用程序从操作系统获得消息有两种方式:一种就是应用程序调用Windows提供的消息获取函数;另外一种就是回调函数,由操作系统自己调用。

这种消息驱动机制,有点像银行的柜台业务:早上八点,银行开门(Windows应用程序开始运行),每个营业员(Windwows线程)回到自己的柜台开始办公。

如果有顾客来办理相关业务(相当于Windows消息),那么对应的业务员就进行处理。

顾客来办理业务的时间以及业务类型都是随机的,如果某一时刻没有顾客办理业务并且没有到下班时间(Windows 应用程序退出)的话,那么相关的业务员进入等待状态。

所有的业务员不断重复该过程,直到下班(Windows应用程序退出)。

2、应用程序、操作系统、IO设备之间的相互关系3、窗口元素窗口:是Windows操作系统最重要最基本的一个概念。

Windows环境下32位汇编语言程序设计

Windows环境下32位汇编语言程序设计

谢谢观看
Windows环境下32位汇编语言程 序设计
2013年电子工业出版社出版的图书
01 内容简介
03 推荐
目录
02 作者简介 04 目录
基本信息
《Windows环境下32位汇编语言程序设计》是2013年电子工业出版社出版的图书,作者是罗云彬。本书通过 70多个实例逐步深入Win32汇编语言编程的方方面面,使读者能够快速入门并最终熟练地写出各种Windows应用程 序。
内Hale Waihona Puke 简介内容简介本书从编写应用程序的角度,从“Hello World!”这个简单的例子开始到编写多线程、注册表和网络通信 等复杂的程序,通过70多个实例逐步深入Win32汇编语言编程的方方面面。本书作者有十多年的汇编编程经验, 很清楚初学者在哪些地方会遇到问题,所以本书在系统全面地介绍Win32汇编编程的同时,也穿插了很多作者的 经验之谈,使读者能够快速入门并最终熟练地写出各种Windows应用程序。
推荐
推荐
本书从编写应用程序的角度,从“Hello World!”这个简单的例子开始到编写多线程、注册表和网络通信 等复杂的程序,通过70多个实例逐步深入Win32汇编语言编程的方方面面。本书作者有十多年的汇编编程经验, 很清楚初学者在哪些地方会遇到问题,所以本书在系统全面地介绍Win32汇编编程的同时,也穿插了很多作者的 经验之谈,使读者能够快速入门并最终熟练地写出各种Windows应用程序。
目录
目录
第1篇基础篇 第1章背景知识 2 1.1 Win32的软硬件平台 2 1.1.1 80x86系列处理器简史 2 1.1.2 Windows的历史 4 1.1.3 Win32平台的背后——Wintel联盟 6 1.2 Windows的特色 6 1.3必须了解的东西 7 1.3.1 80x86处理器的工作模式 7 1.3.2 Windows的内存管理 9 1.3.3 Windows的特权保护 17
相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

NULL ); //窗口创建数据指针
if( !hwnd ) return FALSE;
//显示并更新窗口
ShowWindow( hwnd, nCmdShow );
UpdateWindow( hwnd );
return TRUE;
}
//******************************************************************
wc.lpszMenuName = NULL;
wc.lpszClassName = "EasyWin";
//注册窗口类
RegisterClass( &wc );
//创建主窗口
hwnd = CreateWindow(
"EasyWin", //窗口类名称
"一个基本的Win32程序", //窗口标题
{
switch( message )
{
case WM_KEYDOWN://击键消息
switch( wParam )
{
case VK_ESCAPE:
MessageBox(hWnd,"ESC键按下了!","Keyboard",MB_OK);
break;
}
break;
这里有两个概念,一个是实例,一个是句柄。实例代表的是应用程序执行的整个过程和方法,一个应用程序如果没有被执行,只是存在于磁盘上,那么就说它是没有被实例化的;只要一执行,则说该程序的一个实例在运行。句柄,顾名思义,指的是一个对象的把柄。在Windows中,有各种各样的句柄,它们都是32位的指针变量,用来指向该对象所占据的内存区。句柄的使用,可以极大的方便Windows管理其内存中的各种对象。
PAINTSTRUCT ps;
hdc=BeginPaint( hWnd,&ps ); //取得设备环境句柄
SetTextColor(hdc, RGB(0,0,255)); //设置文字颜色
TextOut( hdc, 20, 10, hello, strlen(hello) );//输出文字
#include <windows.h>
#include <windowsx.h>
//函数声明
BOOL InitWindow( HINSTANCE hInstance, int nCmdShow );
LRESULT CALLBACK WinProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam );
wc.hInstance = hInstance;
wc.hIcon = LoadIcon( hInstance, IDI_APPLICATION );
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.hbrBackground = GetStockObject(WHITE_BRUSH);/*这里我编译的时候未通过,前面应该加上强制类型转换(BRUSH)*/
WS_OVERLAPPEDWINDOW, //窗口风格,定义为普通型
100, //窗口位置的x坐标
100, //窗口位置的y坐标
400, //窗口的宽度
300, //窗口的高度
NULL, //父窗口句柄
NULL, //菜单句柄
hInstance, //应用程序实例句柄
{
HWND hwnd; //窗口句柄
WNDCLASS wc; //窗口类结构
//填充窗口类结构
wc.style = CS_VREDRAW | CS_HREDRAW;
wc.lpfnWndProc = (WNDPROC)WinProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
//程序结束
return msg.wParam;
}
//******************************************************************
第三个参数是lpCmdLine,是指向应用程序命令行参数字符串的指针。如在Win95的“开始”菜单中单击“运行”,输入“easywin hello”,则此参数指向的字符串为“hello”。
最后一个参数是nCmdShow,是一个用来指定窗口显示方式的整数。这个整数值可以是SW_SHOW、SW_HIDE、SW_SHOWMAXIMIZED、SW_SHOWMINIMIZED等,关于这些值的含义,将在下一节说明。
第二个参数是hPrevInstance,它是用来标识该应用程序的前一个实例句柄。对于基于Win32的应用程序来说,这个参数总是NULL。这是因为在Win95操作系统中,应用程序的每个实例都有各自独立的地址空间,即使同一个应用程序被执行了两次,在内存中也会为它们的每一个实例分配新的内存空间,所以一个应用程序被执行后,不会有前一个实例存在的可能。也就是说,hPrevInstance这个参数是完全没有必要的,只是为了提供与16位Windows的应用程序形式上的兼容性,才保留了这个参数。在以前的16位Windows环境下(如Windows3.2),hPrevInstance用来标识与hInstance相关的应用程序的前一个句柄。
//**************************************
// 工程:easywin
// 文件:easywin.cpp
// 内容:一个基本的Win32程序//*******************************************************************
//*******************************************************************
//函数:WinMain()
//功能:Win32应用程序入口函数。创建主窗口,处理消息循环
//*******************************************************************
int PASCAL WinMain( HINSTANCE hInstance, //当前实例句柄
HINSTANCE hPrevInstance, //前一个实例句柄
LPSTR lpCmdLine, //命令行字符
int nCmdShow) //窗口显示方式
{
MSG msg;
尽管Windows应用程序千变万化,令人眼花缭乱,但,消息机制和窗口过程却始终它们的基础,掌握了这两项技术,也就相当于把握住了问题的关键。
如果你以前是C程序员或是MFC的忠实用户,只要你学习过C语言的语法,自己亲手编过一些简短的C程序,理解以下的Win32编程基础也不是一件困难的事。
一个最简单的Win32程序
EndPaint( hWnd, &ps ); //释放资源
break;
}
case WM_DESTROY://退出消息
{
PostQuitMessage( 0 );//调用退出函数
break;
}
//调用缺省消息处理过程
return DefWindowProc(hWnd, message, wParam, lParam);
//函数:InitWindow()
//功能:创建窗口。
//******************************************************************
static BOOL InitWindow( HINSTANCE hInstance, int nCmdShow )
再次选择File菜单的New,在出现的对话框中,选择Files栏目(新建文件),并点取其下的C++ Source File项,表示新建一个C++源文件。在右边的File栏中输入“EasyWin”,最后确定让Add to project检查框打上勾 )。单击OK按钮。
在EasyWin.cpp文件中输入以下源程序代码。
//创建主窗口
if ( !InitWindow( hInstance, nCmdShow ) )
return FALSE;
//进入消息循环:
//从该应用程序的消息队列中检取消息,送到消息处理过程,
//当检取到WM_QUIT消息时,退出消息循环。
while (GetMessage(&msg, NULL, 0, 0))
在以前的C语言编程中,一个最简单的程序可以只有两行。
void main(void)
{ printf "Hello World!"; }
而要实现同样功能的Windows程序却最少也要写几十行,这并不是说明Windows应用程序效率低下,难于掌握,只是说明程序在Windows环境下有更丰富的内涵。Windows程序的效率其实不低,在所有的Windows应用程序中,都有一个程序初始化的过程,这得用上几十条语句,这段初始化的代码对于任何Windows应用程序而言,都是大同小异的。下面以一个实现最简单功能的程序EasyWin为例,说明Windows程序的基本框架。
case WM_RBUTTONDOWN://鼠标消息
{
MessageBox(hWnd,"鼠标右键按下了!","Mouse",MB_OK);
相关文档
最新文档