前言:
1.首先介绍的是使用easyx库获得窗口大小和窗口句柄,然后介绍控制台检测的方法,最后再来介绍win程序检测的方法。
2.函数中的getwidth()和getheight()两个函数是easyx库获得窗口大小的功能,可以被替换掉,后面有相应的修改后函数
方法:使用的时候传入要检测的窗口的句柄就能返回是否超出的结果
函数如下:
bool CT_CheckOutWindow(HWND& hWnd) {//检测当前鼠标是否离开窗口所在范围,但无法检测窗口是否激活
static POINT point;
GetCursorPos(&point); // 获取鼠标指针位置(屏幕坐标)
ScreenToClient(hWnd, &point); // 将鼠标指针位置转换为窗口坐标
if (point.x<0 || point.y<0 || point.x>getwidth() || point.y>getheight())
return 1;//超出
return 0;//没超出
}
完整实例(easyx):
#include
#include
bool CT_CheckOutWindow(HWND& hWnd) {//检测当前鼠标是否离开窗口所在范围,但无法检测窗口是否激活
static POINT point;
GetCursorPos(&point); // 获取鼠标指针位置(屏幕坐标)
ScreenToClient(hWnd, &point); // 将鼠标指针位置转换为窗口坐标
if (point.x<0 || point.y<0 || point.x>getwidth() || point.y>getheight())
return 1;//超出
return 0;//没超出
}
int main() {
HWND hWnd = initgraph(200, 200);
while (!_kbhit()) {
CT_CheckOutWindow(hWnd) ? outtextxy(0, 0, "超出范围") : outtextxy(0, 0, "没有超出范围");
Sleep(50);
cleardevice();
}
}
那么,如何摆脱eaxy库,来检测鼠标是否脱离了呢?
Win程序获得句柄就很简单,CreateWindow函数创建窗口就可以获得句柄,窗口宽高由于是自己给的参数,也能通过简单的修改下函数就能检测。
唯独控制台就相对比较麻烦,不过也还是能做到的,首先可以使用如下代码获得控制台窗口句柄
char ch[100];//用来存储获得的控制台标题
GetConsoleTitle(ch, 100);//获得控制台标题,参数分别是,存储用的数组,和其大小
HWND hWnd=FindWindow(NULL, ch);//根据标题名获得控制台窗口句柄
其次,稍微修改下函数
bool CT_CheckOutWindow(HWND& hWnd) {//检测当前鼠标是否离开窗口所在范围,但无法检测窗口是否激活
static POINT point;
static _CONSOLE_SCREEN_BUFFER_INFO p;
static _CONSOLE_FONT_INFO fontp;
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &p);//主要拿来获取窗口大小(字符为单位)
GetCurrentConsoleFont(GetStdHandle(STD_OUTPUT_HANDLE), 0, &fontp);//主要拿来获取字符大小
//上面这两行代码各位可以丢外面去,这个每次都检测只是怕用户调整控制台大小导致出问题
GetCursorPos(&point); // 获取鼠标指针位置(屏幕坐标)
ScreenToClient(hWnd, &point); // 将鼠标指针位置转换为窗口坐标
if (point.x<0 || point.y<0 || point.x>(p.dwSize.X)*(fontp.dwFontSize.X) || point.y>(p.dwSize.Y)*(fontp.dwFontSize.Y))
return 1;//超出
return 0;//没超出
}
最后,准备一个gotoxy函数来代替system(“cls”)功能
void gotoxy(int x, int y) {
COORD pos;
pos.X = x;
pos.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}
然后,开始!
完整实例(控制台):
#include
#include
#include
using namespace std;
void gotoxy(int x, int y) {
COORD pos;
pos.X = x;
pos.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}
bool CT_CheckOutWindow(HWND& hWnd) {//检测当前鼠标是否离开窗口所在范围,但无法检测窗口是否激活
static POINT point;
static _CONSOLE_SCREEN_BUFFER_INFO p;
static _CONSOLE_FONT_INFO fontp;
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &p);//主要拿来获取窗口大小(字符为单位)
GetCurrentConsoleFont(GetStdHandle(STD_OUTPUT_HANDLE), 0, &fontp);//主要拿来获取字符大小
//上面这两行代码个位可以丢外面
GetCursorPos(&point); // 获取鼠标指针位置(屏幕坐标)
ScreenToClient(hWnd, &point); // 将鼠标指针位置转换为窗口坐标
if (point.x<0 || point.y<0 || point.x>(p.dwSize.X)*(fontp.dwFontSize.X) || point.y>(p.dwSize.Y)*(fontp.dwFontSize.Y))
return 1;//超出
return 0;//没超出
}
int main() {
system("mode con cols=20 lines=5");//设置下大小
char ch[100];
GetConsoleTitle(ch, 100);
HWND hWnd=FindWindow(NULL, ch);//完成获得句柄的操作
while (!_kbhit()) {
CT_CheckOutWindow(hWnd) ? cout << "超出\n" : cout << "正常\n";
Sleep(100);
gotoxy(0, 0);//回到初始位置,即刷新
}
}
那么,最后,虽然说了下Win很简单,但是还是得放下代码的
那么这次就先放一个效果图在前边,让长长的Windows代码留在文章的最后作为结尾吧:)
#include
#define X (200)
#define Y (200)
bool CT_CheckOutWindow(HWND& hWnd) {//检测当前鼠标是否离开窗口所在范围,但无法检测窗口是否激活
static POINT point;
GetCursorPos(&point); // 获取鼠标指针位置(屏幕坐标)
ScreenToClient(hWnd, &point); // 将鼠标指针位置转换为窗口坐标
if (point.x<0 || point.y<0 || point.x>X || point.y>Y)
return 1;//超出
return 0;//没超出
}
LRESULT CALLBACK WindowProc(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
) {
switch (uMsg) {
case WM_CLOSE:
DestroyWindow(hwnd);//发送一个消息WM_Destroy,表示毁灭窗口,但程序还在
case WM_DESTROY:
PostQuitMessage(0);//发送正常程序退出的消息
break;
case WM_PAINT://绘图
{
PAINTSTRUCT ps;//绘图结构体
HDC hdc = BeginPaint(hwnd, &ps);
if(CT_CheckOutWindow(hwnd))
TextOut(hdc, 100, 100, TEXT("超出"), strlen("超出"));
else
TextOut(hdc, 100, 100, TEXT("正常"), strlen("正常"));
EndPaint(hwnd, &ps);
break;
}
}
//返回值用默认处理函数
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
int WINAPI wWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPWSTR lpCmdLine,
int nCmdShow)
{
WNDCLASS wc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.hCursor = LoadCursor(NULL, IDC_HAND);
wc.hIcon = LoadIcon(NULL, IDI_HAND);
wc.hInstance = hInstance;
wc.lpfnWndProc = WindowProc;
wc.lpszClassName = TEXT("WIN");
wc.lpszMenuName = NULL;
wc.style = 0;
RegisterClass(&wc);
HWND hwnd = CreateWindow(wc.lpszClassName, TEXT("WINDOWS"), wc.style, CW_USEDEFAULT, CW_USEDEFAULT, X, Y, NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, SW_SHOWNORMAL);
UpdateWindow(hwnd);
MSG msg;
while (1) {
if (GetMessage(&msg, NULL, 0, 0) == FALSE) {
break;
}
//翻译消息
TranslateMessage(&msg);
//分发消息
DispatchMessage(&msg);
Sleep(20);
InvalidateRect(hwnd, NULL, 1);//刷新
}
return 0;
}
好了,致此,本文就告一段落。
本文允许自由转载,但要写明出处,谢谢。