功能需求:现如今有两个进程一个进程A,一个进程B,通过Windows的消息机制实现进程A 发送消息给B, 进程B也能发送消息给A。
平台:首先我们使用Win32程序实现相应的功能,使用VS2017+C++以及Windows API工具与函数惊醒开发。
方案:通过对需求(即我们只需要两个进程能够收到响应的消息,具体应用场景就是两个进程是同种属性的进程,也即都为另一种进程而生存且服务,例如,现在进程A、B都是为了开启主程序C的,如果用户通过进程A开启的,那么主程序开启过后,进程A、B就都可以关闭了,为了做到同步,进程A就要给进程B发送关闭消息,等进程B接收关闭消息就可执行销毁流程)进行分析,采用比较简单的隐藏窗口来接收相关进程发送的消息,并由自己进行后续的处理;
程序实现:
本程序提供的是其模板,并不能直接运行,需要相应的修改才行!
进程A:
#include“processA“
#include<windows>
#include"processA.h"
#define WM_CLOSEPROCESSA (WM_USER + 0x2007)
#define WM_CLOSEPROCESSB (WM_USER + 0x2008)
// 隐藏窗口句柄
HINSTANCE g_hInstance = NULL;
// 气泡系统托盘图标菜单窗口类名
LPCTSTR g_szKBubbleTrayIconMenuWindowClass = _T("QWidget");
// 气泡系统托盘图标菜单窗口标题
LPCTSTR g_szKBubbleTrayIconMenuWindowTitle = _T("1BEEF4DE-B3B3-49CA-A03A-0F2EB34920F1_mini");
// 窗口类名字符串
LPCTSTR g_szToastIconWindowClassName = _T("mini_window");
//窗口标题字符串
LPCTSTR g_szToastIconWindowTitle = _T("23A5B06E-20BB-4E7E-A0AC-6982ED6A6041_tosat");
/*
@brief 调用主程序并发送信息
*/
BOOL sendSomeMessage()
{
/*
lanch process C (or other process)
method: ShellExecute(NULL ,L"open" , ExepathName, CommandPath , NULL , SW_NORMAL);
then send colse message
*/
HWND hwnd = FindWindow(g_szKBubbleTrayIconMenuWindowClass , g_szKBubbleTrayIconMenuWindowTitle);
if (hwnd == NULL)
return false;
::SendMessage(hwnd , WM_CLOSEPROCESSB , 0 , 0);
return true;
}
/*
@brief 处理通知窗口消息
@param uMsg包含mini发送的关闭消息通知
*/
LRESULT CALLBACK HiddenWindowProcess(__in HWND hwnd , __in UINT uMsg , __in WPARAM wParam , __in LPARAM lParam)
{
switch (uMsg)
{
case WM_CLOSEPROCESSA:
closeHandle(g_hInstance);
//处理关闭事宜
break;
default:
return DefWindowProc(hwnd , uMsg , wParam , lParam);
}
return true;
}
/*
*brief 创建用于接收关闭消息的隐藏窗口
*return TRUE创建成功 FALSE创建失败
*/
BOOL CreateHiddenWindow()
{
WNDCLASS wcMinisiteWindowClass = { 0 };
wcMinisiteWindowClass.style = CS_HREDRAW | CS_VREDRAW;
wcMinisiteWindowClass.lpfnWndProc = HiddenWindowProcess;
wcMinisiteWindowClass.cbClsExtra = 0;
wcMinisiteWindowClass.cbWndExtra = 0;
wcMinisiteWindowClass.hInstance = g_hInstance;
wcMinisiteWindowClass.hIcon = NULL;
wcMinisiteWindowClass.hCursor = ::LoadCursor(NULL , IDC_ARROW);
wcMinisiteWindowClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcMinisiteWindowClass.lpszMenuName = NULL;
wcMinisiteWindowClass.lpszClassName = g_szToastIconWindowClassName;
if (::RegisterClass(&wcMinisiteWindowClass) == 0)
return FALSE;
::CreateWindow(g_szToastIconWindowClassName , g_szToastIconWindowTitle , WS_OVERLAPPED , 0 , 0 , 1 , 1 , NULL , NULL , g_hInstance , NULL);
MSG msg;
while (::GetMessage(&msg , NULL,0,0))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
return TRUE;
}
int WINAPI wWinMain(_In_ HINSTANCE hInstance , _In_opt_ HINSTANCE , _In_ LPWSTR cmdLineArgs , _In_ int)
{
CreateHiddenWindow();
/*
do other something...........
*/
sendSomeMessage()
return 0;
}
进程B:
#include“processB“
#include<windows>
#include"processB.h"
#define WM_CLOSEPROCESSA (WM_USER + 0x2007)
#define WM_CLOSEPROCESSB (WM_USER + 0x2008)
// 隐藏窗口句柄
HINSTANCE g_hInstance = NULL;
// 气泡系统托盘图标菜单窗口类名
LPCTSTR g_szKBubbleTrayIconMenuWindowClass = _T("QWidget");
// 气泡系统托盘图标菜单窗口标题
LPCTSTR g_szKBubbleTrayIconMenuWindowTitle = _T("1BEEF4DE-B3B3-49CA-A03A-0F2EB34920F1_mini");
// 窗口类名字符串
LPCTSTR g_szToastIconWindowClassName = _T("mini_window");
//窗口标题字符串
LPCTSTR g_szToastIconWindowTitle = _T("23A5B06E-20BB-4E7E-A0AC-6982ED6A6041_tosat");
/*
@brief 调用主程序并发送信息
*/
BOOL sendSomeMessage()
{
/*
lanch process C (or other process)
method: ShellExecute(NULL ,L"open" , ExepathName, CommandPath , NULL , SW_NORMAL);
then send colse message
*/
HWND hwnd = FindWindow(g_szToastIconWindowClassName , g_szToastIconWindowTitle);
if (hwnd == NULL)
return false;
::SendMessage(hwnd , WM_CLOSEPROCESSA , 0 , 0);//发送信息
return true;
}
/*
@brief 处理通知窗口消息
@param uMsg包含mini发送的关闭消息通知
*/
LRESULT CALLBACK HiddenWindowProcess(__in HWND hwnd , __in UINT uMsg , __in WPARAM wParam , __in LPARAM lParam)
{
switch (uMsg) //接受信息
{
case WM_CLOSEPROCESSB:
closeHandle(g_hInstance);
//处理关闭事宜
break;
default:
return DefWindowProc(hwnd , uMsg , wParam , lParam);
}
return true;
}
/*
*brief 创建用于接收关闭消息的隐藏窗口
*return TRUE创建成功 FALSE创建失败
*/
BOOL CreateHiddenWindow()
{
WNDCLASS wcMinisiteWindowClass = { 0 };
wcMinisiteWindowClass.style = CS_HREDRAW | CS_VREDRAW;
wcMinisiteWindowClass.lpfnWndProc = HiddenWindowProcess;
wcMinisiteWindowClass.cbClsExtra = 0;
wcMinisiteWindowClass.cbWndExtra = 0;
wcMinisiteWindowClass.hInstance = g_hInstance;
wcMinisiteWindowClass.hIcon = NULL;
wcMinisiteWindowClass.hCursor = ::LoadCursor(NULL , IDC_ARROW);
wcMinisiteWindowClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcMinisiteWindowClass.lpszMenuName = NULL;
wcMinisiteWindowClass.lpszClassName = g_szKBubbleTrayIconMenuWindowClass;
if (::RegisterClass(&wcMinisiteWindowClass) == 0)
return FALSE;
::CreateWindow(g_szKBubbleTrayIconMenuWindowClass , g_szKBubbleTrayIconMenuWindowTitle , WS_OVERLAPPED , 0 , 0 , 1 , 1 , NULL , NULL , g_hInstance , NULL);
MSG msg;
while (::GetMessage(&msg , NULL,0,0))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
return TRUE;
}
int WINAPI wWinMain(_In_ HINSTANCE hInstance , _In_opt_ HINSTANCE , _In_ LPWSTR cmdLineArgs , _In_ int)
{
CreateHiddenWindow();
/*
do other something.........
*/
sendSomeMessage()
return 0;
}