unit DDispLogo; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Imaging.pngimage, Vcl.ExtCtrls, System.Generics.Collections, Vcl.Imaging.jpeg, hyieutils, iexBitmaps, hyiedefs, iesettings, iexLayers, iexRulers, ieview, imageenview, imageen; type TTransparentWnd = class(TObject) private bAlphaBlend_: Boolean; public constructor Create(bAlphaBlend: Boolean); reintroduce; procedure SetTransparentWnd(aHWND: HWND; bTransparent: Boolean); end; TOriLabel = class(TLabel) protected pnTaskBar_: TPanel; procedure Paint; override; end; TDlgDispLogo = class(TForm) pnTaskBar: TPanel; pnClient: TPanel; lbLogo: TLabel; imgLogo: TImage; tTime: TTimer; tStayTop: TTimer; imgST: TImageEn; procedure tTimeTimer(Sender: TObject); procedure tStayTopTimer(Sender: TObject); private { Private declarations } TP_: TTransparentWnd; sImgPath_, sLogoTxt_, sDtFormat_: String; lbOriLogo_: TOriLabel; public { Public declarations } Constructor Create(aOwner: TComponent); override; procedure CreateParams(var Params: TCreateParams); override; Destructor Destroy; override; procedure SetSnaptagImg; // nOri로 회전을 시키면 문자열 길이 만큼 시작 점이 아래로 내려가는데, // nOriTop으로 올려주는걸로 보전하는걸 추가했다.. 22_1201 14:10:53 kku procedure SetText(sText: String; aFont: TFont; nPos1, nPos2, nOri, nOriTop: Integer; aTxtColor, aBgColor: TColor; sDtFormat: String; nUpdateMSec: Integer); procedure SetTextHEC(sText: String; nLineCnt: Integer; aFont: TFont; nPos1, nPos2, nOri: Integer; aTxtColor, aBgColor: TColor; sDtFormat: String; nUpdateMSec: Integer); // 현대엔지니어링 요건을 맞추기 위해... 23_0920 14:20:45 kku procedure SetTextWEL(sText: String; nLineCnt: Integer; aFont: TFont; nPos1, nPos2, nOri: Integer; aTxtColor, aBgColor: TColor; sDtFormat: String; nUpdateMSec: Integer); // 현대엔지니어링 요건을 맞추기 위해... 23_0920 14:20:45 kku procedure SetImage(sImgPath: String; nPos1, nPos2: Integer); procedure SetImageFromStream(aStream: TStream; nPos1, nPos2: Integer; nTopMargin: Integer = 0); procedure SetTaskbarDetect(bVal: Boolean); procedure process_WM_SYSCOMMAND(var msg: TWMSysCommand); Message WM_SYSCOMMAND; end; TDlgDispLogoList = class(TList) protected procedure Notify(const Item: TDlgDispLogo; Action: TCollectionNotification); override; public procedure CreateLogos; procedure SetText(sText: String; aFont: TFont; nPos1, nPos2, nOri, nOriTop: Integer; aTxtColor, aBgColor: TColor; sDtFormat: String; nUpdateMSec: Integer); procedure SetTextHEC(sText: String; nLineCnt: Integer; aFont: TFont; nPos1, nPos2, nOri: Integer; aTxtColor, aBgColor: TColor; sDtFormat: String; nUpdateMSec: Integer); // 현대엔지니어링 요건을 맞추기 위해... 23_0920 14:20:45 kku procedure SetTextWEL(sText: String; nLineCnt: Integer; aFont: TFont; nPos1, nPos2, nOri: Integer; aTxtColor, aBgColor: TColor; sDtFormat: String; nUpdateMSec: Integer); procedure SetImage(sImgPath: String; nPos1, nPos2: Integer); procedure SetImageFromStream(aStream: TStream; nPos1, nPos2: Integer; nTopMargin: Integer = 0); procedure SetAlpha(nAlpha: Integer); procedure SetTaskbarDetect(bVal: Boolean); procedure SetCaptureBlock(bVal: Boolean); end; var DlgDispLogo: TDlgDispLogo; implementation uses Tocsg.Safe, Tocsg.Exception, Tocsg.Strings, Tocsg.Convert; {$R *.dfm} { TOriLabel } procedure TOriLabel.Paint; var nH, nTextWidth, nTextHeight, nParentHeight, nParentWidth: Integer; t, dx, dy: Double; begin // Inherited; Canvas.Brush.Style := bsClear; // Font.Orientation := 0; Canvas.Font.Assign(Font); nParentWidth := Width; nParentHeight := Height; if Parent <> nil then begin nParentWidth := Parent.Width; nParentHeight := Parent.Height; // if (pnTaskBar_.Align = alLeft) or (pnTaskBar_.Align = alRight) then // Inc(nParentWidth, + pnTaskBar_.Width); // if (pnTaskBar_.Align = alTop) or (pnTaskBar_.Align = alBottom) then // Inc(nParentHeight, pnTaskBar_.Height); end; nTextWidth := Canvas.TextWidth(Caption); nTextHeight := Canvas.TextHeight(Caption); // 왼쪽 위 사선 // nH := nTextWidth div 2;// Canvas.TextExtent(Caption).cy; if Font.Orientation > 0 then begin t := Font.Orientation * Pi /1800; dx := nTextHeight * Sin(t); dy := nTextWidth * Sin(t); nH := Round(dy); end; Canvas.TextOut(10, nH, Caption); Canvas.TextOut(nParentWidth - nTextWidth, nH, Caption); // 가운데 사선 두개 Canvas.TextOut(10, nParentHeight - nTextHeight, Caption); Canvas.TextOut(nParentWidth - nTextWidth, nParentHeight - nTextHeight - 30, Caption); // 오른쪽 아래 사선 // Canvas.TextOut(10, nParentHeight + nH - (nTextHeight div 2), Caption); end; { TDlgDispLogoList } procedure TDlgDispLogoList.Notify(const Item: TDlgDispLogo; Action: TCollectionNotification); begin if Action = cnRemoved then Item.Free; end; procedure TDlgDispLogoList.CreateLogos; var i: Integer; DispLogo: TDlgDispLogo; begin try for i := 0 to Screen.MonitorCount - 1 do begin DispLogo := TDlgDispLogo.Create(nil); DispLogo.Left := Screen.Monitors[i].Left; DispLogo.Top := Screen.Monitors[i].Top; DispLogo.Width := Screen.Monitors[i].Width {$IFDEF _HE_} - 1 {$ENDIF}; // 알림센터 팝업하게 하려면 화면을 꽉차게 하면 안된다 22_0823 15:26:24 kku DispLogo.Height := Screen.Monitors[i].Height {$IFDEF _HE_} - 1 {$ENDIF}; // 알림센터 팝업하게 하려면 화면을 꽉차게 하면 안된다 22_0823 15:26:24 kku Add(DispLogo); // SetWindowDisplayAffinity(DispLogo.Handle, 1); end; except on E: Exception do begin Clear; ETgException.TraceException(Self, E, 'Fail .. CreateLogos()'); end; end; end; procedure TDlgDispLogoList.SetText(sText: String; aFont: TFont; nPos1, nPos2, nOri, nOriTop: Integer; aTxtColor, aBgColor: TColor; sDtFormat: String; nUpdateMSec: Integer); var i: Integer; begin for i := 0 to Count - 1 do Items[i].SetText(sText, aFont, nPos1, nPos2, nOri, nOriTop, aTxtColor, aBgColor, sDtFormat, nUpdateMSec); end; procedure TDlgDispLogoList.SetTextHEC(sText: String; nLineCnt: Integer; aFont: TFont; nPos1, nPos2, nOri: Integer; aTxtColor, aBgColor: TColor; sDtFormat: String; nUpdateMSec: Integer); var i: Integer; begin for i := 0 to Count - 1 do Items[i].SetTextHEC(sText, nLineCnt, aFont, nPos1, nPos2, nOri, aTxtColor, aBgColor, sDtFormat, nUpdateMSec); end; procedure TDlgDispLogoList.SetTextWEL(sText: String; nLineCnt: Integer; aFont: TFont; nPos1, nPos2, nOri: Integer; aTxtColor, aBgColor: TColor; sDtFormat: String; nUpdateMSec: Integer); var i: Integer; begin for i := 0 to Count - 1 do Items[i].SetTextWEL(sText, nLineCnt, aFont, nPos1, nPos2, nOri, aTxtColor, aBgColor, sDtFormat, nUpdateMSec); end; procedure TDlgDispLogoList.SetImage(sImgPath: String; nPos1, nPos2: Integer); var i: Integer; begin for i := 0 to Count - 1 do Items[i].SetImage(sImgPath, nPos1, nPos2); end; procedure TDlgDispLogoList.SetImageFromStream(aStream: TStream; nPos1, nPos2: Integer; nTopMargin: Integer = 0); var i: Integer; begin for i := 0 to Count - 1 do Items[i].SetImageFromStream(aStream, nPos1, nPos2, nTopMargin); end; procedure TDlgDispLogoList.SetAlpha(nAlpha: Integer); var i: Integer; begin for i := 0 to Count - 1 do begin if nAlpha > 0 then begin if not Items[i].AlphaBlend then Items[i].AlphaBlend := true; Items[i].AlphaBlendValue := nAlpha; end else Items[i].AlphaBlend := false; end; end; procedure TDlgDispLogoList.SetTaskbarDetect(bVal: Boolean); var i: Integer; begin for i := 0 to Count - 1 do Items[i].SetTaskbarDetect(bVal); end; procedure TDlgDispLogoList.SetCaptureBlock(bVal: Boolean); var i: Integer; begin for i := 0 to Count - 1 do SetWindowDisplayAffinity(Items[i].Handle, BooleanToInt(bVal, 1, 0)); end; { TTransparentWnd } constructor TTransparentWnd.Create(bAlphaBlend: Boolean); begin Inherited Create; bAlphaBlend_ := bAlphaBlend; end; procedure TTransparentWnd.SetTransparentWnd(aHWND: HWND; bTransparent: Boolean); var nStyle, nExStyle: Integer; begin nExStyle := GetWindowLong(aHWND, GWL_EXSTYLE); if bTransparent then nStyle := nExStyle or WS_EX_LAYERED or WS_EX_TRANSPARENT else begin nStyle := nExStyle and (not WS_EX_TRANSPARENT); if not bAlphaBlend_ then nStyle := nStyle and (nExStyle and (not WS_EX_LAYERED)); end; SetWindowLong(aHWND, GWL_EXSTYLE, nStyle); // SetLayeredWindowAttributes(Form.Handle, 0, 128, LWA_ALPHA); // 128은 반투명 // ? 테스트 안됨 25_0807 10:59:02 kku end; { TDlgDispLogo } Constructor TDlgDispLogo.Create(aOwner: TComponent); begin Inherited Create(aOwner); sImgPath_ := ''; sDtFormat_ := ''; lbOriLogo_ := nil; // 작업표시줄에서 없애기 // SetTransparentWnd() 다음에 하면 SetTransparentWnd()가 무력화 된다 반드시 전에 해야 함 22_0530 17:07:41 kku SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Application.Handle, GWL_EXSTYLE) or WS_EX_TOOLWINDOW); TP_ := TTransparentWnd.Create(true); TP_.SetTransparentWnd(Handle, True); tStayTop.Enabled := true; end; procedure TDlgDispLogo.CreateParams(var Params: TCreateParams); begin inherited CreateParams( Params ); //TDlgDispLogoMain Child에서 벗어나기 위해 처리 Params.WndParent := GetDesktopWindow; end; Destructor TDlgDispLogo.Destroy; begin FreeAndNil(TP_); Inherited; end; procedure TDlgDispLogo.SetSnaptagImg; begin end; procedure TDlgDispLogo.SetText(sText: String; aFont: TFont; nPos1, nPos2, nOri, nOriTop: Integer; aTxtColor, aBgColor: TColor; sDtFormat: String; nUpdateMSec: Integer); begin sLogoTxt_ := sText; if aFont <> nil then lbLogo.Font.Assign(aFont); case nPos1 of 1 : lbLogo.Alignment := taLeftJustify; 2 : lbLogo.Alignment := taRightJustify; else lbLogo.Alignment := taCenter; end; case nPos2 of 1 : lbLogo.Layout := tlTop; 2 : lbLogo.Layout := tlBottom; else lbLogo.Layout := tlCenter; end; lbLogo.Font.Color := aTxtColor; if nOri <> 0 then begin lbLogo.Align := alNone; lbLogo.Top := nOriTop; //(Screen.Height div 2) * -1; lbLogo.Left := 0; lbLogo.Width := Width; if nOriTop < 0 then lbLogo.Height := Height + (nOriTop * -1) else lbLogo.Height := Height; end; lbLogo.Font.Orientation := nOri; if Color <> aBgColor then begin Hide; TransparentColorValue := aBgColor; Color := aBgColor; end; sDtFormat_ := sDtFormat; if sDtFormat_ <> '' then lbLogo.Caption := StringReplace(sLogoTxt_, '{DateTime}', FormatDateTime(sDtFormat_, Now), [rfReplaceAll]) else lbLogo.Caption := StringReplace(sLogoTxt_, '{DateTime}', DateTimeToStr(Now), [rfReplaceAll]); tTime.Enabled := nUpdateMSec > 0; if tTime.Enabled then tTime.Interval := nUpdateMSec; lbLogo.BringToFront; Application.ProcessMessages; Show; end; procedure TDlgDispLogo.SetTextHEC(sText: String; nLineCnt: Integer; aFont: TFont; nPos1, nPos2, nOri: Integer; aTxtColor, aBgColor: TColor; sDtFormat: String; nUpdateMSec: Integer); var i, nRepeat, nWMax: Integer; sTemp, sTemp2, sTemp3: String; begin sLogoTxt_ := sText; lbLogo.Font.Assign(aFont); case nPos1 of 1 : lbLogo.Alignment := taLeftJustify; 2 : lbLogo.Alignment := taRightJustify; else lbLogo.Alignment := taCenter; end; case nPos2 of 1 : lbLogo.Layout := tlTop; 2 : lbLogo.Layout := tlBottom; else lbLogo.Layout := tlCenter; end; lbLogo.Font.Color := aTxtColor; lbLogo.Font.Orientation := nOri; if Color <> aBgColor then begin Hide; TransparentColorValue := aBgColor; Color := aBgColor; end; sTemp := sLogoTxt_; sTemp2 := ''; nWMax := Width * 2; //+ (Width div 3); // 4K 에서 짤림 현상 있다고 해서 2배로 늘림 23_1017 16:12:00 kku nRepeat := nWMax div lbLogo.Canvas.TextWidth(sLogoTxt_); for i := 0 to nRepeat do begin SumString(sTemp2, sTemp, ' '); if lbLogo.Canvas.TextWidth(sTemp2) >= nWMax then break; end; if nOri <> 0 then begin var nOriTop: Integer := (lbLogo.Height + (lbLogo.Height div 2)) * -1; // Round(lbLogo.Canvas.TextWidth(sTemp2) / 2.7) * -1; //(Height - (Height div 4)) * -1; lbLogo.Align := alNone; lbLogo.Top := nOriTop; lbLogo.Left := 0; lbLogo.Width := Width; if nOriTop < 0 then lbLogo.Height := Height + (nOriTop * -1) else lbLogo.Height := Height; end; sTemp := ''; sTemp3 := ''; // sTemp3 := sTemp2; // 처음에 하나 var nH: Integer; if Width > Height then nH := (Height + Round(Height / 3)) div nLineCnt else nH := Height div nLineCnt; var nTextH: Integer := lbLogo.Canvas.TextHeight('abc'); var StrList: TStringList; Guard(StrList, TStringList.Create); i := 0; while i < nH do begin StrList.Add(''); Inc(i, nTextH); end; if StrList.Count > 0 then begin i := StrList.Count div 2; if i < 0 then i := 0 else if i = StrList.Count then i := StrList.Count - 1; StrList[i] := sTemp2; end; for i := 0 to nLineCnt - 1 do sTemp3 := sTemp3 + StrList.Text; sLogoTxt_ := sTemp3; // nRepeat := ((Height - (Height div 4)) div Canvas.TextHeight(sTemp3)); // - (nRepeat div 5); // for i := 0 to nRepeat do // begin // if (nRepeat div 2) = i then // sTemp := sTemp + sTemp2 // 중간에 하나 // else // sTemp := sTemp + #13#10; // end; // sLogoTxt_ := sTemp3 + sTemp + sTemp2; // 끝에 하나 sDtFormat_ := sDtFormat; if sDtFormat_ <> '' then lbLogo.Caption := StringReplace(sLogoTxt_, '{DateTime}', FormatDateTime(sDtFormat_, Now), [rfReplaceAll]) else lbLogo.Caption := StringReplace(sLogoTxt_, '{DateTime}', DateTimeToStr(Now), [rfReplaceAll]); tTime.Enabled := nUpdateMSec > 0; if tTime.Enabled then tTime.Interval := nUpdateMSec; lbLogo.BringToFront; Application.ProcessMessages; Show; end; procedure TDlgDispLogo.SetTextWEL(sText: String; nLineCnt: Integer; aFont: TFont; nPos1, nPos2, nOri: Integer; aTxtColor, aBgColor: TColor; sDtFormat: String; nUpdateMSec: Integer); var i, nRepeat, nWMax: Integer; sTemp, sTemp2, sTemp3: String; lb: TLabel; begin if lbOriLogo_ = nil then begin lbOriLogo_ := TOriLabel.Create(Self); lbOriLogo_.Parent := pnClient; lbOriLogo_.Align := alClient; lbOriLogo_.Transparent := true; lbOriLogo_.pnTaskBar_ := pnTaskBar; lbOriLogo_.Visible := true; end; lb := lbOriLogo_; nLineCnt := 3; // 강제 sLogoTxt_ := sText; lb.Font.Assign(aFont); lbLogo.Font.Assign(aFont); lbLogo.Alignment := taRightJustify; lbLogo.Layout := tlBottom; lbLogo.Font.Color := aTxtColor; lbLogo.Font.Size := 20; lbLogo.Font.Style := lbLogo.Font.Style + [fsBold]; lbLogo.Caption := '무단으로 촬영 및 캡쳐 시 법적 책임을 받게 됩니다.'; lbLogo.Visible := true; case nPos1 of 1 : lb.Alignment := taLeftJustify; 2 : lb.Alignment := taRightJustify; else lb.Alignment := taCenter; end; case nPos2 of 1 : lb.Layout := tlTop; 2 : lb.Layout := tlBottom; else lb.Layout := tlCenter; end; lb.Font.Color := aTxtColor; lb.Font.Orientation := nOri; if Color <> aBgColor then begin Hide; TransparentColorValue := aBgColor; Color := aBgColor; end; sTemp := sLogoTxt_; sTemp2 := ''; nWMax := Width * 2; //+ (Width div 3); // 4K 에서 짤림 현상 있다고 해서 2배로 늘림 23_1017 16:12:00 kku nRepeat := nWMax div lb.Canvas.TextWidth(sLogoTxt_); for i := 0 to nRepeat do begin SumString(sTemp2, sTemp, ' '); if lb.Canvas.TextWidth(sTemp2) >= nWMax then break; end; if nOri <> 0 then begin lb.AutoSize := false; lb.Align := alNone; lb.Top := 0; lb.Left := 0; lb.Width := nWMax; lb.Height := Height; end; // sTemp := ''; // sTemp3 := ''; //// sTemp3 := sTemp2; // 처음에 하나 // var nH: Integer; // if Width > Height then // nH := (Height + Round(Height / 1.3)) div nLineCnt // else // nH := Height div nLineCnt; // var nTextH: Integer := lb.Canvas.TextHeight('abc'); // var StrList: TStringList; // Guard(StrList, TStringList.Create); // i := 0; // while i < nH do // begin // StrList.Add(''); // Inc(i, nTextH); // end; // // if StrList.Count > 0 then // begin //// i := StrList.Count div 2; // i := Round(StrList.Count / 3.5); // if i < 0 then // i := 0 // else if i = StrList.Count then // i := StrList.Count - 1; // StrList[i] := sTemp2; // end; // // for i := 0 to nLineCnt - 1 do // sTemp3 := sTemp3 + StrList.Text; // sLogoTxt_ := sTemp3; sDtFormat_ := sDtFormat; if sDtFormat_ <> '' then lb.Caption := StringReplace(sLogoTxt_, '{DateTime}', FormatDateTime(sDtFormat_, Now), [rfReplaceAll]) else lb.Caption := StringReplace(sLogoTxt_, '{DateTime}', DateTimeToStr(Now), [rfReplaceAll]); tTime.Enabled := nUpdateMSec > 0; if tTime.Enabled then tTime.Interval := nUpdateMSec; lb.BringToFront; Application.ProcessMessages; Show; end; procedure TDlgDispLogo.tStayTopTimer(Sender: TObject); begin // SetWindowPos(Handle, HWND_TOPMOST, Left, Top, Width, Height, SWP_NOMOVE or SWP_NOSIZE); {$IFDEF _HE_} if FindWindow('TDlgLockScreen', nil) <> 0 then exit; {$ENDIF} SetWindowPos(Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE); end; procedure TDlgDispLogo.tTimeTimer(Sender: TObject); var lb: TLabel; begin if lbOriLogo_ <> nil then lb := lbOriLogo_ else lb := lbLogo; if sDtFormat_ <> '' then lb.Caption := StringReplace(sLogoTxt_, '{DateTime}', FormatDateTime(sDtFormat_, Now), [rfReplaceAll]) else lb.Caption := StringReplace(sLogoTxt_, '{DateTime}', DateTimeToStr(Now), [rfReplaceAll]); // Application.ProcessMessages; end; procedure TDlgDispLogo.SetImage(sImgPath: String; nPos1, nPos2: Integer); begin if (CompareText(sImgPath_, sImgPath) <> 0) and FileExists(sImgPath) then begin sImgPath_ := sImgPath; imgLogo.Picture.LoadFromFile(sImgPath_); end; if FileExists(sImgPath) then begin if (nPos1 = -99) and (nPos2 = -99) then begin imgLogo.Visible := false; imgST.Width := 1; imgST.Height := 1; imgST.Align := alClient; imgST.Wallpaper.LoadFromFile(sImgPath); imgST.Visible := true; end else begin case nPos1 of 1 : imgLogo.Left := 0; 2 : imgLogo.Left := pnClient.Width - imgLogo.Width; else imgLogo.Left := (pnClient.Width div 2) - (imgLogo.Width div 2); end; case nPos2 of 1 : imgLogo.Top := 0; 2 : imgLogo.Top := pnClient.Height - imgLogo.Height; else imgLogo.Top := (pnClient.Height div 2) - (imgLogo.Height div 2); end; imgST.Visible := false; imgLogo.Visible := true; end; end else imgLogo.Picture.Assign(nil); if imgLogo.Visible then imgLogo.SendToBack; if imgST.Visible then imgST.SendToBack; Show; end; procedure TDlgDispLogo.SetImageFromStream(aStream: TStream; nPos1, nPos2: Integer; nTopMargin: Integer = 0); var ms: TMemoryStream; begin Guard(ms, TMemoryStream.Create); ms.CopyFrom(aStream); ms.Position := 0; imgLogo.Picture.LoadFromStream(ms); case nPos1 of 1 : imgLogo.Left := 0; 2 : imgLogo.Left := pnClient.Width - imgLogo.Width; else imgLogo.Left := (pnClient.Width div 2) - (imgLogo.Width div 2); end; case nPos2 of 1 : imgLogo.Top := 0; 2 : imgLogo.Top := pnClient.Height - imgLogo.Height; else imgLogo.Top := (pnClient.Height div 2) - (imgLogo.Height div 2); end; if nTopMargin <> 0 then imgLogo.Top := imgLogo.Top + nTopMargin; imgLogo.SendToBack; Show; end; procedure TDlgDispLogo.SetTaskbarDetect(bVal: Boolean); var hTaskBar: HWND; r: TRect; begin if bVal then begin hTaskBar := FindWindow('Shell_TrayWnd', ''); if hTaskBar <> 0 then begin GetWindowRect(hTaskBar, r); // Top가 0이면 위, 왼쪽 아님 오른쪽 if (r.Left <= 0) and (r.Right < Screen.PrimaryMonitor.Width) then begin // 왼쪽 pnTaskBar.Align := alLeft; pnTaskBar.Width := r.Width; end else if (r.Left <= 0) and (r.Top = 0) and (r.Bottom < Screen.PrimaryMonitor.Height) then begin // 위쪽 pnTaskBar.Align := alTop; pnTaskBar.Height := r.Height; end else if (r.Left <= 0) and (r.Top > 0) then begin // 아래쪽 pnTaskBar.Align := alBottom; pnTaskBar.Height := r.Height; end else begin // 오른쪽 pnTaskBar.Align := alRight; pnTaskBar.Width := r.Width; end; end; end; pnTaskBar.Visible := bVal; end; procedure TDlgDispLogo.process_WM_SYSCOMMAND(var msg: TWMSysCommand); begin if msg.CmdType = SC_MINIMIZE then exit; Inherited; end; end.