SDK编程之理解Window应用程序框架
来源:互联网 发布:新加坡管理大学 知乎 编辑:程序博客网 时间:2024/05/16 11:21
从个人的学习经验看来。为了少走弯路,在深入学习Visual C++ 面向对象与可视化程序设计时,很有必要先对 Window应用程序框架来个初步的深刻的理解 并以此过度到真正的MFC编程中。
好了 废话少说 直奔主题
提示:Window 的一些 函数名称,类型,宏 等都是比较人性化的,所谓的人性化就是与英文的拼写比较接近,这一特征在一下代码有所体现
这里说一下 宏 的定义:C++ 宏 是将一个标识符定义为一个字符串(百度百科上的解释) 这里说一下为什么需要使用宏,
我个人理解使用宏的最重要的一个原因 就是减轻程序猿的记忆负担,将一个毫无规律可循的字符串用一个(有规律可循的,比较好认的)标识符来表示,同时也可以使程序看起来美观吧。举个简单的例子 我们在程序中经常使用的
const double pi = 3.1415926; //定义一个常量PI
但我们也可以用 宏来完成:
#define PI 3.1415926
我们先看一段代码:
这里我为了将 Window 应用程序框架表示的更清晰
用 Init()函数封装了 窗口的设计过程. 然后窗口设计中用到的一些局部变量我就以引用的
方式传给Init() 在传给 函数内部使用了
#include<tchar.h>#include<Windows.h>LRESULT CALLBACK WindowProc( HWND hwnd, // handle to window UINT uMsg, // message identifier WPARAM wParam, // first message parameter LPARAM lParam // second message parameter ); void Init(WNDCLASS &wcex,HINSTANCE &hInstance);// 以上是各种函数的函数声明,函数使用前必须声明啊,系统函数除外,这里必须说明下消息循环函数不是系统函数,// 有程序员编写, 因此函数名就可以自己去 不过一般不改变,在此我使用WindowProc , 我们也可以改为WndProc(..)// 我们可以发现 WindowProc 函数在返回值 LRESULT(这是一个 宏 我们并不需要深究他 只知道他是一个类型就OK 类似于int) // 前面有 CALLBACK 这是怎么回事呢 ? CALLBACK 回调, 有CALLBACK 修饰的函数成为回调函数, 我们可以简单理解为// 由程序员写的 但是由系统调用的函数成为回调函数int WINAPI WinMain( HINSTANCE hInstance, // handle to current instance HINSTANCE hPrevInstance, // handle to previous instance LPSTR lpCmdLine, // command line int nCmdShow // show state ){WNDCLASS wcex; //创建一个WNDCLASS结构对象HWND hwnd;//创建过个窗口句柄MSG msg;//创建一个MSG结构对象Init(wcex, hInstance);//设计窗口// 设计完一个类接下来就是 注册这个类了 //这就好比我们设计了一个好东西,为了防止别人抄袭,我们需要去注册它if( ! RegisterClass(&wcex)) //注册窗口 我们用RegisterClassEx这个系统提供的函数 ,注意前来有个 ! 运算符//从函数命名可以知道这是用来注册用的,至于参数,暂时不管,后面解释 {//MessageBox(NULL,"窗口注册失败","窗口注册",NULL); //MessageBox()其实就是弹出一个(提示)消息框,我们使用电脑时经常也遇到return 0;// 如果注册失败 返回0;}//注册完窗口开始创建窗口了,我们调用系统函数CreateWindow(),//注意他返回的是一个窗口句柄, 我们之前创建的 窗口句柄就是用来 接受它的返回值的hwnd = CreateWindow("可视化编程","程序讲解",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NULL);// 注意 创建窗口只需要调用一个函数就完成了,参数过长可以分多行写if( ! hwnd)// 如果创建窗口失败 hwnd值为NULL !hwnd 为真,返回0 退出WinMain函数{//MessageBox(NULL,"窗口注册失败","窗口注册",NULL);return 0;}//创建完还不行啊,要给使用者看啊。因此需要显示窗口ShowWindow(hwnd,nCmdShow); //注意两个参数,第一个参数就是CreateWindow返回的 hwnd,而第二个//参数就是 我们的WinMain 函数的最后一个参数,窗口的初始状态(是最大化的//还是最小化的))//回想一下我们注册窗口是的背景,我们是用白色是粉刷的,但是结合实际,我们//平常常用的程序一进去并不是白色的,因此我们这里也一样,显示了窗口之后,必要对窗口作一下必要的初始化//用到UpdateWindow() 这个系统函数UpdateWindow(hwnd); //参数也是使用前面的hwnd; 至于为什么 先不管while(GetMessage(&msg,NULL,0,0)) //进行消息循环{TranslateMessage(&msg); // 将虚拟键转化为字符消息,//用键盘进行输入时将按键虚拟键转化为字符消息,一边显示出来DispatchMessage(&msg); //将消息"发送"到指定的窗口函数 即 WindowProc }// 至此,一个应用程序的基本框架就完成了,等等,不是说消息循环是Window程序主体么? //为什么没看到调用窗口消息处理函数,其实程序内部已经调用了 只是我们不知道而已,那么系统是如何调用的?// 我们发现 注册窗口时 Init()函数内 有这么一个表达式 wcex.lpfnWndProc = WindowProc; 系统就是从这里得知消息处理函数的,// 函数地址都已经知道了 调用岂不是容易事, 好了,他的内部操作我们就不深入了return (int) msg.wParam; // 程序对出之后我们返回这个消息的某些参数 wParam是MSG 结构的一个字段}void Init(WNDCLASS &wcex,HINSTANCE &hInstance) //使用的是引用参数,注意我传入的两个参数{wcex.style = 0;// (这里表示将要创建的窗口的类型)//值为0是采用的是默认类型,我们用他默认类型就可以了wcex.cbClsExtra = 0;//有兴趣的可以自己上网查查,这里不做介绍,//在SDK编程中用处也不大。wcex.cbWndExtra = 0;//同上wcex.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //这里表示的是将要创建的窗口的背景//背景需要用画刷(HBRUSH)填充 填充背景一般使用GetStockObject()函数wcex.hIcon = LoadIcon(hInstance,MAKEINTRESOURCE(IDI_APPLICATION));//从函数名可以知道这里加载一个图标hIcon 中的h 表示这是一个Icon的句柄//IDI_APPLICATION 是一个宏,至于为什么是IDI_...//因为这是一个ID 并且是Icon的ID 取Icon首字母I 连起来就是IDI_//此函数的第二个参数一个指针参数,而IDI_APPLICATION只是一个数值,需要类型转换//因此就使用宏MAKEINTRESOURCE() 来转换,其实就是函数转换函数,//至于内部怎么操作的我们就不用管了wcex.hCursor = LoadCursor(hInstance,MAKEINTRESOURCE(IDC_ARROW));//理解如上,IDC_ARROW 表示ARROW(箭头)的Cursor(光标)的IDwcex.hInstance = hInstance;//窗口句柄,使用从WinMain函数中传进的hInstance句柄就可以了(至于为什么后面解释)wcex.lpfnWndProc = WindowProc;//lpfnWndProc中,lp表示长整形(l)的指针(p),WndProc 表示什么相信已经猜到了就是调用//WndProc(...)窗口函数,窗口函数就是消息循环函数的别称罢了//至于等号的右值函数的名称就是函数的地址//与他要求的指针类型完全匹配wcex.lpszClassName = _T("可视化编程"); //这里要注意了,你设计窗口是定于的是什么classname(类名),你后面创建窗口时就必要//使用相同的名字,至于这里为什么要 _T("...") 主要是为了提高程序的移植性。当然也//可以直接用" 可视化编程" 窗口菜单,为了简化这里我们先不要菜单了 所以设值为NULL//就OK,其实0也可以,不过规范的编程中我们使用的是NULL 因为这是一个指针.指针为空时//我们让他指向NULL;wcex.lpszMenuName = NULL;}// 一下是消息处理函数实现代码LRESULT CALLBACK WindowProc( HWND hwnd, // handle to window UINT uMsg, // message identifier WPARAM wParam, // first message parameter LPARAM lParam // second message parameter ){switch(uMsg){case WM_DESTROY:PostQuitMessage(0);break;default:return DefWindowProc(hwnd,uMsg,wParam,lParam);//调用系统默认函数break;}return 0;}
好了.
我们在来理清一下 Window程序的基本框架思路:(函数必要的返回值 参数我就省略了,这样子 看起来思路比较清晰);
WinMain(){// 创建3钟特殊的结构的对象 以后用到WNDCLASS wcexHWND hwnd;MSG msg;// 窗口注册Init(){//窗口的注册,完成一些必要的初始化;//主要用到了 WNDCLASS wcex 这个结构个各种字段;//以及重要的 wcex.lpfnWndProc = WindowProc;//让系统找到 窗口消息函数}//注册窗口 注册失败返回0, 退出程序if( !Register()){return 0;}//完成窗口的创建 并将返回值赋值给 hwndhwnd = CreateWindow(){}if( ! hwnd) //判断是否创建成功 不成功则返回 0 退出程序{return 0;}ShowWindow(); //显示窗口UpdateWindow(); //更新窗口//完成消息循环while( GetMessage(&msg,NULL,0,0)){TranslateMessage(&msg); DispatchMessage(&msg); }return msg.wParam //消息循环时 返回消息的某个字段}
完成到这里,已经基本完成了,这篇文章主要介绍了 Window程序设计的框架,其他的就不在讨论范围了, 像一些系统函数的参数为什么这样 这些问题 只有MSDN 帮到你了
这里强烈建议 想学好的朋友 安装一个MSDN
之前有一个朋友问过我 :你这么厉害啊 函数的参数表都记住了,,我说 ,你来记吧 谁会这么无聊记参数表,其实我只是在MSDN上 查到了 然后粘贴复制的问题罢了。
最后说明 本文写给刚刚进入可视化编程学习的朋友 希望对他们有帮助,, 另本文完成得比较仓促 文中有笔误或者不妥之处就请各位路过的大牛不吝指出,并一起讨论。一起学习了。
- SDK编程之理解Window应用程序框架
- VC编程基础之应用程序框架
- PHP codeigniter 框架编程学习之【应用程序】
- MFC编程之创建Ribbon样式的应用程序框架
- 二 MFC编程入门之VS2010/MFC应用程序框架
- window编程之CreateProcess
- window编程之CreateThread
- OpenGL之应用程序框架
- window 应用程序的组成及编程步骤
- SDK 编程之控件
- Android SDK上手指南:Java应用程序编程
- Windows SDK编程(Delphi版) 之 Windows编程概述与框架
- 理解PHP中的MVC编程之MVC框架简介
- 理解PHP中的MVC编程之MVC框架简介
- 理解Flex 4 SDK和框架
- Qt应用程序之Application Main Window详解
- Window应用程序编程和XNA游戏编程的不同
- C++ SDK+Symbian开发入门之应用程序
- ps -ef | ps -aux
- linux下socket编程
- android删除通讯录机制
- linux解压命令详解及其使用
- Chrome编译
- SDK编程之理解Window应用程序框架
- PHP内核探索:如何执行PHP脚本
- 读书笔记 :前端MVC中的控制器,实现对元素,事件的规划
- 数据结构-线性表
- 在window xp下使用eventquery.vbs脚本输出当天电脑每次的启动时间
- USACO 1.1.1 Your Ride Is Here
- DataGridView标题栏颜色设置无效 ...
- 下载最新的Google Chrome源码并编译
- curl来实现iphone远程通知的服务器端