Qt环境Windows应用程序动态变更系统默认打印机

有些工作环境安装有多个打印机,针对不同需求进行各种输出。如果是用QPrinter进行打印控制,可以通过setPrinterName确定使用哪一个打印机,但如果程序使用了第三方功能进行打印输出,比如通过QAxObject调用系统的文字处理直接输出,就可能会遇到无法明确指定哪一个打印机的问题。这时就需要我们动态变更一下系统的默认打印机。
这里调用了两个windows的API函数,GetDefaultPrinterA和SetDefaultPrinterA。它们的Unicode版名称分别是GetDefaultPrinterW和SetDefaultPrinterW。
工作流程是:Get函数读取当前默认打印机,Set函数把默认打印机设定成任务所需的机器,输出完成之后再用Set函数恢复成之前的默认打印机。
根据机器软件环境,有两种方法来实现这个过程。
如果使用msvc,应该能使用静态库 winspool.lib,直接包含头文件winspool.h,正常使用这两个函数即可。但我项目使用了minGW,没有合适的静态库,只能另外从网上下载个winspool.dll,按动态库的方法来调用。
具体代码如下:

  QFile f;
  QString dllFile = QCoreApplication::applicationDirPath();    //读取项目运行路径
  dllFile.append("/winspool.dll");    //动态库文件名称
  QLibrary lib;    //
  typedef BOOL __stdcall (*pGetDefaultPrinter)(LPTSTR , LPDWORD);//定义两函数的原型
  typedef BOOL __stdcall (*pSetDefaultPrinter)(LPTSTR);//
  pGetDefaultPrinter getPrinterName = NULL;
  pSetDefaultPrinter setPrinterName = NULL;
  bool err = true;    //设置出错标志
    
  if(f.exists(dllFile) ){ //动态库文件是否存在
    lib.setFileName("winspool");    //准备装入动态库
    if(lib.load())        //动态库是装入成功
    {
      getPrinterName  = (pGetDefaultPrinter)lib.resolve("GetDefaultPrinterA");//
      setPrinterName = (pSetDefaultPrinter)lib.resolve("SetDefaultPrinterA") ;//
      if(getPrinterName != NULL && setPrinterName != NULL)    //是否成功获取函数入口
      {
        err = false;        //清除出错标志
      }
    }
  }
  if(err)
  {
    QMessageBox::information(NULL, "注意","winspool.dll 无效,将使用系统默认打印机输出!");
  }

  QSettings setIni("clin.ini", QSettings::IniFormat);
  QString newPrName = setIni.value("sk/printer").toString();    //读取当前任务需要使用的打印机名称
  QString curPrName;

  char prtName[256];  //Get函数需要的参数
  DWORD sz = 256;  //
  if(!getPrinterName((LPTSTR)prtName, (LPDWORD)&sz))        //读取系统当前默认打印机名称
  {
    QMessageBox::information(NULL, "注意","无法获取系统当前打印机名称!");
  }
  curPrName = QString(prtName);        //临时保存默认打印机

  if(!setPrinterName((LPTSTR)newPrName.toLatin1().data()))        //设置新的默认打印机
  {
    QMessageBox::information(NULL, "注意","无法修改系统当前打印机!");
  }
  //
  //进行打印输出
  //
   if(!setPrinterName((LPTSTR)curPrName.toLatin1().data()))  //恢复默认打印机
  {
    QMessageBox::information(NULL, "注意","系统当前打印机已变更,请手动改回!");
  }

posted @ 2024-02-16 13:25  桑底坡  阅读(107)  评论(0编辑  收藏  举报