C语言 如何使用PrintDlg获取选定的打印机?

rsl1atfo  于 2023-10-16  发布在  其他
关注(0)|答案(2)|浏览(118)

我正在测试一个使用Win32 API打印发票的动态链接库。到目前为止,发票的绘制是正确的,但是PrintDlg函数只返回关于默认打印机的信息。
PrintDlg函数是否可以返回有关所选打印机的信息?
下面是代码的最小化版本;

//Variable declarations
   PRINTDLGA *tmpprintdlg = 0;
   char *tmpstr = 0;
   char *tmpstr2 = 0;
   char *tmpstr3 = 0;
   DEVNAMES *tmpdevnames = 0;
   DEVMODEA *tmpdevmode = 0;
   HDC tmphdc = 0;
   int ret = 0;
   int ret2 = 0;

   //Show the print dialog.
   ret = PrntShowPrintDialog(GLB_HWndMainDialog, 
                             &tmpprintdlg);
   if((ret != TSUCCESS) && \
      (ret != FALSE)){
    //Get the error string.
    PrntGetErrorString(&tmpstr);
    MessageBox(NULL, 
               tmpstr, 
               "Error", 
               MB_OK);
    return FALSE;
   } //EndIf

   //Check if the user cancelled the print.
   if(ret == FALSE){
 
    //Returns
    return FALSE;

   } //EndIf

   //Get the selected printer.
   tmpdevnames = (DEVNAMES*)GlobalLock(tmpprintdlg->hDevNames);

   //Use the members in the device names pointer
   //to get information about the printer.

   //Set tmpn to zero.
   tmpn = 0;

   //Get the name of the printer driver.
   tmpn = tmpdevnames->wDriverOffset;
   tmpstr = (char*)(((char*)tmpdevnames) + tmpn);
 
   //Get the name of the printer.
   tmpn = tmpdevnames->wDeviceOffset;
   tmpstr2 = (char*)(((char*)tmpdevnames) + tmpn);

   //Get the name of the printer port.
   tmpn = tmpdevnames->wOutputOffset;
   tmpstr3 = (char*)(((char*)tmpdevnames) + tmpn);

   //Get the device mode for the printer.
   if(tmpprintdlg->hDevMode != NULL){
    tmpdevmode = (DEVMODEA*)GlobalLock(tmpprintdlg->hDevMode);
   } //EndIf 

   //Create a device context for the user selected
   //printer.
   tmphdc = CreateDCA(tmpstr, 
                      tmpstr2, 
                      tmpstr3, 
                      tmpdevmode);
   if(tmphdc == NULL){
    //Get the last Win32 error.
    ret2 = GetLastError();
    //Create an error string.
    PrntCreateErrorString(ret2, \
              TCREATEFAILED, \
              "CreateDC", \
              &tmpstr);
    //Show the error string.
    MessageBox(NULL, \
           tmpstr, \
           "Error", \
           MB_OK);
    //Returns
    return FALSE;
   }

   //Unlock the tmpdevnames memory.
   GlobalUnlock(tmpdevnames);

   //Unlock the tmpdevmode memory.
   if(tmpdevmode != NULL){
    GlobalUnlock(tmpdevmode);
   } //EndIf

下面是PrntShowPrintDialog函数的代码:

TRESULT PrntShowPrintDialog(_IN HWND inobj, \
                            _INOUT PRINTDLGA **outobj){

 //Variable declarations
 PRINTDLGA *tmpprintdlg = 0;
 HWND tmphndwindow = 0;
 HINSTANCE tmphinst = 0;
 int ret = 0;
 int ret2 = 0;

 //Allocate memory to one PRINTDLGA object.
 tmpprintdlg = (PRINTDLGA*)calloc(1024, sizeof(char));
 if(tmpprintdlg == NULL){
  //Create an error string and set the
  //global static variable.
  PrntCreateErrorString(0, 
                        TMEMALLOCFAILED, 
                        "calloc", 
                        NULL);
  //Returns
  return TMEMALLOCFAILED;
 } //EndIf

 //Set some members in the PRINTDLGA object.
 tmpprintdlg->lStructSize = sizeof(PRINTDLGA);
 tmpprintdlg->hwndOwner = tmphndwindow;
 tmpprintdlg->hDevMode = NULL;
 tmpprintdlg->hDevNames = NULL;
 tmpprintdlg->hDC = NULL;
 tmpprintdlg->Flags = PD_ALLPAGES | \
              PD_ENABLEPRINTHOOK | \
              PD_ENABLESETUPHOOK | \
              PD_NONETWORKBUTTON | \
              PD_NOSELECTION | \
              PD_COLLATE | \
              PD_RETURNDC;
 tmpprintdlg->nMinPage = 0;
 tmpprintdlg->nMaxPage = 200;
 tmpprintdlg->nCopies = 1;
 tmpprintdlg->hInstance = tmphinst;
 tmpprintdlg->lCustData = NULL;
 tmpprintdlg->lpfnPrintHook = PrntDlgPrintProc;
 tmpprintdlg->lpfnSetupHook = PrntDlgSetupProc;
 tmpprintdlg->lpPrintTemplateName = NULL;
 tmpprintdlg->lpSetupTemplateName = NULL;
 tmpprintdlg->hPrintTemplate = NULL;
 tmpprintdlg->hSetupTemplate = NULL;

 //Show the print dialog box. This
 //is a modal dialog.
 ret = PrintDlg(tmpprintdlg);

 //Returns
 *outobj = tmpprintdlg;
 if(ret == 0){
  return FALSE;
 }else{
  return TSUCCESS;
 } //EndIf

} //End PrntShowPrintDialog

钩子子程的两个回调函数都是虚函数,只是返回TSUCCESS
这里有一些屏幕截图之前和之后的选择。

在选择之前

选择后
请注意,选择后信息不会更新。

mv1qrgav

mv1qrgav1#

您在调用PrintDlg时已经请求了DC。
使用它。参见PRINTDLGAPD_RETURNDC和成员hDC的文档

l2osamch

l2osamch2#

问题已解决。我必须从PRINTDLGA对象中删除PD_ENABLEPRINTHOOK和PD_ENABLESETUPHOOK标志,并将lpfnPrintHook和lpfnSetupHook成员都设置为NULL。通过这样做,出现了一个更现代的打印对话框,其中有一个打印预览。要恢复到旧版打印对话框,我必须向系统注册表添加一个值。更多信息请访问https://www.winhelponline.com/blog/restore-legacy-print-dialog-windows-11/

相关问题