批处理之家's Archiver

happy886rr 发表于 2016-12-2 21:50

pmos.exe 强大的控制台鼠标位置获取工具

[i=s] 本帖最后由 happy886rr 于 2017-6-5 15:27 编辑 [/i]

[quote]PMOS.EXE
摘要:
=============================================================================
控制台鼠标位置工具,集鼠标位置获取、鼠标按键、鼠标区域浮动等多重功能。同时兼
有对光标的隐藏和位置设置。poms所获取的位置都是像素级的超精细坐标, 让你的BAT
应用点击更加精准;同时为了照顾已有应用,pmos也集成了光标API。
=============================================================================

用法:
-----------------------------------------------------------------------------
pmos [/G]|[/M [x],[y]]|[/W [key]:[time]]|[/A {parameters}]|[/H]|[/P [x],[y]]
-----------------------------------------------------------------------------
---鼠标系---
      /G                获取鼠标瞬时像素坐标
      /M  [x],[y]       移动鼠标到指定像素坐标
      /K  [key]:[time]  在[time]时间内,如果鼠标[key]键被按下,则返回像素坐标
      /F  {[x],[y],[with],[height]}  鼠标区域浮留判定

---光标系---
      /GC               获取光标坐标
      /MC [x],[y]       移动光标到指定坐标
      /KC [key]:[time]  在[time]时间内,如果鼠标[key]键被按下,则返回光标坐标
      /SC [size]        设置光标尺寸
-----------------------------------------------------------------------------

示例:
-----------------------------------------------------------------------------
pmos /G                &REM 获取鼠标瞬时像素坐标,返回值在!errorlevel!中
                        REM X=!errorlevel!/10000, Y=!errorlevel!%%10000

pmos /M 300,500        &REM 移动鼠标到像素坐标(300,500)位置。

pmos /K -1:5000        &REM 在5000毫秒内,如果鼠标左键被按下,则返回像素坐标。
                        REM [key]取值为-1、1对应鼠标左右键。

pmos /F 0,200,100,50  150,200,100,50  300,200,100,50
                       &REM 判断鼠标是否在所给的3个区域中,是则返回区域序号。
-----------------------------------------------------------------------------

英译:
-----------------------------------------------------------------------------
CONSOLE MOUSE TOOL, COPYRIGHT@2016~2018 BY HAPPY, VERSION 1.0
-----------------------------------------------------------------------------
pmos [/G]|[/M [x],[y]]|[/K [key]:[time]]|[/F {parameters}]
-----------------------------------------------------------------------------
     /G   Get the mouse instantaneous position
     /M   Move the mouse to the (x,y)
     /K   Return mouse position when the [key] is pressed in limited [time]
     /F   The mouse area floats
     /GC  Get the cursor instantaneous position
     /MC  Set the cursor to the (x,y)
     /KC  Return  cursor position when the [key] is pressed in limited [time]
     /SC  Set the cursor size
-----------------------------------------------------------------------------
12/02/2016[/quote]

源码发布,请自行编译:[code]/*
    CONSOLE MOUSE TOOL, COPYRIGHT@2016~2018 BY HAPPY
    PMOS.EXE
    VERSION 1.0
*/

#include <stdio.h>
#include <stdbool.h>
#include <Windows.h>
#include <time.h>

//申明函数
HWND WINAPI GetConsoleWindow();

//定义区域结构体
typedef struct
{
    int x;
    int y;
    int with;
    int height;
} AREA;

/***************功能函数群***************/
//隐藏光标
BOOL SizeCursor(int size)
{
    CONSOLE_CURSOR_INFO cursor_info = {(DWORD)((size==0)?25:size), (size==0)?FALSE:TRUE};
    return SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}
//获取光标位置
int GetPos()
{
    HANDLE hConsole =GetStdHandle(STD_OUTPUT_HANDLE);
    CONSOLE_SCREEN_BUFFER_INFO csbi = {0};
    if(GetConsoleScreenBufferInfo(hConsole, &csbi))
    {
        return (csbi.dwCursorPosition.X)*10000+(csbi.dwCursorPosition.Y);
    }
    return -1;
}
//设置光标位置
BOOL SetPos(int x,int y)
{
    COORD  pos ={(SHORT)x, (SHORT)y};
    HANDLE hOutput=GetStdHandle(STD_OUTPUT_HANDLE);
    return SetConsoleCursorPosition(hOutput,pos);
}
//获得鼠标瞬时位置
int GetMouse()
{
    LPPOINT p=(LPPOINT)calloc(1, sizeof(LPPOINT));
    p->x=-1;
    p->y=-1;

    HWND  hCMD=GetConsoleWindow();

    //获取鼠标像素坐标
    GetCursorPos(p);
    //转为当前窗口相对坐标
    ScreenToClient(hCMD, p);

    //获取客户区域大小
    RECT    rect= {0};
    LPRECT  lr=&rect;
    GetClientRect(hCMD, lr);

    //判断是否落在客户区域
    if(
        p->x >= lr->left   &&
        p->y >= lr->top    &&
        p->x <= lr->right  &&
        p->y <= lr->bottom
    )
    {
        return p->x *10000+p->y;
    }
    return -1;
}
//设置鼠标瞬时位置
BOOL MoveMouse(int x,int y)
{
    LPPOINT p=(LPPOINT)calloc(1, sizeof(LPPOINT));
    HWND    hCMD=GetConsoleWindow();
    p->x=0;
    p->y=0;
    ScreenToClient(hCMD, p);
    return SetCursorPos(x- p->x, y- p->y);
}
//在限定时间内,获取鼠标KEY_V键点击时(鼠标||光标)位置, KEY_V取值-1,1分别代表鼠标左右键;
int PressKeyMouse(const int KEY_V, const clock_t delay, BOOL mode)
{
    LPPOINT p=(LPPOINT)calloc(1, sizeof(LPPOINT));
    p->x=-1;
    p->y=-1;

    RECT rect= {0};
    LPRECT  lr=&rect;

    HANDLE StdIn=GetStdHandle(STD_INPUT_HANDLE);
    DWORD  OrgMode, Res;
    INPUT_RECORD InR;
    GetConsoleMode(StdIn, &OrgMode);
    SetConsoleMode(StdIn, OrgMode | ENABLE_WINDOW_INPUT |  ENABLE_MOUSE_INPUT);

    HWND  hCMD=GetConsoleWindow();

    clock_t start=clock();

    while(clock()-start <delay)
    {
        if(mode)
        {
            if(GetAsyncKeyState(KEY_V)&0x8000)
            {
                GetCursorPos(p);
                ScreenToClient(hCMD, p);
                GetClientRect(hCMD, lr);
                if(
                    p->x >= lr->left   &&
                    p->y >= lr->top    &&
                    p->x <= lr->right  &&
                    p->y <= lr->bottom
                )
                {
                    return p->x *10000+p->y;
                }
            }
        }
        else
        {

            if(
                ReadConsoleInputA(StdIn, &InR, 1, &Res)   &&
                InR.EventType==2                          &&
                InR.Event.MouseEvent.dwEventFlags ==0     &&
                InR.Event.MouseEvent.dwButtonState==KEY_V
            )
            {
                SetConsoleMode(StdIn, OrgMode);
                return (InR.Event.MouseEvent.dwMousePosition.X)*10000+(InR.Event.MouseEvent.dwMousePosition.Y);
            }
        }

        //缓解CPU占用
        Sleep(1);
    }
    return -1;
}
//区域浮留
int isINAREA(int argc, char** argv)
{
    LPPOINT p=(LPPOINT)calloc(1, sizeof(LPPOINT));
    HWND    hCMD=GetConsoleWindow();
    int     i, N=argc-2;
    AREA*   input[N];
    for(i=0; i<N; i++)
    {
        input[i]       =(AREA*)calloc(1, sizeof(AREA));
        input[i]->x      =atoi(strtok(argv[i+2], ","));
        input[i]->y      =atoi(strtok(NULL,      ","));
        input[i]->with   =atoi(strtok(NULL,      ","));
        input[i]->height =atoi(strtok(NULL,      ","));
        if(input[i]->with==0||input[i]->height==0)
        {
            fprintf(stdout, "The %dth area needs size\n", i+1);
            exit(-1);
        }
    }
    while(TRUE)
    {
        p->x=-1;
        p->y=-1;
        GetCursorPos(p);
        ScreenToClient(hCMD, p);
        for(i=0; i<N; i++)
        {
            if(
                (input[i]->x < p->x && p->x < input[i]->x+input[i]->with  ) &&
                (input[i]->y < p->y && p->y < input[i]->y+input[i]->height)
            )
            {
                free(input);
                return i+1;
            }
        }
        Sleep(1);
    }
}
//帮助信息
void HelpInfomation(int code)
{
    fputs(
        "CONSOLE MOUSE TOOL, COPYRIGHT@2016~2018 BY HAPPY, VERSION 1.0\n"
        "-----------------------------------------------------------------------------\n"
        "pmos [/G]|[/M [x],[y]]|[/K [key]:[time]]|[/F {parameters}]\n"
        "-----------------------------------------------------------------------------\n"
        "     /G   Get the mouse instantaneous position\n"
        "     /M   Move the mouse to the (x,y)\n"
        "     /K   Return mouse position when the [key] is pressed in limited [time]\n"
        "     /F   The mouse area floats\n"
        "     /GC  Get the cursor instantaneous position\n"
        "     /MC  Set the cursor to the (x,y)\n"
        "     /KC  Return  cursor position when the [key] is pressed in limited [time]\n"
        "     /SC  Set the cursor size\n"
        "-----------------------------------------------------------------------------\n"
        "12/02/2016"
        ,stdout
    );
    exit(code);
}

/*************MAIN主函数入口*************/
int main(int argc, char** argv)
{
    int KEY_V;
    clock_t delay;
    if( (argc >1) && (argv[1][0]=='/') )
    {
        switch(argv[1][1])
        {
        case 'G':
        case 'g':
            if(argv[1][2]=='C'||argv[1][2]=='c')
            {
                return GetPos();
            }
            else
            {
                return GetMouse();
            }

        case 'M':
        case 'm':
            if(argc <3)
            {
                fputs("Missing parameters", stdout);
                exit(1);
            }
            if(argv[1][2]=='C'||argv[1][2]=='c')
            {
                SetPos(atoi(strtok(argv[2], ",")), atoi(strtok(NULL, ",")));
            }
            else
            {
                MoveMouse(atoi(strtok(argv[2], ",")), atoi(strtok(NULL, ",")));
            }
            break;

        case 'K':
        case 'k':
            if(argc <3)
            {
                fputs("Missing parameters", stdout);
                exit(1);
            }
            KEY_V=(atoi(strtok(argv[2], ":"))==1)?2:1;
            delay=(clock_t)atoi(strtok(NULL, ":"));
            if(argv[1][2]=='C'||argv[1][2]=='c')
            {
                return PressKeyMouse(KEY_V, delay, FALSE);
            }
            else
            {
                return PressKeyMouse(KEY_V, delay, TRUE);
            }

        case 'F':
        case 'f':
            if(argc==2)
            {
                return -1;
            }
            return isINAREA(argc, argv);

        case 'S':
        case 's':
            if(argc <3)
            {
                fputs("Missing parameters", stdout);
                exit(1);
            }
            if(argv[1][2]=='C'||argv[1][2]=='c')
            {
                SizeCursor(atoi(argv[2]));
            }
            else
            {
                fputs("Error option", stdout);
                exit(1);
            }
            break;

        default:
            HelpInfomation(1);

        }
        return 0;
    }
    HelpInfomation(1);
}
[/code]浮留演示:[code]
@echo off
pmos /f 0,200,100,50  150,200,100,50  300,200,100,50
echo 鼠标掠过第%errorlevel%个区域
pause>NUL
[/code]

cfwyy77_bat 发表于 2017-6-5 13:37

好工具,顶一下~

hnfeng 发表于 2018-6-8 10:55

很棒的小工具,请教  /GC 参数怎么用? 想得到光标所在行,然后减去一个数,再 /MC

一直有个想法,但是找不到程序来实现:
批处理中 pause 和 timeout 运行时会显示暂停信息,然后继续运行时,这些信息仍然停留在CMD窗口里,影响美观。
想有个小程序,能够消除这些暂停信息并把光标移动到暂停信息所在位置,就是继续执行批处理后,看不到这些暂停信息了
不知楼主能否写个?
谢谢

补充:曾经使用退格实现,但是兼容性太差,在不同的系统中表现完全不一样

CrLf 发表于 2018-6-8 13:03

源码更新了?

失控的疯子 发表于 2019-1-25 15:49

好工具,顶一下〜

Markting 发表于 2020-1-10 16:19

[b]回复 [url=http://www.bathome.net/redirect.php?goto=findpost&pid=208891&ptid=42578]3#[/url] [i]hnfeng[/i] [/b]


    你可以使用pause>nul或timeout /t n >nul

lancer 发表于 2021-11-2 21:28

有没有编译好的啊,不会编译:'(

lancer 发表于 2021-11-2 21:28

有没有编译好的啊,不会编译:'(

lancer 发表于 2021-11-12 09:42

[b]回复 [url=http://www.bathome.net/redirect.php?goto=findpost&pid=247951&ptid=42578]9#[/url] [i]slimay[/i] [/b]


    找到了,发现这个鼠标坐标获取是根据批处理窗口来的,我以为是相对整个屏幕的坐标呢

页: [1]

Powered by Discuz! Archiver 7.2  © 2001-2009 Comsenz Inc.