我设法创建了一个基于GDI的位图文件打印机例程。它工作稳定,没有任何泄漏。当然,唯一的缺点是在后台处理程序传输程序期间冻结了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;
}
结果:
我已经尝试过将CreateDC / DeleteDC函数移回主线程,并将hDC向下传递给工作线程-结果相同。
有什么想法让这种动物运转吗?
环境: C ++ Builder 10.1 Berlin,Windows10,16GB
谢谢。
答案 0 :(得分:1)
根据雷米(Remy)的建议,我添加了“锁定/解锁对”:
TBitmap *bmp = new TBitmap();
TPicture *pic = new TPicture();
bmp->Canvas->Lock();
----
----
EndPage(hDC);
EndDoc(hDC);
bmp->Canvas->Unlock();
if(hDC) DeleteDC(hDC);
delete pic;
delete bmp;
最后,动物的运行就像是一种符咒-没有更多的图形丢失和GDI泄漏。