第三章 窗口和消息
自己的窗口:CreateWindow的第一个参数就是所谓的窗口类别名称,并且该窗口类别连接所谓的窗口消息处理程序。
大写字母标识符 :
读者可能注意到,HELLOWIN.C中有几个大写的标识符,这些标识符是在Windows表头文件中定义的。有些标识符含有两个字母或者三个字母的前缀,这些前缀后头接着一个底线:
CS_HREDRAW DT_VCENTER SND_FILENAME IDC_ARROW WM_CREATE CW_USEDEFAULT IDI_APPLICATION
这些是简单的数值常数。前缀指示该常数所属的类别,如下所示。
前缀 类别
CS 窗口类别样式
CW 建立窗口
DT 绘制文字
IDI 图示ID
IDC 游标ID
MB 消息框
SND 声音
WM窗口消息
WS窗口样式
VK_ 虚拟键码的名称
BS 开头,它表示「按钮样式」
ES编辑样式
EN 编辑控件
WPARAM和LPARAM,这些名字的来源有点历史背景:当Windows还是16位系统时,WndProc的第三个参数被定义为一个WORD,这是一个16位的 无正负号短(unsigned
short)整数,而第四个参数被定义为一个LONG,这是一个32位有正负号长整数,从而导致了文字「PARAM」前面加上了前置前缀「W」和「L」 。当然,在32位的Windows中,WPARAM被定义为一个UINT,而LPARAM被定义为一个LONG(这就是C中的long整数型态),因此窗口消息处理程序的这两个参数都是32位的值。
四种数据结构
结构 含义
MSG 消息结构
WNDCLASS 窗口类别结构
PAINTSTRUCT 绘图结构
RECT 矩形结构
句柄简介
的作用,又描述了其数据型态,就比较容易避免产生数据型态不合的错误。
前缀 数据型态
c char或WCHAR或TCHAR
by BYTE (无正负号字符)
n short
i int
x, y int分别用作x坐标和y坐标
cx, cy int分别用作x长度和y长度;C代表「计数器」
b或f BOOL (int);f代表「旗标」
w WORD (无正负号短整数)
l LONG (长整数)
dw DWORD (无正负号长整数)
fn function(函数)
s string(字符串)
sz 以字节值0结尾的字符串
h 句柄
p 指标
lParam 一个32位的消息参数,其值与消息有关。
time 消息放入消息队列中的时间。
pt 消息放入消息队列时的鼠标坐标。
一般来说,Windows程序写作者使用switch和case结构来确定窗口消息处理程序接收的是什么消息,以及如何适当地处理它。窗口消息处理程序在处理消息时,必须传回0。窗口消息处理程序不予处理的所有消息应该被传给名为DefWindowProc的Windows函数。从DefWindowProc传回的值必须由窗口消息处理程序传回。
switch (iMsg)
{
case WM_CREATE :
处理WM_CREATE消息
return 0 ;
处理WM_PAINT消息
return 0 ;
case WM_DESTROY :
处理WM_DESTROY消息
return 0 ;
}
return DefWindowProc (hwnd, iMsg, wParam, lParam) ;
作。在这些工作中,Windows呼叫WndProc,将第一个参数设定为窗口句柄,第二个参数设定为WM_CREATE。WndProc处理WM_CREATE消息并将控制传回给Windows。Windows然后可以从CreateWindow呼叫中传回到HELLOWIN中,继续在WinMain中进行下一步的处理。
通常,窗口消息处理程序在WM_CREATE处理期间进行一次窗口初始化。HELLOWIN对这个消息的处理中播放一个名为HELLOWIN.WAV的声音文件。它使用简单的PlaySound函数来做到这一点。该函数说明在/Platform SDK/Graphics and Multimedia
Services/Multimedia Audio/Waveform Audio中, 而文件在/Platform SDK/Graphicsand Multimedia Services/Multimedia Reference/Multimedia Functions中。PlaySound的第一个参数是声音文件的名称(它也可能是在Control Panel的Sounds中定义的一种声音的别名,或者是一个程序资源)。第二个参数只有当声音文件是一种资源时才被使用。第三个参数指定一些选项。在这个例子中,我指定第一个参数是一个文件名,并且异步地播放声音,即PlaySound函数呼叫在声音文件开始播放时立即传回,而不会等待它的完成。在这种方法下,程序能够继续初始化。WndProc通过从窗口消息处理程序中传回0,结束了整个WM_CREATE的处理。
caseWM_PAINT:
hdc = BeginPaint (hwnd, &ps) ;
使用GDI函数
EndPaint (hwnd, &ps) ;
义如下:
typedef struct tagPAINTSTRUCT
{
HDC hdc ;
BOOL fErase ;
RECT rcPaint ;
BOOL fRestore ;
BOOL fIncUpdate ;
BYTE rgbReserved[32] ;
} PAINTSTRUCT ;
ReleaseDC:
hdc = GetDC (hwnd) ;
使用GDI函数
ReleaseDC (hwnd, hdc) ;
TextOut (hdc, x, y, psText, iLength) ;
以下将详细地讨论这个函数。
第一个参数是设备内容句柄,它既可以是GetDC的传回值,也可以是在处理WM_PAINT消息时BeginPaint的传回值。
设备内容的属性控制了被显示的字符串的特征。
TextOut中的x和y定义显示区域内字符串的开始位置,x是水平位置,y是垂直位置。字符串中第一个字符的左上角位于坐标点(x,y)。在内定的设备内容中,原点(x和y均为0的点)是显示区域的左上角。如果在TextOut中将x和y设为0,则将从显示区域左上角开始输出字符串。
crColor = GetPixel (hdc, x, y) ;
hwndParent = GetParent (hwnd) ;
id = GetDlgCtrlID (hwndChild) ;
虽然函数中的「Dlg」部分指的是对话框,但实际上这是一个通用的函数。
知道ID和父窗口句柄,您就能获得子窗口句柄:
hwndChild = GetDlgItem (hwndParent, id) ;
SendMessage (hwndButton, BM_SETSTATE, 1, 0) ;
下面的呼叫使按钮恢复正常:
SendMessage (hwndButton, BM_SETSTATE, 0, 0) ;
您也可以向按键发送BM_GETSTATE消息,子窗口控件传回按钮目前的状态:如果按钮被按下,则传回TRUE;如果按钮处于正常状态,则传回FALSE。但是,绝大多数应用并不需要这一消息。因为按钮不保留任何开/关信息,所以BM_SETCHECK消息和BM_GETCHECK消息不会被用到。
SetWindowText (hwnd, pszString) ;
iLength = GetWindowText (hwnd, pszBuffer, iMaxLength) ;
iMaxLength指定复制到pszBuffer指向的缓冲区中的最大字符数。该函数传回复制的字符数。您可以首先通过下面的呼叫来获得特定文字的长度:
iLength = GetWindowTextLength (hwnd) ;
ShowWindow (hwndChild, SW_SHOWNORMAL) ;
通过呼叫ShowWindow将子窗口隐藏起来:
ShowWindow (hwndChild, SW_HIDE) ;
IsWindowVisible (hwndChild) ;
的呼叫使窗口不被启用:
EnableWindow (hwndChild, FALSE) ;
EnableWindow (hwndChild, TRUE) ;
IsWindowEnabled (hwndChild) ;
GetSystemMetrics (SM_CYHSCROLL) ;
或者垂直滚动条的宽度:
GetSystemMetrics (SM_CXVSCROLL) ;
i = GetWindowLong ((HWND) lParam, GWL_ID) ;
SetScrollPos (hwndScroll[i], SB_CTL, color[i], TRUE) ;
SetWindowText (hwndValue[i], szBuffer) ;
SetFocus (hwndScroll[idFocus]) ; 其中idFocus是一个整体变量。
SendMessage (hwndEdit, WM_COPY, 0, 0) ;
SendMessage (hwndEdit, WM_CLEAR, 0, 0) ;
您也可以将剪贴簿上的文字插入到编辑控件中的光标位置: SendMessage (hwndEdit, WM_PASTE, 0, 0) ;
将资源添加到程序中需要Visual C++ Developer Studio的一些附加功能。对于图示来说,可以使用「Image Editor」(也称为「Graphics Editor」 )来绘制图标的图像。该图像被储存在扩展名为.ICO的图示文件中。Developer Studio还产生一个资源描述档 (扩展名为.RC的文件,有时也称作资源定义文件),它列出了程序的所有资源和一个让程序引用资源的表头文件(RESOURCE.H) 。