Sunday, September 23, 2012

【C++转载好料】Visual C++启动另一个可执行程序的方案


此文章不是我写的,是转载的,为了让大家能更好地了解,我做了点改正+讲解,并已经测试,在VS2005下是没问题的,原文在:http://blog.csdn.net/weaver2007/article/details/5700312

请记得include一个头文件:windows.h

有三个API函数可以运行可执行文件:
  • WinExec(超简单易用)
  • ShellExecute(较多选项,可以获得运行的程序的hWnd(句柄))
  • CreateProcess(因为使用复杂,比较少用)
【WinExec和ShellExecute比一比】

WinExec
- 短名运行:在%path%变量里面的程序
- 返回的是 启动是否成功值(uint)
- 无法设置运行目录
- 只能打开exe/com等可执行的程序,如果是txt文件,是不会打开的
- 如果你的程序是 命令行界面的,要执行的程序也是 命令行界面的话,运行的程序会在同一个窗体

ShellExecute
- 短名运行:在%path%变量里面的程序 + 某些特别程序(比如winword.exe)
- 返回的是 被执行的程序 的实例句柄(hWnd)
- 可以设置运行目录(Working Directory)
- 对于有关联的文件/协议,比如a.txt和http://www.google.com/,是可以打开的
- 运行的程序会在新的窗体,不管是不是命令行界面

【WinExec篇】

UINT WINAPI WinExec(
  _In_  LPCSTR lpCmdLine,
  _In_  UINT uCmdShow
);
  • lpCmdLine:要执行的程序
  • uCmdShow:指明运行程序的窗体要怎样的,请参考 窗体显示方式常量
返回的东西:运行是否成功值
例子:WinExec(’Notepad.exe Readme.txt’, SW_SHOW)

【ShellExecute篇】
HINSTANCE ShellExecute(
  _In_opt_  HWND hwnd,
  _In_opt_  LPCTSTR lpOperation,
  _In_      LPCTSTR lpFile,
  _In_opt_  LPCTSTR lpParameters,
  _In_opt_  LPCTSTR lpDirectory,
  _In_      INT nShowCmd
);
● hWnd:指定父窗口句柄。当函数调用过程出现错误时,它将作为Windows消息窗口的父窗口。例如,可以将其设置为应用程序主窗口句柄,也可以将其设置为桌面窗口句柄(用GetDesktopWindow函数获得)。
  ● Operation:指定要进行的操作。其中“open”操作表示执行由FileName参数指定的程序,或打开由FileName参数指定的文件或文件夹;“print”操作表示打印由FileName参数指定的文件;“explore”操作表示浏览由FileName参数指定的文件夹。当参数设为NULL时,表示执行默认操作“open”。
  ● FileName:指定要打开的文件名、要执行的程序文件名或要浏览的文件夹名。
  ● Parameters:指定命令行参数,可设置为NULL。
  ● Directory:指定运行目录,可设置为NULL。
  ● ShowCmd:指定 窗体显示方式,请参考 窗体显示常量
  若ShellExecute函数调用成功,则返回值为被执行程序的实例句柄。若返回值小于32,则表示出现错误。  

【窗体显示方式常量】
SW_HIDE 隐藏窗口,活动状态给令一个窗口
SW_MINIMIZE 最小化窗口,活动状态给令一个窗口
SW_RESTORE 用原来的大小和位置显示一个窗口,同时令其进入活动状态
SW_SHOW 用当前的大小和位置显示一个窗口,同时令其进入活动状态
SW_SHOWMAXIMIZED 最大化窗口,并将其激活
SW_SHOWMINIMIZED 最小化窗口,并将其激活
SW_SHOWMINNOACTIVE 最小化一个窗口,同时不改变活动窗口
SW_SHOWNA 用当前的大小和位置显示一个窗口,不改变活动窗口
SW_SHOWNOACTIVATE 用最近的大小和位置显示一个窗口,同时不改变活动窗口
SW_SHOWNORMAL 与SW_RESTORE相同

【CreateProcess篇】
注意:这货功能非常多,但会令人吐血(对于我这样的新手来说),如非必要强烈建议避免用这个


BOOL WINAPI CreateProcess(
  _In_opt_     LPCTSTR lpApplicationName,
  _Inout_opt_  LPTSTR lpCommandLine,
  _In_opt_     LPSECURITY_ATTRIBUTES lpProcessAttributes,
  _In_opt_     LPSECURITY_ATTRIBUTES lpThreadAttributes,
  _In_         BOOL bInheritHandles,
  _In_         DWORD dwCreationFlags,
  _In_opt_     LPVOID lpEnvironment,
  _In_opt_     LPCTSTR lpCurrentDirectory,
  _In_         LPSTARTUPINFO lpStartupInfo,
  _Out_        LPPROCESS_INFORMATION lpProcessInformation
);
  • lpApplicationName 和 lpCommandLine :这个有点乱,与其说多多,不如直接这样看待:<lpApplicationName> <lpCommandLine>
比如一个运行命令:C:\Windows\System32\notepad.exe hello.txt,你可以这样:
lpApplicationName = "C:\Windows\System32\notepad.exe"
lpCommandLine = "hello.txt"
或者这样:
lpApplicationName = NULL
lpCommandLine = "C:\Windows\System32\notepad.exe hello.txt"
但是你不能这样:
lpApplicationName = "C:\Windows\System32\notepad.exe hello.txt"
lpCommandLine = NULL
如果不要参数,你就可以这样玩:
lpApplicationName = "C:\Windows\System32\notepad.exe"
lpCommandLine = NULL
或者:
lpApplicationName = NULL
lpCommandLine = "C:\Windows\System32\notepad.exe"
  • lpProcessAttributes 和  lpThreadAttributes:真心不清楚什么来的,请设置为NULL
  • bInheritHandles:决定子进程对父进程继承性,一般设为FALSE。
  • dwCreationFlags:用于标识标志,以便用于规定如何来创建新进程。点击查看相关常量
  • lpEnvironment:指向包含新进程将要使用的环境字符串的内存块,可以设置为NULL
  • lpCurrentDirectory:指定运行目录,可以设置为NULL
  • lpStartupInfo:这货很乱,我消化不来,所以请看后面的example吧……
凌晨1点了,我先睡觉了,有空再续……

Saturday, September 1, 2012

【其他】Windows的“沙漏”,似乎快要失去应有的意义了……

据大家所知,“沙漏”(Vista以下的系统),或者是“光圈”(Vista以上的系统),都是在忙碌时出现的。当这类鼠标出现时,我们都被教导,不要继续操作,不要点击任何东西,知道那熟悉的“箭头”鼠标出来为止。

可是,几年来,我发现,这个所谓的“沙漏”鼠标,似乎出现的几率越来越少,可是我们每次要完成某个任务时,都是要等待一段时间,比如你启动火狐浏览器,如果是第一次启动,恐怕要5秒以上(如果你用的还是悲催的5400转的机械硬盘,大多数现今的手提电脑依然是这个硬盘,速度可能还会更慢)。可是在这个期间,不见得你的鼠标会变成“忙碌”的鼠标,这个导致了某些没有经验的人再次点击,再点击,再点击,结果等下突然一下子出现一大堆的火狐浏览器窗口……

扪心自问,现在大家通常看电脑是否忙碌,都是看哪里的?要么是任务管理器,要么是硬盘指示灯,由于现在电脑的CPU和内存都很强了,比较悲剧的是硬盘罢了,所以一般启动着东西时,硬盘指示灯就是我们喜欢盯着的地方(我还把会一闪一闪的它当做程序的splash screen呢,呵呵),可是鼠标?它可不理你的硬盘有多忙,总之没有收到提示,就是一直“箭头”,或者一下“箭头”一下“沙漏伴箭头”,看起来好像不忙似的,其实你的硬盘正忙得手忙脚乱……

现在的鼠标,还有什么意义呢?它除了能让我们精确地点击某一个地方,可以帮我们选取东西,就没什么其他用处了…… Win7时代的“沙漏”,基本是一个摆设……