(人工操作的那台机子我称之为“服务器”,等待消息自动翻页的机器我称之为“客户机”)
前景知识:
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