我设法创建了一个基于GDI的位图文件打印机例程 . 它工作稳定,没有任何泄漏 . 唯一的缺点当然是它在假脱机程序tranfser期间冻结了UI . 解决方案是将打印例程移动到工作线程中 . 这是代码(错误检查已删除):
void __fastcall PRINT_THREAD::Execute()
{
while(!Terminated)
{
Synchronize(&TalkToOwningThread);
if(PrintFilePath!="") PrintImage(PrintFilePath);
Sleep(10);
}
}
void __fastcall PRINT_THREAD::PrintImage(WideString PrintFilePath)
{
HDC hDC;
DOCINFO di;
int w,h;
bool success=true;
TCHAR szString[32] = TEXT("Printed from a thread");
WideString PrinterName="FinePrint";
TBitmap *bmp = new TBitmap();
TPicture *pic = new TPicture();
hDC=CreateDC(TEXT("WINSPOOL"),PrinterName.c_bstr(),NULL,NULL);
w=GetDeviceCaps(hDC, HORZRES);
h=GetDeviceCaps(hDC, VERTRES);
SecureZeroMemory(&di,sizeof(DOCINFO));
di.cbSize = sizeof(DOCINFO);
di.lpszDocName = TEXT("Print Job");
StartDoc(hDC,&di);
StartPage(hDC);
try
{
pic->LoadFromFile(PrintFilePath);
bmp->Width=w; // set the bitmap dimensions to the printer dimensions
bmp->Height=h;
// fill the bitmap with 1:1 print content
bmp->Canvas->StretchDraw(TRect(0,0,w-1,h-1),pic->Graphic);
}
catch(...){success=false;}
if(success)
{
BitBlt(hDC,0,0,w,h, bmp->Canvas->Handle,0,0, SRCCOPY);
TextOut(hDC,0,100,szString,lstrlen(szString));
}
EndDoc(hDC);
if(hDC) DeleteDC(hDC);
delete pic;
delete bmp;
}
结果:
-
每次打印调用都通过打印机在页面上生成 - 好的
-
仅10页中的大约2页包含位图 - 不行
-
所有页面都包含测试行 - 确定
-
每次调用都会再添加一个GDI-ressource(任务管理器) - 不行
我已经尝试将CreateDC / DeleteDC函数移回主线程并将hDC转发到工作线程 - 结果相同 .
有没有想法让这种动物运转?
环境:C Builder 10.1 Berlin,Windows10,16GB
谢谢 .
1 回答
正如Remy所说,我添加了锁定/解锁对:
最后,动物像魅力一样运行 - 不再缺少图形,也没有更多的GDI泄漏 .