Win32消息处理API---SendMessage

    技术2022-05-11  8

     

    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下:系统仅仅为系统级消息进行封送处理(那些定义在0WM_USER 范围内的消息),要发送自定义消息(那些数值定义在WM_USER之上的消息)到另一个进程,用户必须进行自定义封送处理(就是编组处理之意)。

    如果SendMessage的调用者跟指定窗口处于同一线程,则窗口事件发布函数就如同子程序一样被立即调用;如果而这不在同一线程,则系统就切换到窗口所在线程,并调用相关的窗口事件发布函数。在线程之间发送的消息,只有当接收线程在执行消息检索代码的时候才会被处理,此时SendMessage所在线程会被阻塞,直到接收线程处理该消息完毕,然而,此时发送线程却会处理接到的非队列消息。为了避免这种现象发生,最好使用SendMessageTimeout函数,设置参数为SMTO_BLOCK

    Windows桌面平台支持的所有消息,在Windows CE系统下,并非都支持的,因此在使用SendMesssge之前,要检查发送的消息是否被支持。

     

    适用

    Windows NT3.1及以上版本:Windows95及以上版本;Windows CE1.0及以上版本;头文件:winuser.h;输入库:user32.libUnicode:在Windows NT环境下以UnicodeANSI方式实现。

     

    应用举例

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

     

    #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)