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

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

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

  1. //Variable declarations
  2. PRINTDLGA *tmpprintdlg = 0;
  3. char *tmpstr = 0;
  4. char *tmpstr2 = 0;
  5. char *tmpstr3 = 0;
  6. DEVNAMES *tmpdevnames = 0;
  7. DEVMODEA *tmpdevmode = 0;
  8. HDC tmphdc = 0;
  9. int ret = 0;
  10. int ret2 = 0;
  11. //Show the print dialog.
  12. ret = PrntShowPrintDialog(GLB_HWndMainDialog,
  13. &tmpprintdlg);
  14. if((ret != TSUCCESS) && \
  15. (ret != FALSE)){
  16. //Get the error string.
  17. PrntGetErrorString(&tmpstr);
  18. MessageBox(NULL,
  19. tmpstr,
  20. "Error",
  21. MB_OK);
  22. return FALSE;
  23. } //EndIf
  24. //Check if the user cancelled the print.
  25. if(ret == FALSE){
  26. //Returns
  27. return FALSE;
  28. } //EndIf
  29. //Get the selected printer.
  30. tmpdevnames = (DEVNAMES*)GlobalLock(tmpprintdlg->hDevNames);
  31. //Use the members in the device names pointer
  32. //to get information about the printer.
  33. //Set tmpn to zero.
  34. tmpn = 0;
  35. //Get the name of the printer driver.
  36. tmpn = tmpdevnames->wDriverOffset;
  37. tmpstr = (char*)(((char*)tmpdevnames) + tmpn);
  38. //Get the name of the printer.
  39. tmpn = tmpdevnames->wDeviceOffset;
  40. tmpstr2 = (char*)(((char*)tmpdevnames) + tmpn);
  41. //Get the name of the printer port.
  42. tmpn = tmpdevnames->wOutputOffset;
  43. tmpstr3 = (char*)(((char*)tmpdevnames) + tmpn);
  44. //Get the device mode for the printer.
  45. if(tmpprintdlg->hDevMode != NULL){
  46. tmpdevmode = (DEVMODEA*)GlobalLock(tmpprintdlg->hDevMode);
  47. } //EndIf
  48. //Create a device context for the user selected
  49. //printer.
  50. tmphdc = CreateDCA(tmpstr,
  51. tmpstr2,
  52. tmpstr3,
  53. tmpdevmode);
  54. if(tmphdc == NULL){
  55. //Get the last Win32 error.
  56. ret2 = GetLastError();
  57. //Create an error string.
  58. PrntCreateErrorString(ret2, \
  59. TCREATEFAILED, \
  60. "CreateDC", \
  61. &tmpstr);
  62. //Show the error string.
  63. MessageBox(NULL, \
  64. tmpstr, \
  65. "Error", \
  66. MB_OK);
  67. //Returns
  68. return FALSE;
  69. }
  70. //Unlock the tmpdevnames memory.
  71. GlobalUnlock(tmpdevnames);
  72. //Unlock the tmpdevmode memory.
  73. if(tmpdevmode != NULL){
  74. GlobalUnlock(tmpdevmode);
  75. } //EndIf

下面是PrntShowPrintDialog函数的代码:

  1. TRESULT PrntShowPrintDialog(_IN HWND inobj, \
  2. _INOUT PRINTDLGA **outobj){
  3. //Variable declarations
  4. PRINTDLGA *tmpprintdlg = 0;
  5. HWND tmphndwindow = 0;
  6. HINSTANCE tmphinst = 0;
  7. int ret = 0;
  8. int ret2 = 0;
  9. //Allocate memory to one PRINTDLGA object.
  10. tmpprintdlg = (PRINTDLGA*)calloc(1024, sizeof(char));
  11. if(tmpprintdlg == NULL){
  12. //Create an error string and set the
  13. //global static variable.
  14. PrntCreateErrorString(0,
  15. TMEMALLOCFAILED,
  16. "calloc",
  17. NULL);
  18. //Returns
  19. return TMEMALLOCFAILED;
  20. } //EndIf
  21. //Set some members in the PRINTDLGA object.
  22. tmpprintdlg->lStructSize = sizeof(PRINTDLGA);
  23. tmpprintdlg->hwndOwner = tmphndwindow;
  24. tmpprintdlg->hDevMode = NULL;
  25. tmpprintdlg->hDevNames = NULL;
  26. tmpprintdlg->hDC = NULL;
  27. tmpprintdlg->Flags = PD_ALLPAGES | \
  28. PD_ENABLEPRINTHOOK | \
  29. PD_ENABLESETUPHOOK | \
  30. PD_NONETWORKBUTTON | \
  31. PD_NOSELECTION | \
  32. PD_COLLATE | \
  33. PD_RETURNDC;
  34. tmpprintdlg->nMinPage = 0;
  35. tmpprintdlg->nMaxPage = 200;
  36. tmpprintdlg->nCopies = 1;
  37. tmpprintdlg->hInstance = tmphinst;
  38. tmpprintdlg->lCustData = NULL;
  39. tmpprintdlg->lpfnPrintHook = PrntDlgPrintProc;
  40. tmpprintdlg->lpfnSetupHook = PrntDlgSetupProc;
  41. tmpprintdlg->lpPrintTemplateName = NULL;
  42. tmpprintdlg->lpSetupTemplateName = NULL;
  43. tmpprintdlg->hPrintTemplate = NULL;
  44. tmpprintdlg->hSetupTemplate = NULL;
  45. //Show the print dialog box. This
  46. //is a modal dialog.
  47. ret = PrintDlg(tmpprintdlg);
  48. //Returns
  49. *outobj = tmpprintdlg;
  50. if(ret == 0){
  51. return FALSE;
  52. }else{
  53. return TSUCCESS;
  54. } //EndIf
  55. } //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/

相关问题