{*******************************************************} { } { ProcessWatermark } { } { Copyright (C) 2025 kku } { } {*******************************************************} unit ProcessWM_WELFND; interface uses Winapi.Windows, System.Classes, Vcl.Graphics; function ProcessWartermark_WELFND(DC: HDC; bStartPage: Boolean = true): Boolean; implementation uses AppCtrlDefine, ApiHookPrint, BS1Hook, Tocsg.Safe, System.SysUtils, Condition, Tocsg.Graphic, Winapi.GDIPAPI, Tocsg.Strings, Vcl.Imaging.jpeg, Tocsg.Trace, Tocsg.Convert; procedure DrawRotatedText(Canvas: TCanvas; X, Y, Angle: Integer; const Text: string); var LogFont: TLogFont; OldFont, RotatedFont: HFONT; begin // 기존 폰트를 기반으로 로그폰트 가져오기 GetObject(Canvas.Font.Handle, SizeOf(LogFont), @LogFont); // 회전 각도 설정 (0.1도 단위, 즉 450 = 45도) LogFont.lfEscapement := Angle * 10; LogFont.lfOrientation := Angle * 10; // 안티앨리어싱 등 품질 향상 옵션 LogFont.lfQuality := ANTIALIASED_QUALITY; // 회전 폰트 생성 RotatedFont := CreateFontIndirect(LogFont); OldFont := SelectObject(Canvas.Handle, RotatedFont); // 텍스트 출력 TextOut(Canvas.Handle, X, Y, PChar(Text), Length(Text)); // 자원 정리 SelectObject(Canvas.Handle, OldFont); DeleteObject(RotatedFont); end; function ProcessWartermark_WELFND(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; r: TRect; 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; ZeroMemory(@r, SizeOf(r)); GetClipBox(DC, r); nW := r.Width; nH := r.Height; if nW = 0 then nW := GetDeviceCaps(DC, HORZRES); // 세로모드 : 4961, 가로모드 : 7016, 크로미움 프린트 인쇄시 4760 if nH = 0 then nH := GetDeviceCaps(DC, VERTRES); // 세로모드 : 7016, 가로모드 : 4961, 크로미움 프린트 인쇄시 6814 end; Guard(MemCanvas, TCanvas.Create); MemCanvas.Handle := DC; //CreateCompatibleDC(DC); hbmp := CreateCompatibleBitmap(MemCanvas.Handle, nW, nH); hOldBmp := SelectObject(MemCanvas.Handle, hbmp); // if bStartPage then // PatBlt(MemCanvas.Handle, 0, 0, nW, nH, WHITENESS); nGapW := 0; nGapH := 0; MemCanvas.Font.Name := 'Tahoma'; if (CompareText(gAppHook.ModuleName, 'winword.exe') = 0) or (CompareText(gAppHook.ModuleName, 'notepad++.exe') = 0) then nGapH := 60; // 기본 폰트 조절 if nW > nH then MemCanvas.Font.Size := nW div 160 else MemCanvas.Font.Size := nH div 160; oldColor := GetTextColor(DC); try SetBkMode(MemCanvas.Handle, TRANSPARENT); MemCanvas.Font.Color := clGray; SetTextColor(DC, clGray); sText := gAppHook.Helper.sPrintWaterTxt; // 좌측 상단 MemCanvas.TextOut(nGapW, nGapH, sText); // 우측 상단 MemCanvas.TextOut(nW - MemCanvas.TextWidth(sText) + nGapW, nGapH, sText); // 좌측 하단 MemCanvas.TextOut(nGapW, nH - MemCanvas.TextHeight(sText) + nGapH, sText); // 왼쪽 위 대각선 // DrawRotatedText(MemCanvas, nGapW + (nW div 8), nGapH + (nH div 5), -45, sText); // 오른쪽 아래 대각선 // DrawRotatedText(MemCanvas, nGapW + (nW div 2) + (nW div 5), nGapH + (nH div 2) + (nH div 5), -45, sText); if nW > nH then MemCanvas.Font.Size := nW div 130 else MemCanvas.Font.Size := nH div 130; // 우측 하단 sText := '본 문서에 대한 소유권은 회사에 있으며, 무단으로 반출 시 법적 책임을 받게 됩니다.'; MemCanvas.TextOut(nW - MemCanvas.TextWidth(sText) + nGapW, nH - MemCanvas.TextHeight(sText) + nGapH, sText); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< // 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 := pf32bit; // 이거 켜면 흑백 출력시 안됨 24_0807 15:52:56 kku // _bmpWater.SetSize(nW, nH); // _bmpWater.TransparentColor := clWhite; // _bmpWater.Transparent := true; // // var bmp: TBitmap; // Guard(bmp, TBitmap.Create); // bmp.LoadFromFile(sImgPath); // _bmpWater.Canvas.Draw((_bmpWater.Width div 2) - (bmp.Width div 2), // (_bmpWater.Height div 2) - (bmp.Height div 2), bmp); // // // if _bmpWaterP = nil then // begin // sText := gAppHook.Helper.sPrintWaterTxt; // try // _bmpWaterP := TBitmap.Create; // _bmpWaterP.PixelFormat := pf32bit; // 이거 켜면 흑백 출력시 안됨 24_0807 15:52:56 kku // _bmpWaterP.Canvas.Font.Assign(MemCanvas.Font); // _bmpWaterP.Canvas.Font.Color := $D8D8D8; // clGray; // _bmpWaterP.Canvas.Font.Size := 12; // _bmpWaterP.TransparentColor := clWhite; // _bmpWaterP.Transparent := true; // // var nTW: Integer := _bmpWaterP.Canvas.TextWidth(sText); // _bmpWaterP.SetSize(nTW, nTW); // // DrawRotatedText(_bmpWaterP.Canvas, _bmpWaterP.Canvas.TextHeight(sText), 0, -45, sText); // except // // .. // end; // end; // // if _bmpWaterP <> nil then // begin // LogToReg('_bmpWaterP - 01', ''); // 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.1)); // // // 왼쪽 위 대각선 // // DrawRotatedText(MemCanvas, nGapW + (nW div 8), nGapH + (nH div 5), -45, sText); // // // 오른쪽 아래 대각선 // // DrawRotatedText(MemCanvas, nGapW + (nW div 2) + (nW div 5), nGapH + (nH div 2) + (nH div 5), -45, sText); // // if not gAppHook.Helper.IsExcel or // ( gAppHook.Helper.IsExcel and bStartPage and not _bDoStartProc) or // ( gAppHook.Helper.IsExcel and not bStartPage ) then // begin // nX := nW div 13; // nY := nH div 8; // DrawBitmapWaterEx(_bmpWater.Canvas.Handle, nX, nY, _bmpWaterP, @cTrMatrix); // // nX := nW div 3; // nY := nH div 3; // DrawBitmapWaterEx(_bmpWater.Canvas.Handle, nX, nY, _bmpWaterP, @cTrMatrix); // end; // end; // 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.05)); // // if not gAppHook.Helper.IsExcel or // ( gAppHook.Helper.IsExcel and bStartPage and not _bDoStartProc) or // ( gAppHook.Helper.IsExcel and not bStartPage ) then // begin // DrawBitmapWaterEx2(MemCanvas.Handle, 0, 0, _bmpWater, @cTrMatrix); // end; // end; // 사선 텍스트 if _bmpWaterP = nil then begin sText := gAppHook.Helper.sPrintWaterTxt; try _bmpWaterP := TBitmap.Create; _bmpWaterP.PixelFormat := pf32bit; // 이거 켜면 흑백 출력시 안됨 24_0807 15:52:56 kku // _bmpWaterP.SetSize(nW, nH); _bmpWaterP.Canvas.Font.Assign(MemCanvas.Font); _bmpWaterP.Canvas.Font.Color := $D8D8D8; // clGray; _bmpWaterP.Canvas.Font.Size := 50; _bmpWaterP.TransparentColor := clWhite; _bmpWaterP.Transparent := true; // LogToReg('TW', IntToStr(_bmpWaterP.Canvas.TextWidth(sText))); // LogToReg('TH', IntToStr(_bmpWaterP.Canvas.TextHeight(sText))); var nTW: Integer := _bmpWaterP.Canvas.TextWidth(sText); // var dx: Integer := Round(_bmpWaterP.Canvas.TextHeight(sText) * Sin(45)); // var dy: Integer := Round(_bmpWaterP.Canvas.TextWidth(sText) * Sin(45)); _bmpWaterP.SetSize(nTW, nTW); // _bmpWaterP.SetSize(500, 500); DrawRotatedText(_bmpWaterP.Canvas, _bmpWaterP.Canvas.TextHeight(sText), 0, -45, sText); except // .. end; end; if _bmpWaterP <> nil then begin LogToReg('_bmpWaterP - 01', ''); 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, BooleanToFloat(gAppHook.Helper.CtrlOpt.fWmTran <> 0.0, gAppHook.Helper.CtrlOpt.fWmTran, 0.1)); if not gAppHook.Helper.IsExcel or ( gAppHook.Helper.IsExcel and bStartPage and not _bDoStartProc) or ( gAppHook.Helper.IsExcel and not bStartPage ) then begin nX := Round(nW / 7); nY := Round(nH / 4.8); DrawBitmapWaterEx3(MemCanvas.Handle, nX, nY, _bmpWaterP, @cTrMatrix); nX := Round(nW / 1.5); nY := Round(nH / 1.5); LogToReg('_bmpWaterP - 02', Format('W=%d, H=%d, X=%d, Y=%d', [nW, nH, nX, nY])); DrawBitmapWaterEx3(MemCanvas.Handle, nX, nY, _bmpWaterP, @cTrMatrix); end; end; 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 := pf32bit; // 이거 켜면 흑백 출력시 안됨 24_0807 15:52:56 kku _bmpWater.TransparentColor := clWhite; _bmpWater.Transparent := true; _bmpWater.LoadFromFile(sImgPath); ScalePercentBmp(_bmpWater, 300); // _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, BooleanToFloat(gAppHook.Helper.CtrlOpt.fWmTran <> 0.0, gAppHook.Helper.CtrlOpt.fWmTran, 0.05)); Dec(nW, nGapW); Dec(nH, nGapH); nX := (nW div 2) - (_bmpWater.Width div 2); nY := (nH div 2) - (_bmpWater.Height div 2); if not gAppHook.Helper.IsExcel or ( gAppHook.Helper.IsExcel and bStartPage and not _bDoStartProc) or ( gAppHook.Helper.IsExcel and not bStartPage ) then begin DrawBitmapWaterEx3(MemCanvas.Handle, nX, nY, _bmpWater, @cTrMatrix); 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; end.