MFC的SendMessage用法

一、定义

Cwnd::SendMessage函数用于向窗口发送消息。以下是 SendMessage 的基本用法示例:

LRESULT SendMessage(
    UINT message,   // 消息类型
    WPARAM wParam,  // 参数1
    LPARAM lParam   // 参数2
);

其中:

  • message 是要发送的消息类型,通常是一个预定义的 Windows 消息常量(例如,WM_CLOSEWM_COMMAND 等)或者自定义的消息类型。
  • wParam 和 lParam 是消息的参数,其具体含义取决于消息类型

二、SendMessage 特点

  1. 同步调用: SendMessage 是一个同步函数,它会将消息发送到指定的窗口,并等待窗口的消息处理函数完成后才返回。这意味着它会阻塞当前线程,直到消息处理完成。这对于确保消息的有序处理非常有用。

  2. 线程内通信: 通常情况下,SendMessage 用于在同一线程内的不同窗口之间进行消息传递,以确保消息的同步和有序处理。

  3. 消息参数: wParamlParam 参数的具体含义取决于消息的类型,不同的消息有不同的参数。请查阅相关消息的文档以了解详细信息。

  4. 返回值: SendMessage 的返回值通常包含有关消息处理结果的信息,其具体含义也取决于消息类型。通常,返回值是消息处理函数返回的结果。

需要注意的是,由于 SendMessage 是同步调用,如果在主 UI 线程中的某个窗口上使用它来发送消息,而消息处理函数执行耗时较长,可能会导致界面冻结。因此,要谨慎使用 SendMessage,确保不会阻塞主 UI 线程。在某些情况下,可以考虑使用 PostMessage 来进行异步消息传递,以避免界面冻结。

三、同一进程中发送消息

实例

// 向窗口发送 WM_CLOSE 消息,请求关闭窗口
::SendMessage(hWnd, WM_CLOSE, 0, 0);

// 向窗口发送自定义消息,传递两个参数
UINT customMessage = WM_USER + 1;  // 自定义消息,WM_USER 是一个用户自定义消息的基准值
WPARAM wParam = 42;
LPARAM lParam = 123;
::SendMessage(hWnd, customMessage, wParam, lParam);

传递两个字符串

void CAaaDlg::OnButton1()
{
    char* p1 = "Willis";
    char* p2 = "VCHelp";
    SendMessage(WM_CURRENTINFO, (WPARAM)p1, (LPARAM)p2);
}

四、 不同进程发送消息传递字符串

问题

两个进程由于使用的是相互独立的两个虚拟内存空间,同一地址对不同的进程来说并不一定指向同一物理内存,内容也就不一定一样,因此不同进程无法通过传地址的方式传递字符串(但是同一进程下的不同线程是可以的)

解决办法

发送WM_COPYDATA消息在进程间传送数据,使用FindWindow找到窗口,然后发送WM_COPYDATA消息,字符串附加到COPYDATASTRUCT 结构体

实例

首先,创建两个 MFC 应用程序项目,一个作为发送方,另一个作为接收方。

发送方示例:

  1. 打开发送方的 MFC 应用程序项目。

  2. 在发送方的窗口类中,添加一个按钮用于触发消息发送,以及一个编辑框用于输入要发送的字符串。

  3. 在 CMySendAppDlg.cpp 中实现按钮的点击事件,以便发送字符串消息。
// MySendAppDlg.h
class CMySendAppDlg : public CDialogEx
{
public:
    // ...
    afx_msg void OnBnClickedSendButton();
private:
    CEdit m_Edit;
    // ...
};

// MySendAppDlg.cpp
void CMySendAppDlg::OnBnClickedSendButton()
{
    CString strMessage;
    m_Edit.GetWindowText(strMessage);

    // 创建 COPYDATASTRUCT 结构并填充数据
    COPYDATASTRUCT cds;
    cds.dwData = 1;  // 用户自定义的消息标识
    cds.cbData = (DWORD)(strMessage.GetLength() + 1) * sizeof(TCHAR);
    cds.lpData = (PVOID)(LPCTSTR)strMessage;

    // 查找接收方窗口句柄,替换为接收方的窗口句柄
    HWND hwndReceiver = ::FindWindow(NULL, _T("ReceiverApp Title"));

    if (hwndReceiver)
    {
        // 发送消息
        ::SendMessage(hwndReceiver, WM_COPYDATA, (WPARAM)NULL, (LPARAM)&cds);
    }
    else
    {
        AfxMessageBox(_T("接收方应用程序未找到!"));
    }
}

接收方示例:

  1. 打开接收方的 MFC 应用程序项目。

  2. 在接收方的窗口类中,添加一个用于显示接收到的消息的编辑框。

  3. 在 CMyReceiveAppDlg.cpp 中添加一个消息映射以处理 WM_COPYDATA 消息。
// MyReceiveAppDlg.h
class CMyReceiveAppDlg : public CDialogEx
{
public:
    // ...
    afx_msg LRESULT OnCopyData(WPARAM wParam, LPARAM lParam);
private:
    CEdit m_Edit;
    // ...
};

// MyReceiveAppDlg.cpp
BEGIN_MESSAGE_MAP(CMyReceiveAppDlg, CDialogEx)
    // ...
    ON_MESSAGE(WM_COPYDATA, OnCopyData)
    // ...
END_MESSAGE_MAP()

LRESULT CMyReceiveAppDlg::OnCopyData(WPARAM wParam, LPARAM lParam)
{
    COPYDATASTRUCT* pcds = (COPYDATASTRUCT*)lParam;

    if (pcds)
    {
        CString strMessage((LPCTSTR)pcds->lpData);
        m_Edit.SetWindowText(strMessage);
    }

    return 0;
}

在这个示例中,当发送方应用程序点击按钮发送消息时,接收方应用程序会通过 WM_COPYDATA 消息接收并显示接收到的消息。

确保在实际应用程序中使用正确的窗口标题(FindWindow 中的 "ReceiverApp Title" 和接收方应用程序的窗口标题)和消息标识符(dwData 中的 1 和 WM_COPYDATA 消息的处理部分)。此外,对于实际应用程序,还应该考虑错误处理和安全性。

SendMessage和PostMessage发送消息(不同进程传递字符串)_sendmessage发送字符串_紫松Win的博客-CSDN博客

  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MFC的PostMessage函数用于将消息发送到指定的窗口。以下是PostMessage函数的一般用法: 1. 导入头文件:在需要使用PostMessage函数的地方,首先要导入头文件 "afxwin.h"。 2. 获取窗口句柄:找到要发送消息的窗口,可以使用FindWindow或GetDlgItem等函数获取其窗口句柄。 3. 构造消息参数:确定要发送的消息类型和相关参数。消息类型可以是预定义的Windows消息,也可以是自定义的消息。 4. 调用PostMessage函数:使用窗口句柄和消息参数调用PostMessage函数发送消息。 以下是一个使用PostMessage函数发送WM_USER自定义消息的示例: ```cpp #include <afxwin.h> // 获取要发送消息的窗口句柄 HWND hWnd = ::FindWindow(NULL, _T("My Window")); if (hWnd) { // 构造自定义消息参数 UINT msg = WM_USER + 1; WPARAM wParam = 0; LPARAM lParam = 123; // 发送消息 ::PostMessage(hWnd, msg, wParam, lParam); } ``` 在这个示例中,我们使用FindWindow函数找到窗口标题为"My Window"的窗口,并将其句柄存储在hWnd变量中。然后,我们构造了一个自定义消息参数,包括消息类型(msg)、wParam和lParam。最后,我们使用PostMessage函数将消息发送到指定窗口。 请注意,PostMessage函数是异步的,它将消息放入接收窗口的消息队列中,并立即返回,不会等待消息被处理。如果需要等待消息被处理并处理完毕后再继续执行代码,可以考虑使用SendMessage函数。 希望这个例子对你有所帮助!如果你有任何其他问题,请随时提问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值