C++ windows编程学习笔记(一)——程序结构的解析
2012-06-30 22:29
176 查看
#include<Windows.h> #include<iostream> #include<sstream> #include<string> using namespace std; //偶尔测试用的,不过好像没什么反应。。。 LRESULT CALLBACK WindowProcedure(HWND,UINT,WPARAM,LPARAM); //WParam即Word Parameter,LPARAM即Long Parameter。两个参量。 //“在Win 3.x中,WPARAM是16位的,而LPARAM是32位的,两者有明显的区别。 //因为地址通常是32位的,所以LPARAM 被用来传递地址,这个习惯在Win32 API中仍然能够看到。 //在Win32 API中,WPARAM和LPARAM都是32位,所以没有什么本质的区 别。 //Windows的消息必须参考帮助文件才能知道具体的含义。 //如果是你定义的消息,愿意怎么使这两个参数都行。 //但是习惯上,我们愿意使用LPARAM传 递地址,而WPARAM传递其他参数。” char szClassName[] = "WindowsApp"; int i=0; int WINAPI/*函数调用方式,入栈跟出栈方式,跟CALLBACK其实是没有区别的*/ WinMain(HINSTANCE hThisInstance, HINSTANCE hPrevInstance, //HINSTANCE中,H为Handle即句柄,Instance,即为实例。 //总共生成了两个HINSTANCE,一个为当前的句柄,一个为之前的句柄,也就是说这两个指向的 //分别为当前打开的进程和之前打开的两个进程,有点类似于,argv。 LPSTR lpszArgument, //Local Pointer to String,指向字符串的局部指针。做什么的? //好像是运行程序时需要传递给程序的一个字符串,比如一个指令,或者一个文件的位置等。 int nFunsterStil) //貌似是窗口的显示方式。 //以上主要是通过 //int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) //推断的,可能是错的,主要是觉得一个是CMD控制台的初始化,一个是窗口化,可视化的初始化。 //这几个参数是程序运行的时候Windows传给WinMain的么?等会反汇编一下。 //汇编结果只看到了四个压栈操作,没有别的东西,也不知道参数的来源是什么。。。 //且一开始nFunsterStil 的值就是1。默认的? //嗯~~~最后还是发现,这个nFunsterStil是系统__tmainCRTStartup传递给WinMain的。 //__tmainCRTStartup有默认的值传递给WinMain不过这个值也是可以修改的。 { HWND hwnd; //H_Window,一个指向窗口的句柄,表示当前显示的窗口吧,或者说,对应的是现在运行的进程,定义了这么一个变量 MSG messages; //初步理解这应该是用户操作所产生信息的容器吧。 //线程的消息队列,与初步理解出入不大。 //那这个我能定义多个变量么? WNDCLASSEX wincl; //这是一个窗口实例,从这里才真正建立了一个窗口的变量。 //Window Class "Example"?就是窗口类实例的意思? //额。。。应该是Windows Extra Class 吧。。。 wincl.hInstance = hThisInstance; //窗口的句柄指向当前打开的程序,或进程,即WinMain中的hThisInstance wincl.lpszClassName = szClassName; //Local pointer to String end with "Zero", //明白了,这就是一个对wincl的类的一个描述,根本没有实际意义,判断用得上。 wincl.lpfnWndProc = WindowProcedure; //Long Pointer to Windows Procedure.到底是Long还是Local,个人觉得应该是Local //因为指向函数的指针怎么会分长短。这又不是汇编里的LCALL和ACALL。 //后来又发现Windows Procedure返回值为long。迷糊了。 //LRESULT CALLBACK WindowsProcedure(HWND,UINT,WPARAM,LPARAM); //最后这个应该是Long吧 wincl.style = CS_DBLCLKS; //窗口风格,不懂,慢慢理解吧,用用就知道了可能。。。这个应该就是设置单个窗口吧 //WS_OVERLAPPEDWINDOW指定一个具有所有标准控件的窗口,是一个组合体。简单的说,一个可以最大化、最小化、随意改变大小等等地窗口; //WS_OVERLAPPED指定一个具有标题栏和边界的重叠窗口,一个具有标题栏、可改变大小的窗口; //WS_POPUP指定一个弹出的窗口,一个光秃秃的窗口; //WS_VISIBLE指定一个初始时可见的窗口,一个黑色的大方框,可能你要用它写一个全屏的游戏,选择; //窗口类风格:这个可能是一类窗口吧,可能一个WNDCLASS不一定只有一个窗口说的就这个吧。。。 //可是一个窗口类怎么对应多个窗口的。。。 //CS_HREDRAW:一旦移动或尺寸调整使客户区的宽度发生变化,就重新绘制窗口; //CS_VREDRAW:一旦移动或尺寸调整使客户区的高度发生变化,就重新绘制窗口; //CS_OWNDC:为该类中的每一个窗口分配一个唯一的设备上下文; //CS_DBLCLKS:当用户双击鼠标时向窗口过程发送双击消息;就是双击会使窗口产生反应吧。 wincl.cbSize = sizeof(WNDCLASSEX); //查了好多地方才知道,这是一个标识变量,区别不同的版本能用到, //就跟lpszClassName基本一个作用——标识。 //下面就是一些窗口图形特性的设置了 wincl.hIcon = LoadIcon(NULL,IDI_APPLICATION); wincl.hIconSm = LoadIcon(hThisInstance,"icon.ico"); //使用系统预定义的图标 wincl.hCursor = LoadCursor(NULL,IDC_ARROW); //使用系统预定义的光标 wincl.lpszMenuName = NULL; //指向菜单的指针,因为没有菜单,所以为NULL; wincl.cbClsExtra = 0; //类给自己的预留内存, wincl.cbWndExtra = 0; //窗体在类中的预留内存,当这两个数值变化时发现程序的内存占用也变了。 wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND; //改变窗体的背景颜色,可是不知道这个是不是RGB。。 if(!RegisterClassEx(&wincl)) { return 0; } //注册窗体,向Windows声明一下这个窗体,因为Windows编程毕竟是要向操作系统通信才能用的。。。 hwnd = CreateWindowEx( //这里才是真正的窗体生成。。看"Create"... 0, //Dword Ex Window Style,一个双字变量的扩展窗体风格 //#define WS_EX_RIGHT 0x00001000L //#define WS_EX_LEFT 0x00000000L //#define WS_EX_RTLREADING 0x00002000L //#define WS_EX_LTRREADING 0x00000000L //#define WS_EX_LEFTSCROLLBAR 0x00004000L //#define WS_EX_RIGHTSCROLLBAR 0x00000000L //#define WS_EX_CONTROLPARENT 0x00010000L //#define WS_EX_STATICEDGE 0x00020000L //#define WS_EX_APPWINDOW 0x00040000L //#define WS_EX_OVERLAPPEDWINDOW (WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE) //#define WS_EX_PALETTEWINDOW (WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST) szClassName, //把这个窗体命个名,这个命名跟后面的lpWindowsName还是不一样。 //一个是显示出来的,一个可以理解为给系统看的。 "Windows App", //这个就是窗口显示出来的名字 WS_OVERLAPPEDWINDOW, /*只注意到下面几种了,定义文件里还有别的窗体风格。 其中一中为层叠窗口,平时主要用的就是这种,一种为弹出窗口,另一种为子窗口。 #define WS_OVERLAPPEDWINDOW (WS_OVERLAPPED | \ WS_CAPTION | \ WS_SYSMENU | \ WS_THICKFRAME | \ WS_MINIMIZEBOX | \ WS_MAXIMIZEBOX) #define WS_POPUPWINDOW (WS_POPUP | \ WS_BORDER | \ WS_SYSMENU) #define WS_CHILDWINDOW (WS_CHILD)*/ CW_USEDEFAULT, //操作系统确定窗口横坐标 CW_USEDEFAULT, //操作系统确定窗口纵坐标 544, //窗口宽度 375, //窗口高度 HWND_DESKTOP, // hWndParent,意思就是窗口句柄的父类为Desktop,说明这个窗体隶属于Desktop? //HWND_DESKTOP为新建窗口时用的一些特殊参数。 NULL, //没有菜单 hThisInstance, //窗体隶属于哪个程序的句柄吧。。。 NULL //NULL跟0的区别在于,NULL为指针,0为数值,这区别说小,几乎没有,说大也大了去了。 ); ShowWindow(hwnd,nFunsterStil); //到这里窗体就显示出来了。而那个nFunsterStil是干什么的? //这个Windows 显示出来也有风格。。。那个nFunsterStil就是干这个的。 while(GetMessage(&messages,NULL,0,0)) //GetMessage的messages是哪来的?不懂。。。 { TranslateMessage(&messages); //这Translate的messages又变成什么了? DispatchMessage(&messages); //这个函数是干什么的。。。。 } return messages.wParam; } LRESULT CALLBACK WindowProcedure(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) //不知道怎么莫名其妙就调用到这个函数了。。。 //给我的感觉特别像中断函数。。。 { switch(message) { case WM_DESTROY: { //这个WM_DESTROY是怎么来的? PostQuitMessage(0); //这个是干什么的? //发送退出消息,退出程序吧? } break; case WM_PAINT: { //这个WM_PAINT是怎么来的? //难道系统会不停地给程序WM_PAINT的指令么?貌似是这样的啊 PAINTSTRUCT ps; //画图准备吧。。。声明这个变量,表示要开始画图了? HDC hdc; hdc = BeginPaint(hwnd,&ps); //这个貌似是定义画图区间吧。。。 Ellipse(hdc,10,0,200,100); //分别代表左上端点坐标,及右下端点距左上端点的距离。 EndPaint(hwnd,&ps); //很有可能在这里把ps delete掉了。 } break; case WM_LBUTTONDOWN: //如果有左键操作,则显示一个对话框,显示i的值。 //本来只是想计录一下不符合case的消息数,看看是不是Windows一直在发消息给程序。 //但是结果i的值好像并没有随时间的推移增大。 //结果这次我错了。。。在我不停得按键盘的时候,增大了,而且增大了好多。 //似乎Windows会有一个固定的频率,如果没有其实用户操作的时候。 { string a; ostringstream os; //声明一个数据流和string变量,将i转换成字符串,即char[]或者*st; os<<i; //然后发现自己的字符串操作很不熟练。。。回去练。 a = os.str(); LPCSTR st = a.c_str(); //好不容易才转换成功了。 MessageBox(hwnd,st,"你好",1); } break; case WM_CLOSE: { int i = MessageBox(hwnd,"确定退出吗?","退出确认",MB_OKCANCEL); if(i == IDOK) PostQuitMessage(0); } break; default: i++; return DefWindowProc(hwnd,message,wParam,lParam); //这个函数是干什么的? //该函数调用缺省的窗口过程来为应用程序没有处理的任何窗口消息提供缺 //省的处理。该函数确保每一个消息得到处理。 //调用DefWindowProc函数时使用窗口过程接收的相同参数。 break; } return 0; } //个人猜想应该是不停得会收到信息,信息是windows来的么? //然后getMessage,再Translate,再dispatch,是dispatch调用的WindowProcedure么,好像是哈。 //然后比较Translate过来的Message值。可是为什么每次得到的int值会不一样呢? //这个windows发送的数据都有什么? //不懂的同学研究一下Windows消息机制吧 //然后就继续学习喽。。。可能很多人觉得,MFC可以很容易得实现这些东西,这些可以交给电脑来作,交给可视化编译器来做。可是真的是这样的么?
相关文章推荐
- C++ 以类为单位的程序结构
- c++ 自己创建的namespace,声明在h文件中,定义在cpp文件中,这种程序结构应该是合理的吧,欢迎不同见解的朋友来讨论。
- 2013级C++第3周【项目1-掌握有对象的程序结构】
- 实例解析C++/CLI程序进程之间的通讯
- Flex程序包装页面(wrapper)结构解析
- c++程序入门(三)——用结构和类分别实现复数加法和乘法
- 【C++】多文件程序结构
- C++ 多文件程序结构
- C++ 以函数为单位的程序结构
- 程序基础设计模式的解析和实现(C++)之二十-Visitor模式
- 程序结构和解析 1
- 一个C++的 XML 解析程序
- C++入门进阶之4: C++程序结构
- C++ 基础知识点 四 第5章 C++函数与程序结构
- C++反汇编揭秘1 – 一个简单C++程序反汇编解析 (Rev. 3)
- 对于C语言MFC的详细的解析(4)--MFC程序结构分析
- c++ 学习笔记之程序结构
- 数据结构图文解析之:AVL树详解及C++模板实现
- C++反汇编揭秘1 – 一个简单C++程序反汇编解析 (Rev. 3)
- C/C++怎样编写高质量的程序:头文件和源文件模板------高质量C++/C编程指南-第1章-文件结构