SendMessage

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;

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值