牛刀教程笔记—消息

来源:互联网 发布:影楼网络客服销售技巧 编辑:程序博客网 时间:2024/05/06 04:49

#include <windows.h>
//LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
/**************************************************
HINSTANCE是句柄定义了两个句柄,LPSTR是字符串指针
typedef CHAR *LPSTR, *PSTR; 其中CHAR typedef char CHAR;
***************************************************/
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )

{

HWND hwnd;//不是结构体,是句柄说明了是一个32位的数
MSG Msg;//是结构体如下
/*########################## Message structure###############

/*typedef struct tagMSG {
HWND hwnd;
UINT message;
WPARAM wParam;
LPARAM lParam;
DWORD time;
POINT pt;
#ifdef _MAC
DWORD lPrivate;
#endif
} MSG, *PMSG, NEAR *NPMSG, FAR *LPMSG;
##################################################################*/
WNDCLASS wndclass;//是结构体 typedef WNDCLASSA WNDCLASS;
/*#typedef struct tagWNDCLASSA {
UINT style;
WNDPROC lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
HINSTANCE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCSTR lpszMenuName;
LPCSTR lpszClassName;
} WNDCLASSA, *PWNDCLASSA, NEAR *NPWNDCLASSA, FAR *LPWNDCLASSA;
####################################################################*/


char lpszClassName[]="窗口";//l long,p pointer,sz string
char lpszTitle[]="做自己的窗口";
wndclass.style=0;
wndclass.lpfnWndProc=WndProc;
wndclass.cbClsExtra=0;
wndclass.cbWndExtra=0;
wndclass.hInstance=hInstance;//实例句柄这个句柄表明当前程序当我们使用WinMain函数时,
//函数中就传递过来了
wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);//HICON是图标句柄这里用LoadIcon函数
//调用了一个系统图标
wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);//光标也用系统LoadCursor函数调用系统的一个光标
wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);//HBRUSH是一个画刷。这里用WITE_BRUSH.
//可以改为BLACK_BRUSH试试看
wndclass.lpszMenuName=NULL;//菜单指向NULL,没有菜单
wndclass.lpszClassName=lpszClassName;
/*******************************************************
RegisterClass是向系统注册窗体 我们的系统与DOS系统不同,
是多任务系统。每个句柄都是一个资源WINDOWS,最多有2^32种资源。
每一个句柄都要让系统知道这个句柄,在程序运行之前注册,注册
有可能失败,所以写成以下形式:
********************************************************/

if(!RegisterClass(&wndclass))
{
MessageBeep(0);
return FALSE;
}
/************************************************************
下面这个函数返回一个句柄,其实是得到一个窗口句柄。我们上面的赋值
仅仅是将我们的想法告诉一个结构体,结构本身是一堆数据,注册结构体
是告诉系统我们需要用这些结构体产生一个窗体,而CreateWindow则是产
这个窗体。
第一个参数:窗口类名
就是我们上面的那个名字,为什么要用这个名字呢?因为这个名字的窗口
我们向系统已经注册了,系统中已经有这个名字的窗口存在了。所以我们
产生窗口就必须是这个名字的窗口,当然你可能会想不是有结构体吗?还
用名字做啥?因为结构体一旦注册了窗口,使命就完成了结构体是一种数
据结构,而窗口是一种系统资源。
第二个参数:窗口标题名
第三个参数:窗口样式
还有以下几种
WS_BORDER
WS_CAPTION
WS_VICROLL
WS_MAXIMIZEBOX
WS_MAXIMIZE
WS_MINIMIZEBOX
WS_MINIMIZE
WS_OVERLAPPED
WS_OVERLAPPEDW
WS_POPUP
WS_POPUPWINDOW
WS_SYSMENU
WS_HSCROLL
再下面就是窗口左上角坐标与窗口的宽度与高度
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
CW_USEDEFAULT采用系统默认值CW_USEDEFAULT
再下面就是窗口句柄,菜单句柄,实例句柄等。
NULL,NULL,hInstance,NULL
*************************************************************/
hwnd=CreateWindow(lpszClassName,lpszTitle,WS_OVERLAPPEDWINDOW
,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL
,NULL,hInstance,NULL);
/************************************************************
ShowWindow(hwnd,nShowCmd);第一个参数是窗口句柄,第二个是窗口状
态。
*************************************************************/


ShowWindow(hwnd,nShowCmd);
UpdateWindow(hwnd);
/***********************************************************
消息循环GetMessage 得到消息,将其放在Msg结构体中。
GetMessage函数的返回值就在接收刀WM_QUIT消息时返回0值,其他消息
均不返回0值。WM_CLOSE WM_QUIT  WM_DESTROY  这三个消息是按顺序进行的。
WM_QUIT消息不是由系统发出的而是由PostQuitMessage(0)发出的。也就是我们
用户如果没有对WM_CLOSE函数做处理,则系统会自动调用PostQuitMessage(0)
函数发出一条WM_QUIT。所以说在我们的程序中必须有一条WM_QUIT消息发出来,
如果一旦由用户将VM_CLOSE消息处理了,那我们的程序就关不了。VM_CLOSE和
VM_CREATE消息只产生一次,VM_CREATE消息为窗口还没有产生,即创建消息时的消息;
而VM_DESTROY为窗口结束了,关闭后的消息。vm_close是关闭窗体的消息但没有退出循环
但窗体不能完,应该是WM_DESTROY的事,而退出消息循环应该是WM_QUIT的事。

 

这三个消息的顺序为:

 

WM_CLOSE
WM_DESTROY
WM_QUIT

这证明人家原来书上的一些结论没有错,是牛刀错了

再一个就是说, WM_QUIT消息没办法捕捉,必须由系统调用,功能是结
束进程,也就是说,我们在编程中不可以对 WM_QUIT消息编程,当然如果
我们知道其执行机理了,也可以进行编程了,事情不能一概而论。

第三就是 WM_CLOSE消息完了后, WM_DESTROY之前就销毁窗体,
如果我们要在窗体销毁之前做事情,就需要响应 WM_CLOSE消息,如果我们

要在窗体销毁之后做事,就去响应 WM_DESTROY消息,呵呵,其实 destroy
就是销毁的意思嘛,有时候忘文生意更好,但我们要知道,一旦有了这个消息发
出了,窗体已经不存在了,所以一般情况下,这里的处理基本上都是调用
PostQuitMessage(0)。

*************************************************************/
while(GetMessage(&Msg,NULL,0,0))
{
TranslateMessage(&Msg);//翻译消息:如当按下键和松开按键时
//得到VM_KEYDOWN和VM_KEYUP消息。而消息
//字符VM_CHAR就是通过TranslateMessage这个
//函数翻译过来的
DispatchMessage(&Msg);//分发消息

}
return Msg.wParam; //返回消息中的一个数据
}
/***************************************************************************
WndProc名称可以改。
typedef LRESULT (CALLBACK* WNDPROC)(HWND, UINT, WPARAM, LPARAM);
HWND hwnd:是句柄,窗口句柄,因为下面的操作都是对这个窗口进行操作的所以必须有
这个句柄。
UINT message:无符号整数,传来的是消息,这个函数中主要是处理消息。处理过程是在
WinMain消息循环中。处理消息由本函数来承担。
WPARAM wParam,LPARAM lParam:一个是十六位参数。W(WORD),L(LONG)。

**************************************************************************/
LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
RECT rt;
POINT pt;
switch(message)
{

case WM_PAINT:
hdc=BeginPaint(hwnd,&ps);
{
pt.x=20;
pt.y=20;
TextOut(hdc,pt.x,pt.y,"学做WINDOWS程序",15);
}
EndPaint(hwnd,&ps);
break;
case WM_CLOSE:
MessageBox(hwnd,"关不掉呵呵","使用资源管理器关",MB_OK);
//PostQuitMessage(0);//发出VM_QUIT消息
break;
default:
return DefWindowProc(hwnd,message,wParam,lParam);

}

return 0;
}

 

 

消息只不过其将数据改成了 "宏",我们可以看一些定义:

 

 

#define WM_SETFOCUS 0x0007
#define WM_KILLFOCUS 0x0008
#define WM_ENABLE 0x000A
#define WM_SETREDRAW 0x000B
#define WM_SETTEXT 0x000C
#define WM_GETTEXT 0x000D
#define WM_GETTEXTLENGTH 0x000E
#define WM_PAINT 0x000F
#define WM_CLOSE 0x0010
#define WM_QUERYENDSESSION 0x0011
#define WM_QUIT 0x0012
#define WM_QUERYOPEN 0x0013
#define WM_ERASEBKGND 0x0014
#define WM_SYSCOLORCHANGE 0x0015
#define WM_ENDSESSION 0x0016
#define WM_SHOWWINDOW 0x0018
#define WM_WININICHANGE 0x001A

  

接上程序:

LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{

 

 

 

switch(message)
{
HDC hdc;
PAINTSTRUCT ps;
RECT rt;
POINT pt;//计算机中的坐标系统与我们直角坐标系不同,直角坐标系是
//x轴向右,y轴向上的,而计算机中却是 x轴向右,y轴向下,坐标原点为右上角

case WM_PAINT:
hdc=BeginPaint(hwnd,&ps);//设备描述表是一个接口,并且规定了一套 API函数
// BeginPaint是产生一个设备描述表,而 EndPaint是注销设备描述表,
//而一旦我们拿到设备描述表,就可以用我们的与设备描述表相关的 API函
//数直接向屏幕上写东西了。
{
SetTextColor(hdc,RGB(255,0,0));//其实我们不是更改了汉字的属性,而是用 SetTextColor改变了设备描述表的
//属性,我们汉字的显示就相应地不同了,那到底是哪儿不同了呢?当然是设备描
//述表所指向的某一项数据改变了,至于哪项数据改变了,我们暂时先不讨论,因
//为这些东西的确很复杂。我们这要说的是 RGB(255,0,0)并不是一个函数,而是一个宏,其中的每个参数分别表示红(R)绿(G)蓝(B)
pt.x=20;
pt.y=20;
TextOut(hdc,pt.x,pt.y,"学做WINDOWS程序",15);
}
EndPaint(hwnd,&ps);
break;
case WM_CLOSE:
PostQuitMessage(0);//发出VM_QUIT消息
break;
default:
return DefWindowProc(hwnd,message,wParam,lParam);

}

return 0;
}

 

 

 

 

 

 

 

 

原创粉丝点击