您的位置:首页 > 其它

Win32消息处理API---SendMessage

2009-04-03 10:38 501 查看

05、SendMessage

功能说明
该函数发送消息时,系统会调用指定窗口(hWnd)的事件发布函数,获取所发消息,等待窗口事件发布函数对该消息处理完毕,SnedMessage函数才能返回。如果指定窗口为广播窗口(HWND_BROADCAST),则消息接收对象就是所在系统的所有顶层窗口,而SendMessage不能为所有窗口之子窗口发送消息。SendMessage发送消息为同步发送,必须要等待接收方处理该消息完毕之后,才能够返回。
跟PostMessage区别:PostMessage将一个消息投递到一个线程的消息队列或者接收窗口后立即返回,不会等待消息的处理结果,只关心消息投递是否成功,也就是说PostMessage是异步的。

函数形式
LRESULT SendMessage(
HWND hWnd, // 指定的消息接收窗口,其窗口事件发布函数将接收和处理消息
UINT Msg, // 所发消息之消息ID
WPARAM wParam,// 所发消息之字参数
LPARAM Iparam // 所发消息之值参数
);

参数说明
1>、hWnd [in]
指定的消息接收窗口,其窗口事件发布函数将接收和处理消息。如果此参数为HWND_BROADCAST,则消息将被发送到系统中所有顶层窗口,包括无效或不可见的非自身拥有的窗口、被覆盖的窗口和弹出式窗口,但消息不会发送到它们的子窗口。另外hWnd为非空参数。

2>、Msg[in]
指定被发送的消息ID。

3>、wParam[in]
发送消息的字参数,跟消息类型、性质相关。

4>、lParam[in]
发送消息的值参数,跟消息类型、性质相关。

返回值
返回值依赖于所发送的消息类型及性质,所发消息的处理结果。

备注
需要以 HWND_BROADCAST方式发送消息的应用程序,应当用函数 RegisterwindwosMessage来获得应用程序间通信的特征消息。
Win32下:系统仅仅为系统级消息进行封送处理(那些定义在0到WM_USER 范围内的消息),要发送自定义消息(那些数值定义在WM_USER之上的消息)到另一个进程,用户必须进行自定义封送处理(就是编组处理之意)。
如果SendMessage的调用者跟指定窗口处于同一线程,则窗口事件发布函数就如同子程序一样被立即调用;如果而这不在同一线程,则系统就切换到窗口所在线程,并调用相关的窗口事件发布函数。在线程之间发送的消息,只有当接收线程在执行消息检索代码的时候才会被处理,此时SendMessage所在线程会被阻塞,直到接收线程处理该消息完毕,然而,此时发送线程却会处理接到的非队列消息。为了避免这种现象发生,最好使用SendMessageTimeout函数,设置参数为SMTO_BLOCK。
Windows桌面平台支持的所有消息,在Windows CE系统下,并非都支持的,因此在使用SendMesssge之前,要检查发送的消息是否被支持。

适用
Windows NT:3.1及以上版本:Windows:95及以上版本;Windows CE:1.0及以上版本;头文件:winuser.h;输入库:user32.lib;Unicode:在Windows NT环境下以Unicode和ANSI方式实现。

应用举例
处理键盘输入的一段代码。下面的例子演示了在一个简单的文本编辑器中如何使用插入记号,更新插入位置为用户类型打印字符,并使用各种键移动通过客户端区。

#define TEXTMATRIX(x, y) *(pTextMatrix + (y * nWindowCharsX) + x)
// Global variables.
HINSTANCE hinst; // current instance
HBITMAP hCaret; // caret bitmap
HDC hdc; // device context
PAINTSTRUCT ps; // client area paint info
static char *pTextMatrix = NULL; // points to text matrix
static int nCharX, // width of char. in logical units
nCharY, // height of char. in logical units
nWindowX, // width of client area
nWindowY, // height of client area
nWindowCharsX, // width of client area
nWindowCharsY, // height of client area
nCaretPosX, // x-position of caret
nCaretPosY; // y-position of caret
static UINT uOldBlink; // previous blink rate
int x, y; // coordinates for text matrix
TEXTMETRIC tm; // font information

LONG APIENTRY MainWndProc(
HWND hwnd, // window handle
UINT message, // type of message
UINT wParam, // additional information
LONG lParam) // additional information
{
switch (message) {
case WM_CREATE:
// Select a fixed-width system font, and get its text metrics.
hdc = GetDC(hwnd);
SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));
GetTextMetrics(hdc, &tm);
ReleaseDC(hwnd, hdc);
// Save the avg. width and height of characters.
nCharX = tm.tmAveCharWidth; nCharY = tm.tmHeight;
return 0;
case WM_SIZE:
// Determine the width of the client area, in pixels and in number of characters.
nWindowX = LOWORD(lParam); nWindowCharsX = max(1, nWindowX/nCharX);
// Determine the height of the client area, in pixels and in number of characters.
nWindowY = HIWORD(lParam); nWindowCharsY = max(1, nWindowY/nCharY);
// Clear the buffer that holds the text input.
if (pTextMatrix != NULL) free(pTextMatrix);
// If there is enough memory, allocate space for the text input buffer.
pTextMatrix = malloc(nWindowCharsX * nWindowCharsY);
if (pTextMatrix == NULL) ErrorHandler("Not enough memory.");
else
for (y = 0; y < nWindowCharsY; y++)
for (x = 0; x < nWindowCharsX; x++) TEXTMATRIX(x, y) = ' ';
// Move the caret to the origin.
SetCaretPos(0, 0);
return 0;
case WM_KEYDOWN:
switch (wParam)
{
case VK_HOME: // Home
nCaretPosX = 0; break;
case VK_END: // End
nCaretPosX = nWindowCharsX - 1; break;
case VK_PRIOR: // Page Up
nCaretPosY = 0; break;
case VK_NEXT: // Page Down
nCaretPosY = nWindowCharsY -1; break;
case VK_LEFT: // Left arrow
nCaretPosX = max(nCaretPosX - 1, 0); break;
case VK_RIGHT: // Right arrow
nCaretPosX = min(nCaretPosX + 1, nWindowCharsX - 1); break;
case VK_UP: // Up arrow
nCaretPosY = max(nCaretPosY - 1, 0); break;
case VK_DOWN: // Down arrow
nCaretPosY = min(nCaretPosY + 1, nWindowCharsY - 1); break;
case VK_DELETE: // Delete
// Move all the characters that followed the deleted character (on the same line) one
// space back (to the left) in the matrix.
for (x = nCaretPosX; x < nWindowCharsX; x++)
TEXTMATRIX(x, nCaretPosY) = TEXTMATRIX(x + 1, nCaretPosY);
// Replace the last character on the line with a space.
TEXTMATRIX(nWindowCharsX - 1, nCaretPosY) = ' ';
// The application will draw outside the WM_PAINT message processing, so hide the caret.
HideCaret(hwnd);
// Redraw the line, adjusted for the deleted character.
hdc = GetDC(hwnd);
SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));
TextOut(hdc, nCaretPosX * nCharX, nCaretPosY * nCharY, &TEXTMATRIX(nCaretPosX, nCaretPosY),
nWindowCharsX - nCaretPosX);
ReleaseDC(hwnd, hdc);
// Display the caret.
ShowCaret(hwnd);
break;
}
// Adjust the caret position based on the virtual-key processing.
SetCaretPos(nCaretPosX * nCharX, nCaretPosY * nCharY);
return 0;
case WM_CHAR:
switch (wParam)
{
case 0x08: // Backspace
// Move the caret back one space, and then process this like the DEL key.
if (nCaretPosX > 0) {
nCaretPosX--;
SendMessage(hwnd, WM_KEYDOWN, VK_DELETE, 1L);
}
break;
case 0x09: // Tab
// Tab stops exist every four spaces, so add spaces until the user hits the next tab.
do { SendMessage(hwnd, WM_CHAR, ' ', 1L); } while (nCaretPosX % 4 != 0); break;
case 0x0D: // Carriage return
// Go to the beginning of the next line. The bottom line wraps around to the top.
nCaretPosX = 0;
if (++nCaretPosY == nWindowCharsY) nCaretPosY = 0;
break;
case 0x1B: // Escape
case 0x0A: // Linefeed
MessageBeep((UINT) -1); break;
default: // Add the character to the text buffer.
TEXTMATRIX(nCaretPosX, nCaretPosY) = (char) wParam;
// The application will draw outside the
// WM_PAINT message processing, so hide the caret.
HideCaret(hwnd);
// Draw the character on the screen.
hdc = GetDC(hwnd);
SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));
TextOut(hdc, nCaretPosX * nCharX, nCaretPosY * nCharY, &TEXTMATRIX(nCaretPosX, nCaretPosY), 1);
ReleaseDC(hwnd, hdc);
// Display the caret.
ShowCaret(hwnd);
// Prepare to wrap around if you reached the end of the line.
if (++nCaretPosX == nWindowCharsX) {
nCaretPosX = 0;
if (++nCaretPosY == nWindowCharsY) nCaretPosY = 0;
}
break;
}
// Adjust the caret position based on the character processing.
SetCaretPos(nCaretPosX * nCharX, nCaretPosY * nCharY);
return 0;
case WM_PAINT:
// Draw all the characters in the buffer, line by line.
hdc = BeginPaint(hwnd, &ps);
SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));
for (y = 0; y < nWindowCharsY; y++)
TextOut(hdc, 0, y * nCharY, &TEXTMATRIX(0, y), nWindowCharsX);
EndPaint(hwnd, &ps);
case WM_SETFOCUS:
// The window has the input focus. Load the application-defined caret resource.
hCaret = LoadBitmap(hinst, MAKEINTRESOURCE(120));
// Create the caret.
CreateCaret(hwnd, hCaret, 0, 0);
// Adjust the caret position.
SetCaretPos(nCaretPosX * nCharX, nCaretPosY * nCharY);
// Display the caret.
ShowCaret(hwnd);
break;
case WM_KILLFOCUS:
// The window is losing the input focus, so destroy the caret.
DestroyCaret();
break;
default: return DefWindowProc(hwnd, message, wParam, lParam);
}
return NULL;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: