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 <memory>

#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的运用,还有就是设计好三者之间切换的流程。即将焦点切换的动作交给目标进程来做,自身进程只负责发消息,避免逻辑混乱。

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

(0)

相关推荐

  • Qt实现苹果状态切换按钮

    本文实例为大家分享了Qt实现苹果状态切换按钮的具体代码,供大家参考,具体内容如下 代码如下 #include "button.h" #include <QDebug> Button::Button(QWidget *parent) : QPushButton(parent) { status = 0; span_length = 0; rl_flag = false; release_flag =true; timeline = new QTimeLine; connect

  • 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,否则显示或隐藏它们.这里不再赘

  • python3+PyQt5+Qt Designer实现界面可视化

    前言 以前制作一个Python窗体界面,我都是用GUI窗口视窗设计的模块Tkinter一点一点敲出来的,今天朋友问我有没有Python窗体的设计工具,"用鼠标拖拖"就能完成窗体设计,我查了查相关资料,果然有一款好用的工具--Qt Designer. 1.安装Qt Designer 这里需要安装两个东西:PyQt5和PyQt5-tools: 安装PyQt5:打开CMD或者PowerShell,在命令窗中输入 pip install PyQt5 执行结果如下: 安装PyQt5-tools:

  • jQuery实现表单input中提示文字value随鼠标焦点移进移出而显示或隐藏的代码

    复制代码 代码如下: <input value="请输入用户名" type="text"> <input value="请输入密码" type="text"> <input value="提交" type="submit"> <script> $(function(){ //输入框中文字颜色控制 $("input:not(:las

  • Android实现闪屏及注册和登录界面之间的切换效果

    在没给大家介绍正文之前先给大家说下实现思路: 先分别实现闪屏.注册界面.登录界面的活动,再用Intent将相关的活动连接起来,实现不同活动之间的跳转.此次试验代码较多,我只列出主要代码,详细的代码可用底部的下载链接下载. 一.实验效果图: 二.主要代码: (1)WelcomeActivity.Java(这部分代码实现的是第一页的欢迎页面) package com.example.flashscreendemo; import android.app.Activity; import androi

  • 详谈android界面之间数据的传递

    不同界面之间,数据的传递是很常用的一个操作,这种数据的携带也是很简单的. 效果: 跳转后: 这个例子很简单,但是我们把第一个界面输入的姓名张三顺利传递到了第二个界面 附代码如下: 主界面: package com.yy.activity.value; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.text.TextUtils; import

  • C#简单获取全屏中鼠标焦点位置坐标的方法示例

    本文实例讲述了C#简单获取全屏中鼠标焦点位置坐标的方法.分享给大家供大家参考,具体如下: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Drawing; using System.Threading; namespace ConsoleApplication1 { class Program { static void Main(string[]

  • VS+Qt+Halcon 显示图片,实现鼠标缩放、移动图片

    目录 摘要 关键代码解释 1️.Qt函数与Halcon算子获取的文件路径字符串的区别 摘要 本篇博文记录一下,用VS+Qt+Halcon实现对图片的读取以及鼠标缩放,移动(鼠标事件调用了halcon自带的算子)的过程.以及遇到的坑.....

  • C++ Qt绘制时钟界面

    首先来看一下效果: 大概就是这样子,需要注意的是,这里你需要创建一个基类为Widget的界面来绘制时钟,以至于后期你想把这个时钟放到任意一个界面,你只需要在那个界面的ui里面添加一个widget,然后将它提升为这个时钟界面,并设定它的大小. widget.h文件 #ifndef WIDGET_H #define WIDGET_H #include<math.h> #include<QResizeEvent> #include<QGroupBox> #include<

  • Qt一个进程运行另一个进程的实现方法

    目录 1. 一个进程运行另一个进程 2. 例程代码 1. 一个进程运行另一个进程 Qt 的 QProcess 类用来启动一个外部程序并与其进行通信. 使用 start() 函数运行一个进程,之后 QProcess 进入 Starting 状态: 当程序已经运行后,QProcess 就会进入 Running 状态并发送 started() 信号: 当进程退出后,QProcess 重新回到 NoRunning 状态并发射 finished() 信号. 2. 例程代码 mainwindow.h #if

  • VirtualBox安装CentOS实现鼠标自动切换和复制粘贴功能

    1. 输入命令: cd /media 2. 输入命令: sh VBoxLinuxAdditions.run 3. 可能会出现错误: 解决的办法是依次输入命令: yum install update yum update kernel yum update kernel-devel yum install kernel-headers yum install gcc yum install gcc make 然后再运行: sh VBoxLinuxAdditions.run 就可以了: 以上所述是小

随机推荐