Windows程序设计--学习笔记 (三)

第三章: 窗口与消息

创建窗口:调用函数 CreateWindow

"Windows向应用程序发送了一条消息" 意思就是说:“Windows调用了该程序内部的一个函数”,这个函数就是我们自己写的,此函数的参数描述了由Windows所发送并由我们的程序所接收的特定消息。这个函数被称为“窗口过程”;

应用程序所创建的每一个窗口都有一个与之相关联的窗口过程,这个窗口过程可以是应用程序的某一个函数,也可以位于一个动态链接库中。

Windows通过调用“窗口过程”来向窗口传递消息,“窗口过程”依据这些消息来做出相应的处理,然后将控制权返还给Windows;

窗口总是依据“窗口类”来创建,窗口类标识了用于处理传递给窗口的消息的窗口过程。窗口类的使用允许多个窗口共享同一窗口类,因而多个窗口可以使用相同的窗口过程。

当Windows程序开始执行时,Windows首先为该程序创建一个“消息队列”(message queue)。该消息队列中存放着应用程序可能创建的所有窗口的消息。Windows应用程序中一般都包含一小段称为"消息循环"(message loop)的代码,该代码用于从消息队列中检索消息,并将其分发给相应的窗口过程。

创建一个窗口,首先需要注册一个窗口类,且需要为窗口类提供一个“窗口过程函数”(即处理消息的函数);

HELLOWIN程序:

HELLOWIN.cpp


#include

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,PSTR szCmdLine,int iCmdShow)
{
	//MessageBox(NULL,TEXT("Hello,Windows 98!"),TEXT("HelloMsg"), MB_OKCANCEL);

	static TCHAR szAppName[] = TEXT("HelloWin");
	HWND hwnd;
	MSG msg;

	WNDCLASS wndclass;
	wndclass.style             = CS_HREDRAW | CS_VREDRAW;
	wndclass.lpfnWndProc       = WndProc;  // 窗口过程函数
	wndclass.cbClsExtra        = 0;
	wndclass.cbWndExtra		   = 0;
	wndclass.hInstance         = hInstance;
	wndclass.hIcon			   = LoadIcon(NULL,IDI_APPLICATION);
	wndclass.hCursor = LoadCursor(NULL,IDC_ARROW);
	wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
	wndclass.lpszMenuName = NULL;
	wndclass.lpszClassName = szAppName;  //窗口类名称,

	if (!RegisterClass(&wndclass))       // 注册窗口类
	{
		MessageBox(NULL,TEXT("This program requires Windows NT"),szAppName,MB_ICONERROR);
		return 0;	
	}

    //CreateWindow就是通过第一个参数 szAppName (窗口类名称)与上面注册的窗口类关联起来的  
    // CreateWindow会创建窗体,并在创建过程中向窗口过程发送一条WM_CREATE消息
	hwnd = CreateWindow(szAppName,     // 窗口类名称
		TEXT("The Hello Program!"),    // 窗口标题
		WS_OVERLAPPEDWINDOW,           // 窗口风格,或称窗口格式
		CW_USEDEFAULT,                 // 初始x坐标
		CW_USEDEFAULT,                 // 初始y坐标
		CW_USEDEFAULT,                 // 初始x方向尺寸
		CW_USEDEFAULT,                 // 初始y方向尺寸
		NULL,                          // 父窗口句柄
		NULL,                          // 菜单窗口句柄
		hInstance,                     // 程序实例句柄
		NULL);                         // 创建参数

	ShowWindow(hwnd,iCmdShow); // 会向窗口过程发送一个WM_SIZE消息和WM_SHOWWINDOW消息
	UpdateWindow(hwnd);        // 会向窗口过程发送一个WM_PAINT消息

	while (GetMessage(&msg,NULL,0,0))  // 从消息队列中取消息,如果message为WM_QUIT则返回0
	{
		TranslateMessage(&msg);        //翻译(或者说转换)一些键盘消息
		DispatchMessage(&msg);         // 把消息推送给窗口过程函数(就是上面给wndclass.lpfnWndProc赋值的WndProc函数)
	}

	return msg.wParam;
}


LRESULT CALLBACK WndProc(HWND hwnd,UINT MESSAGE,WPARAM wParam,LPARAM lParam)
{
	HDC hdc;
	PAINTSTRUCT ps;
	RECT rect;

	switch (MESSAGE)
	{
	case WM_CREATE: // 下面的函数需要添加 winmm.lib 库,添加方法见(图二)
		PlaySound(TEXT("hellowin.wav"),NULL,SND_FILENAME | SND_ASYNC);
		return 0;
	case WM_PAINT:
		hdc = BeginPaint(hwnd,&ps);
		GetClientRect(hwnd,&rect);
		DrawText(hdc,TEXT("Hello,Windows 98!"),-1,&rect,DT_SINGLELINE | DT_CENTER | DT_VCENTER);
		EndPaint(hwnd,&ps);
		return 0;
	case WM_DESTROY:
		PostQuitMessage(0);//将一个WM_QUIT消息插入到程序的消息队列中
		return 0;

	default:
		break;
	}

	return DefWindowProc(hwnd,MESSAGE,wParam,lParam);

}


运行结果:(图一)

Windows程序设计--学习笔记 (三)_第1张图片

添加winmm.lib:(图二)

Windows程序设计--学习笔记 (三)_第2张图片

Windows函数调用:

1:LoadIcon  加载图标,以供程序使用。
2:LoadCursor  加载鼠标光标,以供程序使用。
3:GetStockObject 获取一个图形对象。在本例中是一个用来对窗口的背景进行重绘的画刷。
4:RegisterClass  为应用程序的窗口注册一个窗口类。
5:MessageBox     显示信息框
6:CreateWindow  基于窗口类创建一个窗口。
7:ShowWindow   在屏幕中显示窗口
8:UpdateWindow  指示窗口对其自身进行重绘。
9:GetMessage     从消息队列中获取消息
10:TranslateMessage  翻译一些键盘消息。
11:DispatchMessage  将消息发送给窗口过程。
12:PlaySound    播放声音文件。
13:BeginPaint    标明窗口绘制开始。
14:GetClientRect  获取窗口客户区的尺寸。
15:DrawText      显示一个文本字符串。
16:EndPaint       结束窗口绘制。
17:PostQuitMessage  将“退出”消息插入消息队列。
18:DefWindowProc   执行默认的消息处理。
 以上函数大部分在winuser.h中

大写标识前缀

前缀 常量
CS 类风格选项
CW 创建窗口选项
DT 文本绘制选项
IDI 图标的ID号
IDC 光标的ID号
MB 信息框选项
SND 声音选项
WM 窗口消息
WS 窗口风格

 

 

 

 

 

 

 

 

 

 

4种结构:
 

结构 含义
MSG 消息结构
WNDCLASS 窗口类结构
PAINTSTRUCT 绘制结构
RECT 矩形结构

 

 

 

 

 

 

句柄:

标识符 含义
HINSTANCE 实例句柄------程序本身
HWND 窗口句柄
HDC 设备环境句柄

句柄本质上是引用某个对象的数值(通常为32位)。Windows中的句柄非常类似于传统的C或MS-DOS程序中

使用的文件句柄。应用程序通过调用Windows函数开获取句柄,应用程序通过在其他Windows函数中使用句柄

来引用相应对象。

 

匈牙利标记法:(本书使用的变量名前缀)

前缀 数据类型
c char 或 WCHAR 或 TCHAR
by BYTE(无符号字符)
n short(短整型)
i int(整型)
x,y int ,表示x坐标 或 y坐标
cx,cy int ,表示x或y的长度,c表示“count”(计数)
B或f BOOL(int) ;f表示“flag”
w WORD(无符号短整型)
l LONG(长整型)
dw DWORD(无符号长整型)
fn 函数
s 字符串
sz 以0结束的字符串
h 句柄
p 指针

 

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;
typedef struct tagWNDCLASSW {
    UINT        style;
    WNDPROC     lpfnWndProc;
    int         cbClsExtra;
    int         cbWndExtra;
    HINSTANCE   hInstance;
    HICON       hIcon;
    HCURSOR     hCursor;
    HBRUSH      hbrBackground;
    LPCWSTR     lpszMenuName;
    LPCWSTR     lpszClassName;
} WNDCLASSW, *PWNDCLASSW, NEAR *NPWNDCLASSW, FAR *LPWNDCLASSW;
#ifdef UNICODE
typedef WNDCLASSW WNDCLASS;
typedef PWNDCLASSW PWNDCLASS;
typedef NPWNDCLASSW NPWNDCLASS;
typedef LPWNDCLASSW LPWNDCLASS;
#else
typedef WNDCLASSA WNDCLASS;
typedef PWNDCLASSA PWNDCLASS;
typedef NPWNDCLASSA NPWNDCLASS;
typedef LPWNDCLASSA LPWNDCLASS;
#endif // UNICODE

在WNDCLASS结构体中,两个最重要的字段是第二个字段合最后一个字段。第二个字段(lpfnWndProc)是用于基于该窗口类的

所有窗口的窗口过程的地址。最后一个字段是窗口类的名称,允许用户任意命名。

  如果新建窗口为顶级窗口(例如应用程序窗口),注释为“父窗口句柄”的参数就应设为NULL,通常。当两个窗口之间存在父子

关系时,子窗口总是位于父窗口的前方。应用程序窗口总是位于桌面窗口的前方,但不必为了调用CreateWindow函数而设法获取桌面窗口的句柄。

 

ShowWindow(hwnd,iCmdShow):
     iCmdShow:SW_SHOWNORMAL 正常显示
                        SW_SHOWMAXIMIZED  窗口最大化显示
                        SW_SHOWMINIMIZED  窗口最大化显示
                        SW_SHOWMINNOACTIVE 窗口只显示在任务栏

 

UpdateWindow(hwnd);
       是通过向窗口过程发送一条WM_PAINT消息而完成的;

消息循环:
   //msg的message字段不等于WM_QUIT(其值为0x0012),则GetMessage返回一个非0值,否则返回0,出错返回-1
   while(GetMessage(&msg,NULL,0,0))
   {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
  }

typedef struct tagMSG {
    HWND        hwnd;      // 消息所指向的窗口的句柄
    UINT        message;   // 消息标识符,在WINUSER.h 中都为其定义了一个以WM为前缀的标识符
    WPARAM      wParam;    // 消息参数,具体含义取决于具体的消息
    LPARAM      lParam;    // 消息参数,具体含义取决于具体的消息
    DWORD       time;      // 消息进入消息队列的时间
    POINT       pt;        // 消息进入消息队列中时鼠标指针的位置坐标
#ifdef _MAC
    DWORD       lPrivate;
#endif
} MSG, *PMSG, NEAR *NPMSG, FAR *LPMSG;

typedef struct tagPOINT
{
    LONG  x;
    LONG  y;
} POINT, *PPOINT, NEAR *NPPOINT, FAR *LPPOINT;

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(windows)