qt 进程间切换焦点_Qt实现进程界面之间的鼠标焦点切换

本文实例为大家分享了Qt实现进程界面之间鼠标焦点切换的具体代码,供大家参考,具体内容如下

需求

有三个软件A、B、C。A是主要软件,B、C是辅助软件。

⑴ 在使用A的过程中,按N键可以呼出软件B,按M键可以呼出软件C。再次按下可以隐藏它们。

⑵ 在软件B、C都存在的条件下,按J键可以实现鼠标焦点以A->B->C的顺序在软件之间切换。

分析

需求(1)

在按键事件中对M或N键做处理,当对应键按下时,首先判断B.exe或C.exe是否存在,如果不存在则执行对应exe,否则显示或隐藏它们。这里不再赘述。

需求(2)

以从A切到B为例,由A通过UDP发消息给B,B收到消息后将焦点切到自身。其他类似。

定义通用变量

主要定义软件端口、消息类型、发送者类型。后面将建立三个Qt工程,MainDlg代表软件A,compass代表软件B,chatlist代表软件C。定义如下:

/*****************************************************

Author: 张志浩

Mail: 791745123@qq.com

Time: 2019-1-5

Function:

通用变量、宏定义头文件

DESTPORT : 目标主机端口

SENDERTYPE : 发送者类型

MSGTYPE : 消息类型

Version: v 1.0

*****************************************************/

#pragma once

typedef enum

{

PORT_MAINDLG = 8000,

PORT_COMPASS,

PORT_CHATLIST

}DESTPORT;

typedef enum

{

PROCESS_NONE = 100,

PROCESS_MAINDLG,

PROCESS_COMPASS,

PROCESS_CHATLIST

}SENDERTYPE;

typedef enum

{

MSG_NONE = 10,

MSG_CHANGEMOUSEPOS

}MSGTYPE;

设计通信报文

写一个报文基类,包含消息类型、发送者、附加消息三类信息。后期可以继承它来丰富信息种类。实现如下:

/*****************************************************

Author: 张志浩

Mail: 791745123@qq.com

Time: 2019-1-5

Function:

报文基类

Version: v 1.0

*****************************************************/

#pragma once

#include "commonType.h"

#include

#define BUFF_LENGTH 128

class CInfoBase

{

public:

CInfoBase():infoType(0), senderType(0)

{

memset(addMsg, 0, BUFF_LENGTH);

}

bool InputAddMsg(const char* buff, int length)

{

if (length < BUFF_LENGTH && length > 0)

{

memcpy(addMsg, buff, length);

return true;

}

return false;

}

public:

//消息类型

int infoType;

//发送者

int senderType;

//附加消息

char addMsg[BUFF_LENGTH];

};

焦点切换

焦点切换按以下几步进行:

//获取自身窗口句柄并置前

HWND hwnd = ::FindWindow(NULL, L"compass");

::SetForegroundWindow(hwnd);

//获取置前窗口句柄(该步骤可省略,直接用上一步获得的句柄)

HWND hForeWnd = ::GetForegroundWindow();

//获取当前工作线程ID

DWORD dcurid = ::GetCurrentThreadId();

//获取置前窗口的线程ID

DWORD dfoid = ::GetWindowThreadProcessId(hForeWnd, NULL);

//依附

::AttachThreadInput(dcurid, dfoid, TRUE);

//设置鼠标位置

QRect rect = this->geometry();

SetCursorPos(rect.left() + 200, rect.top() + 200);

依附的步骤是必要的,因为如果不依附,就算鼠标位置从A移到B了,此时的键盘输入焦点还在A。按J键只会进入A的键盘事件,除非手动点击一下B再按J。

整体流程梳理

以从MainDlg切往compass为例,此时三个软件都已经打开并显示在桌面。

1 按J键进入MainDlg键盘事件,发送消息到compass

void MainDlg::keyPressEvent(QKeyEvent * event)

{

switch(event->key())

{

case Qt::Key_J:

{

CInfoBase m_sendMsg;

m_sendMsg.infoType = MSG_CHANGEMOUSEPOS;

m_sendMsg.senderType = PROCESS_MAINDLG;

m_myudp.SendData((char*)&m_sendMsg, sizeof(m_sendMsg), PORT_COMPASS, "127.0.0.1");

break;

}

default:

{

}

}

}

2 compass收到UDP消息,切换焦点

void CUdpMsgBase::DataHanding(const char* data)

{

int msgType = MSG_NONE;

::memcpy(&msgType, data, sizeof(int));

if (msgType == MSG_NONE)

{

}

if (msgType == MSG_CHANGEMOUSEPOS)

{

emit changepos();

}

return;

}

进入槽函数

void MainDlg::changePos()

{

HWND hwnd = ::FindWindow(NULL, L"MainDlg");

::SetForegroundWindow(hwnd);

HWND hForeWnd = ::GetForegroundWindow();

DWORD dcurid = ::GetCurrentThreadId();

DWORD dfoid = ::GetWindowThreadProcessId(hForeWnd, NULL);

::AttachThreadInput(dcurid, dfoid, TRUE);

QRect rect = this->geometry();

SetCursorPos(rect.left() + 200, rect.top() + 200);

}

效果

总结

主要考察到对AttachThreadInput的运用,还有就是设计好三者之间切换的流程。即将焦点切换的动作交给目标进程来做,自身进程只负责发消息,避免逻辑混乱。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持随便开发网。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值