{
Unit StrMsgs;

This unit is designed to display a messagebox containing both program-supplied
and string resource text.  Foreign language translations are easier if the 
text is contained in a string resource, but parts of a message (like file 
names) need to be supplied at run time. Each message text string resource 
can be split into 7 pieces, interspersed with 6 program-supplied strings.  
Caption string resources can be split into 4, interspersed with 3 program-
supplied strings. 

MsgTok was adapted from Function StrTok, written by John Cooper, Tower 
Software & Systems, 76356,3601, uploaded to CIS as STRPAR.PAS and donated 
to Public Domain. Thanks to John. 

To create MsgTok, StrTok was revisd to return #0 instead of nil when no 
more tokens exist.  Thus if the return value of #0 is passed to a string 
function like StrCopy, it won't cause the function to crash--which would 
happen if nil was passed.  Likewise, MsgTok can be called again after it 
has returned #0 without itself crashing on its own string function.  MsgTok 
now uses a constant pChar delimeter, '+' for the exclusive purpose of 
parsing the string table. 

GiveMsg reads the strings from a string resource using an offset of 
IDS_Msg=15. (You could use any multiple of 16-1; I use 5007 since I have 
already used IDs starting at 1,2,3 & 4 thousand) String resources are read 
in blocks of 16 beginning with ID 0. IDS_Msg+1 is therefore the beginning 
of a 16-string block.  Subsequent blocks begin at IDS_Msg+(n*16)+1. The 
string resource must use a '+' to indicate where program supplied 
information should be inserted. 

Example: 

Stringtable
begin
  IDS_Msg    , "English string table"
  IDS_Msg + 1, "The quick brown + jumped over the lazy +."
  IDS_Msg + 2, "+ is Quick"
end

var
  PcharOne, 
  pCharTwo,
  pCharThree: PChar;

begin
   pCharOne:=strnew('fox');
   pCharTwo:=strnew('dog');
   pCharThree:=strnew('Jumping Fox');

   arMsg[1]:=pCharOne;
   arMsg[2]:=pCharTwo;
   arCap[1]:=pCharThree;
   GiveMsg(hWindow,1,2,mb_OK or mb_iconexclamation,mb_iconexclamation);

Resulting Message box:

                       Jumping Fox is Quick

              The quick brown fox jumped over the lazy dog.

Note that in this case the caption begins with program supplied information, so
the string resource must begin with a '+'.

This unit was written by:

Ravi Nielsen
Maple Hill Software
73200,601
and is donated to the Public Domain.

Please send your comments to BPascal forum or EMail.
}

Unit StrMsgs;

Interface

uses wintypes,winprocs, Strings;

var
  arMsg: array [1..6] of pChar;
  arCap: array [1..3] of pChar;

Function MsgTok(Phrase:Pchar):Pchar;
Function GiveMsg(hOwner:hWnd;TxtResID,CapResID,TextType,BeepType:Word):word;

Implementation

const
  EOS: pchar = #0;
  delimeter: pchar = '+';
  IDS_Msg = 15;

var
    TokenPointer,
    WorkPointer : PChar;

Function MsgTok(Phrase:Pchar):Pchar;
 var
  NullPointer : Pchar;
 begin
  if (Phrase<>Nil) then WorkPointer := Phrase
   else WorkPointer := TokenPointer;

  if workpointer<>EOS then
    begin
      NullPointer := StrPos(WorkPointer,Delimeter);
      if (NullPointer<> Nil) then
        begin
          NullPointer^ := #0;
          TokenPointer  := NullPointer + 1;
        end
       else
          TokenPointer:=EOS;
    end;
  MsgTok := WorkPointer;
 end;

procedure InitMsgArrays;
var ndx:byte;
begin
  for ndx:=1 to 6 do arMsg[ndx]:=nil;
  for ndx:=1 to 3 do arCap[ndx]:=nil;
end;

Function GiveMsg(hOwner:hWnd;TxtResID,CapResID,TextType,BeepType:Word):Word;
var
  ndx:byte;
  Msg,MsgRes,Cap,CapRes:array[0..255] of char;
  BoxResponse:word;
begin
  MsgRes[0]:=#0;
  CapRes[0]:=#0;
  if TxtResID>0 then LoadString(hinstance,ids_Msg+TxtResID,MsgRes,256);
  if CapResID>0 then LoadString(hinstance,ids_Msg+CapResID,CapRes,256);

  {Copy first message token to Msg}
  StrCopy(Msg,MsgTok(MsgRes));
  Ndx:=0;
  {Intersperse program-supplied and resource-supplied message strings until out of
   program-supplied strings or maximum of 6 in array is reached}
  repeat
    Inc(ndx);
    if arMsg[ndx]<>nil then StrCat(Msg,arMsg[ndx]);
    StrCat(Msg,MsgTok(nil));
  until (arMsg[ndx]=nil) or (ndx=6);

  {Copy first caption token to Cap}
  StrCopy(Cap,MsgTok(CapRes));
  Ndx:=0;
  {Intersperse program-supplied and resource-supplied caption strings until out of
   program-supplied strings or maximum of 3 in array is reached}
  repeat
    Inc(ndx);
    if arCap[ndx]<>nil then StrCat(Cap,arCap[ndx]);
    StrCat(Cap,MsgTok(nil));
  until (arCap[ndx]=nil) or (ndx=3);

  Messagebeep(BeepType);
{$ifndef BWCC}
  BoxResponse:=MessageBox(hOwner, Msg, Cap, TextType);
{$else}
  BoxResponse:=BWCCMessageBox(hOwner, Msg, Cap, TextType);
{$endif}
  InitMsgArrays;
  GiveMsg:=BoxResponse;
end;

begin
  InitMsgArrays;
end.

