{ Testing to define accelerators.
  Accelerators are quit simple.
  They are interpreted in the  wUtiles0.pp  unit, in the function
  AccelTableMSGCreate(msgNumber) --> HACCEL;

  But if at number 10100 of the .msg file we have
  10100 AutoCreate
  0 #here we define accelerators
  ...
  0 ...END

  Then the accelerators are automatically loaded.

  c.f. also tEx046
  --------------------------------------------}
program tEx045;

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

Uses
  Windows
// ,wGlobals2
 ,wApplication0
 ,wWindow0
 ,wDialogCreatorLow2
 ,wUtiles0 // for the AccelTableMSGCreate function
 ,wDebug0;

type
  PMyWindow = ^TMyWindow;
  TMyWindow = object(TWindow)
  //"""""""""""""""""""""""""
  hAccel      : HACCEL; // handle on an accelerator table.

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

  procedure Test1;
  procedure Test2;

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

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

var
  oApp        : TApplication;
  poMyMainWin : PMyWindow;

// var nNotUsed : integer; // only to avoid an error message while compliling in DevPascal 1.9

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

hAccel:=0;

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

destructor TMyWindow.Done;
//=========================
begin
// The created accelerator table must be destroyed before ending.
if (hAccel <> 0) then DestroyAcceleratorTable(hAccel);

inherited Done;
end;  // TMyWindow.Done

procedure TMyWindow.Test1;
//========================
// First test
var
  arAccel     : array[1..10] of ACCEL;

begin
// Put a combinaison of the following flags, separated with the "or" operator
// FALT or FCONTROL or FNOINVERT or FSHIFT or FVIRTKEY
arAccel[1].fVirt :=FVIRTKEY or FCONTROL; // It's not the ASCII code, but the key itself
                                         // Must be used with CTRL to generate the WM_COMMAND message
arAccel[1].key   :=VK_1; // key character "1" correspond to this accel.
arAccel[1].Cmd   :=201;  // = LoWord(wPar) in the generated WM_COMMAND

arAccel[2].fVirt :=FVIRTKEY or FCONTROL;
arAccel[2].key   :=VK_2;
arAccel[2].Cmd   :=202;

arAccel[3].fVirt :=FVIRTKEY or FCONTROL;
arAccel[3].key   :=VK_B;
arAccel[3].Cmd   :=203;

arAccel[4].fVirt :=FVIRTKEY or FALT;
arAccel[4].key   :=VK_T;
arAccel[4].Cmd   :=204;

arAccel[5].fVirt :=FVIRTKEY or FALT or FCONTROL;
arAccel[5].key   :=VK_R;
arAccel[5].Cmd   :=205;

// The created accelerator table must be destroyed before ending.
if (hAccel <> 0) then DestroyAcceleratorTable(hAccel);

// Create an accelerator table
hAccel:=CreateAcceleratorTable(arAccel[1], 5);

DBW(1, 'Accelerator table created. hAccel=' + ITS(hAccel));

// Defines the application's accelerator table.
oApp.hAccelTable:=hAccel;
end;  // TMyWindow.Test1

procedure TMyWindow.Test2;
//========================
// Create the accelerator table from a description in the .msg file
begin
// The created accelerator table must be destroyed before ending.
if (hAccel <> 0) then DestroyAcceleratorTable(hAccel);

// Create an accelerator table
// The number 10100 is the standard one where the library will search automatically
hAccel:=AccelTableMSGCreate(10100);

DBW(1, 'Accelerator table created. hAccel=' + ITS(hAccel));

// Defines the application's accelerator table.
oApp.hAccelTable:=hAccel;
end;  // TMyWindow.Test2

function TMyWindow.WMCommand(wPar:WPARAM; lPar:LPARAM):LRESULT;
//=============================================================
// Handles the menu messages
Var wNrMenu     : word;
begin
WMCommand := 0; // Default return value when processing a message

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;

   111 : DialogExecMSG(21199, @Self);
   112 : DialogCreateMSG(21299, @Self);
   113 : DialogCreateMSG(21399, @Self);

   200..599 : DBW(1, 'wNrMenu=' + ITS5(wNrMenu));

   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('Example045');

// Creation of the main window
new(poMyMainWin, Init('tEx045. Testing to define accelerators.'));

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

