unit Udialog;

interface

uses Messages, Windows, SysUtils, Classes, Controls, StdCtrls, Graphics,
  ExtCtrls, Buttons, Dialogs, GR32_Image, GR32, FreeBitmap, FreeImage, FreeUtils;

type
  TSilentPaintPanel = class(TPanel)
  protected
    procedure WMPaint(var Msg: TWMPaint); message WM_PAINT;
  end;

  TmyOpenPictureDialog = class(TOpenDialog)
  private
    FPicturePanel: TPanel;
    FPictureLabel: TLabel;
    FPreviewButton: TSpeedButton;
    FPaintPanel: TPanel;
    FImageCtrl: TImage32;
    FSavedFilename: string;
    FExtraCheckbox : Tcheckbox;
    FBitmap: TFreeWinBitmap;

    FExtraPanel  : TPanel;
    FExtrabtn :Tbitbtn;

    function  IsFilterStored: Boolean;
    procedure PreviewKeyPress(Sender: TObject; var Key: Char);
    procedure FExtraCheckboxOnClick(sender:tobject);
    procedure ExtrabtnOnClick(Sender: TObject);
  protected
    procedure PreviewClick(Sender: TObject); virtual;
    procedure DoClose; override;
    procedure DoSelectionChange; override;
    function loadfile(s:string):boolean;
    procedure DoShow; override;
    function TaskModalDialog(DialogFunc: Pointer; var DialogData): Bool; override;
    property ImageCtrl: TImage32 read FImageCtrl;
    property PictureLabel: TLabel read FPictureLabel;
  published
    property Filter stored IsFilterStored;
    property ExtraCheckbox: Tcheckbox read FExtraCheckbox write FExtraCheckbox;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    function Execute: Boolean; override;
  end;

  TmySavePictureDialog = class(TmyOpenPictureDialog)
  private
    Fenablesaveopt:boolean;
  protected
    procedure DoTypeChange; override;
  published
    property enablesaveopt: boolean read Fenablesaveopt write Fenablesaveopt;
  public
    constructor Create(AOwner: TComponent); override;
    function Execute: Boolean; override;
  end;

  function _messagedlg(owner:tcontrol;text:string;dlgtype:TMsgDlgType;selbutton:TMsgDlgBtn=mbOK):integer;

implementation
uses Consts, math, CommDlg, forms, Ufrmsaveopt;

{$R Udialog.res}

procedure TSilentPaintPanel.WMPaint(var Msg: TWMPaint);
begin
  try
    inherited;
  except
    Caption := SInvalidImage;
  end;
end;

constructor TmyOpenPictureDialog.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Filter := GraphicFilter(TGraphic);
  FPicturePanel := TPanel.Create(Self);
  with FPicturePanel do
  begin
    Name := 'PicturePanel';
    Caption := '';
    SetBounds(204, 5, 169, 200);
    BevelOuter := bvNone;
    BorderWidth := 6;
    TabOrder := 1;
    FPictureLabel := TLabel.Create(Self);
    with FPictureLabel do
    begin
      Name := 'PictureLabel';
      Caption := '';
      SetBounds(6, 6, 157, 23);
      Align := alTop;
      AutoSize := False;
      Parent := FPicturePanel;
    end;
    FPreviewButton := TSpeedButton.Create(Self);
    with FPreviewButton do
    begin
      Name := 'PreviewButton';
      SetBounds(77, 1, 23, 22);
      Enabled := False;
      Glyph.LoadFromResourceName(HInstance, 'PREVIEWGLYPH');
      Hint := SPreviewLabel;
      ParentShowHint := False;
      ShowHint := True;
      OnClick := PreviewClick;
      Parent := FPicturePanel;
    end;
    FPaintPanel := TSilentPaintPanel.Create(Self);
    with FPaintPanel do
    begin
      Name := 'PaintPanel';
      Caption := '';
      SetBounds(6, 29, 157, 145);
      Align := alClient;
      BevelInner := bvRaised;
      BevelOuter := bvLowered;
      TabOrder := 0;
      FImageCtrl := TImage32.Create(Self);
      Parent := FPicturePanel;
      with FImageCtrl do
      begin
        Name := 'PaintBox';
        Align := alClient;
        ScaleMode:=smResize;
        BitmapAlign:=baCenter;
        OnDblClick := PreviewClick;
        Parent := FPaintPanel;
      end;
    end;
  end;
  FExtraCheckbox := Tcheckbox.Create(Self);
  FExtraCheckbox.Caption:='미리보기 사용';
  FExtraCheckbox.Align:=albottom;
  FExtraCheckbox.Parent:=FPaintPanel;
  FExtraCheckbox.OnClick:=FExtraCheckboxOnClick;

  FExtraPanel := TPanel.Create(Self);
  FExtraPanel.Font.Name:='굴림';
  FExtraPanel.Font.Size:=9;
  FExtraPanel.Caption := '';
  FExtraPanel.BevelOuter := bvNone;
  FExtraPanel.BorderWidth := 2;
  FExtraPanel.TabOrder := 1;

  FExtrabtn:=Tbitbtn.Create(self);
  FExtrabtn.Left:=10;
  FExtrabtn.Top:=2;
  FExtrabtn.Width:=126;
  FExtrabtn.Height:=24;
  FExtrabtn.Glyph.LoadFromResourceName(HInstance, 'SAVEOPTIONGLYPH');
  FExtrabtn.Caption:='이미지 저장옵션';
  FExtrabtn.Parent:=FExtraPanel;
  FExtrabtn.Enabled:=false;
  FExtrabtn.OnClick:=ExtrabtnOnClick;

  FBitmap:=TFreeWinBitmap.Create();
end;

destructor TmyOpenPictureDialog.Destroy;
begin
  FBitmap.Free;
  inherited;
end;

procedure TmyOpenPictureDialog.ExtrabtnOnClick(Sender: TObject);
begin
  frmsaveopt:=Tfrmsaveopt.Create(self);
  try
    frmsaveopt.selectformat:=FExtrabtn.Tag;
    if frmsaveopt.ShowModal=mrok then ;
  finally
    frmsaveopt.Free;
  end;
end;

//template 사용을 위해
function TmyOpenPictureDialog.TaskModalDialog(DialogFunc: Pointer; var DialogData): Bool;
begin
  if owner is Tform then
   TOpenFilename(DialogData).hWndOwner := Tform(owner).handle;
  TOpenFileName(DialogData).hInstance := FindClassHInstance(Self.ClassType);
  Result := inherited TaskModalDialog(DialogFunc, DialogData);
end;

procedure TmyOpenPictureDialog.FExtraCheckboxOnClick(sender:tobject);
begin
  if FExtraCheckbox.Checked then begin
    FSavedFilename:='';
    DoSelectionChange;
  end else begin
    FPictureLabel.Caption := SPictureLabel;
    FPreviewButton.Enabled := False;
    FImageCtrl.Bitmap.Delete;
    FImageCtrl.Enabled:=false;
    FPaintPanel.Caption := srNone;
  end;
end;

function TmyOpenPictureDialog.loadfile(s:string):boolean;
var
  w,h:integer;
  FreeMemoryIO1:TFreeMemoryIO;
  stream:tmemorystream;
  pdata:PByte;
  SizeInBytes: DWORD;
begin
  result:=false;
  if FBitmap.Load(s)=false then
    exit;
  w:=FBitmap.GetWidth;
  h:=FBitmap.GetHeight;
  FreeMemoryIO1:=TFreeMemoryIO.Create();
  try
    FBitmap.SaveToMemory(FIF_BMP,FreeMemoryIO1);
    FreeMemoryIO1.Acquire(pdata,SizeInBytes);
    stream:=tmemorystream.Create;
    try
      stream.Write(pdata^,SizeInBytes);
      stream.Position:=0;
      FImageCtrl.Bitmap.DrawMode:=dmblend;
      FImageCtrl.Bitmap.LoadFromStream(stream);
    finally
      stream.Free;
    end;
    result:=true;
  finally
    FreeMemoryIO1.Free;
  end;
end;

procedure TmyOpenPictureDialog.DoSelectionChange;
var
  FullName: string;
  ValidPicture: Boolean;

  function ValidFile(const FileName: string): Boolean;
  begin
    Result := GetFileAttributes(PChar(FileName)) <> $FFFFFFFF;
  end;

begin
  if FExtraCheckbox.Checked=false then exit;
  FullName := FileName;
  if FullName <> FSavedFilename then
  begin
    FSavedFilename := FullName;
    ValidPicture := FileExists(FullName) and ValidFile(FullName);
    if ValidPicture then
    try
      ValidPicture:=loadfile(FullName);
      if ValidPicture then begin
        FImageCtrl.Enabled:=true;
        FPictureLabel.Caption := Format(SPictureDesc,
          [FImageCtrl.Bitmap.Width, FImageCtrl.Bitmap.Height]);
        FPreviewButton.Enabled := True;
        FPaintPanel.Caption := '';
      end;
    except
      ValidPicture := False;
    end;
    if not ValidPicture then
    begin
      FPictureLabel.Caption := SPictureLabel;
      FPreviewButton.Enabled := False;
      FImageCtrl.Bitmap.Delete;
      FImageCtrl.Enabled:=false;
      FPaintPanel.Caption := srNone;
    end;
  end;
  inherited DoSelectionChange;
end;

procedure TmyOpenPictureDialog.DoClose;
begin
  inherited DoClose;
  { Hide any hint windows left behind }
  Application.HideHint;
end;

procedure TmyOpenPictureDialog.DoShow;
var
  PreviewRect, StaticRect, ExtRect: TRect;
begin
  { Set preview area to entire dialog }
  GetClientRect(Handle, PreviewRect);
  StaticRect := GetStaticRect;
  { Move preview area to right of static area }
  PreviewRect.Left := StaticRect.Left + (StaticRect.Right - StaticRect.Left);
  Inc(PreviewRect.Top, 4);
  FPicturePanel.BoundsRect := PreviewRect;
  FPreviewButton.Left := FPaintPanel.BoundsRect.Right - FPreviewButton.Width - 2;
  FImageCtrl.Bitmap.Delete;
  FSavedFilename := '';
  FPaintPanel.Caption := srNone;
  FPicturePanel.ParentWindow := Handle;

  ExtRect.Top := StaticRect.Bottom;
  ExtRect.Left := StaticRect.Left;
  ExtRect.Bottom := ExtRect.Top+30;
  ExtRect.Right := StaticRect.Right;
  FExtraPanel.ParentWindow := Handle;
  FExtraPanel.BoundsRect := ExtRect;

  inherited DoShow;
end;

function TmyOpenPictureDialog.Execute;
begin
  if NewStyleControls and not (ofOldStyleDialog in Options) then
    Template := 'EXTDLGTEMPLATE' else
    Template := nil;
  Result := inherited Execute;
end;

procedure TmyOpenPictureDialog.PreviewClick(Sender: TObject);
var
  PreviewForm: TForm;
  Panel: TPanel;
  w,h:integer;
begin
  PreviewForm := TForm.Create(Self);
  with PreviewForm do
  try
    Name := 'PreviewForm';
    Visible := False;
    Caption := SPreviewLabel;
    BorderStyle := bsSizeToolWin;
    KeyPreview := True;
//    Position := poScreenCenter;
    OnKeyPress := PreviewKeyPress;
    Panel := TPanel.Create(PreviewForm);
    with Panel do
    begin
      Name := 'Panel';
      Caption := '';
      Align := alClient;
      BevelOuter := bvNone;
      BorderStyle := bsSingle;
      BorderWidth := 3;
      Color := clWindow;
      Parent := PreviewForm;
      DoubleBuffered := True;
      with TImgView32.Create(PreviewForm) do
      begin
        Name := 'Image';
        Align := alClient;
        Bitmap.Assign(FImageCtrl.Bitmap);
        Parent := Panel;
      end;
    end;
    w:=FImageCtrl.Bitmap.Width+40;
    h:=FImageCtrl.Bitmap.Height+40;
    ClientWidth:=w;
    ClientHeight:=h;
    if Width>screen.WorkAreaWidth then Width:=screen.WorkAreaWidth;
    if Height>screen.WorkAreaHeight then Height:=screen.WorkAreaHeight;
    Left:=screen.WorkAreaRect.Left+(screen.WorkAreaWidth div 2)-(Width div 2);
    Top:=screen.WorkAreaRect.Top+(screen.WorkAreaHeight div 2)-(Height div 2);

    if left<screen.WorkAreaRect.Left then left:=screen.WorkAreaRect.Left;
    if Top<screen.WorkAreaRect.Top then Top:=screen.WorkAreaRect.Top;
    if left+width>screen.WorkAreaRect.Right then left:=screen.WorkAreaRect.Right-width;
    if Top+Height>screen.WorkAreaRect.Bottom then Top:=screen.WorkAreaRect.Bottom-Height;

    ShowModal;
  finally
    Free;
  end;
end;

procedure TmyOpenPictureDialog.PreviewKeyPress(Sender: TObject; var Key: Char);
begin
  if Key = #27 then TForm(Sender).Close;
end;

function TmyOpenPictureDialog.IsFilterStored: Boolean;
begin
  Result := not (Filter = GraphicFilter(TGraphic));
end;


{TmySavePictureDialog}
constructor TmySavePictureDialog.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Fenablesaveopt:=true;
end;

procedure TmySavePictureDialog.DoTypeChange;
var
  f:FREE_IMAGE_FORMAT;
begin
  if Fenablesaveopt=false then begin
    FExtrabtn.Enabled:=false;
    exit;
  end;
  f:=FIU_GetFIFType2(FIU_GetSelectExt(FilterIndex));
  case f of
    FIF_BMP,FIF_JPEG,FIF_PNG,FIF_TIFF:
      FExtrabtn.Enabled:=true;
    else
      FExtrabtn.Enabled:=false;
  end;
  FExtrabtn.Tag:=f;
end;

function TmySavePictureDialog.Execute: Boolean;
begin
  if NewStyleControls and not (ofOldStyleDialog in Options) then
    Template := 'EXTDLGTEMPLATE' else
    Template := nil;
  DoTypeChange;
  Result := DoExecute(@GetSaveFileName);
end;


var
  ModalResults: array[TMsgDlgBtn] of Integer = (
    mrYes, mrNo, mrOk, mrCancel, mrAbort, mrRetry, mrIgnore, mrAll, mrNoToAll,
    mrYesToAll, 0);
  ButtonNames: array[TMsgDlgBtn] of string = (
    'Yes', 'No', 'OK', 'Cancel', 'Abort', 'Retry', 'Ignore', 'All', 'NoToAll',
    'YesToAll', 'Help');
  Captions: array[TMsgDlgType] of string = (SMsgDlgWarning, SMsgDlgError,
    SMsgDlgInformation, SMsgDlgConfirm, '');
  IconIDs: array[TMsgDlgType] of PChar = (IDI_EXCLAMATION, IDI_HAND,
    IDI_ASTERISK, IDI_QUESTION, nil);
  ButtonWidths : array[TMsgDlgBtn] of integer;  // initialized to zero
  ButtonCaptions: array[TMsgDlgBtn] of string = (
    SMsgDlgYes, SMsgDlgNo, SMsgDlgOK, SMsgDlgCancel, SMsgDlgAbort,
    SMsgDlgRetry, SMsgDlgIgnore, SMsgDlgAll, SMsgDlgNoToAll, SMsgDlgYesToAll,
    SMsgDlgHelp);

type
  TMessageForm = class(TForm)
  private
    Message: TLabel;
    parenthandle:thandle;

    procedure HelpButtonClick(Sender: TObject);
  protected
    procedure CustomKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
    procedure WriteToClipBoard(Text: String);
    function GetFormText: String;
    procedure CreateParams(var Params: TCreateParams); override;
  public
//    constructor Create(AOwner:TComponent;parenthandle:thandle); reintroduce;
    constructor CreateNew(AOwner: TComponent;phandle:thandle); reintroduce;
  end;

 {
constructor TMessageForm.Create(AOwner:TComponent;parenthandle:thandle);
begin
  self.parenthandle:=parenthandle;
  inherited Create(AOwner);
end;
}
procedure TMessageForm.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  with Params do begin
    WndParent := parenthandle;
  end;
end;

constructor TMessageForm.CreateNew(AOwner: TComponent;phandle:thandle);
var
  NonClientMetrics: TNonClientMetrics;
begin
  parenthandle:=phandle;
  inherited CreateNew(AOwner);
  NonClientMetrics.cbSize := sizeof(NonClientMetrics);
  if SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, @NonClientMetrics, 0) then
    Font.Handle := CreateFontIndirect(NonClientMetrics.lfMessageFont);
end;

procedure TMessageForm.HelpButtonClick(Sender: TObject);
begin
  Application.HelpContext(HelpContext);
end;

procedure TMessageForm.CustomKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
  if (Shift = [ssCtrl]) and (Key = Word('C')) then
  begin
    Beep;
    WriteToClipBoard(GetFormText);
  end;
end;

procedure TMessageForm.WriteToClipBoard(Text: String);
var
  Data: THandle;
  DataPtr: Pointer;
begin
  if OpenClipBoard(0) then
  begin
    try
      Data := GlobalAlloc(GMEM_MOVEABLE+GMEM_DDESHARE, Length(Text) + 1);
      try
        DataPtr := GlobalLock(Data);
        try
          Move(PChar(Text)^, DataPtr^, Length(Text) + 1);
          EmptyClipBoard;
          SetClipboardData(CF_TEXT, Data);
        finally
          GlobalUnlock(Data);
        end;
      except
        GlobalFree(Data);
        raise;
      end;
    finally
      CloseClipBoard;
    end;
  end
  else
    raise Exception.CreateRes(@SCannotOpenClipboard);
end;

function TMessageForm.GetFormText: String;
var
  DividerLine, ButtonCaptions: string;
  I: integer;
begin
  DividerLine := StringOfChar('-', 27) + sLineBreak;
  for I := 0 to ComponentCount - 1 do
    if Components[I] is TButton then
      ButtonCaptions := ButtonCaptions + TButton(Components[I]).Caption +
        StringOfChar(' ', 3);
  ButtonCaptions := StringReplace(ButtonCaptions,'&','', [rfReplaceAll]);
  Result := Format('%s%s%s%s%s%s%s%s%s%s', [DividerLine, Caption, sLineBreak,
    DividerLine, Message.Caption, sLineBreak, DividerLine, ButtonCaptions,
    sLineBreak, DividerLine]);
end;

function GetAveCharSize(Canvas: TCanvas): TPoint;
var
  I: Integer;
  Buffer: array[0..51] of Char;
begin
  for I := 0 to 25 do Buffer[I] := Chr(I + Ord('A'));
  for I := 0 to 25 do Buffer[I + 26] := Chr(I + Ord('a'));
  GetTextExtentPoint(Canvas.Handle, Buffer, 52, TSize(Result));
  Result.X := Result.X div 52;
end;

function CreateMessageDialog(owner:tform; const Msg: string; DlgType: TMsgDlgType;
  Buttons: TMsgDlgButtons; SelButton:TMsgDlgBtn): TForm;
const
  mcHorzMargin = 8;
  mcVertMargin = 8;
  mcHorzSpacing = 10;
  mcVertSpacing = 10;
  mcButtonWidth = 50;
  mcButtonHeight = 14;
  mcButtonSpacing = 4;
var
  DialogUnits: TPoint;
  HorzMargin, VertMargin, HorzSpacing, VertSpacing, ButtonWidth,
  ButtonHeight, ButtonSpacing, ButtonCount, ButtonGroupWidth,
  IconTextWidth, IconTextHeight, X, ALeft: Integer;
  B, DefaultButton, CancelButton: TMsgDlgBtn;
  IconID: PChar;
  TextRect: TRect;
begin
  Result := TMessageForm.CreateNew(owner,owner.Handle);
  with Result do
  begin
    BiDiMode := Application.BiDiMode;
    BorderStyle := bsDialog;
    Canvas.Font := Font;
    KeyPreview := True;
    OnKeyDown := TMessageForm(Result).CustomKeyDown;
    DialogUnits := GetAveCharSize(Canvas);
    HorzMargin := MulDiv(mcHorzMargin, DialogUnits.X, 4);
    VertMargin := MulDiv(mcVertMargin, DialogUnits.Y, 8);
    HorzSpacing := MulDiv(mcHorzSpacing, DialogUnits.X, 4);
    VertSpacing := MulDiv(mcVertSpacing, DialogUnits.Y, 8);
    ButtonWidth := MulDiv(mcButtonWidth, DialogUnits.X, 4);
    for B := Low(TMsgDlgBtn) to High(TMsgDlgBtn) do
    begin
      if B in Buttons then
      begin
        if ButtonWidths[B] = 0 then
        begin
          TextRect := Rect(0,0,0,0);
          Windows.DrawText( canvas.handle,
            PChar(ButtonCaptions[B]), -1,
            TextRect, DT_CALCRECT or DT_LEFT or DT_SINGLELINE or
            DrawTextBiDiModeFlagsReadingOnly);
          with TextRect do ButtonWidths[B] := Right - Left + 8;
        end;
        if ButtonWidths[B] > ButtonWidth then
          ButtonWidth := ButtonWidths[B];
      end;
    end;
    ButtonHeight := MulDiv(mcButtonHeight, DialogUnits.Y, 8);
    ButtonSpacing := MulDiv(mcButtonSpacing, DialogUnits.X, 4);
    SetRect(TextRect, 0, 0, Screen.Width div 2, 0);
    DrawText(Canvas.Handle, PChar(Msg), Length(Msg)+1, TextRect,
      DT_EXPANDTABS or DT_CALCRECT or DT_WORDBREAK or
      DrawTextBiDiModeFlagsReadingOnly);
    IconID := IconIDs[DlgType];
    IconTextWidth := TextRect.Right;
    IconTextHeight := TextRect.Bottom;
    if IconID <> nil then
    begin
      Inc(IconTextWidth, 32 + HorzSpacing);
      if IconTextHeight < 32 then IconTextHeight := 32;
    end;
    ButtonCount := 0;
    for B := Low(TMsgDlgBtn) to High(TMsgDlgBtn) do
      if B in Buttons then Inc(ButtonCount);
    ButtonGroupWidth := 0;
    if ButtonCount <> 0 then
      ButtonGroupWidth := ButtonWidth * ButtonCount +
        ButtonSpacing * (ButtonCount - 1);
    ClientWidth := Max(IconTextWidth, ButtonGroupWidth) + HorzMargin * 2;
    ClientHeight := IconTextHeight + ButtonHeight + VertSpacing +
      VertMargin * 2;
    Left := (Screen.Width div 2) - (Width div 2);
    Top := (Screen.Height div 2) - (Height div 2);
    if DlgType <> mtCustom then
      Caption := Captions[DlgType] else
      Caption := Application.Title;
    if IconID <> nil then
      with TImage.Create(Result) do
      begin
        Name := 'Image';
        Parent := Result;
        Picture.Icon.Handle := LoadIcon(0, IconID);
        SetBounds(HorzMargin, VertMargin, 32, 32);
      end;
    TMessageForm(Result).Message := TLabel.Create(Result);
    with TMessageForm(Result).Message do
    begin
      Name := 'Message';
      Parent := Result;
      WordWrap := True;
      Caption := Msg;
      BoundsRect := TextRect;
      BiDiMode := Result.BiDiMode;
      ALeft := IconTextWidth - TextRect.Right + HorzMargin;
      if UseRightToLeftAlignment then
        ALeft := Result.ClientWidth - ALeft - Width;
      SetBounds(ALeft, VertMargin,
        TextRect.Right, TextRect.Bottom);
    end;
    DefaultButton:=SelButton;
{    if mbOk in Buttons then DefaultButton := mbOk else
      if mbYes in Buttons then DefaultButton := mbYes else
        DefaultButton := mbRetry;}
    if mbCancel in Buttons then CancelButton := mbCancel else
      if mbNo in Buttons then CancelButton := mbNo else
        CancelButton := mbOk;
    X := (ClientWidth - ButtonGroupWidth) div 2;
    for B := Low(TMsgDlgBtn) to High(TMsgDlgBtn) do
      if B in Buttons then
        with TButton.Create(Result) do
        begin
          Name := ButtonNames[B];
          Parent := Result;
          Caption := ButtonCaptions[B];
          ModalResult := ModalResults[B];
          if B = DefaultButton then begin
            Default := True;
            TabOrder:=0;
          end;
          if B = CancelButton then Cancel := True;
          SetBounds(X, IconTextHeight + VertMargin + VertSpacing,
            ButtonWidth, ButtonHeight);
          Inc(X, ButtonWidth + ButtonSpacing);
          if B = mbHelp then
            OnClick := TMessageForm(Result).HelpButtonClick;
        end;
  end;
end;

function MessageDlgPosHelp(owner:tform; const Msg: string; DlgType: TMsgDlgType;
  Buttons: TMsgDlgButtons; HelpCtx: Longint; X, Y: Integer;
  const HelpFileName: string; SelButton:TMsgDlgBtn): Integer;
begin
  with CreateMessageDialog(owner, Msg, DlgType, Buttons, SelButton) do
    try
      HelpContext := HelpCtx;
      HelpFile := HelpFileName;
      if X >= 0 then Left := X;
      if Y >= 0 then Top := Y;
      if (Y < 0) and (X < 0) then Position := poOwnerFormCenter;//poScreenCenter;
      Result := ShowModal;
    finally
      Free;
    end;
end;

function _messagedlg(owner:tcontrol;text:string;dlgtype:TMsgDlgType;selbutton:TMsgDlgBtn=mbOK):integer;
begin
  while not (owner is tform) do
    owner:=owner.Parent;
  if dlgtype=mtinformation then begin
    Result := MessageDlgPosHelp(owner as tform, text, mtinformation, [mbok], 0, -1, -1, '', selbutton);
  end else if dlgtype=mtConfirmation then begin
    Result := MessageDlgPosHelp(owner as tform, text, mtConfirmation, [mbYes, mbNo], 0, -1, -1, '', selbutton);
  end else if dlgtype=mtError then begin
    Result := MessageDlgPosHelp(owner as tform, text, mtError, [mbok], 0, -1, -1, '', selbutton);
  end else if dlgtype=mtCustom then begin
    Result := MessageDlgPosHelp(owner as tform, text, mtConfirmation, [mbYes, mbNo, mbCancel], 0, -1, -1, '', selbutton);
  end;
end;

end.
