C/C++ 使用 API 函数 ShellExecuteEx 实现文件打印
本文章主要介绍使用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完成打印文件了。
- 创建一个命名为PrintByShellExecuteEx的MFC项目
- 界面设计
对话框窗口设计如下图所示
- 编辑控件,添加变量。
打印机名称m_PrintName,打印机路径m_Path - 在源文件头部添加上依赖库
#include "winspool.h"
#include <io.h>
#include "shlwapi.h"
- 编辑打印按钮
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 实现文件打印相关推荐
- API函数ShellExecute与ShellExecuteEx用法
ShellExecute: 1.函数功能: 你可以给它任何文件的名字,它都能识别出来并打开它. 2.函数原型: HINSTANCE ShellExecute( HWND hwnd, LPCTSTR l ...
- Windows API函数大全
1. API之网络函数 WNetAddConnection 创建同一个网络资源的永久性连接 WNetAddConnection2 创建同一个网络资源的连接 WNetAddConnection3 创建同 ...
- [转]会自动消失的对话框API函数:MessageBoxTimeout
//以下两个函数由user32.dll导出,只是没有微软官方文档记载,大家在cpp中包含了以下部分,就可以调用MessageBoxTimeout了. extern "C"{int ...
- 管理输入光标的 WIN32 API 函数
下面的 API 函数是用来管理输入光标的 API 函数,下面是在使用C#时声明的这些函数: /**//// <summary> /// 参数说明: /// hwnd : ...
- Delphi 常用API 函数(好多都没见过)
2019独角兽企业重金招聘Python工程师标准>>> AdjustWindowRect 给定一种窗口样式,计算获得目标客户区矩形所需的窗口大小 AnyPopup 判断屏幕上是否存在 ...
- 用Debug函数实现API函数的跟踪
用Debug函数实现API函数的跟踪 如果我们能自己编写一个类似调试器的功能,这个调试器需要实现我们对于跟踪监视工具的要求,即自动记录输入输出参数,自动让目标进程继续运行.下面我们就来介绍在不知道函数 ...
- C#调用Win32 的API函数--User32.dll
Win32的API函数是微软自己的东西,可以直接在C#中直接调用,在做WinForm时还是很有帮助的.有时候我们之直接调用Win32 的API,可以很高效的实现想要的效果. using System; ...
- C#通过WMI的wind32 的API函数实现msinfo32的本地和远程计算机的系统摘要信息查看功能...
最近做一个项目碰到要实现查看本地和远程计算机的摘要信息,采用命令行msinfo32可以很快查看到,如下图: 需要在用C#来实现类似信息查看.尤其远程计算机的..因此通过MSDN查询到.win32的AP ...
- 使用MLX90640自制红外热像仪(二):API函数的使用
前面一篇文章介绍了MLX90640的相关信息和API库的移植,接下来介绍一下API库中的函数,和使用方法. 首先给出API函数的调用顺序,再对每个用到的API函数做说明: #define FP ...
最新文章
- 第一次来,试发一帖!--ASP.NET 2.0 中的SqlCacheDependency特性
- MATLAB如何保存仿真高清图片(matlab)
- 阶段1 语言基础+高级_1-3-Java语言高级_1-常用API_1_第8节 Math类_18_数学工具类Math...
- 【Lucene】Lucene的使用和优化
- 单步调试理解webpack里通过require加载nodejs原生模块实现原理
- JS判断字符串变量是否含有某个字串的方法
- 计算机统考分数短信显示合格,今年起全省八年级网考信息技术 成绩不合格不能升高中...
- jquery html5 file 上传图片显示图片(上传图片预览)
- 【渗透测试实战】具体案例——讲讲SQL注入攻击是怎么回事?
- Python 分析 35 年的考研英语真题词汇,解读孤独的考研大军!
- android4.0root,最强大一键ROOT 轻松搞定安卓4.0
- 苹果IPSW文件提取软件
- 海天MA3200Ⅱ/1700卧式_节能注塑机
- 加强化工企业危化品管理的几点建议
- 写论文一定要会-------中英文参考文献的导出方法
- 手机扫描条形码二维码原理和实现等网上资料整理
- 佛寺风飘飘,塔上幡摇摇
- k8s UAT改环境
- Android 7.0 增加以太网设置DHCP和静态IP
- 2020年Android面试题整理
热门文章
- unity 3D打飞碟游戏,虚拟现实大作业
- MATLAB中将数据写入TXT文本文档中
- QT环境中 _TCHAR 和 QString 互相转换
- lego-LOAM跑自己的数据包无法显示全局点云地图解决(速腾聚创RS-LiDAR-16 雷达 )---SLAM不学无术小问题
- 解决cuda error:device-side assert triggered
- android打开视频噔_Android中三种视频的播放
- 处理得怎么样填空词语_二年级语文下册第六单元综合复习题
- 我明白,我的爱,只是一种无限期的等待,也不会有你的归来
- TD算法超详细解释,一篇文章看透彻!
- minicom指令_linux minicom 自动化对串口下命令