windows消息运行机制
windows操作系统原理

windows操作系统原理Windows操作系统原理是指Windows操作系统设计与实现的基本原理和机制。
Windows操作系统是由微软公司开发的一种面向个人计算机的操作系统。
Windows操作系统的原理包括以下几个方面:1. 多任务管理:Windows操作系统采用了抢占式的多任务处理机制,通过任务调度器来管理多个任务的执行。
每个任务独立运行在自己的进程中,操作系统根据进程的优先级和时间片来进行任务调度。
2. 内存管理:Windows操作系统使用虚拟内存管理机制,将物理内存划分为多个页框,每个进程有自己的虚拟地址空间。
操作系统通过分页机制将虚拟内存映射到物理内存中,以便实现进程间的隔离和保护。
3. 文件系统:Windows操作系统使用NTFS文件系统作为默认的文件系统。
NTFS文件系统支持文件和目录的权限控制、文件压缩和加密等功能。
4. 设备管理:Windows操作系统通过设备驱动程序来管理硬件设备。
每个设备驱动程序负责与特定设备的通信,并提供统一的接口供应用程序调用。
5. 网络通信:Windows操作系统支持TCP/IP协议栈,并提供了各种网络通信服务,如网络协议栈、网络接口、套接字接口等,以实现应用程序之间的网络通信。
6. 用户界面:Windows操作系统提供了图形用户界面(GUI),包括窗口管理、菜单、对话框等,使得用户可以通过鼠标、键盘等输入设备与计算机进行交互。
7. 安全性:Windows操作系统通过用户账户和权限管理来保护系统和用户数据的安全性。
每个用户都有自己的账户,并且可以通过权限控制来限制对文件和系统资源的访问。
这些原理和机制共同构成了Windows操作系统的核心。
通过合理地设计和实现,Windows操作系统能够提供稳定、安全、高效的计算环境,满足用户的各种需求。
板书5

板书:1、在编写控制台程序的时候一切流程都是有先后关系、并行的,而且所有函数都是由我们来调用的,比如下面的实例性代码:printf("确定请输入y,取消输入n");char c = getchar();if(c=='y'){///}else if(c=='n'){///}我们可以用getchar来等待用户输入一个值。
但是到了Windows编程中就不一样了,同一时刻用户即可能点击【OK】按钮,又可能点击【Cancel】按钮,又可能在文本框中输入几个字,还可能在窗口上双击几下,这样就无法同时等待用户的这些动作。
为了解决这个问题,Windows引入了消息机制(也可以叫做回调机制或者事件机制)。
在程序启动的时候把函数func1要响应【OK】按钮1的点击动作、函数func2要响应【Cancel】按钮的点击动作、函数func3要响应窗口的双击动作等等这些信息告诉Windows,然后当用户执行相应操作的时候Windows就会来主动调用你注册的函数,主动通知你。
不再是程序调用操作系统的函数,而是操作系统反过来调用你的函数。
Don't call me ,I'll call you!(也被人称为“好莱坞法则”)。
2、关于上面的这个问题要慢慢来理解,下面就来通过第一个例子来初步理解这个Don't call me ,I'll call you!创建一个对话框程序,然后来分析代码。
看Main_OnCommand方法,初探windows的消息机制。
void Main_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify){switch(id){case IDC_OK:MessageBox(hwnd,"You click OK!","Test003",MB_OK);EndDialog(hwnd, id);break;case IDC_CANCEL:MessageBox(hwnd,"You click Cancel!","Test003",MB_OK);EndDialog(hwnd, id);break;default:break;}}按钮被按下的时候Main_OnCommand方法被调用,hwnd是对话框句柄(什么是句柄后面讲,通俗的说就是通过它能够操纵对话框),id是控件的id,后两个参数暂时不关心。
sendmessage用法

sendmessage用法Sendmessage是一种非常常见的Windows API,它能够在应用程序之间传递消息,并执行一些操作。
在本篇文章中,我们将深入探讨sendmessage的用法,为大家提供一些有用的技巧和技巧。
一、理解Sendmessage函数的原理及参数Sendmessage可以理解为发送消息的函数。
它的完整原型如下:LRESULT SendMessage(HWND hWnd, //消息目标窗口的句柄UINT Msg, //消息IDWPARAM wParam, //消息的额外参数(可能是一个值或者指针)LPARAM lParam //消息的额外参数(可能是一个值或者指针));其中,hWnd为消息目标窗口的句柄,Msg为消息ID,wParam和lParam 分别是消息所需要的参数。
例如,如果您想要发送一条命令消息(如WM_COMMAND)给一个窗口控件,您需要提供控件的句柄(hWnd)和控件的ID(Msg),并将wParam和lParam设置为所需的附加参数。
二、使用Sendmessage函数发送消息发送消息的过程非常简单。
首先,您需要确定消息的接收方窗口的句柄。
一旦您有了这个,您只需要使用Sendmessage函数提供的控制信息,将消息发送给这个句柄就可以了。
下面是一个示例,展示了如何使用sendmessage函数在一个应用程序之间发送消息:例子1:向另一程序发送消息HWND hWndTarget = FindWindow(NULL, L"目标应用程序"); //查找目标窗口的句柄int msgID = RegisterWindowMessage(L"MY_MESSAGE"); //注册自定义消息SendMessage(hWndTarget, msgID, (WPARAM)hwnd, (LPARAM)nIndex); //发送自定义消息在这个例子中,由于使用了注册自定义消息的办法,你可以在不同的应用程序之间发送消息,并进行一些交互操作。
mfc工作原理

mfc工作原理MFC(Microsoft Foundation Classes)是微软公司开发的一套用于Windows操作系统的应用程序框架,它在C++语言的基础上封装了一些常用的图形用户界面(GUI)功能,简化了Windows应用程序的开发过程。
本文将围绕MFC的工作原理展开阐述。
MFC的工作原理主要包括以下几个方面:1. 类库结构:MFC是一个面向对象的类库,它由一系列C++类组成。
这些类封装了Windows API的功能,提供了一种更加便捷的方式来创建和管理Windows应用程序。
MFC的类库结构包含了一些基本的类,如CObject、CWnd和CFrameWnd等,以及一些用于界面设计的类,如CButton、CEdit和CListBox等。
2. 消息映射机制:在MFC中,窗口类派生自CWnd类,通过消息映射机制来处理用户输入、系统消息等事件。
当用户操作窗口时,例如点击按钮、拖动滚动条等,系统会生成相应的消息,MFC会将这些消息映射到窗口类的成员函数上进行处理。
开发者只需重载对应的成员函数,就可以实现自定义的响应逻辑。
3. 对话框和控件:MFC提供了对话框和控件的封装,使得开发者可以方便地创建和管理用户界面。
对话框是一个独立的窗口,可以包含各种控件,如按钮、文本框、列表框等。
开发者可以使用MFC 提供的类来创建和设置对话框及其控件,通过消息映射机制来处理用户操作。
4. 文档视图模型(Document-View模式):MFC采用了文档视图模型来处理应用程序的数据和界面显示。
开发者可以通过MFC提供的类来创建文档类和视图类,文档类用于管理应用程序的数据,视图类用于显示和编辑数据。
MFC会自动处理文档和视图之间的关联,使得数据的修改能够实时反映到界面上。
5. 消息循环:MFC应用程序在启动后会进入一个消息循环,不断地接收和处理消息。
消息循环负责分发消息,并将消息传递给对应的窗口类进行处理。
MFC提供了一个消息映射表,用于将消息和相应的处理函数关联起来。
C#Hook

C#Hook前⾔ 在说C# Hook之前,我们先来说说什么是Hook技术。
相信⼤家都接触过外挂,不管是修改游戏客户端的也好,盗取密码的也罢,它们都是如何实现的呢? 实际上,Windows平台是基于事件驱动机制的,整个系统都是通过消息的传递来实现的。
当进程有响应时(包括响应⿏标和键盘事件),则Windows会向应⽤程序发送⼀个消息给应⽤程序的消息队列,应⽤程序进⽽从消息队列中取出消息并发送给相应窗⼝进⾏处理。
⽽Hook则是Windows消息处理机制的⼀个平台,应⽤程序可以在上⾯设置⼦程以监视指定窗⼝的某种消息,⽽且所监视的窗⼝可以是其他进程所创建的。
当消息到达后,在⽬标窗⼝处理函数之前处理它。
钩⼦机制允许应⽤程序截获处理window消息或特定事件。
所以Hook就可以实现在键盘/⿏标响应后,窗⼝处理消息之前,就对此消息进⾏处理,⽐如监听键盘输⼊,⿏标点击坐标等等。
某些盗号⽊马就是Hook了指定的进程,从⽽监听键盘输⼊了什么内容,进⽽盗取账户密码。
C# Hook 我们知道C#是运⾏在.NET平台之上,⽽且是基于CLR动态运⾏的,所以只能操作封装好的函数,且⽆法直接操作内存数据。
⽽且在C#常⽤的功能中,并未封装Hook相关的类与⽅法,所以如果⽤C#实现Hook,必须采⽤调⽤WindowsAPI的⽅式进⾏实现。
WindowsAPI函数属于⾮托管类型的函数,我们在调⽤时必须遵循以下⼏步: 1、查找包含调⽤函数的DLL,如User32.dll,Kernel32.dll等。
2、将该DLL加载到内存中,并注明⼊⼝ 3、将所需参数转化为C#存在的类型,如指针对应Intptr,句柄对应int类型等等 4、调⽤函数 我们本篇需要使⽤的函数有以下⼏个: SetWindowsHookEx ⽤于安装钩⼦ UnhookWindowsHookEx ⽤于卸载钩⼦ CallNextHookEx 执⾏下⼀个钩⼦ 详细API介绍请参考MSDN官⽅声明 接下来在C#中需要⾸先声明此API函数:[DllImport("user32.dll",CharSet=CharSet.Auto,CallingConvention=CallingConvention.StdCall)]public static extern int SetWindowsHookEx(int idHook, HookProc lpfn,IntPtr hInstance, int threadId);[DllImport("user32.dll",CharSet=CharSet.Auto,CallingConvention=CallingConvention.StdCall)]public static extern bool UnhookWindowsHookEx(int idHook);[DllImport("user32.dll",CharSet=CharSet.Auto,CallingConvention=CallingConvention.StdCall)]public static extern int CallNextHookEx(int idHook, int nCode,IntPtr wParam, IntPtr lParam); 声明后即可实现调⽤,SetWindowsHookEx()把⼀个应⽤程序定义的钩⼦⼦程安装到钩⼦链表中,SetWindowsHookEx函数总是在Hook链的开头安装Hook⼦程。
windows(2)

第1大题:单选题(重要题:共40题,每题1分,难中易比例2:4:4)1.在Windows编程约定中,软件开发包的英文缩写是______。
(易| 重要)A. APIB. SDIC. SDKD. MDI正确答案:C2.以下对应于unsigned long 的数据类型为:()(易| 重要)A. WORDB. DWORDC. INTD. BYTE正确答案:B3.如果要严格按照匈牙利命名法命名1个全局窗口句柄,以下变量命名正确的是()。
(中| 重要)A. g_hWndB. m_hWndC. g_pWndD. m_pWnd正确答案:A4.典型的Windows窗口程序的流程为:()(中| 重要)A. 注册窗口类->创建窗口->显示窗口->更新窗口->消息循环B. 创建窗口->注册窗口类->显示窗口->更新窗口->消息循环C. 创建窗口->注册窗口类->显示窗口->更新窗口->消息循环D. 注册窗口类->创建窗口->更新窗口->显示窗口->消息循环正确答案:A5.GDI环境中,窗口的坐标系是如何构成的?(易| 重要)A. 左上角为原点,x轴正方向为水平向右,y轴正方向为竖直朝上B. 中间为原点,x轴正方向为水平向右,y轴正方向为竖直朝上C. 左下角为原点,x轴正方向为水平向右,y轴正方向为竖直朝下D. 左上角为原点,x轴正方向为水平向右,y轴正方向为竖直向下正确答案:D6.Windows编程中,定时器消息是()(易| 重要)A. WM_TIMEB. WM_TIMERC. WM_ON_TIMED. WM_COMMAND正确答案:A7.设备环境DC的全称为:(易| 重要)A. Device ContentB. Device ContextsC. Device ConfigD. Device Conter正确答案:B8.进程最常见和最理想的结束方式为:()(中| 重要)A. 主线程的入口函数返回B. 进程中的一个线程调用ExitProcess函数C. 另一个进程中的线程调用TerminateProcess函数D. 进程中的所有线程自行终止运行正确答案:A9.线程正常结束的方式是:()(中| 重要)A. 线程函数返回B. 调用ExitThread函数C. TerminateThreadD. 包含线程的进程终止运行正确答案:A10.两个没有任何安全措施的线程同时对一个数作自增(++)运算,以下说法正确的是:()(难| 重要)A. 自增(++)是原子操作,不会出现错误B. 自增(++)是原子操作,但是两个加法先后顺序未知C. 自增(++)不是原子操作,最后结果是加2D. 自增(++)不是原子操作,最后结果不一定是2正确答案:D11.SetWaitableTimer的参数lPeriod如果为正值,单位是什么?(中| 重要)A. 分钟(m)B. 秒(s)C. 毫秒(ms)D. 纳秒(ns)正确答案:C12.在MFC编程中,如果要显示1个树型视图,那么适合选用的视图类是()。
windows r3 与r0通信原理
windows r3 与r0通信原理Windows R3与R0通信原理Windows操作系统是当今世界上最为流行的操作系统之一,它提供了许多强大的功能和便捷的用户界面。
在Windows操作系统中,R3和R0是两个重要的层次,它们分别代表用户态和内核态。
本文将深入探讨Windows R3与R0之间的通信原理。
我们要了解R3和R0的含义。
R3是指Ring 3,即用户态,它是操作系统的最高层次之一。
在R3中,运行着应用程序和用户进程,它们可以访问用户空间的资源,如内存、文件等。
R0是指Ring 0,即内核态,它是操作系统的最低层次。
在R0中,运行着操作系统的内核,它负责管理硬件资源和提供系统服务。
在Windows操作系统中,R3和R0之间的通信是通过系统调用来实现的。
系统调用是一种机制,允许用户态程序向内核态请求服务。
当一个应用程序需要访问受限资源时,它可以通过系统调用请求操作系统的帮助。
例如,当一个应用程序需要读取一个文件时,它可以通过系统调用请求操作系统打开并读取该文件。
具体来说,当一个应用程序发起系统调用请求时,操作系统会将该请求传递给R0中的内核。
内核会根据请求的类型和参数执行相应的操作,并将结果返回给应用程序。
这个过程涉及到用户态和内核态之间的切换。
当应用程序发起系统调用时,它会触发一个特殊的异常,将控制权转移到内核态。
内核会在完成请求后,将控制权再次转移到用户态,使应用程序可以继续执行。
在系统调用中,应用程序和内核之间的通信是通过参数传递的。
应用程序将请求的类型和参数传递给内核,内核根据这些参数执行相应的操作。
参数的传递可以通过寄存器、栈或共享内存等方式进行。
具体的参数传递方式取决于操作系统的实现和架构。
除了系统调用,Windows操作系统还提供了其他的通信机制,如进程间通信(IPC)。
IPC允许不同的应用程序之间进行数据交换和共享资源。
在Windows操作系统中,IPC可以通过命名管道、共享内存、消息队列等方式实现。
什么是Windows钩子
什么是Windows钩子1. Windows钩子简介在DOS操作系统下编程的时候,如果想截获某种系统功能,可以采取截获中断的办法,比如要获取击键的动作可以截获9号中断,要获取应用程序对文件操作功能的调用可以截获21h号DOS中断,由于DOS是单任务系统,所以这些操作几乎全部是内存驻留程序做的。
DOS下截获中断的方法是这样的简单和随意,不管在驱动程序层次还是在应用程序层次都可以完成,以至于到最后大半的截获操作是由病毒使用的。
在Windows下就不同了,我们已经知道保护模式下的中断描述符表是受系统保护的,在应用程序层次是不可能再通过修改中断向量来截获系统中断了,但这样也对一些应用造成了不便,当做一种变通的措施,Windows提供了钩子来完成类似的功能。
那么,钩子是什么呢?Win32 API手册中是这样描述的:“A hook is a point in the Microsoft Windows message-handling mechanism where an application can install a subroutine to monitor the message traffic in the system and process certain types of messages before they reach the target window procedure.”翻译过来就是:“钩子是Windows的消息处理机制中的一个监视点,应用程序可以在这里安装一个监视子程序,这样就可以在系统中的消息流到达目的窗口过程前监控它们。
”也就是说,钩子可以用来截获系统中的消息流,显然,钩子不是像截获中断一样用来随心所欲地截获系统底层功能的,那么钩子能够用来做什么事情呢?(我仿佛听到了一些阴险的笑声……)不用笑得这么阴险嘛!大家想得没错,如果把钩子用在后台执行的程序中,就能够偷偷检查任何程序中发生的WM_CHAR消息,这样用户输入的任何内容:账号、密码、情书——不管是什么,不管是否显示在屏幕上——都可以被记录下来。
WPF的消息机制(二)- WPF内部的5个窗口之隐藏消息窗口
WPF的消息机制(二)- WPF内部的5个窗口之隐藏消息窗口目录WPF的消息机制(一)-让应用程序动起来WPF的消息机制(二)-WPF内部的5个窗口(1)隐藏消息窗口(2)处理激活和关闭的消息的窗口和系统资源通知窗口(3)用于用户交互的可见窗口(4)用于UI窗口绘制的可见窗口WPF的消息机制(三)-WPF输入事件的来源WPF的消息机制(四)-WPF中UI的更新WPF内部的5个窗口对于Windows系统来说,它是一个消息系统,消息系统的核心就是窗口。
对于WPF来说也是如此。
那么WPF内部为什么需要窗口,又存在哪些窗口呢?在上一篇,我们频繁的提及“线程”,“Dispatcher”其实,运行WPF应用程序所在的线程就是WPF所谓的UI线程,在Application.Run之后,调用Dispatcher.Run时会检查当前线程是否已经存在了一个Dispatcher对象,如果没有就构造一个,在这里,一个线程对应一个Dispatcher。
因此,WPF的对象在获取this.Dispatcher属性时,不同对象取的都是同一个Dispatcher实例。
另外,前面提到的“消息循环”,“消息队列”等都是Win32应用程序的概念,我们知道,提起这些概念,必然会跟Win32的“窗口”,“Handle”,“WndProc”之类的概念离不开,那么WPF里面究竟有没有“窗体”,“Handle”,“WndProc”呢?我想说的是:有,还不止一个,只不过没有暴露出来,外面不需要关心这些。
通常情况下,一个WPF应用程序在运行起来的时候,后台会创建5个Win32的窗口,帮助WPF系统来处理操作系统以及应用程序内部的消息。
在这5个窗口中,只有一个是可见的,可以处理输入事件与用户交互,其他4个窗口都是不可见的,帮助WPF处理来自其他方面的消息。
接下来我会来介绍究竟这5个Win32的窗口如何帮助WPF处理消息,我会根据每个窗口创建的顺序来介绍。
mfc框架的基本运行原理
MFC框架的基本运行原理一、概述MFC(Microsoft Foundation Classes)是微软公司开发的基于C++的框架库,用于开发Windows应用程序。
MFC框架的基本运行原理是通过提供一系列的类和函数,封装了Windows操作系统的API,使开发者能够更加方便地创建、管理和操作Windows应用程序的各种界面元素。
二、MFC框架结构MFC框架的结构可以分为以下几个主要部分:1. 应用程序类MFC应用程序类(CWinApp)是MFC框架的入口点,一个MFC应用程序只能有一个应用程序类的实例。
应用程序类负责初始化MFC框架,创建主窗口,处理消息循环等。
2. 窗口类MFC窗口类(CWnd)是应用程序中各个窗口的基类,包括主窗口、对话框等。
窗口类负责创建和管理窗口对象,并处理窗口消息。
3. 控件类MFC控件类(CButton、CEdit、CListCtrl等)是MFC框架提供的一系列封装了Windows操作系统控件的类。
通过使用控件类,开发者可以快速创建和使用各种常见的窗口控件。
4. 文档视图模型类MFC文档视图模型类(CDocument、CView)是MFC框架中用于实现文档视图模型的基类。
文档类负责处理文件的读写和数据的保存,视图类负责显示数据并响应用户输入。
三、MFC消息循环MFC框架是事件驱动的,通过消息循环来处理用户输入和系统消息。
消息循环是一个无限循环,等待用户输入和系统消息的到来,然后将消息分发给相应的窗口进行处理。
消息循环的基本流程如下:1.调用消息循环函数,如AfxWinMain。
2.接收并分发消息,包括用户输入和系统消息。
3.若消息为退出消息,则退出消息循环;否则,将消息发送给相应的窗口进行处理。
4.窗口处理消息,并根据消息类型执行相应的操作。
MFC框架通过封装Windows操作系统的消息机制,使开发者能够以面向对象的方式处理消息,并将消息与具体的窗口对象关联起来。
四、MFC的事件处理机制MFC框架提供了一种基于消息映射的事件处理机制,通过事件处理函数来响应用户输入和系统消息。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1.消息 在windows程序中,消息是由MSG结构体来表示的。 typedfstructtagMSG( HWND hwnd; //消息所属窗口 UINT message; //指定消息的标识符,不同的消息对应不同的数值,但是由于数值不便于记忆,windows将消息对应的数值定义为WM_XXX宏。例如WM_LBUTTONDOWN; WPARAM wParam; // wParam和lParam用于指定消息的附加信息 LPARAM lParam; DWORD time; //表示消息投递到消息队列中的时间 POINT pt; //表示鼠标的当前位置 )msg;
2.WinMain函数的定义 int WINAPI WinMain( HINSTANCE hInstance, //表示该程序当前运行的实例的句柄,这好似一个数值 HINSTANCE hPrevInstance, //表示当前实例的前一个实例的句柄 LPSTR lpCmdLine, //一个以空终止的字符串 intnCmdShow //指定程序的窗口应该如何显示 ); 3.窗口的创建 ①设计一个窗口; ②注册窗口; ③创建窗口; ④显示及更新窗口。 (1) 设计一个窗口类 typedefstruct _WNDCLASS( UINT style; //指定这一类型窗口的样式 WNDPROC lpfnWndProc; //函数指针,指向窗口过程函数 intcbClsExtra; //类附加内存 intcbWndExtra; HANDLE hInstance; //包含窗口过程的程序的实例句柄 HICON hIcon; //指定窗口的图标句柄 HCURSOR hCursor; //指定窗口类的光标句柄 HBRUSH hbrBackground; //指定窗口类的背景画刷句柄 LPCTSTR lpszMenuName; //一个以空终止的字符串,指定菜单资源的名字 LPCTSTR lpszClassName; //一个以空终止的字符串。指定窗口类的名字 )WNDCLASS; (2) 注册窗口类 ATOM RegisterClass(CONST WNDCLASS *lpfnWndClass); //只有一个参数,即窗口类对象的指针 (3) 创建窗口 HWND CreateWindow( LPCTSTR lpClassName, //指定窗口类的名字 LPCTSTR lpWindowName,//指定窗口的名字 DWORD dwStyle, //指定创建窗口的样式 int x, //x.y,nWidth,nHeight分别指定窗口左上角的x,y坐标和窗口的宽度,高度 int y, // intnWidth, // intnHeight, // HWND hWndparent, //指定被创建窗口的父窗口句柄 HMENU hMenu, //指定窗口菜单的句柄 HANDLE hInstance, //指定窗口所属的应用程序实例的句柄 LPVOID lpParm, //作为WM_CREATE消息的附加参数lParam传入的数据指针 ); (4) 显示及更新窗口 BOOL ShowWindow( HWND hWnd, //创建窗口后返回的句柄 intnCmdShow //指定窗口的显示状态 ); BOOL UpdateWindow( HWND hwnd //创建窗口后返回的句柄 );
4.消息循环 BOOL GetMessage( LPMSG lpMsg, //指向一个消息结构体,GetMessage从线程的消息队列中取出的消息信息将保存在该结构体对象中 HWND hwnd, // 指定接收属于哪一个窗口的消息 UINT wMsgFilterMin, //指定要获取消息的最小值 UINT wMsgFilterMax //指定要获取消息的最大值 ); 例: /***************************************************** GetMessage函数只有在接收到WM_QUIT消息时才返回0。才会挑出 while循环。否则将始终处于运行状态 ******************************************************/ MSG msg while(GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); //翻译消息 DispatchMessage(&msg); //将消息回传给操作系统 }
5.编写窗口过程函数 LRESULT CALLBACK windowProc( HWND hwnd, //窗口句柄 UINT uMsg, //消息代码,由TranslateMessage翻译得到 WPARAM wParam, //消息附加参数 LPARAM lParam //消息附加参数 ); //窗口过程函数的名字可以随便取,在窗口过程函数内部使用switch/case语句来确定窗口过程接收到的是什么消息 例: switch(uMag) { case WM_CHAR: ...... break; case WM_LBUTTONDOEN://用户左击 MessageBox(hwnd,"mouse clicked","message",0);//弹出消息窗口告诉用户点击了鼠标 HDC hdc;//创建一个DC对象 hdc=GetDC(hwnd);//用hdc保存GetDC函数返回的与特定窗口相关联的DC的句柄 TextOut(hdc,0,50,"陈祥",strlen("陈祥"));//在窗口(0,50)的位置处输出一行文字 ReleaseDC(hwhdc,hdc);//释放DC所占用的资源,否则会引起内存泄漏 break; . . . . default; returnDefWindowProc(hwnd,uMag,wParam,lParam); };
创建一个Win32应用程序的步骤: ①编写WinMain函数,可以在MSDN上查找并复制; ②设计窗口类; ③注册窗口类; ④创建窗口; ⑤显示并更新窗口; ⑥编写消息循环; ⑦编写窗口过程函数。窗口过程函数的语法,可通过MSDN查看WNDCLASS的lpfnWndProc成员变量,在这个成员的解释中可以查到。 WinMain.cpp /****************************************************** 这是一个Win32 Application类型的项目,主要功能是建立一个窗口 *******************************************************/ #include #include
LRESULT CALLBACK WinSunProc( HWND hwnd, //窗口句柄 UINT uMsg, //消息代码,由TranslateMessage翻译得到 WPARAM wParam, //消息附加参数 LPARAM lParam //消息附加参数 );
int WINAPI WinMain( HINSTANCE hInstance, //表示该程序当前运行的实例的句柄,这好似一个数值 HINSTANCE hPrevInstance, //表示当前实例的前一个实例的句柄 LPSTR lpCmdLine, //一个以空终止的字符串 intnCmdShow //指定程序的窗口应该如何显示 ) { //设计一个窗口类 WNDCLASS wndcls; wndcls.cbClsExtra=0; wndcls.cbWndExtra=0; wndcls.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH); wndcls.hCursor=LoadCursor(NULL,IDC_CROSS); wndcls.hIcon=LoadIcon(NULL,IDI_INFORMATION); wndcls.hInstance=hInstance;//应用程序实例句柄由WinMain函数传进来 wndcls.lpfnWndProc=WinSunProc; wndcls.lpszClassName="chenxiang2016"; wndcls.lpszMenuName=NULL; wndcls.style=CS_HREDRAW | CS_VREDRAW; RegisterClass(&wndcls);
//创建一个窗口,定义一个变量用来保存成功创建窗口后返回的句柄 HWND hwnd; hwnd=CreateWindow("chenxiang2016","窗口测试",WS_OVERLAPPEDWINDOW, 0,0,600,400,NULL,NULL,hInstance,NULL);
//显示及刷新窗口 ShowWindow(hwnd,SW_SHOWNORMAL); UpdateWindow(hwnd);
//定义消息结构体,开始消息循环 MSG msg; while (GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } //用下面的while循环出现鼠标一碰到窗口就退出的现象 // BOOL bRet;