继续上面一章节的,通过注册表注册私有协议,让Chrome可以打开本地程序,本地程序能够播放一个过场动画,然后全屏跳转到ie浏览器指定页面,怎么实现这样的程序?
需要的准备工作:一段视频,安装好带有sdk的VLC播放器。
新建一个vs 2010空项目,不能是命令行程序,如果是命令行程序,跳转的时候会出现黑框,这是不可忍受的。所以我创建了窗口程序,但是这个窗口时不显示的,它直接调用vlc全屏播放视频,然后开启ie浏览器。那么,在C++中如何调用本地程序呢?有如下3中办法:
1、ShellExecute
实例:ShellExecute(NULL, "open", "http://www.baidu.com", NULL, NULL, SW_MAXIMIZE ); ShellExecute可以执行指定文件,程序,例子中就是开启ie浏览器并且以最大化方式打开百度。打开的方式有:
/*
* ShowWindow() Commands
*/
#define SW_HIDE 0
#define SW_SHOWNORMAL 1
#define SW_NORMAL 1
#define SW_SHOWMINIMIZED 2
#define SW_SHOWMAXIMIZED 3
#define SW_MAXIMIZE 3
#define SW_SHOWNOACTIVATE 4
#define SW_SHOW 5
#define SW_MINIMIZE 6
#define SW_SHOWMINNOACTIVE 7
#define SW_SHOWNA 8
#define SW_RESTORE 9
#define SW_SHOWDEFAULT 10
#define SW_FORCEMINIMIZE 11
#define SW_MAX 11
这些打开方式都不是全屏打开,ShellExecute只是调用某一个默认程序执行命令,无法给程序传输指令让其实现全屏,最终没有使用它。
2、WinExec
WinExec(
lpCmdLine: LPCSTR; {文件名和参数; 如没指定路径会按以下顺序查找: 程序目录/当前目录/System32/Windows/PATH环境变量}
uCmdShow: UINT {启动选项}
): UINT;
//说明 :运行指定的程序
//返回值
大于 31 {调用成功}
等于 0 {内存不足}
ERROR_FILE_NOT_FOUND = 2; {文件名错误}
ERROR_PATH_NOT_FOUND = 3; {路径名错误}
ERROR_BAD_FORMAT = 11; {EXE 文件无效}
(请参考FindExecutable函数)
WinExec效果和ShellExecute类似,此处也不能使用;
3、system
例子:system("start vlc -f xx.mp4");使用system,里面的参数执行的效果相当于在cmd中敲入参数再回车。使用system("iexplore -k www.baidu.com")可以实现全屏方式打开,但是system有一个致命弱点:会有命令行黑框弹出,故此处抛弃。
4、CreateProcess
说明:
WIN32API函数CreateProcess用来创建一个新的进程和它的主线程,这个新进程运行指定的可执行文件。
函数原型:
BOOL CreateProcess
(
LPCTSTR lpApplicationName,
LPTSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes。
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCTSTR lpCurrentDirectory,
LPSTARTUPINFO lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
);
详细参数解释情况可以参考msdn。CreateProcess可以执行制定程序,也可以将参数传递进去,最终我选择了它。
其他注意事项:
IE全屏模式打开的命令是-k,不过打开后无法用F11回复普通窗口模式,只能ctrl + w关闭打开的ie窗口。
vlc播放器其实不需要安装SDK,为了防止绝对路径,需要把vlc安装目录下的播放核心和控制核心放到小程序的相同目录,需要的东西如图中蓝色标注部分:
需要通过命令行:vlc -h查看vlc播放的帮助,vlc全屏的命令为-f,无标题的命令是--no-video-title-show,播放完毕(默认不循环)退出的命令式是--play-and-exit。加上窗体部分的代码,即可完成本小程序,我写出来的小程序7k大小,能实现这个功能。以下是代码(126行):
#include <windows.h>
LRESULT CALLBACK WindoWProc(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lparam
);
INT WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmd
)
{
WNDCLASS wndclass;
HWND wndhwnd;
MSG msg;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
//加载图标
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
//加载鼠标样式
wndclass.style = CS_VREDRAW | CS_HREDRAW;
//窗口样式
wndclass.lpfnWndProc = WindoWProc;
//窗口过程回调函数
wndclass.cbClsExtra = 0;
//类额外内存
wndclass.cbWndExtra = 0;
//窗口额外内存
wndclass.hInstance = hInstance;
wndclass.hbrBackground = (HBRUSH)GetStockObject(SYSTEM_FONT);
//窗口颜色
wndclass.lpszClassName = "WinMain";
//窗口类名 //窗口菜单
wndclass.lpszMenuName = NULL;
//窗口菜单
RegisterClassA(&wndclass);
//播放过场动画
/*system("start vlc -f xx.mp4");
Sleep(5000);*/
//全屏跳转到IE浏览器
STARTUPINFO svlc = { sizeof(svlc) };
STARTUPINFO sie = { sizeof(svlc) };
PROCESS_INFORMATION pvlc, pie;
svlc.dwFlags = sie.dwFlags = STARTF_USESHOWWINDOW;
svlc.wShowWindow = sie.wShowWindow = TRUE; //TRUE表示显示创建的进程的窗口
TCHAR cmdlinevlc[] = TEXT("vlc -f --play-and-exit --no-video-title-show D:\\xx.mp4");
TCHAR cmdlineie[] = TEXT("C:\\Program Files (x86)\\Internet Explorer\\iexplore -k http://www.baidu.com");
BOOL bRetvlc ,bRetie;
bRetvlc = CreateProcess (
NULL,
cmdlinevlc, //在Unicode版本中此参数不能为常量字符串,因为此参数会被修改
NULL,
NULL,
FALSE,
CREATE_NEW_CONSOLE,
NULL,
NULL,
&svlc,
&pvlc);
if(bRetvlc){
Sleep(4000);
//打开IE
bRetie = CreateProcess (
NULL,
cmdlineie, //在Unicode版本中此参数不能为常量字符串,因为此参数会被修改
NULL,
NULL,
FALSE,
CREATE_NEW_CONSOLE,
NULL,
NULL,
&sie,
&pie);
//ShellExecute(NULL, "open", "http://www.baidu.com", NULL, NULL, SW_MAXIMIZE );
}
wndhwnd = CreateWindow("WinMain", "MWin", WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL);
ShowWindow(wndhwnd, SW_HIDE);
UpdateWindow(wndhwnd);
//Sleep(1000);
ExitProcess(0);
while(GetMessage(&msg, NULL, 0, 0)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
LRESULT CALLBACK WindoWProc(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lparam
){
HDC hdc, hDC;
PAINTSTRUCT ps;
char szchar[20];
static int i = 0;
switch(uMsg){
case WM_PAINT:
//窗口重绘信息,窗口加载和重绘的时候产生该消息
hdc = BeginPaint(hwnd, &ps);
TextOut(hdc, 0, 0, "窗口加载完成", strlen("窗口加载完成"));
//往窗口输出文本
//MessageBox(hwnd, "Hello", "HI", MB_OK);
EndPaint(hwnd, &ps);
break;
case WM_CHAR:
//处理键盘按键消息
//sprintf(szchar, "char is %c", wParam);
MessageBox(hwnd, szchar, "提示", MB_OK);
break;
case WM_LBUTTONDOWN:
//处理鼠标左键按下消息
MessageBox(hwnd, "mouse left click", "提示", MB_OK);
hDC = GetDC(hwnd);
TextOut(hDC, 0, 50, "鼠标事件处理时显示文字", strlen("鼠标事件处理时显示文字"));
ReleaseDC(hwnd, hDC);
break;
case WM_CLOSE:
//窗口关闭消息
if(IDYES == MessageBox(hwnd, "确定要关闭吗?", "提示", MB_YESNO))
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, uMsg, wParam, lparam);
//使用缺省值来调用窗口过程函数
}
return 0;
}