Qt实现windows通信(不同项目的窗口通信)
有关Qt通信的知识
windows要实现不同项目窗口通信,需要用类似于windows.h的api接口。
数据传输主要通过
typedef struct tagCOPYDATASTRUCT { // cds
DWORD dwData; //自定义数据
DWORD cbData; //指定lpData指向的数据的大小
PVOID lpData; //指向数据的指针
} COPYDATASTRUCT;结构体来实现
- 实现在本窗口中找到目标窗口句柄
include<qt_windows.h>
void Widget::on_pushButton_clicked()
{
HWND hwnd = NULL;
const QString c_strTitle = "win";
// do
//{
LPWSTR path = (LPWSTR)c_strTitle.utf16();
hwnd = ::FindWindowW(NULL,path);
//}
if(::IsWindow(hwnd))
{
qDebug() << "ok ,find it!";
qDebug() << path;
}
}
函数HWND FindWindow(LPCTSTR IpClassName,LPCTSTR IpWindowName);
IpClassName :指向一个指定了类名的空结束字符串,或一个标识类名字符串的成员的指针。如果该参数为一个成员,则它必须为前次调用theGlobafAddAtom函数产生的全局成员。该成员为16位,必须位于IpClassName的低 16位,高位必须为 0。
IpWindowName:指向一个指定了窗口名(窗口标题)的空结束字符串。如果该参数为空,则为所有窗口全匹配。
函数BOOL IsWindow(HWND hWnd);
如果窗口句柄标识了一个已存在的窗口,返回值为非零;如果窗口句柄未标识一个已存在窗口,返回值为零。
2. 把要使用到的信息写入结构体
typedef struct COPYDATASTRUCT {
DWORD dwData; //自定义数据
DWORD cbData; //指定lpData指向的数据的大小
PVOID lpData; //指向数据的指针
} COPYDATASTRUCT;结构体来实现
其中dwData是信息的一种类似于标记的东西,在接收的信息中筛选出该信息
QString content = "close"; //设置消息内容
const ULONG_PTR CUSTOM_TYPE = 10000;
COPYDATASTRUCT cds;
cds.dwData = CUSTOM_TYPE;
cds.cbData = content.toUtf8().size(); //转换成utf8格式,方便后续还原消息
cds.lpData = content.toUtf8().data();
- 最后就是把这个消息给发送出去就好了
//设置发送消息的句柄
HWND sender = (HWND)effectiveWinId();
qDebug() << sender;
//reinterpret_cast运算符是用来处理无关类型之间的转换;它会产生一个新的值,这个值会有与原始参数
//(expressoin)有完全相同的比特位
::SendMessage(hwnd,WM_COPYDATA,reinterpret_cast<WPARAM>(sender),reinterpret_cast<LPARAM>(&cds));
- 接下来是接收窗口的函数写法,使用到的是nativeEvent事件函数,我们需要重写该函数
//在.h文件中声明
#include<qt_windows.h>
//同时在类中声明
private:
bool nativeEvent(const QByteArray &eventType, void *message, long *result);
//在.cpp文件中
#include<QDebug>
const ULONG_PTR CUSTOM_TYPE = 10000;
bool win::nativeEvent(const QByteArray &eventType, void *message, long *result)
{
MSG *param = static_cast<MSG *>(message);
switch(param->message)
{
case WM_COPYDATA:
{
COPYDATASTRUCT* cds = reinterpret_cast<COPYDATASTRUCT *>(param->lParam);
if(cds->dwData == CUSTOM_TYPE)
{
QString strMessage = QString::fromUtf8(reinterpret_cast<char*>(cds->lpData),cds->cbData);
//使用massagebox显示消息
QMessageBox::information(this,QStringLiteral("消息"),strMessage);
*result = 1;
return true;
}
}
}
return QWidget::nativeEvent(eventType,message,result);
}
其中MSG是windows的消息结构体,经过筛选后可以拿到之前发出的消息,之后还原成utf8形式就好啦。