unit gvBWCC;

{ Graphics Vision: Borland Windows Custom Controls support
  Copr. 1995,1999 Matthias K"oppe

  $Id$
}

{$ifndef FPK}
{$A+,B-,F+,G+,I-,O+,P-,Q-,R-,S-,T-,V+,X+}
{$endif}

interface

uses Objects, WinRes, GvDialog, GvWinDlg;

const
  BWCC: PStream = nil;
  BWCCButtonSize: TPoint = (X: 63; Y: 39);

procedure InitBWCC;
procedure DoneBWCC;

function BorCreateMessageBox(var Bounds: TRect;
  ATitle, AText: string; AOptions: Word): PDialog;

function BorMessageBox(Res: PStream; Name: PChar;
  BitmapRes: PStream; BitmapName: PChar; Text: string): PWinDialog;

const
  { Additional button ids. (For standard Windows ids, see WinRes unit.)
  }
  id_Help = 998;
  id_Generic = 999;

  { BWCC button state bitmaps:
    LoadBitmapImg(bwcc^, bwcc_button_XXXX + id_XXXX);
  }
  bwcc_button_normal = MakeIntResource(1000);
  bwcc_button_down = MakeIntResource(3000);
  bwcc_button_focused = MakeIntResource(5000);

  { Add-on value for small button version
  }
  bwcc_button_small = MakeIntResource(1000);

  { BWCC dialogs:
    LoadDialog(bwcc^, bwcc_dialog_XXXX);
  }
  bwcc_dialog_Ok = MakeIntResource(10);
  bwcc_dialog_OkCancel = MakeIntResource(11);
  bwcc_dialog_AbortRetryIgnore = MakeIntResource(12);
  bwcc_dialog_YesNoCancel = MakeIntResource(13);
  bwcc_dialog_YesNo = MakeIntResource(14);
  bwcc_dialog_RetryCancel = MakeIntResource(15);

  { BWCC message box bitmaps:
    LoadBitmapImg(bwcc^, bwcc_bitmap_XXXX);
  }
  bwcc_bitmap_Hand = MakeIntResource(1901);
  bwcc_bitmap_Question = MakeIntResource(1902);
  bwcc_bitmap_Exclamation = MakeIntResource(1903);
  bwcc_bitmap_Information = MakeIntResource(1904);

{ Following is an extract from BWCC.PAS,
  which is copr. 1992 Borland Intl.
}
  BorDlgClass  = 'BorDlg';
  BorDlgProp   = 'FB';

  Button_Class = 'BorBtn';
  Radio_Class  = 'BorRadio';
  Check_Class  = 'BorCheck';
  bbs_Bitmap       = $8000;
  bbs_DlgPaint     = $4000;
  bbs_ParentNotify = $2000;
  bbs_OwnerDraw    = $1000;

  Shade_Class = 'BorShade';
  bss_Group         =     1;
  bss_Hdip          =     2;
  bss_Vdip          =     3;
  bss_Hbump         =     4;
  bss_Vbump         =     5;
  bss_RGroup        =     6;
  bss_Caption       = $8000;
  bss_CtlColor      = $4000;
  bss_NoPrefix      = $2000;
  bss_Left          = $0000;
  bss_Center        = $0100;
  bss_Right         = $0200;
  bss_AlignMask     = $0300;

  Static_Class =   'BorStatic';

implementation

{$ifdef Windows}
uses WinTypes, WinProcs, OMemory, GvViews, GvBitmap, GvMsgBox;

procedure InitBWCC;
var
  DLL: THandle;
begin
  DLL := LoadLibrary('BWCC.DLL');
  If DLL < 32
  then DLL := 0
  else begin
    BWCC := New(PResStream, Init(DLL));
  end;
end;

procedure DoneBWCC;
begin
  If BWCC <> nil
  then Dispose(BWCC, Done);
end;

{$else}
uses Misc, Dos, Memory, GvViews, GvBitmap, GvMsgBox;

procedure InitBWCC;
var
  Path: PathStr;
begin
  Path := FSearch('bwcc.dll', GetWinDir + '\system;' + GetEnv('PATH'));
  BWCC := OpenResource(Path);
  If BWCC^.Status <> stOK
  then DoneBWCC
end;

procedure DoneBWCC;
begin
  If BWCC <> nil
  then begin
    Dispose(BWCC, Done);
    BWCC := nil
  end
end;
{$endif Windows}

function BorMessageBox(Res: PStream; Name: PChar;
  BitmapRes: PStream; BitmapName: PChar; Text: string): PWinDialog;
{ This function retrieves a BWCC message box from a resource
  and puts a bitmap and a text into it.
}
var
  Dlg: PWinDialog;
  Bounds: Objects.TRect;
  P: PGView;
begin
  Dlg := LoadDialog(Res^, Name);
  If Dlg <> nil
  then begin
    { Control 33 is supposed to be a static template for a bitmap viewer.
      We insert a real bitmap viewer directly in front of the template.
      Then we kill the template.
    }
    P := Dlg^.GetControl(33);
    If P <> nil then
    with P^ do
    begin
      GetBounds(Bounds);
      Dlg^.InsertBefore(
	New(PBmpView, Init(Bounds, BitmapRes, BitmapName, 0)),
	P);
      Free
    end;
    { Control 34 is supposed to be an empty static text.
      We fill it with text.
    }
    P := Dlg^.GetControl(34);
    If P <> nil then
    PStaticText(P)^.Text := NewStr(Text);
    Dlg^.Options := Dlg^.Options or ofCentered;
  end;
  BorMessageBox := Dlg
end;

function BorCreateMessageBox(var Bounds: Objects.TRect;
  ATitle, AText: string; AOptions: Word): PDialog;
{ This is our implementation of the CreateMessageBox hook function,
  using the above function to create a message box.
}
var
  DlgName, BmpName: PChar;
  Dialog: PDialog;
begin
  If LowMemory
  then begin
    BorCreateMessageBox := StdCreateMessageBox(Bounds, ATitle, AText, AOptions);
    Exit
  end;
  case AOptions and $0F00 of
    mfOKButton:
      DlgName := PChar(bwcc_dialog_Ok);
    mfOKButton + mfCancelButton:
      DlgName := PChar(bwcc_dialog_OkCancel);
    mfYesButton + mfNoButton + mfCancelButton:
      DlgName := PChar(bwcc_dialog_YesNoCancel);
    mfYesButton + mfNoButton:
      DlgName := PChar(bwcc_dialog_YesNo);
    else
      DlgName := PChar(bwcc_dialog_AbortRetryIgnore);
  end;
  case AOptions and $000F of
    mfWarning:
      BmpName := PChar(bwcc_bitmap_Exclamation);
    mfError:
      BmpName := PChar(bwcc_bitmap_Hand);
    mfInformation:
      BmpName := PChar(bwcc_bitmap_Information);
    mfConfirmation:
      BmpName := PChar(bwcc_bitmap_Question);
    else
      BmpName := nil;
  end;
  Dialog := BorMessageBox(BWCC, DlgName, BWCC, BmpName, AText);
  If Dialog = nil
  then begin
    BorCreateMessageBox := StdCreateMessageBox(Bounds, ATitle, AText, AOptions);
    Exit
  end;
  Dialog^.Title := NewStr(ATitle);
  If Bounds.B.X = -1
  then Dialog^.Options := Dialog^.Options or ofCentered
  else Dialog^.MoveTo(Bounds.A.X, Bounds.A.Y);
  BorCreateMessageBox := Dialog
end;

end.
