typedef struct tagMSG { // msg
HWND hwnd; //标识窗口过程接收消息的窗口。
UINT message; //指定消息号。
WPARAM wParam; //指定有关消息的更多信息。 确切含义取决于 message 成员的值
LPARAM lParam; //指定有关消息的更多信息。 确切含义取决于 message 成员的值。
DWORD time; //指定传递消息时的时间。
POINT pt; //当传递消息时指定了,光标位置,在屏幕坐标。
} MSG;
句柄(HANDLE),资源的标识。
操作系统要管理和操作这些资源,都是通过句柄来找到对应的资源。按资源的类型,又可将句柄细分成图标句柄(HICON),光标句柄(HCURSOR),窗口句柄(HWND),应用程序实例句柄(HINSTANCE)等等各种类型的句柄。操作系统给每一个窗口指定的一个唯一的标识号即窗口句柄。
#include <windows.h>
#include <stdio.h>
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, // handle to current instance
HINSTANCE hPrevInstance, // handle to previous instance
LPSTR lpCmdLine, // command line 命令行参数
int nCmdShow // show state
)
//创建一个完整的窗口需要经过下面四个操作步骤:
//设计一个窗口类;
//注册窗口类;
//创建窗口;
//显示及更新窗口。
{
WNDCLASS wndcls; //1 设计一个窗口类
wndcls.cbClsExtra=0; //窗口类的额为数据 通常设为0
wndcls.cbWndExtra=0; //窗口附加内存
wndcls.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH); //画刷的句柄 BLACK_BRUSH黑色的画刷 white_brush
//(HBRUSH)强制类型转换 GetStockObject返回的是HGDIOBJ 这个类型
wndcls.hCursor=LoadCursor(NULL,IDC_CROSS); //光标的句柄 NULL微软设置好的标准光标
wndcls.hIcon=LoadIcon(NULL,IDI_ERROR); //图标的句柄 NULL微软设置好的标准图标
wndcls.hInstance=hInstance; //当前应用程序的实例号
wndcls.lpfnWndProc=WinSunProc; //窗口的回调函数
/*
第二个成员变量lpfnWndProc指定了这一类型窗口的过程函数,也称回调函数。回调函数的原理是这样的,当应用程序收到给某一窗口的消息时(还记得前面讲过的消息通常与窗口相关的吗?),就应该调用某一函数来处理这条消息。这一调用过程不用应用程序自己来实施,而由操作系统来完成,但是,回调函数本身的代码必须由应用程序自己完成。对于一条消息,操作系统到底调用应用程序中的哪个函数(回调函数)来处理呢?操作系统调用的就是接受消息的窗口所属的类型中的lpfnWndProc成员指定的函数。每一种不同类型的窗口都有自己专用的回调函数,该函数就是通过lpfnWndProc成员指定的。
*/
wndcls.lpszClassName="Weixin2003"; //给窗口设计一个名字
wndcls.lpszMenuName=NULL; //设置菜单的名字
wndcls.style=CS_HREDRAW | CS_VREDRAW; //窗口类型 水平重画和垂直重画
RegisterClass(&wndcls); //2. //向操作系统注册一个窗口类
//3.创建一个窗口
HWND hwnd; //定义一个句柄 保存创建窗口的标示
hwnd=CreateWindow("Weixin2003","北京维新科学技术培训中心",WS_OVERLAPPEDWINDOW,
0,0,600,400,NULL,NULL,hInstance,NULL);
/*
HWND CreateWindow(
LPCTSTR lpClassName, //注册的类名 基于已经注册的类名的设计
LPCTSTR lpWindowName, //窗口的名字
DWORD dwStyle, //窗口的类型 WS_OVERLAPPED
int x,
int y, // x,y窗口的坐标 CW_USEDEFAULT
int nWidth, //窗口的宽度
int nHeight, //窗口的高度
HWND hWndParent, //父窗口的句柄
HMENU hMenu, //菜单的句柄
HANDLE hInstance, //当前应用实例的句柄
PVOID lpParam //WM_CREATE 的附加参数
);
*/
// 3,显示一个窗口
ShowWindow(hwnd,SW_SHOWNORMAL);
// 4,登记窗口
UpdateWindow(hwnd);
BOOL GetMessage(
LPMSG lpMsg,
HWND hWnd, //null设置任何消息队列的消息
UINT wMsgFilterMin, //0
UINT wMsgFilterMax //消息的最大值 0没有范围的过滤
);
MSG msg;
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg); //对取到的消息进行转换 把keydown,updown消息 转换为wchar消息
DispatchMessage(&msg); //将收到的消息转到回调函数进行处理
}
return 0;
}
LRESULT CALLBACK WinSunProc( //callback 函数调用的约定
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); //0标示确定按钮
HDC hdc; //作图
hdc=GetDC(hwnd); //获取与窗口相关的dc
TextOut(hdc,0,50,"计算机编程语言培训",strlen("计算机编程语言培训"));
//文本输出函数 0,50坐标
ReleaseDC(hwnd,hdc); //释放dc 注意一定要释放,防止内存泄露
break;
case WM_PAINT: //当窗口重绘时,不能在这里设置断点
HDC hDC;
PAINTSTRUCT ps;
hDC=BeginPaint(hwnd,&ps); //获取一个DC句柄
TextOut(hDC,0,0,"维新培训",strlen("维新培训"));
EndPaint(hwnd,&ps);
break;
case WM_CLOSE:
if(IDYES==MessageBox(hwnd,"是否真的结束?","weixin",MB_YESNO))
//if语句做判断的时候我们把常量放在前面
{
DestroyWindow(hwnd);//销毁一个指定的窗口
}
break;
case WM_DESTROY: //窗口已经销毁
PostQuitMessage(0); //
break;
default:
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
return 0;
}
HWND hwnd; //标识窗口过程接收消息的窗口。
UINT message; //指定消息号。
WPARAM wParam; //指定有关消息的更多信息。 确切含义取决于 message 成员的值
LPARAM lParam; //指定有关消息的更多信息。 确切含义取决于 message 成员的值。
DWORD time; //指定传递消息时的时间。
POINT pt; //当传递消息时指定了,光标位置,在屏幕坐标。
} MSG;
句柄(HANDLE),资源的标识。
操作系统要管理和操作这些资源,都是通过句柄来找到对应的资源。按资源的类型,又可将句柄细分成图标句柄(HICON),光标句柄(HCURSOR),窗口句柄(HWND),应用程序实例句柄(HINSTANCE)等等各种类型的句柄。操作系统给每一个窗口指定的一个唯一的标识号即窗口句柄。
#include <windows.h>
#include <stdio.h>
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, // handle to current instance
HINSTANCE hPrevInstance, // handle to previous instance
LPSTR lpCmdLine, // command line 命令行参数
int nCmdShow // show state
)
//创建一个完整的窗口需要经过下面四个操作步骤:
//设计一个窗口类;
//注册窗口类;
//创建窗口;
//显示及更新窗口。
{
WNDCLASS wndcls; //1 设计一个窗口类
wndcls.cbClsExtra=0; //窗口类的额为数据 通常设为0
wndcls.cbWndExtra=0; //窗口附加内存
wndcls.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH); //画刷的句柄 BLACK_BRUSH黑色的画刷 white_brush
//(HBRUSH)强制类型转换 GetStockObject返回的是HGDIOBJ 这个类型
wndcls.hCursor=LoadCursor(NULL,IDC_CROSS); //光标的句柄 NULL微软设置好的标准光标
wndcls.hIcon=LoadIcon(NULL,IDI_ERROR); //图标的句柄 NULL微软设置好的标准图标
wndcls.hInstance=hInstance; //当前应用程序的实例号
wndcls.lpfnWndProc=WinSunProc; //窗口的回调函数
/*
第二个成员变量lpfnWndProc指定了这一类型窗口的过程函数,也称回调函数。回调函数的原理是这样的,当应用程序收到给某一窗口的消息时(还记得前面讲过的消息通常与窗口相关的吗?),就应该调用某一函数来处理这条消息。这一调用过程不用应用程序自己来实施,而由操作系统来完成,但是,回调函数本身的代码必须由应用程序自己完成。对于一条消息,操作系统到底调用应用程序中的哪个函数(回调函数)来处理呢?操作系统调用的就是接受消息的窗口所属的类型中的lpfnWndProc成员指定的函数。每一种不同类型的窗口都有自己专用的回调函数,该函数就是通过lpfnWndProc成员指定的。
*/
wndcls.lpszClassName="Weixin2003"; //给窗口设计一个名字
wndcls.lpszMenuName=NULL; //设置菜单的名字
wndcls.style=CS_HREDRAW | CS_VREDRAW; //窗口类型 水平重画和垂直重画
RegisterClass(&wndcls); //2. //向操作系统注册一个窗口类
//3.创建一个窗口
HWND hwnd; //定义一个句柄 保存创建窗口的标示
hwnd=CreateWindow("Weixin2003","北京维新科学技术培训中心",WS_OVERLAPPEDWINDOW,
0,0,600,400,NULL,NULL,hInstance,NULL);
/*
HWND CreateWindow(
LPCTSTR lpClassName, //注册的类名 基于已经注册的类名的设计
LPCTSTR lpWindowName, //窗口的名字
DWORD dwStyle, //窗口的类型 WS_OVERLAPPED
int x,
int y, // x,y窗口的坐标 CW_USEDEFAULT
int nWidth, //窗口的宽度
int nHeight, //窗口的高度
HWND hWndParent, //父窗口的句柄
HMENU hMenu, //菜单的句柄
HANDLE hInstance, //当前应用实例的句柄
PVOID lpParam //WM_CREATE 的附加参数
);
*/
// 3,显示一个窗口
ShowWindow(hwnd,SW_SHOWNORMAL);
// 4,登记窗口
UpdateWindow(hwnd);
BOOL GetMessage(
LPMSG lpMsg,
HWND hWnd, //null设置任何消息队列的消息
UINT wMsgFilterMin, //0
UINT wMsgFilterMax //消息的最大值 0没有范围的过滤
);
MSG msg;
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg); //对取到的消息进行转换 把keydown,updown消息 转换为wchar消息
DispatchMessage(&msg); //将收到的消息转到回调函数进行处理
}
return 0;
}
LRESULT CALLBACK WinSunProc( //callback 函数调用的约定
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); //0标示确定按钮
HDC hdc; //作图
hdc=GetDC(hwnd); //获取与窗口相关的dc
TextOut(hdc,0,50,"计算机编程语言培训",strlen("计算机编程语言培训"));
//文本输出函数 0,50坐标
ReleaseDC(hwnd,hdc); //释放dc 注意一定要释放,防止内存泄露
break;
case WM_PAINT: //当窗口重绘时,不能在这里设置断点
HDC hDC;
PAINTSTRUCT ps;
hDC=BeginPaint(hwnd,&ps); //获取一个DC句柄
TextOut(hDC,0,0,"维新培训",strlen("维新培训"));
EndPaint(hwnd,&ps);
break;
case WM_CLOSE:
if(IDYES==MessageBox(hwnd,"是否真的结束?","weixin",MB_YESNO))
//if语句做判断的时候我们把常量放在前面
{
DestroyWindow(hwnd);//销毁一个指定的窗口
}
break;
case WM_DESTROY: //窗口已经销毁
PostQuitMessage(0); //
break;
default:
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
return 0;
}