根据需求,需要在我们的应用程序中可以播放PPT并操作翻页。
由于使用的是c++ builder,没有VS的Windows控件库,所以一开始的打算是把PPT当成一个整体窗口来处理。
操作步骤:
(1)以播放方式打开PPT
通过Baidu发现是POWERPNT.EXE启动的PPT,所以可以通过ShellExcute(windowsApi),使用exe打开指定的PPT,当然也有其他的启动方式,大家可以自己搜索一下ShellExcute就会找到相关的内容。播放方式就是像在dos中操作文件一样,加个/s的参数,这样就可以以播放方式打开ppt。
(2)获得窗口句柄
使用Spyxx.exe(spy++, windows自带的窗口监测工具),查看PPT的播放窗口属性,发现不同的文件的播放窗体有同一个父窗口,类名是“ScreenClass”。那么就可以使用FindWindow(windowsApi)来获取窗口句柄。值得注意的是,由于播放窗口打开需要时间,加上系统的性能,所以使用FindWindow之前需要一定的延时。如果直接获取可能会找不到窗口。
(3)嵌入窗口
这步非常简单,由于播放模式下,PPT的显示格式也不需要修改,自动居中。我就直接调用的SetParent(我们的应用程序窗体句柄,PPT句柄),PPT就会在我们的程序里播放啦。
(4)翻页
如果需要使用触摸、手势翻页,可以对窗体发送键盘消息,因为键盘的上下左右等键可以操作PPT窗口。可以使用WindowsApi(POSTMessage\SendMessage\SendInput)来发送窗体消息。
程序参考:
对应上面。
(1)以播放方式打开PPT
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); //初始化Com组件
directory = "/s " + directory;
LPCWSTR dir = directory.c_str(); //显示PPT
hinstance = ShellExecute(GetDesktopWindow(), L"open", L"C:\\Program Files (x86)\\Microsoft Office\\Office14\\POWERPNT.EXE",
dir, NULL, SW_SHOWNORMAL);
pptHwnd = NULL;
int dec = 0;
while (pptHwnd == NULL) //不会立即找到句柄,ShellExecute有延时
{
dec ++;
pptHwnd = FindWindow(L"ScreenClass", NULL);
if (dec > 1000000)
{
MessageBox (NULL, TEXT ("None ppt was open!"), TEXT ("Error"), MB_SYSTEMMODAL) ;
break;
}
}
::SetParent(pptHwnd, formHwnd);
(4)翻页
PostMessage(hwndChild, WM_KEYDOWN, VK_LEFT, 0);
SendMessage(hwndChild, WM_SETFOCUS , NULL, NULL);
INPUT input[2];
memset(input, 0, 2 * sizeof(INPUT));
input[0].type = INPUT_KEYBOARD;
input[0].ki.wVk = VK_RETURN;
input[1].ki.dwFlags = KEYEVENTF_KEYDOWN;
SendInput(1, input, sizeof(INPUT));
input[1].type = INPUT_KEYBOARD;
input[1].ki.wVk = VK_RETURN;
input[1].ki.dwFlags = KEYEVENTF_KEYUP;
SendInput(1, input + 1, sizeof(INPUT));