BroadcastSystemMessage广播消息
BroadcastSystemMessage能在不同程序进程间通信
广播消息程序:
// BroadcastSystemMessageDlg.cpp: 实现文件 // #include "pch.h" #include "framework.h" #include "BroadcastSystemMessage.h" #include "BroadcastSystemMessageDlg.h" #include "afxdialogex.h" #ifdef _DEBUG #define new DEBUG_NEW #endif // 用于应用程序“关于”菜单项的 CAboutDlg 对话框 class CAboutDlg : public CDialogEx { public: CAboutDlg(); // 对话框数据 #ifdef AFX_DESIGN_TIME enum { IDD = IDD_ABOUTBOX }; #endif protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 // 实现 protected: DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX) { } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx) END_MESSAGE_MAP() // CBroadcastSystemMessageDlg 对话框 CBroadcastSystemMessageDlg::CBroadcastSystemMessageDlg(CWnd* pParent /*=nullptr*/) : CDialogEx(IDD_BROADCASTSYSTEMMESSAGE_DIALOG, pParent) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CBroadcastSystemMessageDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CBroadcastSystemMessageDlg, CDialogEx) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_BUTTON1, &CBroadcastSystemMessageDlg::OnBnClickedButton1) END_MESSAGE_MAP() UINT WM_MSG;//消息号 #define REG_MSG (_T("{liming19960318}")) //自定义消息字符串 // CBroadcastSystemMessageDlg 消息处理程序 BOOL CBroadcastSystemMessageDlg::OnInitDialog() { CDialogEx::OnInitDialog(); // 将“关于...”菜单项添加到系统菜单中。 // IDM_ABOUTBOX 必须在系统命令范围内。 ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != nullptr) { BOOL bNameValid; CString strAboutMenu; bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX); ASSERT(bNameValid); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动 // 执行此操作 SetIcon(m_hIcon, TRUE); // 设置大图标 SetIcon(m_hIcon, FALSE); // 设置小图标 // TODO: 在此添加额外的初始化代码 WM_MSG = ::RegisterWindowMessage(REG_MSG);//注册消息 return TRUE; // 除非将焦点设置到控件,否则返回 TRUE } void CBroadcastSystemMessageDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialogEx::OnSysCommand(nID, lParam); } } // 如果向对话框添加最小化按钮,则需要下面的代码 // 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序, // 这将由框架自动完成。 void CBroadcastSystemMessageDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // 用于绘制的设备上下文 SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0); // 使图标在工作区矩形中居中 int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // 绘制图标 dc.DrawIcon(x, y, m_hIcon); } else { CDialogEx::OnPaint(); } } //当用户拖动最小化窗口时系统调用此函数取得光标 //显示。 HCURSOR CBroadcastSystemMessageDlg::OnQueryDragIcon() { return static_cast<HCURSOR>(m_hIcon); } void CBroadcastSystemMessageDlg::OnBnClickedButton1() { DWORD d = BSM_APPLICATIONS; long l = BroadcastSystemMessage(BSF_POSTMESSAGE,&d, WM_MSG,NULL,NULL);//广播消息 /* 广播消息给系统中所有的顶级窗口 消息接受者可以是:一般的应用程序、可装载的驱动程序、网络驱动程序、系统级的设备驱动程序 或者 上述的任意组合 参数1:DWORD flags 广播选项,可以是下面中的1个 或者 多个组合 BSF_ALLOWSFW=0x00000080 允许接受者在处理消息的时候将窗口设置为前置窗口 BSF_FLUSHDISK=0x00000004 在每个接受者处理完消息后刷新磁盘 BSF_FORCEIFHUNG=0x00000020 继续广播 即时接受者之一没有响应 或者 超时 BSF_IGNORECURRENTTASK=0x00000002 忽略掉当前任务 也就是自己,消息不会发到当前程序。这样,应用程序就不会接收自己的消息 BSF_NOHANG=0x00000008 没有响应的应用程序视作超时。其中一个接受者超时就不再继续广播 BSF_NOTIMEOUTIFNOTHUNG=0x00000040 只要接受者没有给不响应的动作,就一直等待这个消息的响应,不做超时处理 BSF_POSTMESSAGE=0x00000010 使用post方式发送消息,不能和BSF_QUERY组合使用 BSF_QUERY=0x00000001 一次发送一个消息,当前接受者返回TRUE之后才会继续往后发 BSF_SENDNOTIFYMESSAGE=0x00000100 使用SendNotifyMessage函数发送消息,不能够和BSF_QUERY组合使用 参数2:LPDWORD lpInfo in:指定接受这个消息的接受者类别;out:实际接收消息的接受者类别 输入输出变量。作为输入变量时,指定接受这个消息的接受者类别;作为输出变量时,当函数返回时 该变量为 实际接收消息的接受者类别 此变量可为下列值的组合: BSM_ALLCOMPONENTS=0x00000000 广播给所有系统组件 BSM_ALLDESKTOPS=0x00000010 广播给所有的桌面,需要SE_TCB_NAME设置特权 BSM_APPLICATIONS=0x00000008 广播给所有的应用程序 当函数返回时,此变量接受上述值的组合,以确定真正接受消息的接受者。如果此参数为NULL,则将消息广播到所有的组件 参数3:UINT Msg 消息号 参数4:WPARAM wParam 参数5:LPARAM lParam 返回值:long 如果函数调用成功,返回值是正数。 如果函数不能广播消息,返回值是-1。 如果参数flags为BSF_QUERY且至少一个接受者返回BROADCAST_QUERY_DENY给相应的消息,返回值是零 系统只对0 到 ( (WM_USER-1) ) 范围内的系统消息进行发送。 若要将其他消息 (这些 >= WM_USER) 发送到另一个进程,必须执行自定义发送 注意:如果用WindowProc等系统消息函数接受消息,参数1 BSF_POSTMESSAGE和BSF_SENDNOTIFYMESSAGE必须选其一 */ CString str; str.Format(_T("l=%d\r\n"),l); ::OutputDebugString(str); }
实例工程下载:
链接:https://pan.baidu.com/s/1kBK8KihLbkV5pSILXEBVSA
提取码:6666
接受消息程序:
// AADlg.cpp: 实现文件 // #include "pch.h" #include "framework.h" #include "AA.h" #include "AADlg.h" #include "afxdialogex.h" #ifdef _DEBUG #define new DEBUG_NEW #endif // 用于应用程序“关于”菜单项的 CAboutDlg 对话框 class CAboutDlg : public CDialogEx { public: CAboutDlg(); // 对话框数据 #ifdef AFX_DESIGN_TIME enum { IDD = IDD_ABOUTBOX }; #endif protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 // 实现 protected: DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX) { } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx) END_MESSAGE_MAP() // CAADlg 对话框 CAADlg::CAADlg(CWnd* pParent /*=nullptr*/) : CDialogEx(IDD_AA_DIALOG, pParent) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CAADlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CAADlg, CDialogEx) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() END_MESSAGE_MAP() UINT WM_MSG;//消息号 #define REG_MSG (_T("{liming19960318}")) //自定义消息字符串 // CAADlg 消息处理程序 BOOL CAADlg::OnInitDialog() { CDialogEx::OnInitDialog(); // 将“关于...”菜单项添加到系统菜单中。 // IDM_ABOUTBOX 必须在系统命令范围内。 ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != nullptr) { BOOL bNameValid; CString strAboutMenu; bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX); ASSERT(bNameValid); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动 // 执行此操作 SetIcon(m_hIcon, TRUE); // 设置大图标 SetIcon(m_hIcon, FALSE); // 设置小图标 // TODO: 在此添加额外的初始化代码 WM_MSG = RegisterWindowMessage(REG_MSG);//给窗口增加一个消息 return TRUE; // 除非将焦点设置到控件,否则返回 TRUE } void CAADlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialogEx::OnSysCommand(nID, lParam); } } // 如果向对话框添加最小化按钮,则需要下面的代码 // 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序, // 这将由框架自动完成。 void CAADlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // 用于绘制的设备上下文 SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0); // 使图标在工作区矩形中居中 int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // 绘制图标 dc.DrawIcon(x, y, m_hIcon); } else { CDialogEx::OnPaint(); } } //当用户拖动最小化窗口时系统调用此函数取得光标 //显示。 HCURSOR CAADlg::OnQueryDragIcon() { return static_cast<HCURSOR>(m_hIcon); } LRESULT CAADlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { static int i = 0; CString str; if (message == WM_MSG) { str.Format(_T("接受到消息 i=%d"), i); SetDlgItemText(IDC_STATIC1, str);//设置文本 ::OutputDebugString(str); i++; } return CDialogEx::WindowProc(message, wParam, lParam); }
实例工程下载:
链接:https://pan.baidu.com/s/1yJmpLT99dtywRGNoGhByDQ
提取码:6666