1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > 孙鑫VC++深入详解第一章学习笔记

孙鑫VC++深入详解第一章学习笔记

时间:2021-03-09 05:54:12

相关推荐

孙鑫VC++深入详解第一章学习笔记

第一章 Windows程序内部运行机制

1.1 API和SDK

API:Windows操作系统提供给应用程序编程的接口。

SDK(软件开发包):用于开发的所有资源的集合。

1.2 窗口和句柄

窗口

句柄:系统在创建资源时会为他们分配内存,并返回这些资源的标识号,即句柄。(类似于指针)

窗口句柄(HWND)、图标(HICON)、光标(HCURSOR)、画刷(HBRUSH)

1.3 消息和队列

消息(先进先出)

typedef struct tagMSG {HWND hwnd; //HWND:窗口变量,hwnd:消息所属的窗口UINT message; //message消息标识符,数值定义为WM_XXX (P4)WPARAM wParam; LPARAM lParam; //指定消息的附加信息,ASCII等DWORD time; //消息投递到消息队列中的时间POINT pt; //当前鼠标的位置} MSG, *PMSG;

1.4 WinMain

Win32实现的步骤:

定义WinMain函数;创建窗口;消息循环;窗口过程函数。

1.4.1 WinMain函数的定义

winmain函数是程序入口函数,由系统调用。

int WINAPI WinMain(HINSTANCE hInstance,// handle to current instanceHINSTANCE hPrevInstance, // handle to previous instance,always NULL in Win32LPSTR lpCmdLine,// 空终止的字符串,指定传递给应用程序的命令行参数int nCmdShow // 指定窗口应该如何显示);

1.4.2 窗口的创建

步骤:

设计窗口类;注册窗口;创建窗口;显示及更新窗口;

1.4.2.1 设计窗口类

typedef struct _WNDCLASS//窗口类{UINT style; /*(P7知识点方框)窗口样式;CS_XXX(都只有一位是1,且1位各不相同:位标志);多种特点组合用(|)号;去掉style中的样式用(&~)*/WNDPROC lpfnWndProc; //指向回调函数的指针;在特定的事件发生时,用于对该事件的响应int cbClsExtra;int cbWndExtra; //cbClsExtra和cbWndExtra两个附加内存,一般都为0HINSTANCE hInstance;//实例句柄HICONhIcon; //图标句柄;HICON LoadIcon(HINSTANCE hInstance, LPCTSTR lpIconName);HCURSOR hCursor; //光标句柄;HCURSOR LoadCursor(HINSTANCE hInstance,LPCTSTR lpCursorName);HBRUSHhbrBackground; //画刷句柄,背景颜色;wndcls.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);LPCTSTR lpszMenuName; //菜单名字,NULLLPCTSTR lpszClassName; //类名,和创建窗口CreateWindow函数中的lpClassName一致} WNDCLASS, *PWNDCLASS;

1.4.2.2 注册窗口

ATOM RegisterClass( CONST WNDCLASS *lpWndClass ); // 注册窗口

1.4.2.3 创建窗口

HWND CreateWindow( LPCTSTR lpClassName, // registered class name,与窗口类WNDCLASS中的lpszClassName一致LPCTSTR lpWindowName, // window name,DWORD dwStyle, /*window style;和WNDCLASS中的style不同,style是指定具体窗口的样式,dwstyle是窗口都具有的样式常用WS_OVERLAPPEDWINDOW*/int x,// horizontal position of windowint y,// vertical position of windowint nWidth, // window widthint nHeight,// window height;/*如果x设为CW_USEDEFAULT,系统为窗口选择左上角并忽略y;nWidth设为CW_USEDEFAULT,系统为默认大小并忽略nHeight。窗口之间的父子关系,子窗口必须有WS_CHILD*/HWND hWndParent,// handle to parent or owner window(父窗口句柄);NULLHMENU hMenu,// menu handle or child identifier;NULLHINSTANCE hInstance, // handle to application instance;hInstanceLPVOID lpParam // window-creation data;NULL);

注意:创建窗口成功,函数返回系统为该窗口分配的句柄,否则返回NULL。创建窗口之前应先定义一个窗口句柄变量来接收创建窗口之后返回的句柄值。

1.4.2.4 显示及更新窗口

显示窗口

BOOL ShowWindow(HWND hWnd,// 哪一个窗口?int nCmdShow // 如何显示?;常用SW_SHOWNORMAL);

更新窗口

BOOL UpdateWindow(HWND hWnd // handle to window);

1.4.3 消息循环

BOOL GetMessage(LPMSG lpMsg, // 指向一个消息结构体MSG,GetMessage取出的消息放入该结构体对象中HWND hWnd, // handle to window,设为NULL接收所用窗口UINT wMsgFilterMin, // first messageUINT wMsgFilterMax // last message;范围过滤,获得所有消息则设为0);

注意:GetMessage函数除了接收到WM_QUIT(退出消息)外都返回非零值,出错返回-1。

通常编写的消息循环代码如下:

MSG msg;//声明消息结构体变量while(GetMessage(&msg,NULL,0,0))//没接收到WM_QUIT时一致循环{TranslateMessage(&msg);//将WM_KEYDOWN和WM_KEYUP转化为WM_CHAR,不修改原消息DispatchMessage(&msg);//将消息发送至操作系统,后者用窗口过程函数对消息响应; Dispatch:派遣}

图1.1 Windows应用程序的消息处理机制

1.4.2窗口创建和1.4.3消息循环都包含在WinMain函数体内

1.4.4 窗口过程函数

即回调函数

LRESULT CALLBACK WindowProc(HWND hwnd,// 窗口句柄UINT uMsg,// 消息代码WPARAM wParam, // first message parameterLPARAM lParam // second message parameter);

过程函数名WindowProc可以换,但要和声明保持一致。使用switch/case来对不同消息作出不同反应。

如下方例子中的过程函数所示。

例子1.1

#define _CRT_SECURE_NO_DEPRECATE#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>#include <windows.h>#include <stdexcept>/*******************函数声明****************************/LRESULT CALLBACK WinSunProc(HWND hwnd,// handle to windowUINT uMsg,// message identifierWPARAM wParam, // first message parameterLPARAM lParam // second message parameter);/*******************WinMain函数*************************/int WINAPI WinMain(HINSTANCE hInstance,// handle to current instanceHINSTANCE hPrevInstance, // handle to previous instanceLPSTR lpCmdLine,// command lineint nCmdShow // show state){/*设计一个窗口类*/WNDCLASS wndcls;wndcls.cbClsExtra = 0;wndcls.cbWndExtra = 0;wndcls.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);wndcls.hCursor = LoadCursor(NULL, IDC_CROSS);wndcls.hIcon = LoadIcon(NULL, IDI_ERROR);wndcls.hInstance = hInstance;wndcls.lpfnWndProc = WinSunProc;wndcls.lpszClassName="sunxin";wndcls.lpszMenuName = NULL;wndcls.style = CS_HREDRAW | CS_VREDRAW;RegisterClass(&wndcls);/*创建窗口*/HWND hwnd;hwnd = CreateWindow("sunxin", "sx's home.", 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);//将WM_KEYDOWN和WM_KEYUP转化为WM_CHAR,不修改原消息DispatchMessage(&msg);//将消息发送至操作系统,后者用窗口过程函数对消息响应}return msg.wParam;}/*******************窗口过程函数*************************/LRESULT CALLBACK WinSunProc(HWND hwnd,// handle to windowUINT uMsg,// message identifierWPARAM wParam, // first message parameterLPARAM lParam // second message parameter){switch (uMsg){case WM_CHAR:char szChar[20];sprintf(szChar, "char code is %d", wParam);MessageBox(hwnd, szChar, "char", 0);break;case WM_LBUTTONDOWN:MessageBox(hwnd, "mouse clicked", "message", 0);HDC hdc;//要在窗口中输出文字或显示图形,要用到设备描述表(DC)。DC是一个包含设备信息的结构体,所有的图形操作都是利用DC来完成。//定义类型为HDC的变量hdchdc = GetDC(hwnd);//GetDC返回与特定窗口相关联的DC句柄TextOut(hdc, 0, 50, "sx's home",strlen("sx's home"));ReleaseDC(hwnd, hdc);//在使用完GetDC后一定要注意释放break;case WM_PAINT://窗口重绘HDC hDC;PAINTSTRUCT ps;hDC = BeginPaint(hwnd, &ps);TextOut(hDC, 0, 0, "", strlen(""));EndPaint(hwnd, &ps);//WM_PAINT、BeginPaint、EndPaint一起用,而不能用GetDCbreak;case WM_CLOSE://关闭消息if (IDYES == MessageBox(hwnd, "是否真的结束了?", "message", MB_YESNO)){DestroyWindow(hwnd);//销毁窗口}break;//此时窗口销毁,但程序还在后台运行case WM_DESTROY:PostQuitMessage(0);//在响应消息后,投递一个退出的消息使用程序安全退出break;default:return DefWindowProc(hwnd, uMsg, wParam, lParam);//调用缺省的消息处理过程函数,对没有处理的其他消息以默认处理}return 0;}

问题反思

1、创建新的项目:vs>>Windows桌面应用程序

2、vs中如遇到类似cannot convert from ‘const char [7]’ to 'LPCWSTR’的错误,请对工程进行字符设置菜单栏-<项目-<xxx 属性-<配置属性-<高级-<字符集,改成“not set”或改成“Use Multi-Byte Character Set”。

参考文献

[1] VC++深入详解 孙鑫 第一章 Windows程序内部运行机制 - focusahaha - 博客园 ()./focusahaha/p/12601081.html

[2]孙鑫.VC++深度详解修订版[M]. 北京:电子工业出版社, . 1-26.

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。