我正在开发一个仅限Windows的Qt应用程序,我需要从Microsoft OneNote插件接收数据.该插件是用C#编写的,可以发送WM_COPYDATA消息.如何在C++ Qt应用程序中收到这些消息?
我需要:
这可以在Qt内处理:
使用将捕获WM_COPYDATA消息的类扩展QWidget:
class EventReceiverWindow : public QWidget
{
Q_OBJECT
public:
EventReceiverWindow();
signals:
void eventData(const QString & data);
private:
bool winEvent ( MSG * message, long * result );
};
Run Code Online (Sandbox Code Playgroud)生成一个GUID以设置为QWidget的windowTitle:
EventReceiverWindow::EventReceiverWindow()
{
setWindowTitle("ProjectName-3F2504E0-4F89-11D3-9A0C-0305E82C3301::EventReceiver");
}
Run Code Online (Sandbox Code Playgroud)覆盖winEvent以处理WM_COPYDATA结构并在获取时发出信号:
bool EventReceiverWindow::winEvent ( MSG * message, long * result )
{
if( message->message == WM_COPYDATA ) {
// extract the string from lParam
COPYDATASTRUCT * data = (COPYDATASTRUCT *) message->lParam;
emit eventData(QString::fromAscii((const char *)data->lpData, data->cbData));
// keep the event from qt
*result = 0;
return true;
}
// give the event to qt
return false;
}
Run Code Online (Sandbox Code Playgroud)在另一个类中,您可以使用此类来接收消息字符串:
EventReceiverWindow * eventWindow = new EventReceiverWindow;
QObject::connect(eventWindow, SIGNAL(eventData(const QString &)), this, SLOT(handleEventData(const QString &)));
Run Code Online (Sandbox Code Playgroud)
...
void OneNoteInterface::handleEventData(const QString &data)
{
qDebug() << "message from our secret agent: " << data;
}
Run Code Online (Sandbox Code Playgroud)在发送消息的程序中,只需通过唯一的窗口标题找到窗口.这是C#中的一个例子:
private struct COPYDATASTRUCT
{
public IntPtr dwData;
public int cbData;
[MarshalAs(UnmanagedType.LPStr)]
public string lpData;
}
private const int WM_COPYDATA = 0x4A;
[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName);
[DllImport("User32.dll", EntryPoint = "SendMessage")]
private static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, ref COPYDATASTRUCT lParam);
private void sendMessageTo(IntPtr hWnd, String msg)
{
int wParam = 0;
int result = 0;
if (hWnd != IntPtr.Zero )
{
byte[] sarr = System.Text.Encoding.Default.GetBytes(msg);
int len = sarr.Length;
COPYDATASTRUCT cds;
cds.dwData = IntPtr.Zero;
cds.lpData = msg;
cds.cbData = len + 1;
result = SendMessage(hWnd, WM_COPYDATA, wParam, ref cds);
}
}
Run Code Online (Sandbox Code Playgroud)
然后你可以:
IntPtr hwnd = FindWindowByCaption(IntPtr.zero, "ProjectName-3F2504E0-4F89-11D3-9A0C-0305E82C3301::EventReceiver");
sendMessageTo(hwnd, "omg hai");
Run Code Online (Sandbox Code Playgroud)| 归档时间: |
|
| 查看次数: |
7017 次 |
| 最近记录: |