BSOne.SFC/Tocsg.Module/AppCtrl/DLL_AppCtrl/ApiHookPrint.pas

1481 lines
52 KiB
Plaintext

{*******************************************************}
{ }
{ ApiHookPrint }
{ }
{ Copyright (C) 2023 kku }
{ }
{*******************************************************}
unit ApiHookPrint;
interface
uses
System.SysUtils, System.Classes, Winapi.Windows, Vcl.Graphics;
type
// 프린트
TFun_StartDocA = function(dc: HDC; pDocInfo: PDocInfoA): Integer; stdcall;
TFun_StartDocW = function(dc: HDC; pDocInfo: PDocInfoW): Integer; stdcall;
TFun_HDC = function(dc: HDC): Integer; stdcall;
TFun_CreateDC = function(lpszDriver, lpszDevice, lpszOutput: LPCWSTR;
lpdvmInit: PDeviceMode): HDC; stdcall;
TFun_CreateDCA = function(lpszDriver, lpszDevice, lpszOutput: LPCSTR;
lpdvmInit: PDeviceModeA): HDC; stdcall;
TFun_CreateDCW = function(lpszDriver, lpszDevice, lpszOutput: LPCWSTR;
lpdvmInit: PDeviceModeW): HDC; stdcall;
TFun_WritePrinter = function(hPrinter: THandle; pBuf: Pointer; cbBuf: DWORD;
var pcWritten: DWORD): BOOL; stdcall;
// 마스킹
// TFun_DrawTextA = function(hDC: HDC; lpString: LPCSTR; nCount: Integer;
// var lpRect: TRect; uFormat: UINT): Integer; stdcall;
// TFun_DrawTextW = function(hDC: HDC; lpString: LPCWSTR; nCount: Integer;
// var lpRect: TRect; uFormat: UINT): Integer; stdcall;
// TFun_DrawTextExA = function(DC: HDC; lpchText: LPCSTR; cchText: Integer; var p4: TRect;
// dwDTFormat: UINT; DTParams: PDrawTextParams): Integer; stdcall;
// TFun_DrawTextExW = function(DC: HDC; lpchText: LPCWSTR; cchText: Integer; var p4: TRect;
// dwDTFormat: UINT; DTParams: PDrawTextParams): Integer; stdcall;
// TFun_ExtTextOutA = function(DC: HDC; X, Y: Integer; Options: Longint;
// Rect: PRect; Str: LPCSTR; Count: Longint; Dx: PInteger): BOOL; stdcall;
// TFun_ExtTextOutW = function(DC: HDC; X, Y: Integer; Options: Longint;
// Rect: PRect; Str: LPCWSTR; Count: Longint; Dx: PInteger): BOOL; stdcall;
// TFun_TextOutA = function(DC: HDC; X, Y: Integer; Str: LPCSTR; Count: Integer): BOOL; stdcall;
// TFun_TextOutW = function(DC: HDC; X, Y: Integer; Str: LPCWSTR; Count: Integer): BOOL; stdcall;
// TFun_PolyTextOutA = function(DC: HDC; const PolyTextArray; Strings: Integer): BOOL; stdcall;
// TFun_PolyTextOutW = function(DC: HDC; const PolyTextArray; Strings: Integer): BOOL; stdcall;
// TFun_TabbedTextOutA = function(hDC: HDC; X, Y: Integer; lpString: LPCSTR; nCount, nTabPositions: Integer;
// var lpnTabStopPositions; nTabOrigin: Integer): Longint; stdcall;
// TFun_TabbedTextOutW = function(hDC: HDC; X, Y: Integer; lpString: LPCWSTR; nCount, nTabPositions: Integer;
// var lpnTabStopPositions; nTabOrigin: Integer): Longint; stdcall;
function CreateDCHook(lpszDriver, lpszDevice, lpszOutput: LPCWSTR;
lpdvmInit: PDeviceMode): HDC; stdcall;
function CreateDCAHook(lpszDriver, lpszDevice, lpszOutput: LPCSTR;
lpdvmInit: PDeviceModeA): HDC; stdcall;
function CreateDCWHook(lpszDriver, lpszDevice, lpszOutput: LPCWSTR;
lpdvmInit: PDeviceModeW): HDC; stdcall;
function StartDocAHook(dc: HDC; pDocInfo: PDocInfoA): Integer; stdcall;
function StartDocWHook(dc: HDC; pDocInfo: PDocInfoW): Integer; stdcall;
function StartPageHook(dc: HDC): Integer; stdcall;
function EndPageHook(dc: HDC): Integer; stdcall;
function EndDocHook(dc: HDC): Integer; stdcall;
function WritePrinterHook(hPrinter: THandle; pBuf: Pointer; cbBuf: DWORD;
var pcWritten: DWORD): BOOL; stdcall;
//function DrawTextAHook(hDC: HDC; lpString: LPCSTR; nCount: Integer;
// var lpRect: TRect; uFormat: UINT): Integer; stdcall;
//function DrawTextWHook(hDC: HDC; lpString: LPCWSTR; nCount: Integer;
// var lpRect: TRect; uFormat: UINT): Integer; stdcall;
//function DrawTextExAHook(DC: HDC; lpchText: LPCSTR; cchText: Integer; var p4: TRect;
// dwDTFormat: UINT; DTParams: PDrawTextParams): Integer; stdcall;
//function DrawTextExWHook(DC: HDC; lpchText: LPCWSTR; cchText: Integer; var p4: TRect;
// dwDTFormat: UINT; DTParams: PDrawTextParams): Integer; stdcall;
//function ExtTextOutAHook(DC: HDC; X, Y: Integer; Options: Longint;
// Rect: PRect; Str: LPCSTR; Count: Longint; Dx: PInteger): BOOL; stdcall;
//function ExtTextOutWHook(DC: HDC; X, Y: Integer; Options: Longint;
// Rect: PRect; Str: LPCWSTR; Count: Longint; Dx: PInteger): BOOL; stdcall;
//function TextOutAHook(DC: HDC; X, Y: Integer; Str: LPCSTR; Count: Integer): BOOL; stdcall;
//function TextOutWHook(DC: HDC; X, Y: Integer; Str: LPCWSTR; Count: Integer): BOOL; stdcall;
//function PolyTextOutAHook(DC: HDC; const PolyTextArray; Strings: Integer): BOOL; stdcall;
//function PolyTextOutWHook(DC: HDC; const PolyTextArray; Strings: Integer): BOOL; stdcall;
//function TabbedTextOutAHook(hDC: HDC; X, Y: Integer; lpString: LPCSTR; nCount, nTabPositions: Integer;
// var lpnTabStopPositions; nTabOrigin: Integer): Longint; stdcall;
//function TabbedTextOutWHook(hDC: HDC; X, Y: Integer; lpString: LPCWSTR; nCount, nTabPositions: Integer;
// var lpnTabStopPositions; nTabOrigin: Integer): Longint; stdcall;
function DrawBitmapWater(aDestDC: HDC; nX, nY: Integer; aSrcBmp: TBitmap): Boolean; stdcall;
procedure LogToReg(sVName, sLog: String); inline;
//function WritePrinter(
// hPrinter: THandle;
// pBuf: Pointer;
// cbBuf: DWORD;
// var pcWritten: DWORD
//): BOOL; stdcall; external 'winspool.drv' name 'WritePrinter';
var
ozCreateDC: TFun_CreateDC = nil;
ozCreateDCA: TFun_CreateDCA = nil;
ozCreateDCW: TFun_CreateDCW = nil;
ozStartDocA: TFun_StartDocA = nil;
ozStartDocW: TFun_StartDocW = nil;
ozStartPage: TFun_HDC = nil;
ozEndPage: TFun_HDC = nil;
ozEndDoc: TFun_HDC = nil;
ozWritePrinter: TFun_WritePrinter = nil;
// ozDrawTextA: TFun_DrawTextA = nil;
// ozDrawTextW: TFun_DrawTextW = nil;
// ozDrawTextExA: TFun_DrawTextExA = nil;
// ozDrawTextExW: TFun_DrawTextExW = nil;
// ozExtTextOutA: TFun_ExtTextOutA = nil;
// ozExtTextOutW: TFun_ExtTextOutW = nil;
// ozTextOutA: TFun_TextOutA = nil;
// ozTextOutW: TFun_TextOutW = nil;
// ozPolyTextOutA: TFun_PolyTextOutA = nil;
// ozPolyTextOutW: TFun_PolyTextOutW = nil;
// ozTabbedTextOutA: TFun_TabbedTextOutA = nil;
// ozTabbedTextOutW: TFun_TabbedTextOutW = nil;
var
_bmpWater: TBitmap;
_bmpWaterP: TBitmap;
_sbmpWaterIf: String;
_sLabelName: String;
_bIgrPrtWater: Boolean;
_PrtDC: HDC;
_bDoStartProc: Boolean;
_bDoEndProc: Boolean;
_nFontSize: Integer;
_sDrvName: String;
_sDevName: String;
_sPrtName: String;
_sPrtDocId: String;
gPrtWatering: Boolean;
implementation
uses
{$IFDEF _BS1HP_}
BS1Hook, DefineHelper,
ProcessWM_JUVIS, ProcessWM_KBIZ, ProcessWM_HEC, ProcessWM_GEC, ProcessWM_KOCES,
ProcessWM_SHSC, ProcessWM_SHCI, ProcessWM_Custom, ProcessWM_Def, ProcessWM_WINSTN,
ProcessWM_SANKYO, ProcessWM_WELFND, ProcessWM_SERVE1, ProcessWM_DEMO, ProcessWM_SOLMIX,
ProcessWM_KORENTAL, ProcessWM_SKEC,
{$ELSE}
AppHook, ProcessWM,
{$ENDIF}
Condition, ApiHookDraw, Tocsg.Safe,
AppCtrlDefine, Vcl.Imaging.jpeg, Tocsg.Files, Tocsg.Shell, Winapi.WinSpool,
Vcl.Imaging.pngimage, Tocsg.Network, Tocsg.Graphic, Tocsg.WndUtil,
Tocsg.Path, Tocsg.Registry, superobject, Winapi.Messages, Tocsg.Strings,
Tocsg.Process, Winapi.ActiveX, Winapi.GDIPOBJ, System.UIConsts,
Winapi.GDIPAPI, Tocsg.Convert, Winapi.MultiMon, Tocsg.Printer;
const
CaptureBlt = $40000000;
var
_nPageCnt: Integer = 0;
_sDocName: String = '';
procedure LogToReg(sVName, sLog: String); inline;
begin
// SetRegValueString(HKEY_CURRENT_USER, 'SOFTWARE\eCrmHomeEdition', sVName, sLog, true);
end;
function DrawBitmapWater(aDestDC: HDC; nX, nY: Integer; aSrcBmp: TBitmap): Boolean; stdcall;
//const
// cTrMatrix: TColorMatrix = (
// (1.0, 0.0, 0.0, 0.0, 0.0),
// (0.0, 1.0, 0.0, 0.0, 0.0),
// (0.0, 0.0, 1.0, 0.0, 0.0),
// (0.0, 0.0, 0.0, 0.5, 0.0),
// (0.0, 0.0, 0.0, 0.0, 1.0));
var
GPGraphics: TGPGraphics;
ms: TMemoryStream;
// GPStream: IStream;
GPImg: TGPImage;
ImageAttributes: TGPImageAttributes;
GPRect: TGPRect;
nWW, nHH: Integer;
begin
Result := true;
try
Guard(ms, TMemoryStream.Create);
aSrcBmp.SaveToStream(ms);
ms.Position := 0;
// ms.SaveToFile('C:\Users\kku\Desktop\test111.bmp');
Guard(GPGraphics, TGPGraphics.Create(aDestDC));
// GPGraphics.SetSmoothingMode(SmoothingModeAntiAlias);
GPGraphics.SetPageScale(0.33);
// IStream 메모리 해제를 위해 여기에 변수 선언해야 함 24_0125 10:58:12 kku
var GPStream: IStream := TStreamAdapter.Create(ms, soOwned) as IStream;
Guard(GPImg, TGPImage.Create(GPStream));
Guard(ImageAttributes, TGPImageAttributes.Create);
// 흰색 배경 투명처리
ImageAttributes.SetColorKey(System.UIConsts.MakeColor(255, 255, 255), System.UIConsts.MakeColor(255, 255, 255));
// 빨간색 배경 투명처리
// ImageAttributes.SetColorKey(System.UIConsts.MakeColor(255, 0, 0), System.UIConsts.MakeColor(255, 0, 0));
// ImageAttributes.SetColorMatrix(MakeColorMatrix(0.1, 0.1, 0.5, 0.2)); // Gray, 하늘색
// ImageAttributes.SetColorMatrix(MakeColorMatrix(0.1, 0.5, 0.5, 0.2)); // Gray, 녹색
// ImageAttributes.SetColorMatrix(MakeColorMatrix(0.1, 1.1, 0.5, 0.2)); // Gray, 연두색
// ImageAttributes.SetColorMatrix(MakeColorMatrix(0.2, 0.2, 0.2, 0.2)); // Gray, 실버
ImageAttributes.SetColorMatrix(MakeColorMatrix(0.2, 0.2, 0.2, 0.3)); // Gray, 회색
// ImageAttributes.SetColorMatrix(MakeTransparentMatrix(0.4)); // 그 외 mode, type 옵션 의미 없음..
nWW := GPImg.GetWidth;
nHH := GPImg.GetHeight;
// var GPUnit: TUnit := GPGraphics.GetPageUnit;
GPRect.X := nX;
GPRect.Y := nY;
GPRect.Width := nWW;
GPRect.Height := nHH;
GPGraphics.DrawImage(GPImg, GPRect, 0, 0, Round(nWW), Round(nHH), UnitPixel, ImageAttributes);
except
Result := false;
end;
end;
procedure GetPrinterName(sDriver, sDevice: String);
begin
_sDrvName := sDriver;
_sDevName := sDevice;
end;
function GetScaleFactorFromDriverName(sDriverName: String): Double;
var
DC: HDC;
nDPIW, nDPIH: Integer;
nW, nH: Integer;
begin
Result := 0.0;
try
DC := CreateDC(nil, PChar(sDriverName), nil, nil);
if DC <> 0 then
begin
nW := GetDeviceCaps(DC, HORZRES); // 세로모드 : 4961, 가로모드 : 7016, 크로미움 프린트 인쇄시 4760
nH := GetDeviceCaps(DC, VERTRES); // 가로모드 : 7016, 가로모드 : 4961, 크로미움 프린트 인쇄시 6814
LogToReg('DC=' + sDriverName, Format('W=%d, H=%d', [nW, nH]));
try
nDPIW := GetDeviceCaps(DC, LOGPIXELSX);
nDPIH := GetDeviceCaps(DC, LOGPIXELSY);
LogToReg('DC=' + sDriverName, Format('W=%d, H=%d, DPI_W=%d, DPI_H=%d', [nW, nH, nDPIW, nDPIH]));
Result := nDPIW / 96.0;
finally
DeleteDC(DC);
end;
end;
except
// ..
end;
end;
function GetMonitorScaleFactor: Double;
var
hMon: HMONITOR;
MonInfo: MONITORINFOEX;
DC: HDC;
nDPI: Integer;
begin
Result := 0.0;
try
// LogToReg('GetMonitorScaleFactor() - 1', '');
if gAppHook = nil then
exit;
if gAppHook.Helper.CtrlOpt.hMainWnd = 0 then
exit;
// LogToReg('GetMonitorScaleFactor() - 2', '');
// DC := GetDC(gAppHook.Helper.CtrlOpt.hMainWnd);
// if DC <> 0 then
begin
try
// nDPI := GetDeviceCaps(DC, LOGPIXELSX);
nDPI := GetDpiForWindow(gAppHook.Helper.CtrlOpt.hMainWnd);
// LogToReg('GetMonitorScaleFactor() - 3', Format('DPI = %d', [nDPI]));
Result := nDPI / 96.0;
finally
ReleaseDC(gAppHook.Helper.CtrlOpt.hMainWnd, DC);
end;
end;
// hMon := MonitorFromWindow(gAppHook.Helper.CtrlOpt.hMainWnd, MONITOR_DEFAULTTONEAREST);
// if hMon = 0 then
// exit;
//
// ZeroMemory(@MonInfo, SizeOf(MonInfo));
// MonInfo.cbSize := SizeOf(MonInfo);
// if GetMonitorInfo(hMon, @MonInfo) then
// begin
// DC := CreateDC(nil, MonInfo.szDevice, nil, nil);
// if DC <> 0 then
// begin
// try
// nDPI := GetDeviceCaps(DC, LOGPIXELSX);
// LogToReg('GetMonitorScaleFactor() - 5', Format('MonName = %s, DPI = %d', [MonInfo.szDevice, nDPI]));
// Result := nDPI / 96.0;
// finally
// DeleteDC(DC);
// end;
// end;
// end;
except
// ..
end;
end;
function GetMonitorWidth: Integer;
var
hMon: HMONITOR;
MonInfo: MONITORINFOEX;
DC: HDC;
nDPI: Integer;
begin
Result := 0;
try
if gAppHook = nil then
exit;
if gAppHook.Helper.CtrlOpt.hMainWnd = 0 then
exit;
try
hMon := MonitorFromWindow(gAppHook.Helper.CtrlOpt.hMainWnd, MONITOR_DEFAULTTONEAREST);
MonInfo.cbSize := SizeOf(MonInfo);
if GetMonitorInfo(hMon, @MonInfo) then
begin
Result := MonInfo.rcMonitor.Right - MonInfo.rcMonitor.Left;
// Height := MonitorInfo.rcMonitor.Bottom - MonitorInfo.rcMonitor.Top;
end;
finally
ReleaseDC(gAppHook.Helper.CtrlOpt.hMainWnd, DC);
end;
except
// ..
end;
end;
function CreateDCHook(lpszDriver, lpszDevice, lpszOutput: LPCWSTR;
lpdvmInit: PDeviceMode): HDC;
begin
GetPrinterName(String(lpszDriver), String(lpszDevice));
Result := ozCreateDC(lpszDriver, lpszDevice, lpszOutput, lpdvmInit);
end;
function CreateDCAHook(lpszDriver, lpszDevice, lpszOutput: LPCSTR;
lpdvmInit: PDeviceModeA): HDC;
begin
GetPrinterName(AnsiString(lpszDriver), AnsiString(lpszDevice));
Result := ozCreateDCA(lpszDriver, lpszDevice, lpszOutput, lpdvmInit);
end;
function CreateDCWHook(lpszDriver, lpszDevice, lpszOutput: LPCWSTR;
lpdvmInit: PDeviceModeW): HDC;
begin
GetPrinterName(String(lpszDriver), String(lpszDevice));
Result := ozCreateDCW(lpszDriver, lpszDevice, lpszOutput, lpdvmInit);
end;
procedure SetAlphaBlend(var img: TPngImage; const Alpha: Byte);
var
mScanline, mPixel: Integer;
mScanArray: pByteArray;
begin
try
img.CreateAlpha;
for mScanline := 0 to img.Height - 1 do
begin
mScanArray := img.AlphaScanline[mScanline];
for mPixel := 0 to img.Width - 1 do
mScanArray[mPixel] := Alpha;
end;
except
exit;
end;
end;
function ProcessWartermarkCustomer(dwCustomer: DWORD; DC: HDC; bStartPage: Boolean): Boolean;
begin
if _bIgrPrtWater then
begin
Result := true;
exit;
end;
gPrtWatering := true;
try
if (gAppHook <> nil) and gAppHook.Helper.CtrlOpt.PrtWaterCfg.bActive then
begin
{$IFDEF _BS1HP_}
Result := ProcessWartermark_Custom(dc, bStartPage);
{$ELSE}
Result := false;
{$ENDIF}
end else
case dwCustomer of
{$IFDEF _BS1HP_}
CUSTOMER_GEC : Result := ProcessWartermark_GEC(dc, bStartPage);
CUSTOMER_HDENG : Result := ProcessWartermark_HEC(dc, bStartPage);
CUSTOMER_JUVIS : Result := ProcessWartermark_JUVIS(dc, bStartPage);
CUSTOMER_KOCES : Result := ProcessWartermark_KOCES(dc, bStartPage);
CUSTOMER_KBIZ : Result := ProcessWartermark_KBIZ(dc, bStartPage);
CUSTOMER_SHCI : Result := ProcessWartermark_SHCI(dc, bStartPage);
CUSTOMER_SHSC : Result := ProcessWartermark_SHSC(dc, bStartPage);
CUSTOMER_WINSTN : Result := ProcessWartermark_WINSTN(dc, bStartPage);
CUSTOMER_SANKYO : Result := ProcessWartermark_SANKYO(dc, bStartPage);
CUSTOMER_WELFNI,
CUSTOMER_WELFND : Result := ProcessWartermark_WELFND(dc, bStartPage);
CUSTOMER_SERVE1 : Result := ProcessWartermark_SERVE1(dc, bStartPage);
CUSTOMER_SOLMIX : Result := ProcessWartermark_SOLMIX(dc, bStartPage);
CUSTOMER_KORENTAL : Result := ProcessWartermark_KORENTAL(dc, bStartPage);
CUSTOMER_SKEC : Result := ProcessWartermark_SKEC(dc, bStartPage);
CUSTOMER_DEMO : Result := ProcessWartermark_DEMO(dc, bStartPage);
{$ENDIF}
{$IFNDEF _BS1HP_}
113001 : Result := ProcessWartermark(dc, bStartPage); // DEV
{$ENDIF}
else Result := ProcessWartermark(dc, bStartPage);
end;
finally
gPrtWatering := false;
end;
end;
function FindPrintingFile(sDocName: String; bIgrRB: Boolean = false): String;
var
sDir, sChk: String;
FList: TModFileList;
i, n: Integer;
// Plf: TParserLinkFile;
begin
Result := '';
if gAppHook = nil then
exit;
// Result := gAppHook.GetRFilePath(sDocName);
// exit;
sDir := GetWindowsDir;
if sDir = '' then
exit;
sDir := sDir[1] + Format(':\Users\%s\AppData\Roaming\Microsoft\Windows\Recent\', [gAppHook.Helper.CtrlOpt.sAcName]);
Guard(FList, TModFileList.Create(TModeFileComparer.Create));
ExtrModFilesFromDir(sDir, FList);
if FList.Count > 0 then
begin
FList.Sort;
if bIgrRB then
sDocName := StrsReplace(sDocName, ['(', ')', '[', ']'], '0');
for i := 0 to FList.Count - 1 do
begin
if bIgrRB then
sChk := StrsReplace(CutFileExt(FList[i].sFName), ['(', ')', '[', ']'], '0')
else
sChk := CutFileExt(FList[i].sFName);
// 최근문서 파일처리 보완 24_0722 14:54:30 kku
if (sChk.Length > 0) and (sChk[sChk.Length] = ')') then
begin
n := LastIndexOf(' (', sChk);
if n > 0 then
Delete(sChk, n, sChk.Length - n + 1);
end;
if Pos(sChk, sDocName) > 0 then
begin
Result := GetTargetExeFromLink(sDir + FList[i].sFName);
if DirectoryExists(Result) then
continue;
// Guard(Plf, TParserLinkFile.Create);
// if Plf.LoadFromFile(sDir + FList[i].sName) then
// begin
// Result := GetLfiValueFromCaption(Plf.LfiEntList, 'Base Path');
// if not FileExists(Result) then
// Result := '';
// end;
exit;
end;
end;
// PDF의 경우... 문서 이름에 파일 이름이 안들어 가는 경우가 있다...
// PDF 파일 최근파일 내역을 찾을 수 없다면 맨 첫번째 있는 PDF 파일을 넘겨준다.. 24_0418 15:10:27 kku
if Pos('.PDF', sDocName.ToUpper) > 0 then
begin
for i := 0 to FList.Count - 1 do
begin
sChk := CutFileExt(FList[i].sFName);
if GetFileExt(sChk).ToUpper = 'PDF' then
begin
Result := sChk;
exit;
end;
end;
end;
end;
end;
function SendData(h: HWND; dwCmd: DWORD; const sData: String): LONGLONG;
var
CopyData: TCopyDataStruct;
begin
CopyData.dwData := dwCmd;
CopyData.cbData := (Length(sData) + 1) * 2;
CopyData.lpData := PChar(sData);
Result := SendMessage(h, WM_COPYDATA, 0, NativeInt(@CopyData));
end;
function FindAipMdWnd: HWND;
var
nTO: Integer;
sPath,
sFind, sFind2,
sPName: String;
begin
sPath := gAppHook.Helper.CtrlOpt.sAipPath;
if (sPath = '') or not FileExists(sPath) then
begin
Result := 0;
exit;
end;
nTO := 0;
sFind2 := 'BSOne-AIP-T140713';
sFind := sFind2 + '-' + ExtractFileName(sPath);
Result := FindWindow(nil, PChar(sFind));
if Result = 0 then
Result := FindWindow(nil, PChar(sFind2)); // todo : 업데이트가 바로 안될경우를 대비해서 이전 식별자로 한번더 해준다.. 나중에 정리 필요
if Result = 0 then
begin
var sAipDMail: String := gAppHook.Helper.CtrlOpt.sAccount + '@hec.co.kr';
sPName := ExtractFileName(sPath);
while Result = 0 do
begin
if nTO > 40 then
break;
if GetProcessPidByName(sPName) = 0 then
begin
if not FileExists(sPath) then
break;
ExecutePath_hide(sPath, '-r ' + sAipDMail); // 차단으로 연결이 안되는 경우가 있다...
Sleep(1000);
end;
Result := FindWindow(nil, PChar(sFind));
if Result = 0 then
Result := FindWindow(nil, PChar(sFind2)); // todo : 업데이트가 바로 안될경우를 대비해서 이전 식별자로 한번더 해준다.. 나중에 정리 필요
Sleep(200);
Inc(nTO);
end;
if Result = 0 then
TerminateProcessByName(sPName);
end;
end;
function ProcStartDoc(sDocName: String): Boolean;
var
sChkDoc: AnsiString;
i: Integer;
CtrlOpt: TAppCtrlOpt;
sWText,
sDept,
sDocPath,
sUName, sIpAddr: String;
O: ISuperObject;
begin
Result := true;
_nPageCnt := 0;
_bDoStartProc := false;
_sDocName := sDocName;
CtrlOpt := gAppHook.Helper.CtrlOpt;
// 필요 시 문서 식별 번호 생성, 저장
case CtrlOpt.dwCustomerType of
CUSTOMER_DEMO,
CUSTOMER_WELFND,
CUSTOMER_WELFNI :
begin
_sPrtDocId := StrsReplace(TGUID.NewGuid.ToString, ['{', '}'], '');
SetRegValueString(HKEY_CURRENT_USER, 'Software\eCrmHomeEdition', 'PrtDocId', _sPrtDocId, true);
end;
else _sPrtDocId := '';
end;
// if not SetRegValueString(HKEY_CURRENT_USER, 'Software\eCrmHomeEdition', 'PrtPName', gAppHook.ModuleName, true) then
// SaveStrToFile('C:\ProgramData\HE\PrtPName.txt', Format('ProcStartDoc() ... PName=%s', [gAppHook.ModuleName]));
// SetRegValueString(HKEY_CURRENT_USER, 'Software\eCrmHomeEdition', 'PrtPName1', '11111', true);
// SaveStrToFile('C:\ProgramData\HE\test.txt', Format('ProcStartDoc() ... PName=%s', [gAppHook.ModuleName]));
sUName := CtrlOpt.sUName;
if sUName = '' then
sUName := CtrlOpt.sEmpNo;
sDept := gAppHook.Helper.CtrlOpt.sDeptName;
sIpAddr := GetHostIP;
case CtrlOpt.dwCustomerType of
CUSTOMER_GEC,
CUSTOMER_HDENG : sWText := sIpAddr{CtrlOpt.sIpAddr}; // Result.sPrintWaterTxt := Result.sDeptName + '/' + gMgSvc.EmpNo + '/' + gMgSvc.NicService.GetIP + '/' + FormatDateTime('yyyy-mm-dd', Now);
CUSTOMER_INZENT : sWText := {Result.sDeptName + '/' + } CtrlOpt.sEmpNo + '/' + FormatDateTime('yyyy-mm-dd', Now) + '/INZENT';
CUSTOMER_SOLIDEO :
begin
if sDept <> '' then
begin
sDept := ExtrLastDelimiterStr(sDept, ';');
sWText := Format('(주)솔리데오 / %s / %s / %s', [sDept, sUName, FormatDateTime('yyyy-mm-dd hh:nn:ss', Now)]);
end else
sWText := Format('(주)솔리데오 / %s / %s', [sUName, FormatDateTime('yyyy-mm-dd hh:nn:ss', Now)]);
end;
CUSTOMER_CJONS :
begin
if sDept <> '' then
begin
sDept := ExtrLastDelimiterStr(sDept, ';');
sWText := Format('%s/%s/%s', [sUName, sDept, FormatDateTime('yyyy-mm-dd hh:nn', Now)]);
end else
sWText := Format('%s/%s', [sUName, FormatDateTime('yyyy-mm-dd hh:nn', Now)]);
end;
CUSTOMER_UNITUS,
CUSTOMER_MOTRAS :
begin
if sUName <> '' then
sWText := Format('%s / %s / %s / %s / %s', [sUName, sDept, gAppHook.Helper.CtrlOpt.sEmpNo, sIpAddr, FormatDateTime('yyyy-mm-dd hh:nn', Now)])
else if sDept <> '' then
sWText := Format('%s / %s / %s / %s', [sDept, gAppHook.Helper.CtrlOpt.sEmpNo, sIpAddr, FormatDateTime('yyyy-mm-dd hh:nn', Now)])
else
sWText := Format('%s / %s / %s', [gAppHook.Helper.CtrlOpt.sEmpNo, sIpAddr, FormatDateTime('yyyy-mm-dd hh:nn', Now)]);
end;
CUSTOMER_SHCI :
begin
if sUName <> '' then
begin
if sUName.Length > 1 then
sUName[2] := '*';
sWText := Format('%s / %s / %s / %s', [gAppHook.Helper.CtrlOpt.sEmpNo, sUName, sDept, FormatDateTime('yyyy-mm-dd hh:nn:ss', Now)])
end else
if sDept <> '' then
sWText := Format('%s / %s / %s', [gAppHook.Helper.CtrlOpt.sEmpNo, sDept, FormatDateTime('yyyy-mm-dd hh:nn:ss', Now)])
else
sWText := Format('%s / %s', [gAppHook.Helper.CtrlOpt.sEmpNo, FormatDateTime('yyyy-mm-dd hh:nn:ss', Now)]);
end;
CUSTOMER_SHSC :
begin
var sEmpNo: String := gAppHook.Helper.CtrlOpt.sEmpNo;
if sEmpNo.Length > 2 then
sEmpNo[3] := '*';
if sEmpNo.Length > 3 then
sEmpNo[4] := '*';
if sUName <> '' then
begin
if sUName.Length > 1 then
sUName[2] := '*';
sWText := Format('%s / %s / %s', [sUName, sEmpNo, FormatDateTime('yyyy-mm-dd hh:nn', Now)])
end else
sWText := Format('%s / %s', [sEmpNo, FormatDateTime('yyyy-mm-dd hh:nn', Now)]);
end;
CUSTOMER_SANKYO :
begin
sUName := CtrlOpt.sUName;
if sUName <> '' then
sWText := Format('%s / %s / %s', [sUName, gAppHook.Helper.CtrlOpt.sEmpNo, FormatDateTime('yyyy-mm-dd hh:nn', Now)])
else
sWText := Format('%s / %s', [gAppHook.Helper.CtrlOpt.sEmpNo, FormatDateTime('yyyy-mm-dd hh:nn', Now)]);
end;
CUSTOMER_WELFND,
CUSTOMER_WELFNI :
begin
var sTemp: String := _sPrtDocId;
if sTemp.Length > 20 then
SetLength(sTemp, 20);
sWText := gAppHook.Helper.CtrlOpt.sEmpNo + '/' + sTemp;
end;
CUSTOMER_SERVE1 :
begin
if sDept <> '' then
begin
sDept := ExtrLastDelimiterStr(sDept, ';');
sWText := Format('%s / %s / %s / %s / %s', [sDept, sUName, gAppHook.Helper.CtrlOpt.sEmpNo, gAppHook.Helper.CtrlOpt.sIpAddr, FormatDateTime('yyyy-mm-dd hh:nn', Now)]);
end else
sWText := Format('%s / %s / %s', [gAppHook.Helper.CtrlOpt.sEmpNo, gAppHook.Helper.CtrlOpt.sIpAddr, FormatDateTime('yyyy-mm-dd hh:nn', Now)]);
end;
CUSTOMER_SOLMIX :
begin
sWText := Format('%s / %s / ', [gAppHook.Helper.CtrlOpt.sEmpNo, FormatDateTime('yyyy-mm-dd hh:nn:ss', Now)]);
end;
CUSTOMER_DEMO :
begin
sWText := _sPrtDocId;
end;
CUSTOMER_KORENTAL :
begin
if gAppHook.Helper.CtrlOpt.sUName <> '' then
sWText := Format('%s/%s/%s/%s/%s', [gAppHook.Helper.CtrlOpt.sEmpNo, gAppHook.Helper.CtrlOpt.sDeptName, gAppHook.Helper.CtrlOpt.sUName, gAppHook.Helper.CtrlOpt.sIpAddr, FormatDateTime('yyyy-mm-dd hh:nn', Now)])
else if gAppHook.Helper.CtrlOpt.sDeptName <> '' then
sWText := Format('%s/%s/%s/%s', [gAppHook.Helper.CtrlOpt.sEmpNo, gAppHook.Helper.CtrlOpt.sDeptName, gAppHook.Helper.CtrlOpt.sIpAddr, FormatDateTime('yyyy-mm-dd hh:nn', Now)])
else
sWText := Format('%s/%s/%s', [gAppHook.Helper.CtrlOpt.sEmpNo, gAppHook.Helper.CtrlOpt.sIpAddr, FormatDateTime('yyyy-mm-dd hh:nn', Now)])
end;
CUSTOMER_SKEC :
begin
if gAppHook.Helper.CtrlOpt.sUName <> '' then
sWText := Format('%s / %s / %s / %s', [FormatDateTime('yyyy-mm-dd hh:nn', Now), gAppHook.Helper.CtrlOpt.sDeptName, gAppHook.Helper.CtrlOpt.sUName, gAppHook.Helper.CtrlOpt.sEmpNo])
else if gAppHook.Helper.CtrlOpt.sDeptName <> '' then
sWText := Format('%s / %s / %s', [FormatDateTime('yyyy-mm-dd hh:nn', Now), gAppHook.Helper.CtrlOpt.sDeptName, gAppHook.Helper.CtrlOpt.sEmpNo])
else
sWText := Format('%s / %s', [FormatDateTime('yyyy-mm-dd hh:nn', Now), gAppHook.Helper.CtrlOpt.sEmpNo]);
end;
else begin
if sUName <> '' then
sWText := Format('%s / %s / %s / %s', [sUName, sDept, gAppHook.Helper.CtrlOpt.sEmpNo, FormatDateTime('yyyy-mm-dd hh:nn', Now)])
else if sDept <> '' then
sWText := Format('%s / %s / %s', [sDept, gAppHook.Helper.CtrlOpt.sEmpNo, FormatDateTime('yyyy-mm-dd hh:nn', Now)])
else
sWText := Format('%s / %s', [gAppHook.Helper.CtrlOpt.sEmpNo, FormatDateTime('yyyy-mm-dd hh:nn', Now)]);
end;
end;
gAppHook.Helper.CtrlOpt := CtrlOpt;
gAppHook.Helper.sPrintWaterTxt := sWText;
// LogToReg('PrintWaterTxt', gAppHook.Helper.sWText);
if _bmpWater <> nil then
FreeAndNil(_bmpWater);
if _bmpWaterP <> nil then
FreeAndNil(_bmpWaterP);
_nFontSize := 0;
// 웹브라우저의 경우 CreateDC를 디스플레이로 한번 더 하기 때문에
// _sDevName에 프린터 이름이 사라지는 현상이 있다 그래서 아래처럼 추가 처리 24_0627 14:19:34 kku
if _sDevName <> '' then
_sPrtName := _sDevName;
// SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_UNAWARE);
// SetProcessDpiAwareness(DPI_AWARENESS_CONTEXT_UNAWARE);
// DelRegValue(HKEY_CURRENT_USER, 'SOFTWARE\eCrmHomeEdition', 'Step0');
// DelRegValue(HKEY_CURRENT_USER, 'SOFTWARE\eCrmHomeEdition', 'Step1');
// DelRegValue(HKEY_CURRENT_USER, 'SOFTWARE\eCrmHomeEdition', 'Step2');
// DelRegValue(HKEY_CURRENT_USER, 'SOFTWARE\eCrmHomeEdition', 'Step3');
// DelRegValue(HKEY_CURRENT_USER, 'SOFTWARE\eCrmHomeEdition', 'Step4');
// DelRegValue(HKEY_CURRENT_USER, 'SOFTWARE\eCrmHomeEdition', 'Step5');
// DelRegValue(HKEY_CURRENT_USER, 'SOFTWARE\eCrmHomeEdition', 'Step6');
// DelRegValue(HKEY_CURRENT_USER, 'SOFTWARE\eCrmHomeEdition', 'Step7');
// LogToReg('Step1', Format('StartDocAHook, Cnt=%d', [gAppHook.PrtMaskList.Count]));
gAppHook.Helper.bIsPrinting_ := true;
(*
if gAppHook.Helper.CtrlOpt.bPrintMasking and (gAppHook.PrtMaskList.Count = 0) then
begin
// LogToReg('Step2', Format('StartDocAHook, Cnt=%d', [gAppHook.PrtMaskList.Count]));
// var sMskPath: String := 'C:\ProgramData\HE\Task\$mk.dat';
// if FileExists(sMskPath) then
// begin
// LogToReg('Step3', Format('StartPageHook, Cnt=%d', [gAppHook.PrtMaskList.Count]));
// var StrList: TStringList;
// Guard(StrList, TStringList.Create);
// StrList.LoadFromFile(sMskPath, TEncoding.UTF8);
// SplitString(StrList.Text, ',', gAppHook.PrtMaskList, false, true);
// DeleteFile(PChar(sMskPath));
// LogToReg('Step4', Format('StartPageHook, Cnt=%d', [gAppHook.PrtMaskList.Count]));
// end;
var sVal: String := GetRegValueAsString(HKEY_CURRENT_USER, 'SOFTWARE\eCrmHomeEdition', 'PrtMk');
// LogToReg('Step3', Format('StartDocAHook, Val=%s', [sVal]));
SplitString(sVal, ',', gAppHook.PrtMaskList, false, true);
// LogToReg('Step4', Format('StartDocAHook, Cnt=%d', [gAppHook.PrtMaskList.Count]));
end;
*)
// LogToReg('Step0', 'PrintWater .. 0');
if gAppHook.Helper.CtrlOpt.bPrintSecu or gAppHook.Helper.CtrlOpt.bPrintWater then
begin
_bIgrPrtWater := sDocName.EndsWith(' *BSOne-');
_sLabelName := '';
// LogToReg('Step1', 'PrintWater .. 1 : ' + sDocName);
case gAppHook.Helper.CtrlOpt.dwCustomerType of
// CUSTOMER_CJONS,
CUSTOMER_SOLIDEO :
begin
// LogToReg('Step00', '_sPrtName : ' + _sPrtName);
if _sPrtName <> '' then
begin
var sChk: String := gAppHook.Helper.CtrlOpt.sPrintWaterImg;
if sChk.StartsWith('*HB*|') then
begin
_bIgrPrtWater := true;
var StrList: TStringList;
Guard(StrList, TStringList.Create);
SplitString(UpperCase(sChk), '|', StrList);
sChk := UpperCase(_sPrtName);
for i := 0 to StrList.Count - 1 do
begin
if Pos(StrList[i], sChk) > 0 then
begin
_bIgrPrtWater := false;
break;
end;
end;
end;
end;
end;
CUSTOMER_GEC,
CUSTOMER_HDENG :
begin
// 프린터에 따라 출력 처리
// if (gAppHook.Helper.CtrlOpt.dwCustomerType = CUSTOMER_GEC) and (_sPrtName <> '') then
// begin
// if (Pos('CANON', UpperCase(_sPrtName)) = 0) then
// begin
// _sLabelName := 'NoPrt';
// _bIgrPrtWater := true;
// end;
// end;
if _sLabelName = '' then
begin
sDocPath := sDocName;
if not FileExists(sDocPath) then
begin
// 엑셀에서 대괄호 [ 를 모두 괄호 ( 로 인식하는 문제가 있어서 아래처럼 처리 23_1218 10:44:27 kku
sDocPath := FindPrintingFile(sDocPath, CompareText('excel.exe', gAppHook.ModuleName) = 0);
end;
// LogToReg('Step2', 'PrintWater .. 2 : ' + sDocPath);
if (sDocPath = '') and (CompareText('notepad.exe', gAppHook.ModuleName) = 0) then
begin
// Windows 11 메모장에서 문서 이름이 현재 파일이 아닌 단순 "메모장"으로 뜨게된다. 23_0322 10:57:54 kku
sDocPath := GetWindowCaption(GetForegroundWindow);
sDocPath := FindPrintingFile(sDocPath);
end;
SetRegValueString(HKEY_CURRENT_USER, 'SOFTWARE\eCrmHomeEdition', 'PrtPath', sDocPath, true);
if FileExists(sDocPath) then
begin
// LogToReg('Step3', 'PrintWater .. 3 : ' + sDocPath);
// _sLabelName := ExtractFileName(sDocPath);
// _sLabelName := sDocPath;
// 오피스 파일은 열려 있는 상태에서 레이블 확인이 불가능하다. 복사해서 처리 23_1018 17:28:11 kku
var sTaskDir: String := 'C:\ProgramData\HE\HEC\';
if ForceDirectories(sTaskDir) then
begin
// LogToReg('Step4', 'PrintWater .. 4 : ' + sDocPath);
var sDest: String := sTaskDir + ExtractFileName(sDocPath);
if CopyFile(PChar(sDocPath), PChar(sDest), false) then
begin
// LogToReg('Step5', 'PrintWater .. 5 : ' + sDocPath);
var h := FindWindow(nil, 'BSOne-AIP-T140713-BSOne-AIP-Decrypt.exe');
// if h = 0 then
// h := FindAipMdWnd;
if h <> 0 then
begin
// LogToReg('Step6', 'PrintWater .. 6 : ' + gAppHook.Helper.CtrlOpt.sAcSSid);
O := SO;
O.S['src'] := sDest;
O.S['dst'] := sDest + '.tmp';
O.S['ssid'] := gAppHook.Helper.CtrlOpt.sAcSSid;
DelRegValue(HKEY_CURRENT_USER, 'SOFTWARE\eCrmHomeEdition', 'ALabel');
if SendData(h, 4, O.AsString) = 10 then
begin
_sLabelName := GetRegValueAsString(HKEY_CURRENT_USER, 'SOFTWARE\eCrmHomeEdition', 'ALabel');
// LogToReg('Step7', 'PrintWater .. 7 : ' + _sLabelName);
if gAppHook.Helper.CtrlOpt.dwCustomerType = CUSTOMER_HDENG then
begin
i := Pos('(', _sLabelName);
if i > 0 then
SetLength(_sLabelName, i - 1);
end;
_bIgrPrtWater := (_sLabelName = '') or
(Pos('일반', _sLabelName) > 0) or
(Pos('ANYUSER', _sLabelName.ToUpper) > 0);
if _bIgrPrtWater then
_sLabelName := '';
end;
// else
// LogToReg('Step6', 'PrintWater .. 6 : ' + gAppHook.Helper.CtrlOpt.sAcSSid + ' Code : ' + IntToStr(i));
end;
DeleteFile(PChar(sDest));
end;
end;
end else
// 파일을 찾을 수 없을 경우 무조건 워터마크 찍도록 변경 23_1110 12:43:01 kku
// if CompareText(gAppHook.ModuleName, 'MSIP.Viewer.exe') = 0 then
begin
// AIP 뷰어로 보는 파일은 파일 이름을 알아낼 방법이 없다..
// 그래서 강제 지정.. 23_1019 15:37:40 kku
if gAppHook.Helper.CtrlOpt.dwCustomerType = CUSTOMER_HDENG then
_sLabelName := '대외비'
else
_sLabelName := '대외비(Restricted)';
_bIgrPrtWater := false;
end;
end;
if _sLabelName = '' then
_bIgrPrtWater := true;
end;
CUSTOMER_TMAP :
begin
sDocPath := sDocName;
if not FileExists(sDocPath) then
begin
// 엑셀에서 대괄호 [ 를 모두 괄호 ( 로 인식하는 문제가 있어서 아래처럼 처리 23_1218 10:44:27 kku
sDocPath := FindPrintingFile(sDocPath, CompareText('excel.exe', gAppHook.ModuleName) = 0);
end;
if (sDocPath = '') and (CompareText('notepad.exe', gAppHook.ModuleName) = 0) then
begin
// Windows 11 메모장에서 문서 이름이 현재 파일이 아닌 단순 "메모장"으로 뜨게된다. 23_0322 10:57:54 kku
sDocPath := GetWindowCaption(GetForegroundWindow);
sDocPath := FindPrintingFile(sDocPath);
end;
{$IFDEF _BS1HP_}
if FileExists(sDocPath) then
begin
if SendCopyData(gAppHook.Helper.CtrlOpt.hRcvWnd,
HPCMD_CHECK_PRINTWATER_EXCEPT, sDocPath) = 300 then _bIgrPrtWater := true;
end;
{$ENDIF}
end;
end;
{$IFDEF _BS1HP_}
// 워터마크 예외 처리 추가 25_1014 14:12:19 kku
if not _bIgrPrtWater then
begin
O := SO;
O.S['PrtName'] := _sPrtName;
if sDocPath = '' then
begin
sDocPath := sDocName;
sDocPath := FindPrintingFile(sDocPath, CompareText('excel.exe', gAppHook.ModuleName) = 0);
end;
O.S['DocName'] := sDocPath;
O.S['AppName'] := gAppHook.Helper.AppName;
if SendCopyData(gAppHook.Helper.CtrlOpt.hRcvWnd,
HPCMD_CHECK_PRINTWATER_EXCEPT_EX, O.AsJSon) = 300 then _bIgrPrtWater := true;
end;
{$ENDIF}
// gAppHook.Helper.CopyPrintDC(dc);
if gAppHook <> nil then
begin
{$IFDEF _BS1HP_}
// if (gAppHook.Helper.CtrlOpt.hRcvWnd <> 0) and (gAppHook.Helper.sCurDocName_ <> sDocName) then // 다른 프로그램에서 출력하고 다시 동일 문서 출력 시 감지 안됨 25_0917 17:29:13 kku
if gAppHook.Helper.CtrlOpt.hRcvWnd <> 0 then
begin
O := SO;
O.S['PrtName'] := _sPrtName;
O.S['DocName'] := sDocName;
O.S['PrtDocId'] := _sPrtDocId;
O.S['PName'] := gAppHook.ModuleName;
O.I['PID'] := gAppHook.PID;
var nRst: Integer := SendCopyData(gAppHook.Helper.CtrlOpt.hRcvWnd, HPCMD_PRINT_DOCNAME, O.AsJSon);
if nRst = 300 then // 차단 25_1127 14:38:24 kku
Result := false;
// if (gAppHook.Helper.CtrlOpt.dwCustomerType = CUSTOMER_HDENG) and _bIgrPrtWater then
// SendCopyData(gAppHook.Helper.CtrlOpt.hRcvWnd, HPCMD_PRINT_DOCNAME, 'NoWater')
// else
// SendCopyData(gAppHook.Helper.CtrlOpt.hRcvWnd, HPCMD_PRINT_DOCNAME, sDocName);
end;
{$ENDIF}
// _nRecentPage := 0;
gAppHook.Helper.nPtrCnt_ := 0;
gAppHook.Helper.sCurDocName_ := sDocName;
end;
// _bIgrPrtWater := false;
gAppHook.Log('StartDocWHook() - lpszDocName = ' + sDocName);
if FileExists(gAppHook.sLogPath_) then
DeleteFile(PChar(ExtractFilePath(gAppHook.sLogPath_) + 'PrintText.txt'));
end;
end;
function CreateWatermarkBitmap(dc: HDC; sTxt: String): HBITMAP;
var
BmpDC: HDC;
Bmp: HBITMAP;
Font: HFONT;
Text: string;
begin
BmpDC := CreateCompatibleDC(dc);
Bmp := CreateCompatibleBitmap(dc, 800, 200); // 워터마크 영역 크기
SelectObject(BmpDC, Bmp);
Font := CreateFont(48, 0, 0, 0, FW_BOLD, 0, 0, 0, DEFAULT_CHARSET,
OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
ANTIALIASED_QUALITY, VARIABLE_PITCH, 'Arial');
SelectObject(BmpDC, Font);
SetBkMode(BmpDC, TRANSPARENT);
SetTextColor(BmpDC, RGB(150, 150, 150));
Text := sTxt;
TextOut(BmpDC, 100, 50, PChar(Text), Length(Text));
DeleteDC(BmpDC);
Result := Bmp;
end;
function StartDocAHook(dc: HDC; pDocInfo: PDocInfoA): Integer; stdcall;
begin
// SaveStrToFile('C:\ProgramData\HE\test1.txt', Format('StartDocAHook() ... PName=%s', [gAppHook.ModuleName]));
if not ProcStartDoc(AnsiString(pDocInfo.lpszDocName)) then
begin
Result := 0;
exit;
end;
Result := ozStartDocA(dc, pDocInfo);
// CreateWatermarkBitmap(dc, 'StartDocAHook');
// if gAppHook.Helper.CopyPtrBmp_ <> nil then
// Result := ozStartDocW(gAppHook.Helper.CopyPtrBmp_.Canvas.Handle, pDocInfo)
// else
// Result := ozStartDocW(dc, pDocInfo);
end;
function StartDocWHook(dc: HDC; pDocInfo: PDocInfoW): Integer; stdcall;
var
sChkDoc,
sDocName: String;
i: Integer;
begin
SaveStrToFile('C:\ProgramData\HE\test2.txt', Format('StartDocWHook() ... PName=%s', [gAppHook.ModuleName]));
if not ProcStartDoc(String(pDocInfo.lpszDocName)) then
begin
Result := 0;
exit;
end;
Result := ozStartDocW(dc, pDocInfo);
// CreateWatermarkBitmap(dc, 'StartDocWHook');
// if gAppHook.Helper.CopyPtrBmp_ <> nil then
// Result := ozStartDocW(gAppHook.Helper.CopyPtrBmp_.Canvas.Handle, pDocInfo)
// else
// Result := ozStartDocW(dc, pDocInfo);
end;
function StartPageHook(dc: HDC): Integer; stdcall;
begin
_PrtDC := dc;
_bDoEndProc := false;
// if gAppHook.Helper.CtrlOpt.bPrintMasking then
// gAppHook.Helper.PrtDC := DC
// else
// gAppHook.Helper.PrtDC := 0;
// LogToReg('Step-', Format('StartPageHook, DC=%d, Cnt=%d', [DC, gAppHook.PrtMaskList.Count]));
Inc(_nPageCnt);
if gAppHook.Helper.CtrlOpt.bPrintSecu or gAppHook.Helper.CtrlOpt.bPrintWater then
begin
gAppHook.Log('StartPageHook()');
if not _bIgrPrtWater and
(_sPrtName <> '') and (gAppHook.Helper.CtrlOpt.sPrintWaterExp <> '') then
begin
var ExpList: TStringList;
var sChkName: String := UpperCase(_sPrtName);
var i: Integer;
Guard(ExpList, TStringList.Create);
SplitString(UpperCase(gAppHook.Helper.CtrlOpt.sPrintWaterExp), '|', ExpList);
for i := 0 to ExpList.Count - 1 do
begin
if Pos(ExpList[i], sChkName) > 0 then
begin
_bIgrPrtWater := true;
break;
end;
end;
end;
Inc(gAppHook.Helper.nPtrCnt_);
if gAppHook.Helper.CtrlOpt.bPrtCollect and
(gAppHook.Helper.CtrlOpt.sPrtEmfOutDir <> '') then
begin
// gAppHook.Log('sTextOutDir = %s', [gAppHook.Helper.CtrlOpt.sTextOutDir]);
CreateCopyDC(DC, GetValidFileName(_sDocName, '#'), _nPageCnt);
end;
Result := ozStartPage(dc);
// 별도 프로시저 만들어서 사용하면 안된다.. 그래서 StartPageHook(), EndPageHook() 각각 구현 22_0907 15:06:14 kku
if gAppHook.Helper.CtrlOpt.bPrintWater and (Result = 1) and
( not gAppHook.Helper.bEndDocProc_ or gAppHook.Helper.bBothDocProc_) then
begin
gAppHook.Log('StartPageHook() .. ProcessWartermark()');
if not ProcessWartermarkCustomer(gAppHook.Helper.CtrlOpt.dwCustomerType, dc, true) then
Result := -1;
end;
end else begin
Result := ozStartPage(dc);
end;
end;
function EndPageHook(dc: HDC): Integer; stdcall;
begin
if gAppHook.Helper.CtrlOpt.bPrintWater and
(gAppHook.Helper.bEndDocProc_ or gAppHook.Helper.bBothDocProc_) then
begin
gAppHook.Log('EndPageHook() .. ProcessWartermark()');
if not ProcessWartermarkCustomer(gAppHook.Helper.CtrlOpt.dwCustomerType, dc, false) then
Result := -1;
end;
gAppHook.Log('EndPageHook()');
DeleteCopyDC;
gAppHook.Helper.sPtrText_ := '';
_bDoStartProc := false;
Result := ozEndPage(dc);
_PrtDC := 0;
end;
function EndDocHook(dc: HDC): Integer;
begin
// CreateWatermarkBitmap(dc, 'EndDocHook');
Result := ozEndDoc(dc);
try
if gAppHook <> nil then
begin
// SetRegValueString(HKEY_CURRENT_USER, 'Software\eCrmHomeEdition', 'PrtPageCnt', IntToStr(_nPageCnt), true);
gAppHook.Helper.bIsPrinting_ := false;
gAppHook.PrtMaskList.Clear;
// Word에서는 부수 정보를 제대로 가져올 수 없어서
// 이렇게 전체 출력되는 페이지 정보를 별도 가져와서 계산한다 25_0813 14:48:40 kku
// if CompareText('winword.exe', gAppHook.ModuleName) = 0 then
// begin
// var O: ISuperObject := SO;
// O.S['MdPath'] := gAppHook.ModulePath;
// O.S['PrtName'] := _sPrtName;
// O.S['DrvName'] := _sDrvName;
// O.S['DevName'] := _sDevName;
// O.S['DocName'] := _sDocName;
// O.I['PageCnt'] := _nPageCnt;
// SendCopyData(gAppHook.Helper.CtrlOpt.hRcvWnd, HPCMD_PRINT_ENDDOC_INFO, O.AsJSon);
// end;
end;
_bIgrPrtWater := false;
_sLabelName := '';
if _bmpWater <> nil then
FreeAndNil(_bmpWater);
if _bmpWaterP <> nil then
FreeAndNil(_bmpWaterP);
except
// ..
end;
end;
function WritePrinterHook(hPrinter: THandle; pBuf: Pointer; cbBuf: DWORD;
var pcWritten: DWORD): BOOL; stdcall;
begin
// gAppHook.Log('WritePrinterHook()');
// var fs: TFileStream;
// Guard(fs, TFileStream.Create('c:\WritePrinterHook.dat', fmCreate));
// fs.Write(pBuf^, cbBuf);
Result := ozWritePrinter(hPrinter, pBuf, cbBuf, pcWritten);
end;
// 이렇게 하면 Release 빌드 시 프린트가 실패한다;; 이유는 몰라, 귀찮아서 넘어감 22_1013 16:12:53 kku
//function EndDocHook(dc: HDC): Integer; stdcall;
//begin
// if gAppHook.PrintMarkActive and (gAppHook.sRecentPtrDoc_ <> '') then
// gAppHook.ProcessNoti(NOTI_HOOK_MONITOR_PRINT_WATER, gAppHook.sRecentPtrDoc_);
//end;
procedure ReplaceTextA(sStr: LPCSTR); inline; stdcall;
var
sData: AnsiString;
bMod: Boolean;
i: Integer;
begin
try
if gAppHook = nil then
exit;
if not gAppHook.Helper.bIsPrinting_ or (gAppHook.PrtMaskList.Count = 0) then
exit;
bMod := false;
sData := AnsiString(sStr);
for i := 0 to gAppHook.PrtMaskList.Count - 1 do
begin
if Pos(gAppHook.PrtMaskList[i], sData) > 0 then
begin
sData := StringReplace(sData, gAppHook.PrtMaskList[i],
MakeCharStr('*', Length(gAppHook.PrtMaskList[i])), [rfReplaceAll]);
bMod := true;
end;
end;
if bMod then
CopyMemory(@sStr[0], @sData[1], Length(sData));
except
// ..
end;
end;
function LPCWSTRToString(const ws: LPCWSTR): UTF8String;
var
len: Integer;
begin
// WideChar (UTF-16)에서 UTF-8로 변환
len := WideCharToMultiByte(CP_UTF8, 0, ws, -1, nil, 0, nil, nil);
SetLength(Result, len - 1);
if len > 1 then
begin
WideCharToMultiByte(CP_UTF8, 0, ws, -1, PAnsiChar(Result), len - 1, nil, nil);
end;
end;
procedure ReplaceTextW(sStr: LPCWSTR); inline; stdcall;
var
sData: String;
bMod: Boolean;
i: Integer;
begin
try
if gAppHook = nil then
exit;
// LogToReg('Step8', Format('ReplaceTextW, Cnt=%d, DC=%d', [gAppHook.PrtMaskList.Count, gAppHook.Helper.PrtDC]));
// if not gAppHook.Helper.bIsPrinting_ or (gAppHook.PrtMaskList.Count = 0) then
// exit;
LogToReg('Step9', Format('ReplaceTextW, Cnt=%d', [gAppHook.PrtMaskList.Count]));
bMod := false;
sData := WideString(sStr);
// if Pos('로그', sData) > 0 then
// begin
// sData := StringReplace(sData, '로그', '**', [rfReplaceAll]);
// bMod := true;
// end;
// LogToReg(Format('Step10-%d, PName=%s', [_nTest, gAppHook.ModuleName]), sData);
for i := 0 to gAppHook.PrtMaskList.Count - 1 do
begin
if Pos(gAppHook.PrtMaskList[i], sData) > 0 then
begin
sData := StringReplace(sData, gAppHook.PrtMaskList[i],
MakeCharStr('*', Length(gAppHook.PrtMaskList[i])), [rfReplaceAll]);
LogToReg('Step10', Format('ReplaceTextW, Match=%s', [sData, gAppHook.PrtMaskList[i]]));
bMod := true;
end;
end;
if bMod then
CopyMemory(@sStr[0], @sData[1], Length(sData) * 2);
except
// ..
end;
end;
{
// nX := 0;
nX := GetDeviceCaps(DC, ASPECTX);
// nY := GetDeviceCaps(DC, ASPECTY);
// for i := 0 to 3 do
// sOut := sOut + WORD_GAP + sOut;
i := GetDeviceCaps(DC, ASPECTY) - 300; // 0;
nRepeat := 2; // gAppHook.Helper.CtrlOpt.nLineCount;
nGapH := nH div nRepeat; // (nRepeat - 1);
if gAppHook.Helper.bSmallFont_ then
nGapH := nGapH div 7;
while i < nH do // + nGapH do
begin
MemCanvas.TextOut(nX, i, sOut);
Inc(i, nGapH);
Dec(nRepeat);
if nRepeat = 0 then
break;
end;
if bStartPage then
begin
BitBlt(DC, 0, 0, nW, nH, MemCanvas.Handle, 0, 0, SRCCOPY);
// var bf: BLENDFUNCTION;
// ZeroMemory(@bf, SizeOf(bf));
// bf.AlphaFormat := 0; // 일반 비트맵 0, 32비트 비트맵 AC_SRC_ALPHA
// bf.BlendFlags := 0; // 무조건 0
// bf.BlendOp := AC_SRC_OVER; // AC_SRC_OVER
// bf.SourceConstantAlpha := 100; // 투명도(투명 0 - 불투명 255)
// AlphaBlend(DC, 0, 0, nW, nH, MemCanvas.Handle, 0, 0, nW, nH, bf);
end;
}
//
//function DrawTextAHook(hDC: HDC; lpString: LPCSTR; nCount: Integer;
// var lpRect: TRect; uFormat: UINT): Integer; stdcall;
//begin
// if (gAppHook <> nil) and (gAppHook.Helper.PrtDC = hDC) then
// ReplaceTextA(lpString);
// Result := ozDrawTextA(hDc, lpString, nCount, lpRect, uFormat);
//end;
//
//function DrawTextWHook(hDC: HDC; lpString: LPCWSTR; nCount: Integer;
// var lpRect: TRect; uFormat: UINT): Integer; stdcall;
//begin
// if (gAppHook <> nil) and (gAppHook.Helper.PrtDC = hDC) then
// ReplaceTextW(lpString);
// Result := ozDrawTextW(hDc, lpString, nCount, lpRect, uFormat);
//end;
//
//function DrawTextExAHook(DC: HDC; lpchText: LPCSTR; cchText: Integer; var p4: TRect;
// dwDTFormat: UINT; DTParams: PDrawTextParams): Integer; stdcall;
//begin
// if (gAppHook <> nil) and (gAppHook.Helper.PrtDC = DC) then
// ReplaceTextA(lpchText);
// Result := ozDrawTextExA(DC, lpchText, cchText, p4, dwDTFormat, DTParams);
//end;
//
//function DrawTextExWHook(DC: HDC; lpchText: LPCWSTR; cchText: Integer; var p4: TRect;
// dwDTFormat: UINT; DTParams: PDrawTextParams): Integer; stdcall;
//begin
// if (gAppHook <> nil) and (gAppHook.Helper.PrtDC = DC) then
// ReplaceTextW(lpchText);
// Result := ozDrawTextExW(DC, lpchText, cchText, p4, dwDTFormat, DTParams);
//end;
//
//function ExtTextOutAHook(DC: HDC; X, Y: Integer; Options: Longint;
// Rect: PRect; Str: LPCSTR; Count: Longint; Dx: PInteger): BOOL; stdcall;
//begin
// if (gAppHook <> nil) and (gAppHook.Helper.PrtDC = DC) then
// ReplaceTextA(Str);
// Result := ozExtTextOutA(DC, X, Y, Options, Rect, Str, Count, Dx);
//end;
//
//function ExtTextOutWHook(DC: HDC; X, Y: Integer; Options: Longint;
// Rect: PRect; Str: LPCWSTR; Count: Longint; Dx: PInteger): BOOL; stdcall;
//begin
// if (gAppHook <> nil) and (gAppHook.Helper.PrtDC = DC) then
// ReplaceTextW(Str);
// Result := ozExtTextOutW(DC, X, Y, Options, Rect, Str, Count, Dx);
//end;
//
//function TextOutAHook(DC: HDC; X, Y: Integer; Str: LPCSTR; Count: Integer): BOOL; stdcall;
//begin
// if (gAppHook <> nil) and (gAppHook.Helper.PrtDC = DC) then
// ReplaceTextA(Str);
// Result := ozTextOutA(DC, X, Y, Str, Count);
//end;
//
//function TextOutWHook(DC: HDC; X, Y: Integer; Str: LPCWSTR; Count: Integer): BOOL; stdcall;
//begin
// if (gAppHook <> nil) and (gAppHook.Helper.PrtDC = DC) then
// ReplaceTextW(Str);
// Result := ozTextOutW(DC, X, Y, Str, Count);
//end;
//
//function PolyTextOutAHook(DC: HDC; const PolyTextArray; Strings: Integer): BOOL; stdcall;
//type
// TArrayLPCSTR = array [0..0] of LPCSTR;
//var
// i: Integer;
//begin
// if (gAppHook <> nil) and (gAppHook.Helper.PrtDC = DC) then
// begin
// try
// for i := 0 to Strings - 1 do
// ReplaceTextA(TArrayLPCSTR(PolyTextArray)[i]);
// except
// // ..
// end;
// end;
// Result := ozPolyTextOutA(DC, PolyTextArray, Strings);
//end;
//
//function PolyTextOutWHook(DC: HDC; const PolyTextArray; Strings: Integer): BOOL; stdcall;
//type
// TArrayLPCWSTR = array [0..0] of LPCWSTR;
//var
// i: Integer;
//begin
// if (gAppHook <> nil) and (gAppHook.Helper.PrtDC = DC) then
// begin
// try
// for i := 0 to Strings - 1 do
// ReplaceTextW(TArrayLPCWSTR(PolyTextArray)[i]);
// except
// // ..
// end;
// end;
// Result := ozPolyTextOutW(DC, PolyTextArray, Strings);
//end;
//
//function TabbedTextOutAHook(hDC: HDC; X, Y: Integer; lpString: LPCSTR; nCount, nTabPositions: Integer;
// var lpnTabStopPositions; nTabOrigin: Integer): Longint; stdcall;
//begin
// if (gAppHook <> nil) and (gAppHook.Helper.PrtDC = hDC) then
// ReplaceTextA(lpString);
// Result := ozTabbedTextOutA(hDC, X, Y, lpString, nCount, nTabPositions,
// lpnTabStopPositions, nTabOrigin);
//end;
//
//function TabbedTextOutWHook(hDC: HDC; X, Y: Integer; lpString: LPCWSTR; nCount, nTabPositions: Integer;
// var lpnTabStopPositions; nTabOrigin: Integer): Longint; stdcall;
//begin
// if (gAppHook <> nil) and (gAppHook.Helper.PrtDC = hDC) then
// ReplaceTextW(lpString);
// Result := ozTabbedTextOutW(hDC, X, Y, lpString, nCount, nTabPositions,
// lpnTabStopPositions, nTabOrigin);
//end;
initialization
_bmpWater := nil;
_bmpWaterP := nil;
_sbmpWaterIf := '';
_sLabelName := '';
_bIgrPrtWater := false;
_PrtDC := 0;
_bDoStartProc := false;
_bDoEndProc := false;
_nFontSize := 0;
_sDrvName := '';
_sDevName := '';
_sPrtName := '';
gPrtWatering := false;
end.