如何用C++解除classin教室的专注模式
最近疫情更加严重,一些地方转成网课,很多学校都使用ClassIn教室进行上课。但是有一些教室都设置了“专注模式”,使学生无法开启除教室外的别的窗口,十分麻烦。如何用C++解决这个问题呢?
问题一:获得教室窗口句柄
方法一:GetForegroundWindow()函数。
- GetForegroundWindow()获取一个前台窗口的句柄(用户当前工作的窗口)。该系统分配给其他线程比它的前台窗口的线程创建一个稍微更高的优先级。
#include<windows.h>
#include<iostream>
using namespace std;
int main() {
HWND classroom=GetForegroundWindow();//获取最顶层窗口
cout<<classroom;
return 0;
}
此方法十分简单,但是有时候会遇到危险:如果任务栏/Windows主页被当成最顶层窗口,执行操作后会导致一些十分可笑的情景,但是电脑可能会被卡死。
方法二:窗口名查找
- 窗口名查找会让人想到FindWindow函数,但是此函数只能查找父窗口,不能查找子窗口,classin的教室咱们扫描不到。我们可以观察一下classin上课的教室名,然后会发现都带有一个关键的前缀: “Classroom_”,后面有两个较长的数作为教室号。这个时候就容易想到递归遍历每一个窗口,然后逐个判断。由于带有Classroom_的窗口不多,所以这个方法出错的概率小。为了进一步防止出错,如果有0个活2个及以上的窗口的标题带有Classroom_,放弃操作。
- 这里采用递归函数和struct结构体来存储每一个窗体,然后利用获得的句柄移动窗口+解除置顶+允许手动修改大小。
- 修改大小会先查询显示器大小然后将窗口缩小到显示器大小再缩小一点的大小。
#include <iostream>
#include <Windows.h>
#include <set>
#include <vector>
using namespace std;
struct window{
HWND WindowHwnd;
string title;
string type;
void put(string tl,string tp,HWND wh) {
WindowHwnd=wh;
title=tl;
type=tp;
}
bool operator<(const window&a) {
return title < a.title;
}
bool search(string s) {
if(s.size()==0)return true;
if(title.find(s)!=-1)return true;
return false;
}
}tmp;
vector<window>win;
set<string>ss;
string se;
BOOL CALLBACK EnumChildProc(_In_ HWND hwnd, _In_ LPARAM lParam) {
char szTitle[MAX_PATH] = {0};
char szClass[MAX_PATH] = {0};
int nMaxCount = MAX_PATH;
LPSTR lpClassName = szClass;
LPSTR lpWindowName = szTitle;
GetWindowTextA(hwnd, lpWindowName, nMaxCount);
GetClassNameA(hwnd, lpClassName, nMaxCount);
string l=lpWindowName,r=lpClassName;
if(ss.count(l))return TRUE;
ss.insert(l);
if(l.size()==0)return TRUE;
tmp.put(l,r,hwnd);
if(tmp.search(se))win.push_back(tmp);
return TRUE;
}
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) {
char szTitle[MAX_PATH] = {0};
char szClass[MAX_PATH] = {0};
int nMaxCount = MAX_PATH;
LPSTR lpClassName = szClass;
LPSTR lpWindowName = szTitle;
GetWindowTextA(hwnd, lpWindowName, nMaxCount);
GetClassNameA(hwnd, lpClassName, nMaxCount);
string l=lpWindowName,r=lpClassName;
if(ss.count(l))return TRUE;
ss.insert(l);
if(l.size()==0)return TRUE;
tmp.put(l,r,hwnd);
if(tmp.search(se))win.push_back(tmp);
EnumChildWindows(hwnd, EnumChildProc, lParam);
return TRUE;
}
int x,y;
void geti(){
x=GetSystemMetrics(SM_CXSCREEN);
y=GetSystemMetrics(SM_CYSCREEN);
}
bool search(string s) {
geti();
se=s;
ss.clear();
win.clear();
EnumWindows(EnumWindowsProc, 0);
HWND h;
if(win.size()==1)h=win[0].WindowHwnd;
else return 0;
SetWindowPos(h,HWND_NOTOPMOST,0,0,x,y-50,SWP_NOSENDCHANGING);
SetWindowPos(h,HWND_NOTOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
SetWindowLong(h,GWL_STYLE,GetWindowLong(h,GWL_STYLE) | WS_SIZEBOX | WS_MAXIMIZEBOX | WS_MINIMIZEBOX);
return 1;
}
int main() {
if(search("Classroom_"))cout<<"Succeed";
else cout<<"Error.";
return 0;
}
编译运行上述代码,即可解除专注模式。
欢迎一起交流讨论
更加高效的方法,记得点个赞
哦
附上一个我写的窗口资源管理器,也有解除专注模式功能~