现在的位置: 首页 > 综合 > 正文

网络同步两台计算机之间的键盘消息

2013年10月12日 ⁄ 综合 ⁄ 共 2282字 ⁄ 字号 评论关闭

(人工操作的那台机子我称之为“服务器”,等待消息自动翻页的机器我称之为“客户机”)

前景知识:

1、调用API keybd_event()可以模拟一个键盘动作;

调用API mouse_event()可以模拟一个鼠标动作;

以上两个API的不足就是无法指定向特定窗口发送键盘/鼠标消息。

 

2、利用API函数 SendMessage()可以以同步的方式向目标窗体发送一条消息,然后,

等待目标窗体的处理过程处理此消息;

利用API函数 PostMessage()可以以异步的方式向目标窗体发送一条消息,然后,

函数立即返回。

函数原型声明:

LRESULT SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam);

BOOL PostMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam);

(我感觉在客户机上应该使用PostMessage来向PwoerPoint窗口发送按键消息,这样进程就不会阻塞,可以继续监听发送过来的消息)                  

 

3、我们所要做的事情可以分为:

服务器:

•  记录翻页按键(上下箭头/PageUP/PageDown,还可以包括鼠标滚轮的上下方向)

                      我们可以简单化:只要是翻下页我们就发送 1;否则发送0;

服务器和客户端:

• 建立一个基于socket的连接,服务器到客户机,这一步很容易实现,然后,在客户机的程序中判断发送过来的数据是1还是0;

           若是1我们就调用PostMessag向PwoerPoint窗口发送向下翻页的消息(可以采用“向下的箭头”作为按键消息),若是0则相反;

 

关键的两点:

         截获服务器上的按键消息,并且不影响PwoerPoint程序对消息的处理,服务器端的监听程序要有透明性;

          获得客户机端的PwoerPoint窗口的句柄

 

下面来解决这两个关键点:

1、截获服务器上的按键消息,并且不影响PwoerPoint程序对消息的处理,服务器端的监听程序要有透明性

获得一个消息的API:

BOOL GetMessage(LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFIlterMax);

BOOL PeekMessage(LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFIlterMax,UINT wRemoveMsg);

函数参数说明:

lpMsg-- 一个MSG结构的指针,用来接受消息内容

hWnd--指定窗口句柄,函数之接受此窗口相关的消息。如果为NULL则接受任何窗口的消息

wMsgFilterMin--允许接受消息范围的下限

wMsgFilterMax--允许接受消息范围的上限,如果此参数和wMsgFilterMin同时为0,则接受所有消息

返回值--如果受到WM_QUIT,则返回0,如果函数出错,返回-1。否则返回非0数值

PeekMessage的 wRemoveMsg参数--若为PM_NOREMOVE,则函数处理完消息后,消息仍然存在与消息队列中;

                                                  若为PM_REMOVE,则函数处理完消息后,消息从消息队列中移除;

 

总结:

我们就可以在服务器端简单使用 :

MSG myMsg;

PeekMessage(&myMsg,NULL,0,0,PM_NOREMOVE);

来完成第一个关键点;

 

2、获得客户机端的PwoerPoint窗口的句柄

我找到了下面的资料:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`

使用windows API的FindWindow()函数;

函数原型为 : HWND FindWindow ( LPCSTR lpClassName, LPCSTR lpWindowName ); 

lpClassName:指向一个以null结尾的、用来指定类名的字符串或一个可以确定类名字符串的原子。如果这个参数是一个原子,那么它必须是一个在调用此函数前已经通过GlobalAddAtom函数创建好的全局原子。这个原子(一个16bit的值),必须被放置在lpClassName的低位字节中,lpClassName的高位字节置零。 如果该参数为null时,将会寻找任何与lpWindowName参数匹配的窗口。 

lpWindowName 指向一个以null结尾的、用来指定窗口名(即窗口标题)的字符串。如果此参数为NULL,则匹配所有窗口名。 返回值: 如果函数执行成功,则返回值是拥有指定窗口类名或窗口名的窗口的句柄。 如果函数执行失败,则返回值为 NULL 。可以通过调用GetLastError函数获得更加详细的错误信息。 

可作如下使用: 

HWND hDlg=::FindWindow(NULL,"") 

if(hDlg!=NULL) 

{ //Your operations } 

else { GetLastError(); }

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~``

这样只要我们在客户机上调用:

HWND hwnd=::FindWindow(NULL,"ppt窗口的名字");

PostMessage(hwnd,Msg,..);

详细的信息查看:http://msdn.microsoft.com/en-us/library/ms644944(VS.85).aspx

 

抱歉!评论已关闭.