这两天看了孙鑫VC教学视频的第一集:WinDows程序内部运行原理。将所学内容整理成笔记以备将来之需,其文如下:
1. 关于计算机系统,如图所示:
计算机系统大致分为三层:应用程序,操作系统,硬件设备。应用程序通过调用操作系统提供的API来通知操作系统完成对底层硬件设备的操作;相反,操作系统会将硬件设备的感知封装为消息传递到消息队列,然后由应用程序从消息队列中取走,并做出对消息的具体响应。
2. 新名词解释。
句柄:即资源的标识,操作系统将通过句柄来寻找对应的资源。如图标句柄(HICON),光标句柄(HCURSOR),窗口句柄(HWND),应用程序实例句柄(HINSTANCE)
窗口类的一些变量:变量的每一位置1则表示具备对应的那种特性,反之则无。变量中具体位代表的意义难以记忆,所以通过宏来进行代替,如CS_VREDRAW=0x0001,CS_HREDRAW=0x0002。如果想使该变量同时具有几种特性,则可以将这几种特性对应的宏进行OR(|)运算,若要从该变量中去掉每一特性,则将对应的宏取反之后再与该变量进行&运算。举例:style=CS_VREDRAW | CS_HREDRAW | CS_NOCLOSE,表示变量同时设置了以上三种对应的特性。
回调函数:当应用程序收到消息时,需要调用一个函数进行消息处理,函数调用的过程只由操作系统完成,而回调函数的处理方法的代码需要应用程序完成。每一种不同类型的窗口都有自己专用的回调函数,该函数是通过lpfWnsProc成员指定。
3. 第一个WinDows程序。
创建一个完整的窗口程序的四个步骤:
设计一个窗口类:填充WNDCLASS类 注册窗口类:RegisterClass函数ATOM RegisterClass( CONST WNDCLASS *lpWndClass // class data ); 创建窗口:CreateWindow函数HWND CreateWindow( LPCTSTR lpClassName, // registered class name LPCTSTR lpWindowName, // window name DWORD dwStyle, // window style int x, // horizontal position of window int y, // vertical position of window int nWidth, // window width int nHeight, // window height HWND hWndParent, // handle to parent or owner window HMENU hMenu, // menu handle or child identifier HINSTANCE hInstance, // handle to application instance LPVOID lpParam // window-creation data ); 显示并更新窗口:ShowWindow和UpWindow函数,具体声明查询MSDN除此之外,还有两个重要的过程,即通过while循环来获取各种消息以及编写回调函数对不同消息的处理方法。具体编写代码所示:
#include <windows.h>
#include <stdio.h>
LRESULT CALLBACK WinWanProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
int WINAPI WinMain(
HINSTANCE hInstance, // handle to current instance
HINSTANCE hPrevInstance, // handle to previous instance
LPSTR lpCmdLine, // command line
int nCmdShow // show state
)
{
//1.设计一个窗口类
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 = WinWanProc;
wndcls.lpszClassName = "myfirst";
wndcls.lpszMenuName = NULL;
wndcls.style = CS_HREDRAW | CS_VREDRAW;
//2.注册窗口类
RegisterClass(&wndcls);
//3.创建窗口类
HWND hwnd;
hwnd = CreateWindow("myfirst","windows",WS_OVERLAPPEDWINDOW,0,0,600,400,NULL,NULL,hInstance,NULL);
//4.显示和更新窗口
ShowWindow(hwnd,SW_SHOWNORMAL);
UpdateWindow(hwnd);
//获取消息
MSG msg;
while (GetMessage(&msg,NULL,0,0))//从消息队列获取消息,若有消息则一直返回TRUE
{
TranslateMessage(&msg); //将消息对WM_KEYUP和WM_KEYDOWN转换成WM_CHAR消息
DispatchMessage(&msg);//将消息路由给操作系统,由操作系统调用窗口回调函数
}
return 0;
}
//5.回调函数,对不同的消息完成不同的响应
LRESULT CALLBACK WinWanProc(
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 str[20];
sprintf(str,"the key_char is %d",wParam);
MessageBox(hwnd,str,"wang",MB_OK);
break;
case WM_LBUTTONDOWN:
MessageBox(hwnd,"mouse clicked!","wang",MB_YESNO);
HDC hdc; //设备上下文,可以屏蔽设备驱动程序,方便应用程序的调用
hdc = GetDC(hwnd);
TextOut(hdc,0,50,"yes i do!", strlen("yes i do!"));
ReleaseDC(hwnd,hdc);
break;
case WM_PAINT:
HDC hDC;
PAINTSTRUCT ps;
hDC = BeginPaint(hwnd,&ps);
TextOut(hDC,0,0,"paint message!",strlen("paint message!"));
EndPaint(hwnd,&ps);
break;
case WM_CLOSE:
if(IDYES==MessageBox(hwnd,"是否要推出程序?","wang",MB_YESNO))
{
DestroyWindow(hwnd);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
return 0;
}
孙鑫老师的视频讲的深入浅出,我决定将好好学习VC编程,感谢老师提供这么好的资源,强者自强!