我正在测试一个使用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
。
这里有一些屏幕截图之前和之后的选择。
在选择之前
选择后
请注意,选择后信息不会更新。
2条答案
按热度按时间mv1qrgav1#
您在调用
PrintDlg
时已经请求了DC。使用它。参见
PRINTDLGA
中PD_RETURNDC
和成员hDC
的文档l2osamch2#
问题已解决。我必须从PRINTDLGA对象中删除PD_ENABLEPRINTHOOK和PD_ENABLESETUPHOOK标志,并将lpfnPrintHook和lpfnSetupHook成员都设置为NULL。通过这样做,出现了一个更现代的打印对话框,其中有一个打印预览。要恢复到旧版打印对话框,我必须向系统注册表添加一个值。更多信息请访问https://www.winhelponline.com/blog/restore-legacy-print-dialog-windows-11/