{ Test of creating a toolBar.
  Example of using the much more general toobar than the one
  tested in  tEx048.pp
  Some images has been coded in the  Images.msg  file and can be used
  to add them in a toolbar, from the description made in the  tEx052.msg  file
  With the help of  tEx051.pp  any "small" image can be coded into a  .msg  file
  and used on a bitmap button  (@!BM(...))
  There buttons can be used in dialog boxes or in toolbars.
  See documentation  SyntaxDiagram03.txt  to have the syntax of defining
  dialog boxes and toolbars.
  See documentation  SyntaxDiagramHelp.txt  for more help about
  defining dialog boxes and toolbars.
  Examples are given here.

  In the  wToolBar0.pp  unit, is defined the TToolBar window which
  allow to put any control in the toolbar.

  A New control has been defined. It is a push button, with a bitmap
  on it. TButtonBitMap
  --------------------------------------------}
program tEx052;

// To tell FreePascal that the application is a Graphical User Interface
// i.e. is running in windows, not in text mode.
{$APPTYPE GUI}

Uses
  wApplication0
 ,wWindowText0 // To write text in an independent window
 ,wWindow0
 ,wToolBar0
 ,wDialog0
 ,wButtonBitMap0
 ,wComboBox0
// ,wControl0
 ,wWindowBase0
 ,wBitMapImage0
 ,wVariableNumLink2
 ,wMessages2
 ,wDialogCreatorLOW2
 ,wErrors0
 ,wGlobals2
 ,wDebug0
 ,Windows;

type
  PMyWindow = ^TMyWindow;
  TMyWindow = object(TWindow)
  //"""""""""""""""""""""""""

  poToolBar : PToolBar;
  // Remember the toolbar, to destroy it when a new one is wanted.

  wNumImage : word32;
  // image number wanted from the .msg file
  // To see it in little in an image

  poBM204 : PButtonBitMap;
  // Pointer on the button following the combo box of Test2

  strCombo2 : ShortString;
  // just for a demo

  constructor Init(strWinTitlePrm:ShortString);
//  destructor Done; virtual;

  procedure WinCreate(strWinClass:ShortString); virtual;
  // When creating the window, we ask to show the dialog box, not the window

  procedure FillComboImages(poComboP:PComboBox);
  // Fill the choice list of the combo box

  procedure Test1;
  // create a window (the same way a dialog box is bulid),
  // then use it as a toolBar

  procedure Test2;
  // A second example of toolbar.

  procedure Test3;
  // A Third example of toolbar, on two lines

  procedure Test4;

  procedure CtrlVarUpdate(poCtrl:PWindowBase0; pVar:pointer); virtual;
  // When a control changed its value and it is linked to a variable and
  // it belongs to a dialog belonging to a window, then
  // the control calls this method with a pointer on itself and
  // a pointer on the associated variable.
  // Either you know the type, or you can get it with
  // pControl(poCtrl)^.rVarLinkInfo.wVarType

  procedure ButtonClicked(poCtrl:PWindowBase0; wCtrlID:Word32); virtual;
  // When a button is clicked, and it is in a dialog which belongs to a Window,
  // then the button calls this method, with a pointer on itself
  // and the ID it has been given.

  function WMCommand(wPar:WPARAM; lPar:LPARAM):LRESULT; virtual;
  // Handles the menu messages

//  function WindowProc(hWindow:HWND; wMsg:UINT; wPar:WPARAM; lPar:LPARAM):LRESULT; virtual;
  end; // TMyWindow = object(TWindow)

// var glnNotUsed : integer; // To avoid an error in the DevPascal 1.9 environment
var
  oApp        : TApplication;
  poMyMainWin : PMyWindow;

//******************************************************************
// TMyWindow = object(TWindow)
//******************************************************************

constructor TMyWindow.Init(strWinTitlePrm:ShortString);
//=====================================================
begin
inherited Init(strWinTitlePrm);

poToolBar:=NIL;

Word32Field(103, wNumImage);
wNumImage:=11211;
poBM204:=NIL;

StrField(104, strCombo2, SizeOf(strCombo2));
strCombo2:='Give your text';

// This line is all what is needed to have a status line.
new(poStatusLine, Init(@Self));
end;  // TMyWindow.Init

procedure TMyWindow.WinCreate(strWinClass:ShortString);
//=====================================================
Begin
inherited WinCreate(strWinClass);

// Here calling :  DialogExecMSG(11199, @Self);  doesn't work,
// But posting a message to open the dialog box at startup is possible.
// Opens also the help window, indicating the key action.
//PostMessage(hWin, WM_COMMAND, 101, 0);
end;  // TMyWindow.WinCreate

procedure TMyWindow.FillComboImages(poComboP:PComboBox);
//======================================================
// Fill the choice list of the combo box
var
  wPosL       : word;
  strS        : ShortString;
begin
strS:=GetMsg(3000000001); // First image in the  Images.msg  file
repeat
   // Look for the text defining the image
   wPosL:=1;
   while (wPosL < length(strS)) and (strS[wPosL] <> '"') do inc(wPosL);

   strS:=IntToStr(gglwMessages2LastNum-word32(3000000000),0) + ' = ' +
         Copy(strS, wPosL+1, length(strS)-wPosL-1);

   // Add a new choice in the combo list
   poComboP^.AddString(strS);

   strS:=GetMsgNextNum;
   until (gglwMessages2LastNum > 3100000000) or
         (not gglfMessages2LastFound);

// Select the right line in the combo box
with poComboP^ do begin
   strCtrlLabel[length(strCtrlLabel)+1]:=#0;
   SendMessage(hWin, CB_SELECTSTRING, -1, LPARAM(@strCtrlLabel[1]));
   end;
end;  // TMyWindow.FillComboImages

procedure TMyWindow.Test1;
//========================
begin
// Delete the previous toolbar before creating a new one.
if (poToolBar <> NIL) then dispose(poToolBar, Done);

poToolBar:=PToolBar(ToolBarCreateMSG(11199, @self));
end;  // TMyWindow.Test1

procedure TMyWindow.Test2;
//========================
var
  wWidthL,wHeightL : word32;
  poCombo     : PComboBox;

begin
// Delete the previous toolbar before creating a new one.
if (poToolBar <> NIL) then dispose(poToolBar, Done);

poToolBar:=PToolBar(ToolBarCreateMSG(11299, @self));

// To have a pointer on the button following the combo box
poBM204 :=PButtonBitMap(poToolBar^.GetControlFromID(204)); // We know it is a button bit map

// Fill the combo box with the possible image choices
poCombo :=PComboBox(poToolBar^.GetControlFromVar(wNumImage)); // We know it is a combo box
if (poCombo <> NIL) then FillComboImages(poCombo);

// Change the image on it, depending on the value of wNumImage
if (poBM204^.hBitMap <> 0) then DeleteObject(poBM204^.hBitMap);

// Associate a new image to this button
if (wNumImage < 2000) then
     poBM204^.hBitMap:=LoadImageFromMSG(word32(3000000000) + wNumImage, hWin, wWidthL, wHeightL)
else poBM204^.hBitMap:=LoadImageFromMSG(                     wNumImage, hWin, wWidthL, wHeightL);

// Give a new ID to this button
// And to get the right ID in the WM_COMMAND
poBM204^.wCtrlID:=200 + wNumImage;
SetWindowLong(poBM204^.hWin, GWL_ID, poBM204^.wCtrlID);
end;  // TMyWindow.Test2

procedure TMyWindow.Test3;
//========================
begin
// Delete the previous toolbar before creating a new one.
if (poToolBar <> NIL) then dispose(poToolBar, Done);

poToolBar:=PToolBar(ToolBarCreateMSG(11399, @self));
end;  // TMyWindow.Test3

procedure TMyWindow.Test4;
//========================
// A vertical toolbar
begin
// Delete the previous toolbar before creating a new one.
if (poToolBar <> NIL) then dispose(poToolBar, Done);

poToolBar:=PToolBar(ToolBarCreateMSG(11499, @self));
end;  // TMyWindow.Test4

procedure TMyWindow.CtrlVarUpdate(poCtrl:PWindowBase0; pVar:pointer);
//===================================================================
// a variable has changed in a dialog box.
// pVar = pointer on the variable
// poCtrl = pointer on the control linked to this variable
// poCtrl^.poParent = pointer on the dialog box
// PDialog(poCtrl^.poParent)^.wMsgDescriptor =
// = msg which generated the dialog box
var
  wWidthL,    // width and height of the image in the .msg file
  wHeightL    : word32;

begin
// The height of the tool bar can be seen here
//if (poToolBar <> NIL) then DBW(1, 'ToolBar height=' + ITS(poToolBar^.nYSizePix));

if (PDialog(poCtrl^.poParent)^.wMsgDescriptor = 11299) and
   (pVar = @wNumImage) then begin
   // Change the image on the button following the combo box
   // First delete the bitmap used
   if (poBM204^.hBitMap <> 0) then DeleteObject(poBM204^.hBitMap);

   // Associate a new image to this button
   if (wNumImage < 2000) then
        poBM204^.hBitMap:=LoadImageFromMSG(word32(3000000000) + wNumImage, hWin, wWidthL, wHeightL)
   else poBM204^.hBitMap:=LoadImageFromMSG(                     wNumImage, hWin, wWidthL, wHeightL);

   // Give a new ID to this button
   // And to get the right ID in the WM_COMMAND
   poBM204^.wCtrlID:=200 + wNumImage;
   SetWindowLong(poBM204^.hWin, GWL_ID, poBM204^.wCtrlID);

   // Redraw the button
   InvalidateRgn(poBM204^.hWin, 0, TRUE);
   end; // if
end;  // TMyWindow.CtrlVarUpdate

procedure TMyWindow.ButtonClicked(poCtrl:PWindowBase0; wCtrlID:Word32);
//=====================================================================
begin
poCtrl:=poCtrl; // to avoid a hint;

WriteWin(1, 'Button clicked=' + ITS(wCtrlID));
end;  // TMyWindow.ButtonClicked

function TMyWindow.WMCommand(wPar:WPARAM; lPar:LPARAM):LRESULT;
//=============================================================
// There are no menus treatment, only one dialog box
var
  wNrMenu     : word32;

begin
if (lPar <> 0) then begin
   // call the parent WMCommand method.
   WMCommand:=inherited WMCommand(wPar, lPar);
   exit;
   end;

// for the menus,  lPar = 0
//=========================
wNrMenu   := LoWord(wPar);
Case wNrMenu Of
   101 : Test1;
   102 : Test2;
   103 : Test3;
   104 : Test4;

  201..5000 : WriteWin(1, 'From toolBar=' + ITS5(wPar));

   else WMCommand:=inherited WMCommand(wPar, lPar);
   end;  // Case NrMenu Of
end;  // TMyWindow.WMCommand

//**********************************************************************
Begin // MAIN ******
// Name under which the main window is registered. Spaces are not allowed
oApp.Init('Example052');

// Creation of the main window
new(poMyMainWin, Init('tEx052.  A ToolBar with bitmap buttons'));

// The App.WindowClass can be modified here, if wanted. (Not usual)
oApp.Run;
oApp.Done;  // The main window object is disposed here.
End.

