概述
一.Windows程序内部运行原理 1.关于消息和消息队列 系统将每个事件都包装成一个称为消息的结构体MSG来传递给应用程序,MSG结构定义如下: typedef struct tagMsg{ HWND hwnd; UINT message; //消息种类,以WM_开头的一些消息 WPARAM wParam; //这两个是消息的补充 LPARAM lParam; DWORD time; //消息被投递post的时间 POINT pt; //这是一个点数据(结构体,有x、y),记录投递消息时光标cursor的屏幕坐标coordinate }MSG; 2.windows程序的入口WinMain函数 int WINAPI WinMain( HINSTANCE hInstance, // handle to current instance 当前运行的实例句柄 HINSTANCE hPrevInstance, // handle to previous instance 先前运行的实例句柄 LPSTR lpCmdLine, // command line;lp开头(long pointer) 表示指针,str表示字符串;这里是命令行参数 int nCmdShow // show state窗口显示状态(最大化、最小化……) ); (可以在运行里面输入notepad.exe 1.txt传递一个参数) 3.窗口的创建 需要经过下面四个操作步骤: ·设计一个窗口类 ·注册窗口类 ·创建窗口 ·显示及更新窗口 1) typedef struct _WNDCLASS { UINT style; //可以设为CS_HREDRAW,即窗口水平坐标变化时窗口全部重画 WNDPROC lpfnWndProc; //回调函数(由系统调用),直接将函数名赋给此参数(即函数指针) int cbClsExtra; //为窗口类分配附加内存空间(所有属于这个窗口类的窗口共享) int cbWndExtra; //窗口实例附加内存空间 HANDLE hInstance; HICON hIcon; //用LoadIcon赋值 HCURSOR hCursor; //用LoadCursor HBRUSH hbrBackground; //画刷背景,这里用GetStockObject()获取,它参数是系统带的。如:=(HBRUSH)GetStockObject(BLACK_BRUSH),这里有强制类型转换 LPCTSTR lpszMenuName; //CT=constant……菜单名 LPCTSTR lpszClassName; //窗口类名 } WNDCLASS; 经常会遇到一类变量,其每一位bit都对应某一种属性(1有0无),系统定义了一些常量(宏定义),只有一位为1,其余为0。若要同时用这几种特性,则用或运算|;要去掉某一特征,用取反~之后再进行与运算&即实现。(or有;and not取消,类似VB) HICON LoadIcon( HINSTANCE hInstance, //若加载标准图标则为NULL(系统自带的,如IDI_APPLICATION) LPCTSTR lpIconName ); HGDIOBJ GetStockObject( __in int fnObject ); 2) 然后用RegisterClass(&wndcls)注册窗口类 ATOM RegisterClass( CONST WNDCLASS *lpWndClass ); 3) 再用hwnd=CreateWindow()创建窗口 HWND CreateWindow( LPCTSTR lpClassName, //窗口类名,必须是先前设计的 LPCTSTR lpWindowName, //窗口名字 DWORD dwStyle,//窗口样式window styles,如WS_OVERLAPPEDWINDOW,若想去掉最大化按钮(加个&~WS_MAXIMIZEBOX) int x, //窗口初始位置,可设置为CW_USEDEFAULT,这样就忽略y的值了 int y, int nWidth, //宽度,也可用CW_USEDEFAULT int nHeight, HWND hWndParent, //父窗口句柄,没有则为NULL HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam // 作为WM_CREATE消息的参数lParam ); 4)显示窗口ShowWindow BOOL ShowWindow( HWND hWnd, int nCmdShow //窗口状态,如SW_SHOWMAXIMIZED ); 之后用UpdateWindow(hwnd)刷新窗口,这里可有可无 4.获取消息GetMessage BOOL GetMessage( //获取到WM_QUIT消息时,返回值为0;其他为非0值 LPMSG lpMsg, HWND hWnd, //为NULL时表示属于当前线程的所有消息 UINT wMsgFilterMin, //最低的消息值 UINT wMsgFilterMax //最高消息值 ); 消息循环: while(GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); //将按键消息(KEYDOWN/KEYUP和对应字符的扫描码)转换成WM_CHAR消息 DispatchMessage(&msg); //派送消息,将消息发送给窗口程序 } return 0; 5.窗口程序: LRESULT CALLBACK WindowProc( //窗口名可随意取,这里CALLBACK其实就是__stdcall(标准调用格式,宏定义的) HWND hwnd, // handle to window UINT uMsg, // message identifier WPARAM wParam, // first message parameter LPARAM lParam // second message parameter ) { switch(uMsg) { case WM_CHAR: //按下按键 char szChar[20]; sprintf(szChar,"char is %d",wParam); //格式化文本到一个内存区(buffer) MessageBox(hwnd,szChar,"weixin",0); break; case WM_LBUTTONDOWN: MessageBox(hwnd,"mouse clicked","weixin",0); HDC hdc; hdc=GetDC(hwnd); TextOut(hdc,0,50,"计算机编程语言培训",strlen("计算机编程语言培训")); ReleaseDC(hwnd,hdc); break; case WM_PAINT: HDC hDC; PAINTSTRUCT ps; hDC=BeginPaint(hwnd,&ps); TextOut(hDC,0,0,"维新培训",strlen("维新培训")); EndPaint(hwnd,&ps); break; case WM_CLOSE: if(IDYES==MessageBox(hwnd,"是否真的结束?","weixin",MB_YESNO)) { DestroyWindow(hwnd); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd,uMsg,wParam,lParam); } return 0; } 6.所用其他函数分析: 1)int MessageBox( HWND hWnd, LPCTSTR lpText, //显示的文本(存放到一个字符数组,或直接用“”括起输出字符) LPCTSTR lpCaption, //标题 UINT uType // 样式,如MB_OK=0(方便就写0)/MB_OKCANCEL ); 返回值有:IDOK,IDNO,IDYES…… 2)画图、输出 先用GetDC: HDC GetDC( __in HWND hWnd //窗口句柄,若为NULL则返回整个屏幕的DC(device context设备上下文、环境) ); 再用TextOut输出文本: BOOL TextOut( __in HDC hdc, __in int nXStart, //这两者是文本输出的开始坐标 __in int nYStart, __in LPCTSTR lpString, //输出的文本 __in int cbString //输出的字符个数 ); 注意最后要释放DC:用ReleaseDC int ReleaseDC( __in HWND hWnd, __in HDC hDC ); 3)WM_PAINT消息(窗口加载、窗口移动时窗口要重绘) 先用 HDC hdc;PAINTSTRUCT ps; hdc=BeginPaint(hwnd,&ps) //在重绘时获取DC HDC BeginPaint( __in HWND hwnd, __out LPPAINTSTRUCT lpPaint //这里是PAINTSTRUCT变量的指针,如&ps ); 使用(如TextOut(hdc,0,0,"维新培训",strlen("维新培训")))完之后,要用EndPaint释放DC BOOL EndPaint( __in HWND hWnd, __in const PAINTSTRUCT *lpPaint ); 这里BeginPaint和EndPaint只能用WM_PAINT消息中 4)WM_CLOSE(窗口即将关闭时的消息) if(IDYES==MessageBox(hwnd,"是否真的结束?","weixin",MB_YESNO)) { DestroyWindow(hwnd); } 经验:在条件测试的时候,一般把常量(IDYES)写在前面,不容易出错 BOOL DestroyWindow( //销毁窗口,程序还没退出,它会发送WM_DESTROY消息和WM_NCDESTROY消息 HWND hWnd ); 5)WM_DESTROY //窗口销毁 void PostQuitMessage( //投递一个WM_QUIT消息给这个线程的消息队列 int nExitCode //它用来当做WM_QUIT消息的wParam ); 6)其它消息: default: return DefWindowProc(hwnd,uMsg,wParam,lParam); //默认的窗口程序 7.用VC编写: 1)选择win32 application工程(选择空工程) 2)添加C++源文件 3)包含头文件:#include "windows.h" #include "stdio.h" 4) 写WinMain函数,可查msdn int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ); 5)在WinMain函数中设计一个窗口类 { WNDCLASS wndcls; wndcls.cbClsExtra=0; wndcls.cbWndExtra=0; wndcls.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH); wndcls.hIcon=LoadIcon(NULL,IDI_APPLICATION); wndcls.hCursor=LoadCursor(NULL,IDC_ARROW); wndcls.hInstance=hInstance; wndcls.lpfnWndProc=WinSunProc; wndcls.lpszClassName="first"; wndcls.lpszMenuName=NULL wndcls.style=CS_HREDRAW | CS_VREDRAW; } 6)在WinMain中注册窗口类 RegisterClass(&wndcls); 7)创建窗口 HWND hwnd; hwnd=CreateWindow("first","我第一个窗口",WS_OVERLAPPEDWINDOW,USER_DEFAULT,0,0,USER_DEFAULT,NULL,NULL,hInstance,NULL); 8)显示窗口 ShowWindow(hwnd,SW_SHOWNORMAL); UpdateWindow(hwnd); 9)消息循环 MSG msg; while(GetMessage(&msg,NULL,0,0) //获取到WM_QUIT消息时才退出循环,注意这里是NULL表示接受所有消息 { TranslateMessage(&msg); DispatchMessage(&msg); } return 0; //winmain返回0 10)窗口过程 LRESULT CALLBACK WindowProc( //注意改名WinSunProc,和申明 HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { switch(uMsg) { case WM_CHAR: break; case WM_LBUTTONDOWN: break; case WM_PAINT: break; case WM_CLOSE: break; case WM_DESTROY: break; default: return DefWindowProc(hwnd,uMsg,wParam,lParam); } return 0; } 11)编写具体过程: 1.WM_CHAR: char szChar[20]; sprintf(szChar,"asc is %d",wParam); MessageBox(hwnd,szChar,"MyFirst",0); 2.WM_PAINT: PAINTSTRUCT ps; HDC hdc; hdc=BeginPaint(hwnd,&ps); TextOut(hdc,0,0,"painting...",strlen("painting...")); EndPaint(hwnd,&ps); break; 3.WM_CLOSE: if(IDYES==MessageBox(hwnd,"exit?","MyFirst",MB_YESNO)) { DestroyWindow(hwnd); } break; 4.WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd,uMsg,wParam,lParam); } return 0;
最后
以上就是现代棒棒糖为你收集整理的(孙鑫C++)windows 程序内部运行原理的全部内容,希望文章能够帮你解决(孙鑫C++)windows 程序内部运行原理所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复