博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Visual C++ 2008入门经典 第十二章 Windows编程的概念
阅读量:5324 次
发布时间:2019-06-14

本文共 7769 字,大约阅读时间需要 25 分钟。

#include 
using namespace std;/*//第十二章 Windows编程的概念//窗口的基本结构//windows API的概念和用法//windows 消息的概念,如何处理windows消息//windows程序中常用的符号//windows程序中的基本结构//如何使用windows API创建简单的程序,该程序的工作原理//Micrsosft Foundation Classes//基于MFC的程序的基本元素//Windows Forms //Windows Forms应用程序的基本元素//12.1 Windows 编程基础//12.1.1 窗口的元素//12.1.2 windows程序与操作系统//12.1.3 事件驱动型程序//12.1.4 windows消息//12.1.5 Windows API//windows数据类型的完整列表/*BOOL和BOOLEAN boolean变量的值可以是TRUE或FALSE,注意,该类型与值为true或falsh的C++类型bool不同BYTE 8位字节CHAR 8位字符DWORD 32位无符号整数,对应于C++中的unsigned long类型HANDLE 指向某个对像的句柄,是32位的整数值,记录着该对像在内存中的位置HBRUSH 指向某个画刷的句柄,画刷用来以颜色填充某块区域HCURSOR 指向某个光标的句柄HDC 指向某种设备上下文的句柄-设备上下文是允许我们在窗口上绘图的对像HINSTANCE 指向某个实例的句柄LPARAM 消息的形参LPCSTR 指向某个由8位字符构成的,以空字符终止的字符串常量的指针LPHANDLE 指向某个句柄的指针LRESULT 处理消息产生的有符号数值WORD 16位无符号整数,对应于C++中的unsigned short类型//12.1.7 windows程序中的符号b BOOL类型的逻辑变量,等价于intby unsigned char 类型,占用一个字节c char类型dw DWORD类型,等价于unsigned longfn 函数h 用来引用某种对像的句柄i int类型l long 类型lp long类型的指针n int类型p 指针s 字符串sz 零终止的字符串w WORD类型,等价于unsigned short//12.2 Windows程序的结构//12.2.1 WinMain()函数WinMain()函数等价于控制台程序中的main()函数.int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE HPrevInstance, LPSTR lpCmdLine, int nCmdShow);//WINDAPI是一个windows定义的说明符,将使系统以某种特殊的方式处理函数名和实参--该方式碰巧与Pascal和Fortran语言中处理函数的方式一致//第一个参数hInstance属于HINSTANCE类型,是指向某个实例的句柄--这里的实例是正在运行的程序//句柄是标识某种对像(这里是应用程序的实例)的整数值,//下一个参数是hPrevInstance是从16位版本的Windows操作系统继承下来的//第三个参数是lpCmdLine是指向某个字符串的指针,该字符串包含启动程序的命令行字符//LPSTR类型是另一种windows类型,用来指定32位(long)的字符串指针//第四个参数nCmdShow决定着被创建窗口的外观,窗口可以正常显示,也可以最小化显示屏Windows程序中的WinMain()函数需要做以下四件事情:(1) 告诉Windows该程序需要的窗口种类(2) 创建程序窗口(3) 初始化程序窗口(4) 获取属于该程序的Windows消息1 指定程序窗口WNDCLASSEX结构的定义如下所示:struct WNDCLASSEX{ UINT cbSize; UINT style; WNDPROC lpfnWndProc; int cbClsExtra; int cbWndExtra; HINSTANCE hInstance; HICON hIcon; HCURSOR hCursor; HBRUSH hbrbackground; LPCTSTR lpszMenuName; LPCTSTR lpsaClassName; //成员存储着为标识该特定的窗口类而提供的名称 HICON hIconSm;}//创建类//WNDCLASSEX WindowClass;WindowClass.cbSize = sizeof(WNDCLASSEX);WindowClass.style = CS_HREDRAW | CS_VREDRAWWindowClass.lpfnWndProc = WindowProc;WindowClass.hIcon = LoadIcon(0, IDI_APPLICATION);WindowClass.hCursor = LoadCursor(0, IDC_ARROW);WindowClass.hbrBackground = static_cast
(GetStockObject)(GRAY_BRUSH);static LPCTSTR szAppName = L"OFWin";WindowClass.lpszClassName = szAppName;2 创建程序窗口将WNDCLASSEX结构的所有成员都设置为所需数值之后,下一步是把相关的情况告诉Windows,可以使用Windows API函数RegisterClassEx()来做这件事RegisterClassEx(&WindowCLass);给RegisterClassName()函数传递该结构的地址,Windows就会析取并记录所有结构成员的值,该过程被称为注册窗口类提醒: 这里的术语"类"是在"分类"的意义上使用的,与C++中类的概念不同,不要混淆两者//创建函数 CreateWindow();//在CreateWindow()函数之后,被创建的窗口现在已经存在,但还没有显示在屏幕上,需要调用另一个Windows API函数将该窗口显示出来ShowWindow(hWnd, nCmdShow);3 初始化程序窗口//通过调用另一个Window API函数UpdateWindow()请求Windows给程序发送一条重画窗口客户区的消息,该函数和语句如下UpdateWIndow(hWnd);4 处理Windows消息最后一项需要的WinMain()完成的任务是处理Windows为应用程序排好的消息队列,这么说似乎有点奇怪,因为前面曾经说过需要WindowProc()函数来处理消息,但是请允许我稍加解释排队消息与非排队消息一种是被Window放入队列的排队消息,WinMain()函数必须从队列中析取这些消息进行处理,WinMain()函数中做这件事的代码称为消息循环,排队消息包括那些因用户从键盘输入,移动鼠标以及单击鼠标按钮而产生的消息,来自定义时器的消息和请求重画窗口的Windows消息也都是排队消息 另一种是致使Windows直接调用WindowProc()函数的非排队消息,大量的非排队消息是作为处理排队消息的结果产生的消息循环前面曾说过,从消息队列中获取消息是使用某种标准机制完成的,该机制在Windows编程中称为消息泵或消息循环,MSG msg;while(GetMessage(&msg, 0,0,0) == TRUE){ TranslateMessae(&msg); DispatchMessae(&msg);}GetMessage(): 从队列中获取一条消息TranslateMessage(): 对获取的消息执行任何必要的转换DiapatchMessage(): 使Windows调用应该程序的WindowProc()函数来处理消息struct MSG{ HWND hwnd; UINT message; WPARAM wParam; LPARAM lParam; DWORD time; POINT pt;}注意:对于为不同于普通窗口的其他窗口类型指定的消息,也有除了WM之外的前缀,附录C中列出了各种类型的消息前缀多任务如果没有排队的消息,则GetMessage()函数不会返回到程序中,Windows允许执行过程传递给中一个应用程序,仅当队列中有消息时才能调用GetMessage()函数获得返回值,该机制是允许多个应用程序在旧版本windows下运行的基础,称作为协作式多任务在当前的windows版本中,操作系统可能在一段时间之后中断某个应用程序,然后将控制权传递给另一个应用程序,该机制称为抢先式多任务在while循环内,首先对TranslateMessage()函数的调用请求windows为与键盘有关的消息做一些转换工作,然后对DispatchMessage()函数的调用使wisnows分派该消息-换句话说,就是调用程序中的WindowProc()函数来处理该消息,在windowProc()函数结束对消息的处理之前DispatchMessage()函数不会返回,WM_QUIT消息意味着程序应该结束,因此该消息将导致使消息循环停止的FLASH返回给应用程序5 完整的WinMain()函数int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){ WNDCLASSEX WindowClass; static LPCTSTR szAppName = L"OFWin"; HWND hWnd; MSG msg; WindowClass.cbSize = sizeof(WNDCLASSEX); WindowClass.style = CS_HREDRAW | CS_VREDRAW; WindowClass.lpfnWndProc = WindowProc; WindowClass.cbClsExtra = 0; WindowClass.hInstance = hInstance; WindowClass.hIcon = LoadIcon(0, IDI_APPLICATION); WindowClass.hCursor = LoadCursor(0, IDC_ARROW); WindowClass.hbrBackground = static_cast
(GetStockObject(GRAY_BRUSH)); WindowClass.lpszMenuName = 0; WindowClass.lpszClassName = szAppName; WindowClass.hIconSm = 0; RegisterClassEx(&WindowClass); hWnd = CreateWindow( szAppName, L"A Basic Window the Hard Way", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, hInstance, 0 ); ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); while(GetMessage(&msg, 0, 0, 0, ) == TRUE) { TranslateMessage(&msg); DispatchMessage(&msg); }}///12.2.2 消息处理函数除应用程序窗口的通用外观以外,WinMain()函数不包含任何应用程序特有的代码,1:WindowProc()函数WindowProc()函数的原型如下:LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM , wParam, LPARAM lParam);HWND hWnd 是一个句柄,指向致使该消息发生的事件所在的窗口UINT message 指出消息类型的32位整数值IDWPARAM wParam 包含与消息种类有关的附加信息,是32位的数值LPARAM lParam 包含与消息种类有关的附加信息,是32位的数值2 解码Windows消息解码Windows发送的消息的过程通常是基于message的值,在WindowProc()函数中使用switch语句来完成的,然后,选择希望处理的消息类型就只是为switch中的每种情形放一条case语句的问题而已,这样的swtich语句的典型结构switch(message){ case WM_PAINT: break; case WM_LBUTTONDOWN: break; case WM_LBUTTONUP: beak; case WM_DESTROY: break; default: break;}绘制窗口客户区Windows通过给程序发送WM_PAINT消息,告诉程序应该重画客户区,因此在我们的示例中,需要在窗口中输出文本来响应WM_APRINT消息HDC hDC;PAINTSTRUCT PaintSt;hDC = BeginPaint(hWnd, &PaintSt);//可以在RECT结束中获得客户区的坐标RECT aRect;GetClientRect(hWnd, &aRect);SetBkMode(hDC, TRANSPARENT);//第一个实参标识设备上下文,第二个实参设定背景模式,默认选项是OPAQUEDrawText(hDC, L"But, soft! What light through yunder window breaks?", -1, &aRect, DT_SINGLELINE|DT_CENTER|DT_VCENTER);EndPaint(hWnd, &PaintSt);结束程序有人可能认为,关闭窗口就会关闭应用程序,但为了获得这样的特性,我们实际上必须添加一些代码,关闭窗口时应用程序不会自动关闭的原因在于可能需要做一些清理工作,应用程序也可能有多个窗口,当用户通过双击标栏目图标或单击关闭按钮关闭窗口时,系统将生成一条WM_DESTROY消息,因此,为了关闭应用程序,需要在WindowProc()函数中处理WM_DESTROY消息,可能使用下面这条语句生成一条WM_QUIT消息进行处理PostQuitMessage(0);//完整的WindowProc()函数所需的所有元素LRESULT WINAPI WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){ HDC hDC; PAINTSTRUCT PaintSt; RECT aRect; switch(message) { case WM_PAINT: hDC = BeginPaint(hWnd, &PaintSt); GetClientRect(hWnd, &aRect); SetBkMode(hDC, TRANSPARENT); DrawText( hDC, L"But, soft! What light through yonder window breaks?", -1, &aRect, DT_SINGLELINE | DT_CENTER | DT_VECNTER ); EndPaint(hWnd, &PaintSt); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; default: return DefWindowProc(hWnd, message, wParam, lParam); break; }}12.2.3 简单的Windows程序12.3 Windows程序的组织12.4 MFC1 应用程序类class COurApp: public CWinApp{ public: virtual BOOL InitInstance();};2 窗口类class COurWnd: public CFrameWnd{ public: COurWnd() { Create(0, L"Our Dumb MFC Application"); }}3 完成程序BOOL COurApp::InitInstance(void){ m_pMainWnd = new COurWnd; m_pMainWnd->ShowWindo(m_nCmdShow); return TRUE;}COurApp AnApplication;4 最终产品12.5 使用Windows Forms12.6 小结 Windows API 提供了标准的编程接口,应用程序通过该接口与操作系统通信 所有Widnows应用程序都包括一个由操作系统调用的WinMain()函数,其作用是启动应用程序的执行过程,WinMain()函数还包括获取操作系统消息的代码 Windows操作系统调用应用程序中的特定函数来处理具体的消息,应用程序通过调用某个Windows API函数来标识应用程序中各个窗口的消息处理函数 MFC由一级封装了WIndows API,使利用Windows API编程得以简化的类组成 Windows Forms应用程序是在CLR中执行的,windows Forms应用程序中的窗口可以以图形方式创建,而所需要的所有代码都是自动生成的*/int main(){ cout<<"hello "; system("pause"); return 0;}

  

转载于:https://www.cnblogs.com/xiangxiaodong/archive/2012/11/25/2787874.html

你可能感兴趣的文章
python日期及时间格式转换
查看>>
MSP与PSP
查看>>
Android 使用RecyclerView SnapHelper详解
查看>>
Android开发学习:[15]自动导入包
查看>>
Struts2+JFreeChart
查看>>
touch事件记录
查看>>
[C语言 - 9] typedef
查看>>
在100万个数中找到最大的十个数
查看>>
java.io.File中的绝对路径和相对路径
查看>>
spring boot项目升级到2.0.1,提示java.lang.ClassNotFoundException: org.apache.log4j.Logger错误...
查看>>
二、Spring容器使用
查看>>
字符串:格式化 - 零基础入门学习Python015
查看>>
第一个程序 - Windows程序设计(SDK)001
查看>>
二分法原理
查看>>
容器和算法2 - C++快速入门48(完)
查看>>
OpenCV.学习OpenCV.pdf
查看>>
Scala 隐式转换 重要一点 什么是隐式转换以及隐式转换带来的好处
查看>>
依然在路上
查看>>
IOS 下拉菜单
查看>>
SQL经典问题 找出连续日期及连续的天数
查看>>