批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程
[批处理文件精品]批处理版照片整理器[批处理文件精品]纯批处理备份&还原驱动在线第三方下载
返回列表 发帖

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

本帖最后由 happy886rr 于 2017-6-5 15:27 编辑
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


源码发布,请自行编译:
  1. /*
  2.     CONSOLE MOUSE TOOL, COPYRIGHT@2016~2018 BY HAPPY
  3.     PMOS.EXE
  4.     VERSION 1.0
  5. */
  6. #include <stdio.h>
  7. #include <stdbool.h>
  8. #include <Windows.h>
  9. #include <time.h>
  10. //申明函数
  11. HWND WINAPI GetConsoleWindow();
  12. //定义区域结构体
  13. typedef struct
  14. {
  15.     int x;
  16.     int y;
  17.     int with;
  18.     int height;
  19. } AREA;
  20. /***************功能函数群***************/
  21. //隐藏光标
  22. BOOL SizeCursor(int size)
  23. {
  24.     CONSOLE_CURSOR_INFO cursor_info = {(DWORD)((size==0)?25:size), (size==0)?FALSE:TRUE};
  25.     return SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
  26. }
  27. //获取光标位置
  28. int GetPos()
  29. {
  30.     HANDLE hConsole =GetStdHandle(STD_OUTPUT_HANDLE);
  31.     CONSOLE_SCREEN_BUFFER_INFO csbi = {0};
  32.     if(GetConsoleScreenBufferInfo(hConsole, &csbi))
  33.     {
  34.         return (csbi.dwCursorPosition.X)*10000+(csbi.dwCursorPosition.Y);
  35.     }
  36.     return -1;
  37. }
  38. //设置光标位置
  39. BOOL SetPos(int x,int y)
  40. {
  41.     COORD  pos ={(SHORT)x, (SHORT)y};
  42.     HANDLE hOutput=GetStdHandle(STD_OUTPUT_HANDLE);
  43.     return SetConsoleCursorPosition(hOutput,pos);
  44. }
  45. //获得鼠标瞬时位置
  46. int GetMouse()
  47. {
  48.     LPPOINT p=(LPPOINT)calloc(1, sizeof(LPPOINT));
  49.     p->x=-1;
  50.     p->y=-1;
  51.     HWND  hCMD=GetConsoleWindow();
  52.     //获取鼠标像素坐标
  53.     GetCursorPos(p);
  54.     //转为当前窗口相对坐标
  55.     ScreenToClient(hCMD, p);
  56.     //获取客户区域大小
  57.     RECT    rect= {0};
  58.     LPRECT  lr=&rect;
  59.     GetClientRect(hCMD, lr);
  60.     //判断是否落在客户区域
  61.     if(
  62.         p->x >= lr->left   &&
  63.         p->y >= lr->top    &&
  64.         p->x <= lr->right  &&
  65.         p->y <= lr->bottom
  66.     )
  67.     {
  68.         return p->x *10000+p->y;
  69.     }
  70.     return -1;
  71. }
  72. //设置鼠标瞬时位置
  73. BOOL MoveMouse(int x,int y)
  74. {
  75.     LPPOINT p=(LPPOINT)calloc(1, sizeof(LPPOINT));
  76.     HWND    hCMD=GetConsoleWindow();
  77.     p->x=0;
  78.     p->y=0;
  79.     ScreenToClient(hCMD, p);
  80.     return SetCursorPos(x- p->x, y- p->y);
  81. }
  82. //在限定时间内,获取鼠标KEY_V键点击时(鼠标||光标)位置, KEY_V取值-1,1分别代表鼠标左右键;
  83. int PressKeyMouse(const int KEY_V, const clock_t delay, BOOL mode)
  84. {
  85.     LPPOINT p=(LPPOINT)calloc(1, sizeof(LPPOINT));
  86.     p->x=-1;
  87.     p->y=-1;
  88.     RECT rect= {0};
  89.     LPRECT  lr=&rect;
  90.     HANDLE StdIn=GetStdHandle(STD_INPUT_HANDLE);
  91.     DWORD  OrgMode, Res;
  92.     INPUT_RECORD InR;
  93.     GetConsoleMode(StdIn, &OrgMode);
  94.     SetConsoleMode(StdIn, OrgMode | ENABLE_WINDOW_INPUT |  ENABLE_MOUSE_INPUT);
  95.     HWND  hCMD=GetConsoleWindow();
  96.     clock_t start=clock();
  97.     while(clock()-start <delay)
  98.     {
  99.         if(mode)
  100.         {
  101.             if(GetAsyncKeyState(KEY_V)&0x8000)
  102.             {
  103.                 GetCursorPos(p);
  104.                 ScreenToClient(hCMD, p);
  105.                 GetClientRect(hCMD, lr);
  106.                 if(
  107.                     p->x >= lr->left   &&
  108.                     p->y >= lr->top    &&
  109.                     p->x <= lr->right  &&
  110.                     p->y <= lr->bottom
  111.                 )
  112.                 {
  113.                     return p->x *10000+p->y;
  114.                 }
  115.             }
  116.         }
  117.         else
  118.         {
  119.             if(
  120.                 ReadConsoleInputA(StdIn, &InR, 1, &Res)   &&
  121.                 InR.EventType==2                          &&
  122.                 InR.Event.MouseEvent.dwEventFlags ==0     &&
  123.                 InR.Event.MouseEvent.dwButtonState==KEY_V
  124.             )
  125.             {
  126.                 SetConsoleMode(StdIn, OrgMode);
  127.                 return (InR.Event.MouseEvent.dwMousePosition.X)*10000+(InR.Event.MouseEvent.dwMousePosition.Y);
  128.             }
  129.         }
  130.         //缓解CPU占用
  131.         Sleep(1);
  132.     }
  133.     return -1;
  134. }
  135. //区域浮留
  136. int isINAREA(int argc, char** argv)
  137. {
  138.     LPPOINT p=(LPPOINT)calloc(1, sizeof(LPPOINT));
  139.     HWND    hCMD=GetConsoleWindow();
  140.     int     i, N=argc-2;
  141.     AREA*   input[N];
  142.     for(i=0; i<N; i++)
  143.     {
  144.         input[i]       =(AREA*)calloc(1, sizeof(AREA));
  145.         input[i]->x      =atoi(strtok(argv[i+2], ","));
  146.         input[i]->y      =atoi(strtok(NULL,      ","));
  147.         input[i]->with   =atoi(strtok(NULL,      ","));
  148.         input[i]->height =atoi(strtok(NULL,      ","));
  149.         if(input[i]->with==0||input[i]->height==0)
  150.         {
  151.             fprintf(stdout, "The %dth area needs size\n", i+1);
  152.             exit(-1);
  153.         }
  154.     }
  155.     while(TRUE)
  156.     {
  157.         p->x=-1;
  158.         p->y=-1;
  159.         GetCursorPos(p);
  160.         ScreenToClient(hCMD, p);
  161.         for(i=0; i<N; i++)
  162.         {
  163.             if(
  164.                 (input[i]->x < p->x && p->x < input[i]->x+input[i]->with  ) &&
  165.                 (input[i]->y < p->y && p->y < input[i]->y+input[i]->height)
  166.             )
  167.             {
  168.                 free(input);
  169.                 return i+1;
  170.             }
  171.         }
  172.         Sleep(1);
  173.     }
  174. }
  175. //帮助信息
  176. void HelpInfomation(int code)
  177. {
  178.     fputs(
  179.         "CONSOLE MOUSE TOOL, COPYRIGHT@2016~2018 BY HAPPY, VERSION 1.0\n"
  180.         "-----------------------------------------------------------------------------\n"
  181.         "pmos [/G]|[/M [x],[y]]|[/K [key]:[time]]|[/F {parameters}]\n"
  182.         "-----------------------------------------------------------------------------\n"
  183.         "     /G   Get the mouse instantaneous position\n"
  184.         "     /M   Move the mouse to the (x,y)\n"
  185.         "     /K   Return mouse position when the [key] is pressed in limited [time]\n"
  186.         "     /F   The mouse area floats\n"
  187.         "     /GC  Get the cursor instantaneous position\n"
  188.         "     /MC  Set the cursor to the (x,y)\n"
  189.         "     /KC  Return  cursor position when the [key] is pressed in limited [time]\n"
  190.         "     /SC  Set the cursor size\n"
  191.         "-----------------------------------------------------------------------------\n"
  192.         "12/02/2016"
  193.         ,stdout
  194.     );
  195.     exit(code);
  196. }
  197. /*************MAIN主函数入口*************/
  198. int main(int argc, char** argv)
  199. {
  200.     int KEY_V;
  201.     clock_t delay;
  202.     if( (argc >1) && (argv[1][0]=='/') )
  203.     {
  204.         switch(argv[1][1])
  205.         {
  206.         case 'G':
  207.         case 'g':
  208.             if(argv[1][2]=='C'||argv[1][2]=='c')
  209.             {
  210.                 return GetPos();
  211.             }
  212.             else
  213.             {
  214.                 return GetMouse();
  215.             }
  216.         case 'M':
  217.         case 'm':
  218.             if(argc <3)
  219.             {
  220.                 fputs("Missing parameters", stdout);
  221.                 exit(1);
  222.             }
  223.             if(argv[1][2]=='C'||argv[1][2]=='c')
  224.             {
  225.                 SetPos(atoi(strtok(argv[2], ",")), atoi(strtok(NULL, ",")));
  226.             }
  227.             else
  228.             {
  229.                 MoveMouse(atoi(strtok(argv[2], ",")), atoi(strtok(NULL, ",")));
  230.             }
  231.             break;
  232.         case 'K':
  233.         case 'k':
  234.             if(argc <3)
  235.             {
  236.                 fputs("Missing parameters", stdout);
  237.                 exit(1);
  238.             }
  239.             KEY_V=(atoi(strtok(argv[2], ":"))==1)?2:1;
  240.             delay=(clock_t)atoi(strtok(NULL, ":"));
  241.             if(argv[1][2]=='C'||argv[1][2]=='c')
  242.             {
  243.                 return PressKeyMouse(KEY_V, delay, FALSE);
  244.             }
  245.             else
  246.             {
  247.                 return PressKeyMouse(KEY_V, delay, TRUE);
  248.             }
  249.         case 'F':
  250.         case 'f':
  251.             if(argc==2)
  252.             {
  253.                 return -1;
  254.             }
  255.             return isINAREA(argc, argv);
  256.         case 'S':
  257.         case 's':
  258.             if(argc <3)
  259.             {
  260.                 fputs("Missing parameters", stdout);
  261.                 exit(1);
  262.             }
  263.             if(argv[1][2]=='C'||argv[1][2]=='c')
  264.             {
  265.                 SizeCursor(atoi(argv[2]));
  266.             }
  267.             else
  268.             {
  269.                 fputs("Error option", stdout);
  270.                 exit(1);
  271.             }
  272.             break;
  273.         default:
  274.             HelpInfomation(1);
  275.         }
  276.         return 0;
  277.     }
  278.     HelpInfomation(1);
  279. }
复制代码
浮留演示:
  1. @echo off
  2. pmos /f 0,200,100,50  150,200,100,50  300,200,100,50
  3. echo 鼠标掠过第%errorlevel%个区域
  4. pause>NUL
复制代码
1

评分人数

    • a2002: 感谢分享技术 + 1

好工具,顶一下~

TOP

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

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

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

TOP

源码更新了?

TOP

好工具,顶一下〜
为退烧而生

TOP

回复 3# hnfeng


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

TOP

返回列表