本文章主要介绍使用ShellExecuteEx实现打印文件的功能。

函数原型:BOOL ShellExecuteExA(__inout SHELLEXECUTEINFOA *pExecInfo)
输入输出参数都是 SHELLEXECUTEINFO 结构体。
SHELLEXECUTEINFO定义:

typedef struct _SHELLEXECUTEINFO {DWORD     cbSize;//结构大小,sizeof(SHELLEXECUTEINFO)
ULONG     fMask;//指定结构成员的有效性
HWND      hwnd;//父窗口句柄或出错时显示错误父窗口的句柄,可以为 NULL
LPCTSTR   lpVerb;//指定该函数的执行动作
LPCTSTR   lpFile;//操作对象路径
LPCTSTR   lpParameters;//执行参数,可以为 ULL
LPCTSTR   lpDirectory;//工作目录,可以为 NULL
int       nShow;//显示方式
HINSTANCE hInstApp;//如果设置了 SEE_MASK_NOCLOSEPROCESS ,并且调用成功则该值大于32,调用失败者被设置错误值
LPVOID    lpIDList;//ITEMIDLIST结构的地址,存储成员的特别标识符,当fMask不包括SEE_MASK_IDLIST或SEE_MASK_INVOKEIDLIST时该项被忽略
LPCTSTR   lpClass;//指明文件类别的名字或GUID,当fMask不包括SEE_MASK_CLASSNAME时该项被忽略
HKEY      hkeyClass;//获得已在系统注册的文件类型的Handle,当fMask不包括SEE_MASK_HOTKEY时该项被忽略
DWORD     dwHotKey;//程序的热键关联,低位存储虚拟关键码(Key Code),高位存储修改标志位(HOTKEYF_),当fmask不包括SEE_MASK_HOTKEY时该项被忽略
union {HANDLE hIcon;//取得对应文件类型的图标的Handle,当fMask不包括SEE_MASK_ICON时该项被忽略HANDLE hMonitor;//将文档显示在显示器上的Handle,当fMask不包括SEE_MASK_HMONITOR时该项被忽略
} DUMMYUNIONNAME;
HANDLE    hProcess;//指向新启动的程序的句柄。若fMask不设为SEE_MASK_NOCLOSEPROCESS则该项值为NULL。//但若程序没有启动,即使fMask设为SEE_MASK_NOCLOSEPROCESS,该值也仍为NULL。//如果没有新创建进程,也会为空
} SHELLEXECUTEINFO, *LPSHELLEXECUTEINFO;

fMask 用于指定结构成员的内容和有效性,可为下列值的组合:

  • SEE_MASK_DEFAULT (0)默认
  • SEE_MASK_CLASSNAME 使用 lpClass 参数,如果SEE_MASK_CLASSKEY 也有效,则用后者
  • SEE_MASK_CLASSKEY 使用 hkeyClass 参数
  • SEE_MASK_IDLIST 使用 lpIDList 参数
  • SEE_MASK_INVOKEIDLIST 使用选定项目的快捷菜单 IContextMenu 接口处理程序
  • SEE_MASK_ICON 使用 hIcon 给出的菜单,不能与 SEE_MASK_HMONITOR 共用,Vista之后
  • SEE_MASK_HOTKEY 使用 dwHotKey 参数
  • SEE_MASK_NOCLOSEPROCESS
    如果执行之后需要返回进程句柄,或者等待执行完毕的话,则需要指定该参数,从结构参数意义可以看到 hProcess 和 hInstApp
    都依赖该选项
  • SEE_MASK_CONNECTNETDRV 验证共享并连接到驱动器号
  • SEE_MASK_NOASYNC 不等待操作完成,直接返回,会创建一个后台线程运行
  • SEE_MASK_FLAG_DDEWAIT 弃用,使用 SEE_MASK_NOASYNC
  • SEE_MASK_DOENVSUBST 环境变量会被展开
  • SEE_MASK_FLAG_NO_UI 出现错误,不显示错误消息框,比如不会弹出找不到文件之类的窗口,直接返回失败
  • SEE_MASK_UNICODE UNICODE 程序
  • SEE_MASK_NO_CONSOLE 继承父进程的控制台,而不是创建新的控制台,与 CREATE_NEW_CONSOLE 相反
  • SEE_MASK_ASYNCOK 执行在后台线程,调用立即返回
  • SEE_MASK_NOQUERYCLASSSTORE 弃用
  • SEE_MASK_HMONITOR 使用 hmonitor,不能与 SEE_MASK_ICON 共存
  • SEE_MASK_NOZONECHECKS 不执行区域检查
  • SEE_MASK_WAITFORINPUTIDLE 创建新进程后,等待进程变为空闲状态再返回,超时时间为1分钟
  • SEE_MASK_FLAG_LOG_USAGE 跟踪应用程序启动次数
  • SEE_MASK_FLAG_HINST_IS_SITE

lpVerb 参数与 ShellExecute 的 lpOperation 参数一致:

  • edit 用编辑器打开 lpFile 指定的文档,如果 lpFile 不是文档,则会失败
  • explore 浏览 lpFile 指定的文件夹
  • find 搜索 lpDirectory 指定的目录
  • open 打开 lpFile 文件,lpFile 可以是文件或文件夹
  • print 打印 lpFile,如果 lpFile 不是文档,则函数失败
  • properties 显示属性
  • runas 请求以管理员权限运行,比如以管理员权限运行某个exe
  • NULL 执行默认”open”动作

nShow 与 ShellExecute 的该参数一致:

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

如果设置了 SEE_MASK_NOCLOSEPROCESS ,调用成功则 hInstApp 返回大于32的值,调用失败会返回:

  • SE_ERR_FNF (2) 文件未找到
  • SE_ERR_PNF (3) 路径未找到
  • SE_ERR_ACCESSDENIED (5) 拒绝访问
  • SE_ERR_OOM (8) 内存不足
  • SE_ERR_DLLNOTFOUND (32) 动态库未找到
  • SE_ERR_SHARE (26) 无法共享打开的文件
  • SE_ERR_ASSOCINCOMPLETE (27) 文件关联信息不完整
  • SE_ERR_DDETIMEOUT (28) 操作超时
  • SE_ERR_DDEFAIL (29) 操作失败
  • SE_ERR_DDEBUSY (30) DDE 操作忙
  • SE_ERR_NOASSOC (31) 文件关联不可用

返回值:
函数执行成功,返回 TRUE ,否则返回 FALSE ,可使用 GetLastError 获取错误码。

  • ERROR_FILE_NOT_FOUND 文件不存在
  • ERROR_PATH_NOT_FOUND 路径不存在
  • ERROR_DDE_FAIL DDE(动态数据交换)失败
  • ERROR_NO_ASSOCIATION 未找到与指定文件拓展名关联的应用
  • ERROR_ACCESS_DENIED 拒绝访问
  • ERROR_DLL_NOT_FOUND 未找到dll
  • ERROR_CANCELLED 功能提示用户提供额外信息,但是用户取消请求。
  • ERROR_NOT_ENOUGH_MEMORY 内存不足
  • ERROR_SHARING_VIOLATION 发生共享冲突

以后介绍完了ShellExecuteEx的函数说明。现在就开始如何使用ShellExecuteEx完成打印文件了。

  1. 创建一个命名为PrintByShellExecuteEx的MFC项目
  2. 界面设计
    对话框窗口设计如下图所示
  3. 编辑控件,添加变量。
    打印机名称m_PrintName,打印机路径m_Path
  4. 在源文件头部添加上依赖库
#include "winspool.h"
#include <io.h>
#include "shlwapi.h"
  1. 编辑打印按钮
int nLen_FilePath = 0;
BOOL bRet = FALSE;
char szPrinter[256] = {0x00};
char PrintFilePath[MAX_PATH] = { 0x00 };m_PrintName.GetWindowText(szPrinter, sizeof(szPrinter));   //获取打印机名称
bRet = SetDefaultPrinter(szPrinter);                       //设置默认打印机
if (!bRet)
{MessageBox("设备默认打印机失败");return;
}m_Path.GetWindowText(PrintFilePath, sizeof(PrintFilePath));nLen_FilePath = strlen(PrintFilePath);
if ((strcmp(PrintFilePath + nLen_FilePath - 3, "pdf") != 0) && (strcmp(PrintFilePath + nLen_FilePath - 3, "PDF") != 0) &&(strcmp(PrintFilePath + nLen_FilePath - 3, "txt") != 0) && (strcmp(PrintFilePath + nLen_FilePath - 3, "TXT") != 0) &&(strcmp(PrintFilePath + nLen_FilePath - 3, "doc") != 0) && (strcmp(PrintFilePath + nLen_FilePath - 3, "DOC") != 0) &&(strcmp(PrintFilePath + nLen_FilePath - 3, "HTM") != 0) && (strcmp(PrintFilePath + nLen_FilePath - 3, "htm") != 0) &&(strcmp(PrintFilePath + nLen_FilePath - 3, "jpg") != 0) && (strcmp(PrintFilePath + nLen_FilePath - 3, "JPG") != 0) &&(strcmp(PrintFilePath + nLen_FilePath - 4, "docx") != 0) && (strcmp(PrintFilePath + nLen_FilePath - 4, "DOCX") != 0) &&(strcmp(PrintFilePath + nLen_FilePath - 4, "HTML") != 0) && (strcmp(PrintFilePath + nLen_FilePath - 4, "html") != 0))
{return ;
}if (_access(PrintFilePath, 0) != 0 && PathFileExists(PrintFilePath) != TRUE)
{return;
}
else
{if ((strcmp(PrintFilePath + nLen_FilePath - 4, "HTML") != 0) && (strcmp(PrintFilePath + nLen_FilePath - 4, "html") != 0) &&(strcmp(PrintFilePath + nLen_FilePath - 3, "HTM") != 0) && (strcmp(PrintFilePath + nLen_FilePath - 3, "htm") != 0)){SHELLEXECUTEINFO ShExecInfo = { 0 };ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;ShExecInfo.hwnd = NULL;ShExecInfo.lpVerb = TEXT("print");ShExecInfo.lpFile = TEXT(PrintFilePath);  //打印机文件路径ShExecInfo.lpParameters = TEXT("");ShExecInfo.lpDirectory = NULL;ShExecInfo.nShow = SW_HIDE;ShExecInfo.hInstApp = NULL;ShellExecuteEx(&ShExecInfo);WaitForSingleObject(ShExecInfo.hProcess, INFINITE);if ((int)ShExecInfo.hInstApp <= 32){MessageBox("打印失败");return;}}
}

这样就能完成使用 API 函数 ShellExecuteEx 实现打印文件的功能。
工程项目代码下载地址:

C/C++ 使用 API 函数 ShellExecuteEx 实现文件打印相关推荐

  1. API函数ShellExecute与ShellExecuteEx用法

    ShellExecute: 1.函数功能: 你可以给它任何文件的名字,它都能识别出来并打开它. 2.函数原型: HINSTANCE ShellExecute( HWND hwnd, LPCTSTR l ...

  2. Windows API函数大全

    1. API之网络函数 WNetAddConnection 创建同一个网络资源的永久性连接 WNetAddConnection2 创建同一个网络资源的连接 WNetAddConnection3 创建同 ...

  3. [转]会自动消失的对话框API函数:MessageBoxTimeout

    //以下两个函数由user32.dll导出,只是没有微软官方文档记载,大家在cpp中包含了以下部分,就可以调用MessageBoxTimeout了. extern "C"{int ...

  4. 管理输入光标的 WIN32 API 函数

    下面的 API 函数是用来管理输入光标的 API 函数,下面是在使用C#时声明的这些函数: /**//// <summary> /// 参数说明: ///        hwnd   :  ...

  5. Delphi 常用API 函数(好多都没见过)

    2019独角兽企业重金招聘Python工程师标准>>> AdjustWindowRect 给定一种窗口样式,计算获得目标客户区矩形所需的窗口大小 AnyPopup 判断屏幕上是否存在 ...

  6. 用Debug函数实现API函数的跟踪

    用Debug函数实现API函数的跟踪 如果我们能自己编写一个类似调试器的功能,这个调试器需要实现我们对于跟踪监视工具的要求,即自动记录输入输出参数,自动让目标进程继续运行.下面我们就来介绍在不知道函数 ...

  7. C#调用Win32 的API函数--User32.dll

    Win32的API函数是微软自己的东西,可以直接在C#中直接调用,在做WinForm时还是很有帮助的.有时候我们之直接调用Win32 的API,可以很高效的实现想要的效果. using System; ...

  8. C#通过WMI的wind32 的API函数实现msinfo32的本地和远程计算机的系统摘要信息查看功能...

    最近做一个项目碰到要实现查看本地和远程计算机的摘要信息,采用命令行msinfo32可以很快查看到,如下图: 需要在用C#来实现类似信息查看.尤其远程计算机的..因此通过MSDN查询到.win32的AP ...

  9. 使用MLX90640自制红外热像仪(二):API函数的使用

      前面一篇文章介绍了MLX90640的相关信息和API库的移植,接下来介绍一下API库中的函数,和使用方法.   首先给出API函数的调用顺序,再对每个用到的API函数做说明: #define FP ...

最新文章

  1. 第一次来,试发一帖!--ASP.NET 2.0 中的SqlCacheDependency特性
  2. MATLAB如何保存仿真高清图片(matlab)
  3. 阶段1 语言基础+高级_1-3-Java语言高级_1-常用API_1_第8节 Math类_18_数学工具类Math...
  4. 【Lucene】Lucene的使用和优化
  5. 单步调试理解webpack里通过require加载nodejs原生模块实现原理
  6. JS判断字符串变量是否含有某个字串的方法
  7. 计算机统考分数短信显示合格,今年起全省八年级网考信息技术 成绩不合格不能升高中...
  8. jquery html5 file 上传图片显示图片(上传图片预览)
  9. 【渗透测试实战】具体案例——讲讲SQL注入攻击是怎么回事?
  10. Python 分析 35 年的考研英语真题词汇,解读孤独的考研大军!
  11. android4.0root,最强大一键ROOT 轻松搞定安卓4.0
  12. 苹果IPSW文件提取软件
  13. 海天MA3200Ⅱ/1700卧式_节能注塑机
  14. 加强化工企业危化品管理的几点建议
  15. 写论文一定要会-------中英文参考文献的导出方法
  16. 手机扫描条形码二维码原理和实现等网上资料整理
  17. 佛寺风飘飘,塔上幡摇摇
  18. k8s UAT改环境
  19. Android 7.0 增加以太网设置DHCP和静态IP
  20. 2020年Android面试题整理

热门文章

  1. unity 3D打飞碟游戏,虚拟现实大作业
  2. MATLAB中将数据写入TXT文本文档中
  3. QT环境中 _TCHAR 和 QString 互相转换
  4. lego-LOAM跑自己的数据包无法显示全局点云地图解决(速腾聚创RS-LiDAR-16 雷达 )---SLAM不学无术小问题
  5. 解决cuda error:device-side assert triggered
  6. android打开视频噔_Android中三种视频的播放
  7. 处理得怎么样填空词语_二年级语文下册第六单元综合复习题
  8. 我明白,我的爱,只是一种无限期的等待,也不会有你的归来
  9. TD算法超详细解释,一篇文章看透彻!
  10. minicom指令_linux minicom 自动化对串口下命令