今天开始决定好好复习了,为了能更深入更扎实掌握这一门编程技术,下了孙鑫的视频教程,感觉确实不错,说得很明白,让我有想做笔记的冲动,和大家一起分享了,但我只记我感兴趣的部分,呵呵
(20080509 经过第一次修改)
1、操作系统会为每个应用程序建立一个消息队列。
我以前以为windows只有一个消息队列,尽管我知道那样的话会很庞大。
所有主要的api函数都在windows.h头文件中进行了声明。
在windows程序中,有各种各样的资源,系统在创建这些资源时为他们分配内存,并返回标志这些资源的标识号,即句柄(我看就是内存地址吧,指针咯)。
窗口过程,就是程序中专门负责处理消息的函数。
消息由MSG结构体表示:
typedef struct tagMSG {
HWND hwnd; //消息所属的窗口
UINT message; //消息标识符,就是如WM_KEYDOWN之类的宏啦,说明是什么类型的消息
WPARAM wParam; //消息附加信息,这个一般都被拿来判断消息的具体内容
LPARAM lParam; //消息附加信息,这个一般都被拿来判断附加内容
DWORD time; //时间
POINT pt; //鼠标位置
} MSG;
2、窗口的建立过程:
1 设计窗口类
2 注册窗口
3 建立窗口
4 显示窗口
设计窗口类,就是指定窗口特征,由WNDCLASS结构图定义
typedef struct _WNDCLASS {
UINT style; //窗口样式,CS_开头的宏,就是规定窗口是否重绘,有无关闭按钮等
WNDPROC lpfnwndProc; //指向窗口过程的指针,一般是回调函数的指针,这里是WinSunProc
int cbClsExtra; //让系统为WNDCLASS追加多少字节的附加内存空间,存储类附加信息,一般设为0
int cbWndExtra; //让系统为窗口结构追加多少字节附加内存空间,存储窗口附加信息,一般设为0
HANDLE hInstance; //包含窗口的实例的句柄,直接=WINMAIN的传入参数hInstance即可
HICON hIcon; //图标句柄,如果是NULL,则调用系统默认图标,也可以用LoadIcon()加载图标
HCURSOR hCursor; //光标句柄,如果是NULL,每次进窗口都得重新指定,一般LoadCursor()
HBRUSH hbrBackground; //背景画刷句柄,可用GetStockObject()取用系统标准画刷,须类型转换
LPCTSTR lpszMenuName; //菜单资源的名字,可用MAKEINTRESOURCE宏转换资源ID为字串
LPCTSTR lpszClassName; //窗口类名字,将被用到CreateWindow()第一个参数中
} WNDCLASS;
注册窗口,就是把我们编写的窗口过程函数地址交给系统
ATOM RegsiterClass(CONST WNDCLASS *LpWndClass); //参数就是设计窗口类的指针,
创建窗口,我理解就是按要求在内存中构造窗口,返回一个窗口句柄,供显示窗口函数调用
HWND CreateWindow(
LPCTSTR lpClassName, //窗口类名字,就是设计窗口时自己指定的参数 lpszClassName
LPCTSTR lpWindowName, //窗口的名字,随便定啦,用双引号括住
DWORD dwStyle, //窗口的样式
int x, //窗口的左上角坐标
int y,
int nWindth, //窗口的宽高
int nHeight,
HWND hWndParent, //窗口的父窗口句柄,没有就NULL
HMENU hMenu, //窗口菜单句柄,就是设计窗口时定的参数lpszMenuName,是NULL就NULL
HANDLE hInstance, //窗口所属应用程序实例句柄,就是设计窗口类的参数hInstance
LPVOID lpParam //WM_CREATE消息的附加参数,一般为null,多文档窗口须指向
CLIENTCREATESTRUCT结构体
};
显示及更新窗口,
BOOL ShowWindow(
HWND hWnd, //创建窗口后返回的窗口句柄,就是上面那个函数的返回值啦
int nCmdShow //窗口的显示方式
};
调用了ShowWindow()立即刷新窗口
BOOL UpdateWindow(HWND hWnd);
3、 GetDC(hwnd); ReleaseDC(hwnd,hdc); 成对出现,不能用于wm_paint
要在窗口中输出文字或者图形,需要用到设备描述表DC(一个包含设备信息的结构体),windows中所有图形操作都是通过DC来完成的。
4、 BeginPaint(hwnd,&ps); EndPaint(hwnd,&ps); 成对出现,只能用于wm_paint
5、windows 程序基本架构
#include
#include
LRESULT CALLBACK WinSunProc( //回调函数声明
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
int WINAPI WinMain(
HINSTANCE hInstance, // 当前实例句柄,由系统提供
HINSTANCE hPrevInstance, // 当前实例的前一个实例的句柄,win32下无效,一般为NULL
LPSTR lpCmdLine, // 命令行参数
int nCmdShow // 程序或窗口的显示方式
)
{
/构造窗口///
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="Weixin2003";
wndcls.lpszMenuName=NULL;
wndcls.style=CS_HREDRAW | CS_VREDRAW;
RegisterClass(&wndcls); //注册窗口
HWND hwnd;
hwnd=CreateWindow("Weixin2003","北京维新科学技术培训中心",WS_OVERLAPPEDWINDOW,
0,0,600,400,NULL,NULL,hInstance,NULL); //建立窗口。设计类名,窗口标题,窗口类型
ShowWindow(hwnd,SW_SHOWNORMAL); //显示窗口。窗口句柄,显示方式
UpdateWindow(hwnd);
/循环从消息队列中取出消息
MSG msg;
while(GetMessage(&msg,NULL,0,0)) //获取消息,wm_quit返回0,否则返回非0,错误返回-1,随后消息被删
{ //载入消息,哪个窗口(null为该线程的全部窗口),消息过滤最小值,最大值(全0则全部)
TranslateMessage(&msg); //解析消息,就是将虚拟键消息转换为字符消息,然后投入线程消息队列
DispatchMessage(&msg); //分派消息入回调函数,就是将消息丢给系统,系统又调用窗口过程处理消息
} //windows通过这个循环保证程序始终在运行状态,要处理而不删消息,用PeekMessage()
return 0;
}
LRESULT CALLBACK WinSunProc( //显式声明函数方式为_stdcall调用约定,参数调用顺序,堆栈操作不同
HWND hwnd, // 窗口句柄 //vc api都是_stdcall,c++默认_cdecl方式
UINT uMsg, // 消息代码 //这些参数和消息结构前四个一致,处理消息
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
)
{
switch(uMsg)
{
case WM_CHAR: //要始终显示,可以在该消息中处理
char szChar[20];
sprintf(szChar,"char is %d",wParam); //格式化字符串并输入制定内存
MessageBox(hwnd,szChar,"weixin",0); //窗口句柄,字符串,窗口标题,显示方式(ok/yesno类型等)
break;
case WM_LBUTTONDOWN:
MessageBox(hwnd,"mouse clicked","weixin",0);
HDC hdc;
hdc=GetDC(hwnd); //获取主窗口画布
TextOut(hdc,0,50,"计算机编程语言培训",strlen("计算机编程语言培训")); //画布句柄,坐标,字串,字串长
ReleaseDC(hwnd,hdc); //销毁dc
break;
case WM_PAINT:
HDC hDC;
PAINTSTRUCT ps;
hDC=BeginPaint(hwnd,&ps); //ps由系统填充和维护,不需要关心
TextOut(hDC,0,0,"维新培训",strlen("维新培训"));
EndPaint(hwnd,&ps);
break;
case WM_CLOSE:
if(IDYES==MessageBox(hwnd,"是否真的结束?","weixin",MB_YESNO))
{
DestroyWindow(hwnd); //销毁窗口,随后程序会自动再发一个WM_DESTROY
}
break;
case WM_DESTROY:
PostQuitMessage(0); //给窗口过程发送一个WM_QUIT,退出消息循环,销毁程序实例
break;
default:
return DefWindowProc(hwnd,uMsg,wParam,lParam); //默认回调函数,否则窗口一闪就过
}
return 0;
}