win32打印问题,空白文档可以打印,打印有文字的文档就异常退出,坑爹,,求教
UINT_PTR CALLBACK PrintHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam,LPARAM lParam) {
switch (uiMsg)
{
case WM_INITDIALOG:
pd.hDevMode=pd.hDevMode;
pd.hDevNames=pd.hDevNames;
return TRUE;
default:
return FALSE; //好像是这个缺省消息的问题,,指教指教
}
return TRUE;
}
BOOL PrintDraw(HWND hwnd)
{
char *strDocName=NULL;
char *str1=NULL;
long TextLen;
ZeroMemory(&pd,sizeof(pd));
pd.lStructSize=sizeof(pd);
pd.hwndOwner=hwnd;
pd.hDevMode=NULL;
pd.hDevNames=NULL;
pd.Flags=PD_USEDEVMODECOPIESANDCOLLATE | PD_RETURNDC|PD_ENABLEPRINTHOOK;
pd.lpfnPrintHook=PrintHookProc;
pd.nCopies=1;
pd.nFromPage=1;
pd.nToPage=0xFFFF;
pd.nMinPage=1;
pd.nMaxPage=0xFFFF;
hwndEdit=GetDlgItem(hwnd,ID_EDIT);
TextLen= SendMessage(hwndEdit,WM_GETTEXTLENGTH,0,0);
str1=(char*)calloc(TextLen+1,sizeof(char));
SendMessage(hwndEdit,WM_GETTEXT,TextLen+1,(LPARAM)str1);
if (PrintDlg(&pd)==TRUE)
{
//MessageBox(hwnd,(LPCWSTR)str1,TEXT(""),NULL);
char *strPrint;
int prtwd,prthg,prtwdmm,prthgmm;
double xr, yr;
RECT rect,rectTemp;
//定义一个打印作业
//打印有文字的文档每次执行到这里程序都自动关闭
static DOCINFO di={sizeof(DOCINFO),(LPCWSTR)strDocName,NULL}; //貌似这里也有问题。。。不知怎么弄
if(StartDoc(pd.hDC,&di)>0) //开始执行一个打印作业
{
HFONT hFont;
LOGFONT mylf;
mylf=logfont;
strPrint=(char*)calloc(strlen(str1)+1,sizeof(char));//注意要加1,因为最后有一个'\0'
strcpy(strPrint,str1);
prtwd=GetDeviceCaps(pd.hDC,HORZRES);
prthg=GetDeviceCaps(pd.hDC,VERTRES);
prtwdmm = GetDeviceCaps(pd.hDC,HORZSIZE);
prthgmm = GetDeviceCaps(pd.hDC,VERTSIZE);
xr = (double)prtwd/(double)prtwdmm;
yr = (double)prthg/(double)prthgmm;
//放大字体,不然打印出来太小
//为什么这样写?47.32怎么来的?实践来的,如果发现不好,就试试改改这个数。
mylf.lfHeight=logfont.lfHeight*(int)(7/(47.32/(xr+yr))+0.5);
hFont=CreateFontIndirect(&mylf);
SelectObject(pd.hDC,hFont);
SetWindowOrgEx(pd.hDC,0,0,NULL);
//SetTextCharacterExtra(pd.hDC,0);//设置字间距
rect.left=(long)(psd.rtMargin.left*xr/100);
rect.right=(long)(prtwd-psd.rtMargin.right*xr/100);
rect.top=(long)(psd.rtMargin.top*yr/100);
rect.bottom=(long)(prthg-psd.rtMargin.bottom*yr/100);
////////////////////////////
HDC hdcMem;
hdcMem = CreateCompatibleDC(pd.hDC);
/////////////////////////////////
ULONG i,j,PageNum,TextLen,PageEndPos[10000],PosA,PosB,Pos,StartPos;
int StepLen;
char *strCur;
TextLen=strlen(strPrint);
for(i=0;i<10000;i++)
PageEndPos[i]=0;
if(TextLen==0)
PageNum=1;
else
{
PageNum=0;
StepLen=4096;
StartPos=0;
i=0;
i=(i+StepLen>TextLen-1)?(TextLen-1):(i+StepLen);
PosA=StartPos;
PosB=i;
Pos=PosB;
for(;;)
{
strCur=(char *)calloc(Pos-StartPos+1+1,sizeof(char));
for(j=0;j<Pos-StartPos+1;j++)
strCur[j]=strPrint[StartPos+j];
strCur[j]='\0';
rectTemp=rect;
DrawText(pd.hDC,(LPCWSTR)strCur,strlen(strCur),&rectTemp,DT_LEFT|DT_EXPANDTABS|DT_NOPREFIX|DT_EDITCONTROL|DT_WORDBREAK|DT_EXTERNALLEADING|DT_CALCRECT);//DT_CALCRECT计算实际用到的矩形
free(strCur);
if(Pos==i && PosB==i && rectTemp.bottom<=rect.bottom)
{
if(i==TextLen-1)
{
PageEndPos[++PageNum]=TextLen-1;
break;
}
else
{
i=(i+StepLen>TextLen-1)?(TextLen-1):(i+StepLen);
Pos=PosB=i;
}
}
else
{
if(rectTemp.bottom==rect.bottom)
{
PageEndPos[++PageNum]=Pos;
if(Pos>=TextLen-1)
break;
StartPos=Pos+1;
i=(i+StepLen>TextLen-1)?(TextLen-1):(i+StepLen);
PosA=StartPos;
PosB=i;
Pos=PosB;
}
else
{
if(rectTemp.bottom<rect.bottom)
{
PosA=Pos+1;
Pos=(PosA+PosB)/2;
}
else
{
PosB=Pos-1;
Pos=(PosA+PosB)/2;
}
}
if(PosA>PosB)
{
PageEndPos[++PageNum]=Pos;
if(Pos>=TextLen-1)
break;
StartPos=Pos+1;
i=(i+StepLen>TextLen-1)?(TextLen-1):(i+StepLen);
PosA=StartPos;
PosB=i;
Pos=PosB;
}
}
}
}
////////////////////////////
DeleteDC(hdcMem);
////////////////////////////
for(j=1;j<=PageNum;j++)
{
int k;
if(j==1)
k=-1;
else
k=PageEndPos[j-1];
strCur=(char *)calloc(PageEndPos[j]-k+1,sizeof(char));
if(TextLen>0)
{
for(i=0;i<PageEndPos[j]-k;i++)
strCur[i]=strPrint[k+i+1];
strCur[i]='\0';
}
else
{
strCur[0]='\0';
}
StartPage(pd.hDC); //打印机走纸,开始打印
SaveDC(pd.hDC); //保存打印机设备句柄
// 输出一行文字
//TextOut(pd.hDC,1,1,strPrint,strlen(strPrint));
// 输出一条直线
//MoveToEx(pd.hDC,20,20,NULL);
//LineTo(pd.hDC,120,120);
//DT_EXPANDTABS不能少,不然不能输出TAB
//DT_EDITCONTROL | DT_WORDBREAK 使中英文都能正确自动到右边界就换行
//DT_NOPREFIX让&后的字符不加下划线
DrawText(pd.hDC,(LPCWSTR)strCur,strlen(strCur),&rect,DT_LEFT|DT_EXPANDTABS|DT_NOPREFIX|DT_EDITCONTROL|DT_WORDBREAK|DT_EXTERNALLEADING);
free(strCur);
RestoreDC(pd.hDC,-1); //恢复打印机设备句柄
EndPage(pd.hDC); //打印机停纸,停止打
}
EndDoc(pd.hDC); //结束一个打印作业
free(strPrint);
DeleteObject(&hFont);
DeleteObject(&mylf);
//MessageBox(hWnd,"打印完毕!","提示",MB_ICONINFORMATION);
}
else
{
//下面这句本来可以不用,但看到微软自己的记事本会这样,我也来一个
MessageBox(hwnd,TEXT("句柄无效"),strWindowTitle,MB_ICONEXCLAMATION);
DeleteDC(pd.hDC);
return FALSE;
}
// 用API函数DeleteDC销毁一个打印机设备句柄
DeleteDC(pd.hDC);
return TRUE;
}
else
return FALSE;
free(str1);
}
[ 本帖最后由 zhonganyun0 于 2012-8-10 15:26 编辑 ]