BSOne.SFC/eCrmHE/DLL_eCrmHeHelper/PrintWatermark/ProcessWM_Def.pas

430 lines
14 KiB
Plaintext

{*******************************************************}
{ }
{ ProcessWatermark }
{ }
{ Copyright (C) 2025 kku }
{ }
{*******************************************************}
unit ProcessWM_Def;
interface
uses
Winapi.Windows, System.Classes, Vcl.Graphics;
function ProcessWartermark(DC: HDC; bStartPage: Boolean = true): Boolean;
implementation
uses
AppCtrlDefine, ApiHookPrint, BS1Hook, Tocsg.Safe, System.SysUtils, Condition,
Tocsg.Graphic, Tocsg.Trace, EM.DelphiZXingQRCode, Winapi.GDIPAPI, Tocsg.Convert;
function ProcessWartermark(DC: HDC; bStartPage: Boolean = true): Boolean;
var
nW, nH, i, nX, nY,
nGapW, nGapH, nDefDivFont: Integer;
sText: String;
MemCanvas: TCanvas;
hbmp, hOldBmp: HBITMAP;
pen: HPEN;
oldColor: TColor;
begin
Result := true;
if _PrtDC <> DC then
exit;
SaveDC(DC);
gAppHook.Helper.bIsWaterMaking_ := true;
try
// WriteLnFileEndUTF8('C:\ProgramData\HE\prt.log', 'Step-0');
try
if gAppHook.Helper.IsExcel then
begin
// 클리핑 제거 25_0605 14:51:11 kku
SelectClipRgn(DC, 0);
// 엑셀은 출력시트 설정에 따라 전체 영역으로 잡히는 않는 현상이 있다.. 24_0805 13:46:31 kku
nW := GetDeviceCaps(DC, HORZRES); // 세로모드 : 4961, 가로모드 : 7016, 크로미움 프린트 인쇄시 4760
nH := GetDeviceCaps(DC, VERTRES); // 세로모드 : 7016, 가로모드 : 4961, 크로미움 프린트 인쇄시 6814
end else begin
// if bStartPage then // 이럴리 없겠지만 안전장치
// exit;
var rc: TRect;
ZeroMemory(@rc, SizeOf(rc));
GetClipBox(DC, rc);
nW := rc.Width;
nH := rc.Height;
// LogToReg('Step-1', Format('W = %d, H = %d,', [nW, nH]));
// LogToReg('Step-2', Format('W = %d, H = %d,', [GetDeviceCaps(DC, HORZRES), GetDeviceCaps(DC, VERTRES)]));
if nW = 0 then
nW := GetDeviceCaps(DC, HORZRES); // 세로모드 : 4961, 가로모드 : 7016, 크로미움 프린트 인쇄시 4760
if nH = 0 then
nH := GetDeviceCaps(DC, VERTRES); // 세로모드 : 7016, 가로모드 : 4961, 크로미움 프린트 인쇄시 6814
end;
// nX := GetDeviceCaps(DC, ASPECTX);
// nY := GetDeviceCaps(DC, ASPECTY);
// bStartPage := CompareText(gAppHook.ModuleName, 'notepad.exe') = 0;
Guard(MemCanvas, TCanvas.Create);
// if bStartPage then
// begin
// MemCanvas.Handle := CreateCompatibleDC(DC);
// end else
MemCanvas.Handle := DC; //CreateCompatibleDC(DC);
hbmp := CreateCompatibleBitmap(MemCanvas.Handle, nW, nH);
// hbmp := CreateCompatibleBitmap(DC, nW, nH);
hOldBmp := SelectObject(MemCanvas.Handle, hbmp);
// gAppHook.Log(Format('ProcessWartermark() - DocSize X=%d, Y=%d, W=%d, H=%d, dc=%d', [nX, nY, nW, nH, DC]));
// LogToReg('Step0', Format('ProcessWartermark() - DocSize X=%d, Y=%d, W=%d, H=%d, dc=%d', [nX, nY, nW, nH, DC]));
// if bStartPage then
// PatBlt(MemCanvas.Handle, 0, 0, nW, nH, WHITENESS);
// pen := CreatePen(PS_SOLID, 1, RGB(0, 255, 0));
// hOldBmp := SelectObject(MemCanvas.Handle, pen);
nGapW := 0;
nGapH := 0;
// SetBkMode(MemCanvas.Handle, TRANSPARENT);
// MemCanvas.Font.Orientation := 250;
MemCanvas.Font.Name := 'Tahoma';
if gAppHook.Helper.bSmallFont_ then
begin
if Pos('PDF', UpperCase(_sPrtName)) = 0 then
begin
// 일반 프린터에서만 밀리는 현상이 있어서 갭을 준다.. 24_0627 10:52:33 kku
nGapW := 19;
nGapH := 17;
end;
nDefDivFont := 180;
end else
begin
if gAppHook.Helper.bEndDocProc_ then
begin
if CompareText(gAppHook.ModuleName, 'winword.exe') = 0 then
nGapH := 70;
end;
nDefDivFont := 190;
end;
// 기본 폰트 조절
if nW > nH then
MemCanvas.Font.Size := nW div 130
else
MemCanvas.Font.Size := nH div 130;
oldColor := GetTextColor(DC);
// 폰트색 지정... 프로그램에 따라 지정되는 설정이 다르다
MemCanvas.Font.Color := clSilver; // 메모장등
SetTextColor(DC, clSilver); // 엑셀등
try
sText := gAppHook.Helper.sPrintWaterTxt;
SetBkMode(MemCanvas.Handle, TRANSPARENT);
case gAppHook.Helper.CtrlOpt.dwCustomerType of
CUSTOMER_UNITUS,
CUSTOMER_MOTRAS,
CUSTOMER_INZENT : MemCanvas.Font.Size := MemCanvas.Font.Size - 2; // 폰트 크기 줄임 24_0619 14:23:38 kku
CUSTOMER_SOLIDEO :
begin
// MemCanvas.Font.Color := $969696;
// SetTextColor(DC, $969696);
// MemCanvas.Font.Size := MemCanvas.Font.Size - 17;
MemCanvas.Font.Color := clGray; // 메모장등
SetTextColor(DC, clGray); // 엑셀등
MemCanvas.Font.Size := MemCanvas.Font.Size - 9;
Dec(nGapH, 7);
end;
end;
if gAppHook.Helper.CtrlOpt.dwCustomerType = CUSTOMER_DEMO then
begin
nGapH := 0;
// QR 코드 추가 25_1106 20:17:25 kku
var QRCode: TDelphiZXingQRCode;
Guard(QRCode, TDelphiZXingQRCode.Create);
QRCode.Data := sText;
QRCode.QuietZone := 4;
var QrBmp: TBitmap;
Guard(QrBmp, TBitmap.Create);
QrBmp.SetSize(QRCode.Rows, QRCode.Columns);
var R, C, nQrSize: Integer;
for R := 0 to QRCode.Rows - 1 do
begin
for C := 0 to QRCode.Columns - 1 do
begin
if (QRCode.IsBlack[R, C]) then
begin
QrBmp.Canvas.Pixels[C, R] := clBlack;
end else
begin
QrBmp.Canvas.Pixels[C, R] := clWhite;
end;
end;
end;
var rc: TRect;
if nW < nH then
nQrSize := nW div 20
else
nQrSize := nH div 20;
rc.Left := nGapW + nW - nQrSize;
rc.Right := nGapW + nW;
rc.Top := nGapH + nH - nQrSize;
rc.Bottom := nGapH + nH;
MemCanvas.StretchDraw(rc, QrBmp);
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
if _bmpWater = nil then
begin
var sImgPath: String := ExtractFilePath(gAppHook.Helper.DllPath) + 'CI.bmp';
if FileExists(sImgPath) then
begin
try
_bmpWater := TBitmap.Create;
_bmpWater.PixelFormat := pf4bit; // 이거 켜면 흑백 출력시 안됨 24_0807 15:52:56 kku
_bmpWater.LoadFromFile(sImgPath);
// LogToReg('BW-01', BooleanToStr(gAppHook.Helper.CurAppType = catWebb, 'YES', 'NO'));
if gAppHook.Helper.CurAppType = catWebb then
ScalePercentBmp(_bmpWater, 40)
else
ScalePercentBmp(_bmpWater, 140);
_bmpWater.TransparentColor := clWhite;
_bmpWater.Transparent := true;
// _bmpWater.SaveToFile('C:\Users\kku\Desktop\이전 바탕화면\출력 추출 데이터\1.bmp');
except
// ..
end;
end;
end;
if _bmpWater <> nil then
begin
var cTrMatrix: TColorMatrix;
ZeroMemory(@cTrMatrix, SizeOf(cTrMatrix));
if gAppHook.Helper.bSmallFont_ then
cTrMatrix := MakeColorMatrix(0.2, 0.2, 0.2, BooleanToFloat(gAppHook.Helper.CtrlOpt.fWmTran <> 0.0, gAppHook.Helper.CtrlOpt.fWmTran, 0.05))
else
// cTrMatrix := MakeColorMatrix(0.2, 0.2, 0.2, 0.0099);
cTrMatrix := MakeColorMatrix(0.2, 0.2, 0.2, BooleanToFloat(gAppHook.Helper.CtrlOpt.fWmTran <> 0.0, gAppHook.Helper.CtrlOpt.fWmTran, 0.06));
Dec(nW, nGapW);
Dec(nH, nGapH);
nX := (nW div 4) - (_bmpWater.Width div 2);
nY := (nH div 4) - (_bmpWater.Height div 2);
// MemCanvas.Draw(nX, nY, _bmpWater);
if not gAppHook.Helper.IsExcel or
( gAppHook.Helper.IsExcel and bStartPage and not _bDoStartProc) or
( gAppHook.Helper.IsExcel and not bStartPage ) then
begin
DrawBitmapWaterEx(MemCanvas.Handle, nX, nY, _bmpWater, @cTrMatrix);
end;
end;
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
end else begin
MemCanvas.TextOut(nW - MemCanvas.TextWidth(sText) + nGapW,
nH - MemCanvas.TextHeight(sText) + nGapH, sText);
end;
case gAppHook.Helper.CtrlOpt.dwCustomerType of
CUSTOMER_DEMO,
CUSTOMER_INZENT,
CUSTOMER_SOLIDEO,
CUSTOMER_CJONS : ;
else begin
sText := gAppHook.Helper.sCurDocName_;
MemCanvas.TextOut(nGapW, nH - MemCanvas.TextHeight(sText) + nGapH, sText);
end;
end;
// if bStartPage then
// BitBlt(DC, 0, 0, nW, nH, MemCanvas.Handle, 0, 0, SRCCOPY);
SelectObject(MemCanvas.Handle, hOldBmp);
// DeleteObject(pen);
DeleteObject(hbmp);
// if bStartPage then
// DeleteDC(MemCanvas.Handle);
MemCanvas.Handle := 0;
finally
SetTextColor(DC, oldColor);
end;
gAppHook.Log(Format('ProcessWartermark() - Completed, LastError=%d', [GetLastError]));
except
// 실패하면 출력 안되게 해준다 22_0907 14:28:52 kku
Result := false;
DeleteDC(DC);
end;
finally
gAppHook.Helper.bIsWaterMaking_ := false;
RestoreDC(DC, -1);
end;
end;
function ProcessWartermark_Old(DC: HDC; bStartPage: Boolean = true): Boolean;
var
nW, nH, nWW, nHH, i,
nGapH: Integer;
sOut: String;
MemCanvas: TCanvas;
hbmp, hOldBmp: HBITMAP;
bmpText: TBitmap;
begin
Result := true;
// 엑셀 (excel.exe)의 경우 이렇게 안하면 다음 페이지로 밀리는 현상 있음.
// 아마도 DC를 별도 추가 처리 하는 듯 함 23_1024 11:00:13 kku
if _PrtDC <> DC then
exit;
gAppHook.Helper.bIsWaterMaking_ := true;
try
bStartPage := false;
try
nW := GetDeviceCaps(DC, HORZRES);
nH := GetDeviceCaps(DC, VERTRES);
Guard(MemCanvas, TCanvas.Create);
if bStartPage then
MemCanvas.Handle := CreateCompatibleDC(DC)
else
MemCanvas.Handle := DC; //CreateCompatibleDC(DC);
hbmp := CreateCompatibleBitmap(DC, nW, nH);
hOldBmp := SelectObject(MemCanvas.Handle, hbmp);
gAppHook.Log(Format('ProcessWartermark() - DocSize W=%d, H=%d, dc=%d', [nW, nH, DC]));
sOut := gAppHook.Helper.sPrintWaterTxt;
if _nFontSize = 0 then
begin
_nFontSize := MemCanvas.Font.Size;
while True do
begin
if _nFontSize > 200 then
break;
if MemCanvas.TextHeight(sOut) > 60 then
begin
Dec(_nFontSize);
break;
end;
Inc(_nFontSize);
MemCanvas.Font.Size := _nFontSize;
end;
end;
if _bmpWater = nil then
begin
// for i := 0 to 3 do
sOut := sOut + WORD_GAP + sOut;
_bmpWater := TBitmap.Create;
_bmpWater.PixelFormat := pf4bit;
// _bmpWater.PixelFormat := pf32bit;// pf4bit;
nWW := nW div 4;
nHH := nH div 4;
_bmpWater.SetSize(nWW, nHH);
_bmpWater.Canvas.Font.Assign(MemCanvas.Font);
// bmpText.Canvas.Font.Color := clSilver;
_bmpWater.Canvas.Font.Color := clGray; //$F1F1F1; // ; // ;
_bmpWater.Canvas.Font.Size := _nFontSize;
_bmpWater.Canvas.Font.Style := _bmpWater.Canvas.Font.Style + [fsBold];
_bmpWater.Canvas.FillRect(Rect(0, 0, nWW, nHH));
_bmpWater.TransparentColor := clWhite;
_bmpWater.Transparent := true;
Guard(bmpText, TBitmap.Create);
bmpText.PixelFormat := pf4bit;
// bmpText.PixelFormat := pf32bit;// pf4bit;
bmpText.Canvas.Font.Assign(MemCanvas.Font);
// bmpText.Canvas.Font.Color := clSilver;
bmpText.Canvas.Font.Color := clSilver;//$F1F1F1;
bmpText.Canvas.Font.Size := _nFontSize;
bmpText.Canvas.Font.Style := bmpText.Canvas.Font.Style + [fsBold];
// bmpText.Canvas.Font.Orientation := 250;
bmpText.SetSize(_bmpWater.Canvas.TextWidth(sOut), _bmpWater.Canvas.TextHeight(sOut));
bmpText.Canvas.Brush.Color := clWhite;
bmpText.Canvas.Brush.Style := bsSolid;
// SetBkMode(bmpText.Canvas.Handle, TRANSPARENT);
// var textColor: COLORREF := RGB(255, 0, 0);
// var textAlpha: Integer := 128;
// textColor := textColor and ($00FFFFFF or textAlpha shl 24);
// SetTextColor(bmpText.Canvas.Handle, textColor);
bmpText.Canvas.TextOut(0, 0, sOut);
var ii: Integer;
var jj: Integer;
for ii := 0 to bmpText.Width - 1 do
for jj := 0 to bmpText.Height - 1 do
if bmpText.Canvas.Pixels[ii, jj] <> clWhite then
if ((ii + jj) mod 2) = 0 then
bmpText.Canvas.Pixels[ii, jj] := clWhite
else
bmpText.Canvas.Pixels[ii, jj] := clGray;
// bmpText.Canvas.Pixels[ii, jj] := bmpText.Canvas.Pixels[ii, jj] and $00FFFFFF or textAlpha shl 24;
RotateBitmap_PlgBlt(bmpText, -0.45, true, clWhite);
// bmpText.Canvas.FillRect(Rect(0, 0, nWW, nHH));
// bmpText.TransparentColor := clWhite;
// bmpText.Transparent := true;
// if bStartPage then
// PatBlt(MemCanvas.Handle, 0, 0, nW, nH, WHITENESS);
nGapH := bmpText.Height; // nHH div (nRepeat - 1);
i := (nGapH div 2) * -1;
while i < nHH + nGapH do
begin
_bmpWater.Canvas.Draw(0, i, bmpText);
Inc(i, nGapH);
end;
// bmpText.Canvas.TextOut(0, bmpText.Height - (bmpText.Height div 3), sOut);
end;
if _bmpWater <> nil then
MemCanvas.StretchDraw(Rect(0, 0, nW, nH), _bmpWater);
DeleteObject(hbmp);
if bStartPage then
DeleteDC(MemCanvas.Handle);
MemCanvas.Handle := 0;
gAppHook.Log(Format('ProcessWartermark() - Completed, LastError=%d', [GetLastError]));
except
// 실패하면 출력 안되게 해준다 22_0907 14:28:52 kku
Result := false;
DeleteDC(DC);
end;
finally
gAppHook.Helper.bIsWaterMaking_ := false;
end;
end;
end.