简单远程控制(仅传递鼠标和键盘消息)的实现

9 篇文章 0 订阅

假设两个同样的应用程序,运行在相同的操作系统上,要实现远程控制,可以使用传递鼠标和键盘的消息给对方,对方收到后解析出鼠标和键盘消息如何执行即可。


下面是几处关键程序:


一是处理收到消息,下面应该放在套接字接收或者串口接收中:(小心下面的右键单击、双击几处没实现!)

  1. //  
  2. // 解析从客户端发送过来的消息并发送到本机的消息队列  
  3. //  
  4. void DispatchWMMessage(char *szString, void *p)  
  5. {  
  6.     CTestDlg *pDlg = (CTestDlg *)p;  
  7.   
  8.     //鼠标消息  
  9.     struct {char *szWMMouseMsg;}   
  10.     WMMouseMsg[] = {"WM_MM","WM_LBD","WM_LBU","WM_LBK",  
  11.                     "WM_MBD","WM_MBU","WM_MBK",  
  12.                     "WM_RBD","WM_RBU","WM_RBK"};  
  13.   
  14.     // 键盘消息  
  15.     struct {char *szWMKeyBdMsg;}  
  16.     WMKeyBdMsg[] = {"WM_KD","WM_KU"};  
  17.   
  18.     // 通用消息:色彩模式,网格数和压缩消息  
  19.     struct {char *szMsg;}  
  20.     Msg[] = {"WM_COMP","WM_GRID","WM_CMOD"};  
  21.   
  22.     int     nWMMouseMsg;  
  23.     int     nWMKeyBdMsg;  
  24.     int     nMsg;  
  25.   
  26.     struct  CommandList CommandStart;  
  27.     struct  CommandList *pCommandNode;  
  28.     struct  CommandDS   Command;  
  29.     char    *pDest;  
  30.     int     iLoc,nChar;  
  31.     int     iLoop,iParms;  
  32.     char    szString2[2049];  
  33.   
  34.     // 分别得到鼠标,键盘,通用消息的数目  
  35.     nWMMouseMsg = (int)(sizeof(WMMouseMsg)/sizeof(WMMouseMsg[0]));  
  36.     nWMKeyBdMsg = (int)(sizeof(WMKeyBdMsg)/sizeof(WMKeyBdMsg[0]));  
  37.     nMsg = (int)(sizeof(Msg)/sizeof(Msg[0]));  
  38.   
  39.     // 初始化command链表  
  40.     CommandStart.pNext = NULL;  
  41.     pCommandNode = &CommandStart;  
  42.   
  43.     // 分析command命令,截获命令的参数  
  44.     iParms = 0;  
  45.     while (pDest = strchr(szString,';'))  
  46.     {  
  47.         iLoc = pDest - szString;  
  48.         nChar = iLoc;  
  49.         memset(Command.szElement,'\0',sizeof(Command.szElement));  
  50.         strncpy(Command.szElement,szString,nChar);  
  51.         // 发送到命令栈中  
  52.         pCommandNode = Add_Command(pCommandNode,Command);  
  53.         memset(szString2,'\0',sizeof(szString2));  
  54.         strcpy(szString2,&szString[iLoc + 1]);  
  55.         strcpy(szString,szString2);  
  56.   
  57.         iParms++;  
  58.         if (iParms == 5) // 每条命令5个参数  
  59.             break;  
  60.     }  
  61.   
  62.     // 处理命令  
  63.     pCommandNode = CommandStart.pNext;  
  64.     if (pCommandNode)  
  65.     {  
  66.         // 鼠标消息  
  67.         UINT    keyFlags;  
  68.         int     iMessage;  
  69.         int     fWMMouseMsg;  
  70.         DWORD   dwX,dwY;  
  71.   
  72.         // 键盘消息  
  73.         int     fWMKeyBdMsg;  
  74.         UINT    vk;  
  75.         int     fDown;  
  76.         int     cRepeat;  
  77.         UINT    flags;  
  78.   
  79.         // 判断是否有鼠标消息  
  80.         fWMMouseMsg = FALSE;  
  81.         for (iLoop = 0;iLoop < nWMMouseMsg;iLoop++)  
  82.         {  
  83.             if (strcmp(pCommandNode->Command.szElement,WMMouseMsg[iLoop].szWMMouseMsg) == 0)  
  84.             {  
  85.                 // 设置鼠标消息的标志  
  86.                 fWMMouseMsg = TRUE;  
  87.                 // 具体的鼠标消息  
  88.                 if (strcmp(WMMouseMsg[iLoop].szWMMouseMsg,"WM_MM\0") == 0)  
  89.                     iMessage = 1;  
  90.                 else if (strcmp(WMMouseMsg[iLoop].szWMMouseMsg,"WM_LBD\0") == 0)  
  91.                     iMessage = 2;  
  92.                 else if (strcmp(WMMouseMsg[iLoop].szWMMouseMsg,"WM_LBU\0") == 0)  
  93.                     iMessage = 3;  
  94.                 else if (strcmp(WMMouseMsg[iLoop].szWMMouseMsg,"WM_LBK\0") == 0)  
  95.                     iMessage = 4;  
  96.                 else if (strcmp(WMMouseMsg[iLoop].szWMMouseMsg,"WM_MBD\0") == 0)  
  97.                     iMessage = 5;  
  98.                 else if (strcmp(WMMouseMsg[iLoop].szWMMouseMsg,"WM_MBU\0") == 0)  
  99.                     iMessage = 6;  
  100.                 else if (strcmp(WMMouseMsg[iLoop].szWMMouseMsg,"WM_MBK\0") == 0)  
  101.                     iMessage = 7;  
  102.                 else if (strcmp(WMMouseMsg[iLoop].szWMMouseMsg,"WM_RBD\0") == 0)  
  103.                     iMessage = 8;  
  104.                 else if (strcmp(WMMouseMsg[iLoop].szWMMouseMsg,"WM_RBU\0") == 0)  
  105.                     iMessage = 9;  
  106.                 else if (strcmp(WMMouseMsg[iLoop].szWMMouseMsg,"WM_RBK\0") == 0)  
  107.                     iMessage = 10;  
  108.   
  109.                 // 移动到参数栈的下一个节点,x坐标  
  110.                 pCommandNode = pCommandNode->pNext;  
  111.                 dwX = (DWORD)atof(pCommandNode->Command.szElement);  
  112.   
  113.                 // 移动到参数栈的下一个节点,y坐标  
  114.                 pCommandNode = pCommandNode->pNext;  
  115.                 dwY = (DWORD)atof(pCommandNode->Command.szElement);  
  116.   
  117.                 // 移动到参数栈的下一个节点,辅助键  
  118.                 pCommandNode = pCommandNode->pNext;  
  119.                 keyFlags = atoi(pCommandNode->Command.szElement);  
  120.   
  121.                 // 退出循环  
  122.                 break;  
  123.             }  
  124.         }  
  125.   
  126.         // 如果有鼠标消息则对鼠标消息进行处理  
  127.         if (fWMMouseMsg)  
  128.         {  
  129.             // 处理鼠标消息  
  130.             if (iMessage == 1) //光标移动  
  131.             {  
  132.                 //mouse_event(MOUSEEVENTF_ABSOLUTE|MOUSEEVENTF_MOVE,0,0,0,0);  
  133.                 SetCursorPos(dwX,dwY);    
  134.             }  
  135.             else if (iMessage == 2) //左键按下  
  136.             {  
  137.                 mouse_event(MOUSEEVENTF_ABSOLUTE|MOUSEEVENTF_LEFTDOWN,0,0,0,0);  
  138.             }  
  139.             else if (iMessage == 3) //左键抬起  
  140.             {  
  141.                 mouse_event(MOUSEEVENTF_ABSOLUTE|MOUSEEVENTF_LEFTUP,0,0,0,0);  
  142.             }  
  143.             //以下鼠标的消息还未处理!!!  
  144.             else if (iMessage == 4)   
  145.             {  
  146.                 mouse_event(MOUSEEVENTF_ABSOLUTE|MOUSEEVENTF_LEFTDOWN,0,0,0,0);  
  147.                 mouse_event(MOUSEEVENTF_ABSOLUTE|MOUSEEVENTF_LEFTUP,0,0,0,0);  
  148.                 mouse_event(MOUSEEVENTF_ABSOLUTE|MOUSEEVENTF_LEFTDOWN,0,0,0,0);  
  149.                 mouse_event(MOUSEEVENTF_ABSOLUTE|MOUSEEVENTF_LEFTUP,0,0,0,0);  
  150.             }  
  151.             else if (iMessage == 5)   
  152.             {  
  153.                 mouse_event(MOUSEEVENTF_ABSOLUTE|MOUSEEVENTF_MIDDLEDOWN,0,0,0,0);  
  154.             }  
  155.             else if (iMessage == 6)   
  156.             {  
  157.                 mouse_event(MOUSEEVENTF_ABSOLUTE|MOUSEEVENTF_MIDDLEUP,0,0,0,0);  
  158.             }  
  159.             else if (iMessage == 7)   
  160.             {  
  161.                 mouse_event(MOUSEEVENTF_ABSOLUTE|MOUSEEVENTF_MIDDLEDOWN,0,0,0,0);  
  162.                 mouse_event(MOUSEEVENTF_ABSOLUTE|MOUSEEVENTF_MIDDLEUP,0,0,0,0);  
  163.                 mouse_event(MOUSEEVENTF_ABSOLUTE|MOUSEEVENTF_MIDDLEDOWN,0,0,0,0);  
  164.                 mouse_event(MOUSEEVENTF_ABSOLUTE|MOUSEEVENTF_MIDDLEUP,0,0,0,0);  
  165.             }  
  166.             else if (iMessage == 8)   
  167.             {  
  168.                 mouse_event(MOUSEEVENTF_ABSOLUTE|MOUSEEVENTF_RIGHTDOWN,0,0,0,0);  
  169.             }  
  170.             else if (iMessage == 9)   
  171.             {  
  172.                 mouse_event(MOUSEEVENTF_ABSOLUTE|MOUSEEVENTF_RIGHTUP,0,0,0,0);  
  173.             }  
  174.             else if (iMessage == 10)  
  175.             {  
  176.                 mouse_event(MOUSEEVENTF_ABSOLUTE|MOUSEEVENTF_RIGHTDOWN,0,0,0,0);  
  177.                 mouse_event(MOUSEEVENTF_ABSOLUTE|MOUSEEVENTF_RIGHTUP,0,0,0,0);  
  178.                 mouse_event(MOUSEEVENTF_ABSOLUTE|MOUSEEVENTF_RIGHTDOWN,0,0,0,0);  
  179.                 mouse_event(MOUSEEVENTF_ABSOLUTE|MOUSEEVENTF_RIGHTUP,0,0,0,0);  
  180.             }  
  181.         }  
  182.         else  
  183.         {  
  184.             // 没有鼠标消息则判断是否有键盘消息  
  185.             fWMKeyBdMsg = FALSE;  
  186.             for (iLoop = 0;iLoop < nWMKeyBdMsg;iLoop++)  
  187.             {  
  188.                 if (strcmp(pCommandNode->Command.szElement,WMKeyBdMsg[iLoop].szWMKeyBdMsg) == 0)  
  189.                 {  
  190.                     // 设置键盘消息标志  
  191.                     fWMKeyBdMsg = TRUE;  
  192.                     if (strcmp(WMKeyBdMsg[iLoop].szWMKeyBdMsg,"WM_KD\0") == 0)  
  193.                         iMessage = 1;//按下键  
  194.                     else if (strcmp(WMKeyBdMsg[iLoop].szWMKeyBdMsg,"WM_KU\0") == 0)  
  195.                         iMessage = 2;//松开键  
  196.   
  197.                     // 移动到参数链表的下一个节点,Virtural 键码  
  198.                     pCommandNode = pCommandNode->pNext;  
  199.                     vk = atoi(pCommandNode->Command.szElement);  
  200.   
  201.                     //移动到参数链表的下一个节点,按下键标志  
  202.                     pCommandNode = pCommandNode->pNext;  
  203.                     fDown = atoi(pCommandNode->Command.szElement);  
  204.   
  205.                     // 移动到参数链表的下一个节点,按键重复数  
  206.                     pCommandNode = pCommandNode->pNext;  
  207.                     cRepeat = atoi(pCommandNode->Command.szElement);  
  208.   
  209.                     // 移动到参数链表的下一个节点,标志位  
  210.                     pCommandNode = pCommandNode->pNext;  
  211.                     flags = atoi(pCommandNode->Command.szElement);  
  212.   
  213.                     break;  
  214.                 }  
  215.             }  
  216.   
  217.             // 如果有键盘消息,则处理键盘消息  
  218.             if (fWMKeyBdMsg)  
  219.             {  
  220.                 if (iMessage == 1) //模拟按键消息  
  221.                 {  
  222.                     keybd_event((BYTE)vk,(BYTE)vk,0,0);  
  223.                 }  
  224.                 else if (iMessage == 2) //模拟松开键的消息  
  225.                 {  
  226.                     keybd_event((BYTE)vk,(BYTE)vk,KEYEVENTF_KEYUP,0);  
  227.                 }  
  228.             }  
  229.             else // 通用消息  
  230.             {  
  231.                 for (iLoop = 0;iLoop < nMsg;iLoop++)  
  232.                 {  
  233.                     if (strcmp(pCommandNode->Command.szElement,Msg[iLoop].szMsg) == 0)  
  234.                     {  
  235.                         if (strcmp(Msg[iLoop].szMsg,"WM_COMP\0") == 0)  
  236.                         {  
  237.                             // 移动到参数链表的下一个节点,压缩级数  
  238.                             pCommandNode = pCommandNode->pNext;  
  239.                             //iCompressionLevel = atoi(pCommandNode->Command.szElement);  
  240.                         }  
  241.                         else if (strcmp(Msg[iLoop].szMsg,"WM_GRID\0") == 0)  
  242.                         {  
  243.                             // 移动到参数链表的下一个节点,x网格数  
  244.                             pCommandNode = pCommandNode->pNext;  
  245.                             //nGridX = atoi(pCommandNode->Command.szElement);  
  246.   
  247.                             // 移动到参数链表的下一个节点,y网格数  
  248.                             pCommandNode = pCommandNode->pNext;  
  249.                             //nGridY = atoi(pCommandNode->Command.szElement);  
  250.   
  251.                             // 清除当前的显示设置  
  252.                             //ClearDisplay(hServerWnd);  
  253.                             // 初始化新的显示设置  
  254.                             //InitDisplay(hServerWnd);  
  255.                         }  
  256.                         else if (strcmp(Msg[iLoop].szMsg,"WM_CMOD\0") == 0)  
  257.                         {  
  258.                             // 移动到参数链表的下一个节点,每个屏幕点的字节数  
  259.                             pCommandNode = pCommandNode->pNext;  
  260.                             //bmBitsPixel = atoi(pCommandNode->Command.szElement);  
  261.   
  262.                             //ClearDisplay(hServerWnd);  
  263.                             //InitDisplay(hServerWnd);  
  264.                         }  
  265.                     }  
  266.                 }  
  267.             }  
  268.         }  
  269.     }  
  270.     // 清除命令队列  
  271.     Clear_Command(&CommandStart);  
  272. }  
  273.   
  274.   
  275.   
  276. // 添加一个元素到命令栈中  
  277. struct CommandList *Add_Command(struct CommandList *pNode,struct CommandDS Command)  
  278. {  
  279.     if (pNode->pNext = (struct CommandList *)malloc(sizeof(struct CommandList)))  
  280.     {  
  281.         pNode = pNode->pNext;  
  282.         strcpy(pNode->Command.szElement,Command.szElement);  
  283.         pNode->pNext = NULL;  
  284.         return pNode;  
  285.     }  
  286.     return NULL;  
  287. }  
  288.   
  289. //完全清除命令栈元素  
  290. void Clear_Command(struct CommandList *pStart)  
  291. {  
  292.     struct  CommandList *pPrev;  
  293.     struct  CommandList *pNode;  
  294.     while (pNode = pStart->pNext)  
  295.     {  
  296.         pPrev = pStart;  
  297.         pPrev->pNext = pNode->pNext;  
  298.         free(pNode);  
  299.     }  
  300. }  


二是发送处代码,可以放在主对话框(窗口)的PreTranslateMessage,也可以放在App的PreTranslateMessage中:
  1. BOOL CTestDlg::PreTranslateMessage(MSG* pMsg)   
  2. {  
  3.     if (pMsg->message == WM_LBUTTONDOWN)//左键按下  
  4.     {  
  5.         if(m_bSend)  
  6.         {  
  7.             CPoint pt;  
  8.             GetCursorPos(&pt);  
  9.   
  10.             memset(szMsg,'\0',sizeof(szMsg));  
  11.             sprintf(szMsg,"WM_LBD;%d;%d;%d;0;\0",pt.x, pt.y, keyFlags);  
  12.             LanSend(szMsg, strlen(szMsg));  
  13.         }  
  14.     }  
  15.     else if (pMsg->message == WM_LBUTTONUP)//左键抬起  
  16.     {  
  17.         if(m_bSend)  
  18.         {  
  19.             CPoint pt;  
  20.             GetCursorPos(&pt);  
  21.               
  22.             memset(szMsg,'\0',sizeof(szMsg));  
  23.             sprintf(szMsg,"WM_LBU;%d;%d;%d;0;\0",pt.x, pt.y, keyFlags);  
  24.               
  25.             LanSend(szMsg, strlen(szMsg));  
  26.         }  
  27.     }  
  28.     else if (pMsg->message == WM_MOUSEMOVE)  //光标移动  
  29.     {  
  30.         if(m_bSend)  
  31.         {  
  32.             POINT pt;  
  33.             ::GetCursorPos(&pt);  
  34.             memset(szMsg,'\0',sizeof(szMsg));  
  35.             //sprintf(szMsg,"WM_MM;%d;%d;%d;0;\0", GET_X_LPARAM(pMsg->lParam), GET_Y_LPARAM(pMsg->lParam), 0);  
  36.             sprintf(szMsg,"WM_MM;%d;%d;%d;0;\0", pt.x, pt.y, 0);  
  37.             LanSend(szMsg, strlen(szMsg));  
  38.             return FALSE;  
  39.         }  
  40.     }  
  41.     else if (pMsg->message == WM_KEYDOWN)    //键盘按下  
  42.     {  
  43.         if(m_bSend)  
  44.         {  
  45.             memset(szMsg,'\0',sizeof(szMsg));  
  46.             sprintf(szMsg,"WM_KD;%d;%d;%d;%d;\0",pMsg->wParam, 0, 0, 0);  
  47.             LanSend(szMsg, strlen(szMsg));  
  48.         }  
  49.     }  
  50.     else if (pMsg->message == WM_KEYUP)      //键盘抬起  
  51.     {  
  52.         if(m_bSend)  
  53.         {  
  54.             memset(szMsg,'\0',sizeof(szMsg));  
  55.             sprintf(szMsg,"WM_KU;%d;%d;%d;%d;\0",pMsg->wParam, 0, 0, 0);  
  56.             LanSend(szMsg, strlen(szMsg));  
  57.         }  
  58.     }  
  59.   
  60.     return CDialog::PreTranslateMessage(pMsg);  
  61. }  

上述的LanSend是套接字发送(或者是串口发送)函数。
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: WinForm批量远程控制桌面指的是使用WinForm技术实现批量控制远程桌面的功能。 在实现这个功能之前,我们需要了解远程桌面控制的基本原理。远程桌面控制是指通过网络连接远程计算机,并且能够在本地计算机上操作和控制远程计算机的桌面。通常,远程桌面控制涉及两个主要的角色,即服务端和客户端。 服务端是远程计算机上运行的软件,它负责提供远程访问的服务。客户端是本地计算机上运行的软件,它负责连接远程计算机,并且提供用户操作的界面。 在WinForm中实现批量远程控制桌面的基本步骤如下: 1. 创建一个WinForm应用程序,作为客户端的界面。 2. 使用WinForm的界面设计工具,设计一个用户界面,包括远程计算机列表、控制按钮等。 3. 实现远程计算机列表的管理功能,可以添加、删除和编辑远程计算机的信息。 4. 实现连接远程计算机的功能,可以通过网络连接到远程计算机,并且获取到远程桌面的图像数据。 5. 实现桌面控制的功能,可以在本地计算机上操作远程桌面的鼠标键盘等输入设备,并且将操作传递到远程计算机上。 6. 实现批量控制的功能,可以选择多台远程计算机进行批量控制,可以同时进行多个远程桌面控制的操作。 7. 实现远程桌面的图像显示功能,可以将远程计算机的桌面图像实时显示在客户端的界面上。 8. 实现错误处理和异常处理的功能,保证程序的稳定性和安全性。 以上是用300字回答如何使用WinForm实现批量远程控制桌面的问题。希望以上内容对你有帮助。 ### 回答2: WinForm批量远程控制桌面是指通过使用WinForm技术来实现对多个远程桌面的同时控制。这项技术可用于一些需要同时管理多台远程计算机的场景,如企业级系统管理、网络维护等。 实现此功能的方法如下: 1. 建立服务器端:首先搭建一个服务器端程序,用于接收客户端连接和处理远程控制请求。可以基于WinForm开发,采用TCP/IP通信协议,通过监听服务器的IP地址和端口,等待客户端的连接请求。 2. 建立客户端:每个需要被控制的远程计算机都需要安装一个客户端程序,可以基于WinForm开发。客户端程序需要连接到服务器端,并向服务器发送远程控制请求。 3. 连接与通信:客户端请求连接服务器,服务器端接受连接请求后与客户端建立有效的双向通信。可以使用Socket进行数据传输,实现双向的数据交互。 4. 桌面远程控制:服务器端在接受到来自客户端的远程控制请求后,通过使用相关的技术,如远程桌面协议(如RDP协议)、远程控制库(如OpenRPA)或远程桌面工具(如TeamViewer)等方式,实现对远程计算机桌面的实时抓取、远程操作和控制。 5. 批量控制:通过在服务器端管理多个客户端的连接信息,可以实现对多个远程计算机的同时控制。可以通过列表或树形结构显示已连接的客户端,实时更新远程计算机的状态和活动。 总之,WinForm批量远程控制桌面功能的实现需要借助于服务器端和客户端的程序,并通过相关的远程控制技术实现对多台远程计算机的同时控制。这样可以方便地进行集中管理和维护,提高工作效率和减少成本。 ### 回答3: Winforms是一种用于开发Windows桌面应用程序的技术。要实现批量远程控制桌面,通常需要结合远程桌面协议(如RDP)和网络编程来实现。 首先,我们可以使用Winforms开发一个简单的应用程序,用于管理和控制远程桌面。这个程序可以提供用户界面,用于输入和管理要远程控制的目标机器的信息。 然后,我们可以使用远程桌面协议(如RDP)来远程连接到目标机器。在Winforms应用程序中,我们可以使用自带的Windows.Forms类库中的远程桌面控件(如RemoteDesktopControl)来实现桌面的远程访问和控制。 为了实现批量远程控制,我们可以在应用程序中提供一个列表或数据库,用于存储和管理要控制的目标机器的信息。用户可以通过UI界面进行添加、删除和编辑目标机器的信息。 用户可以选择一个或多个目标机器进行远程控制。通过远程桌面协议,我们可以在Winforms应用程序中创建多个远程连接,并将其显示在不同的窗口中,以便同时控制多台机器。 此外,我们还可以在应用程序中实现一些额外的功能,如屏幕共享、文件传输等。这些功能可以通过网络编程来实现,例如使用Socket或WCF通信机制。 在应用程序开发完成后,用户可以通过该应用程序方便地批量远程控制桌面。他们只需选择目标机器,并通过远程桌面控制来实现对这些机器的远程访问和控制。 总之,借助Winforms技术,并结合远程桌面协议和网络编程,我们可以开发一个功能强大的应用程序,实现批量远程控制桌面的需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值