PROGRAM RComp;

{$m 32768}

{**************************************************************************
 *                   Sourcefile fr Speed-386                             *
 *           Created using (c) Borland International 1993                 *
 *        (C) 1993,94 R.Nrnberger Franz-Mehring-Str.2 09112 Chemnitz     *
 *                                                                        *
 * Beschreibung: Der Resourcencompiler fr WIN-386                        *
 *                                                                        *
 **************************************************************************
 }


USES Dos,Crt,RcTypes,RcDialog,RcMenu,RcIcon,RcAccel,PMDialog;

RESOURCE RCOMP;

IMPORTS
       FUNCTION WinGetPs(Win:HWND):HPS:                 'PMWIN' index 757;
       FUNCTION WinReleasePs(ps:HPS):LONGWORD:          'PMWIN' index 848;
       FUNCTION GpiCharStringAt(s:PString;Count:LONGWORD;
                                VAR Point:POINTL;hp:HPS):
                                LONGWORD:               'PMGPI' index 359;
       FUNCTION GpiMove(VAR Point:POINTL;hp:HPS):LONGWORD:
                                                        'PMGPI' index 404;
       FUNCTION GpiBox(VRound,HRound:LONGWORD;VAR Point:POINTL;
                       Control:LONGWORD;hp:HPS):LONGWORD:'PMGPI' index 356;
       FUNCTION WinDrawBorder(flCmd,clrBack,ClrFore,cy,cx:LONGWORD;
                              VAR rec:RECTL;hp:HPS):LONGWORD:'PMWIN' index 731;
       PROCEDURE WinSetDlgItemtext(t:PString;item:LONGWORD;Dlg:HWND):
                                                         'PMWIN' index 859;
       FUNCTION DosCreateThread(Stack,Flags:LONGWORD;Para:POINTER;
                                Adr:POINTER;VAR tid:LONGWORD):
                                 LONGWORD:               'DOSCALLS' index 311;
       PROCEDURE DosKillThread(Tid:LONGWORD):            'DOSCALLS' index 111;
       PROCEDURE WinDisMissDlg(result:LONGWORD;Dlg:HWND):'PMWIN' index 729;
       FUNCTION WinBeginPaint1(prclPaint:PRECTL;
                               _hps:HPS;_hwnd:HWND):
                               LONGWORD:                 'PMWIN' index 703;
       PROCEDURE DosSleep(p:LONGWORD):                   'DOSCALLS' index 229;
       FUNCTION WinSetWindowPos(fl:LONGWORD;
                                cy,cx,y,x:LONGWORD;
                                hwndInsertBehind:HWND;
                                _hwnd:HWND):LONGWORD:   PMWIN index 875;
       FUNCTION WinQueryWindowRect(VAR prclDest:RECTL;
                                      _hwnd:HWND ):
                                      LONGWORD:            PMWIN index 840;
       FUNCTION WinDefDlgProc(Para2,Para1:POINTER;msg:LONGWORD;hwnddlg:HWND):
                           LONGWORD:    PMWIn index 910;
       FUNCTION WinDestroyWindow(_hwnd:HWND):
                                    LONGWORD:              PMWIN index 728;
       FUNCTION WinQueryWindowPos(_swp:SWP;
                                     _hwnd:HWND):LONGWORD: PMWIN index 837;
       FUNCTION WinQuerySysValue(iSysValue:LONGWORD;
                                    hwndDesktop:HWND):
                                    LONGWORD:              PMWIN index 829;
       FUNCTION WinWindowFromID(id:LONGWORD;
                                   hwndParent:HWND):HWND:  PMWIN index 899;
       FUNCTION WinSetWindowText(psztext:PSZ;
                                 _hwnd:HWND):LONGWORD:     PMWIN index 877;
       FUNCTION WinPostMsg(mp2,mp1:POINTER;
                              msg:LONGWORD;
                              _hwnd:HWND):LONGWORD:        PMWIN index 919;
       FUNCTION WinProcessDlg(hwndDlg:HWND):LONGWORD: PMWIN index 796;
END;



TYPE
    TResDialog=Object(TDialog)
                 CONSTRUCTOR Init(Parent,Owner:HWND;hmod:HModule;idDlg:LONGWORD;
                                  PCreateParams:Pointer);
                 DESTRUCTOR Done;
                 FUNCTION DialogHandleEvent(Dlg:HWND;msg:LONGWORD;Para1,Para2:
                                            LONGWORD;VAR Handled:BOOLEAN):
                                            LONGWORD:VIRTUAL;
              END;

    TSuccErrDialog=Object(TDialog)
                 CONSTRUCTOR Init(Parent,Owner:HWND;hmod:HModule;idDlg:LONGWORD;
                                  PCreateParams:Pointer);
                 DESTRUCTOR Done;
                 FUNCTION DialogHandleEvent(Dlg:HWND;msg:LONGWORD;Para1,Para2:
                                            LONGWORD;VAR Handled:BOOLEAN):
                                            LONGWORD:VIRTUAL;
                   END;

VAR
   ResLen:LONGINT;
   Temp:word;
   _About:TDialog;
   _succ,_err:TSuccErrDialog;
   ___r:LONGWORD;
   __D:TResDialog;
   ResTid:LONGWORD;
   ErrStr:STRING;

CONST
   StringCount:WORD=0;


FUNCTION TResDialog.DialogHandleEvent(Dlg:HWND;msg:LONGWORD;Para1,Para2:
                                     LONGWORD;VAR Handled:BOOLEAN):LONGWORD;
VAR H:BOOLEAN;
    r:LONGWORD;
    hp:HPS;
    s:String;
    pt:POINTL;
    ScrWidth,Scrheight:LONGWORD;
    Rec:RECTL;
    _Swp:SWP;
    command:WORD;
    __DirS:DirStr;
    __NameS:NameStr;
    __ExtS:ExtStr;
BEGIN
     r:=Inherited.DialogHandleEvent(Dlg,msg,para1,para2,Handled);
     H:=TRUE;
     CASE msg OF
         WM_INITDLG:
         BEGIN
              {Center dialog on screen}
              ScrWidth:=WinQuerySysValue (20{SV_CXSCREEN},1{HWND_DESKTOP});
              ScrHeight:=WinQuerySysValue (21{SV_CYSCREEN},1{HWND_DESKTOP});
              WinQueryWindowRect (rec,Dlg);
              WinSetWindowPos ($82{SWP_MOVE OR SWP_ACTIVATE},0,0,
                               (ScrHeight-rec.ytop) DIV 2,
                               (ScrWidth-Rec.XRight) DIV 2,
                               3{HWND_TOP},Dlg);
         END;
         WM_PAINT:
         BEGIN
              s:=QuellDat;  {Main file:}
              WinSetDlgItemText (s,2002,Dlg); {Main file:}
              WinSetDlgItemText (s,2003,Dlg); {Assembling:}

              r:=WinDefDlgProc(POINTER(para2),POINTER(para1),msg,Dlg);

              hp:=WinGetPs(Dlg);

              WinQueryWindowRect (rec,Dlg);
              GpiMove (POINTL(rec),hp);
              dec(Rec.xRight);
              dec(Rec.yTop);
              GpiBox (0,0,POINTL(rec.xright),2,hp);
              WinQueryWindowPos (_Swp,WinWindowFromID (2000,Dlg));
              Rec.xLeft:= _Swp.x-1;
              Rec.yBottom:= _Swp.y-1;
              Rec.xRight:= _Swp.x + _Swp.cx + 1;
              Rec.yTop:= _Swp.y + _Swp.cy + 1;
              WinDrawBorder($800,CLR_WHITE,CLR_DARKGRAY,
                            1,1,rec,hp);
              WinQueryWindowPos (_Swp,WinWindowFromID (2001,Dlg));
              Rec.xLeft:= _Swp.x-1;
              Rec.yBottom:= _Swp.y-1;
              Rec.xRight:= _Swp.x + _Swp.cx + 1;
              Rec.yTop:= _Swp.y + _Swp.cy + 1;
              WinDrawBorder($800,CLR_WHITE,CLR_DARKGRAY,
                            1,1,rec,hp);
              WinReleasePs(hp); {Canvas Handle free}
         END;
         WM_DISMISS:
         BEGIN
              WinDisMissDlg(1,ResDlg);
              ErrorDetected:=BOOLEAN(Para1);
         END;
         WM_USER_DRAW_M: {Draw Main file}
         BEGIN
              s:=Quelldat;
              IF Length(s)>30 THEN
              BEGIN
                   FSplit(s,__dirs,__names,__exts);
                   s:='...\'+__names+'.'+__exts;
              END;
              WinSetDlgItemText (s,2002,Dlg); {Main file:}
         END;
         WM_USER_DRAW_A: {Draw current file}
         BEGIN
              s:=Quelldat;
              IF Length(s)>30 THEN
              BEGIN
                   FSplit(s,__dirs,__names,__exts);
                   s:='...\'+__names+'.'+__exts;
              END;
              WinSetDlgItemText (s,2003,Dlg); {Assembling:}
         END;
         WM_COMMAND:
         BEGIN
              command:=Word(Para1);
              IF command=2005 {Cancel} THEN
              BEGIN
                   WinDisMissDlg(1,Dlg);
                   err:='User break';
                   ErrorDetected:=TRUE;  {Cancel pressed}
              END
              ELSE H:=FALSE;
         END;
         ELSE IF not Handled THEN H:=FALSE;
     END; {case}

     Handled:=H;
     DialogHandleEvent:=r;
END;

CONSTRUCTOR TResDialog.Init(Parent,Owner:HWND;hmod:HModule;idDlg:LONGWORD;
                           PCreateParams:Pointer);
BEGIN
     Inherited.Init(Parent,Owner,hmod,idDlg,PCreateParams);
END;

DESTRUCTOR TResDialog.Done;
BEGIN
END;

FUNCTION TSuccErrDialog.DialogHandleEvent(Dlg:HWND;msg:LONGWORD;Para1,Para2:
                                     LONGWORD;VAR Handled:BOOLEAN):LONGWORD;
VAR H:BOOLEAN;
    r:LONGWORD;
    hp:HPS;
    s:String;
    pt:POINTL;
    ScrWidth,Scrheight:LONGWORD;
    Rec:RECTL;
    _Swp:SWP;
    command:WORD;
BEGIN
     r:=0;
     H:=TRUE;
     CASE msg OF
         WM_INITDLG:
         BEGIN
              {Center dialog on screen}
              ScrWidth:=WinQuerySysValue (20{SV_CXSCREEN},1{HWND_DESKTOP});
              ScrHeight:=WinQuerySysValue (21{SV_CYSCREEN},1{HWND_DESKTOP});
              WinQueryWindowRect (rec,Dlg);
              WinSetWindowPos ($82{SWP_MOVE OR SWP_ACTIVATE},0,0,
                               (ScrHeight-rec.ytop) DIV 2,
                               (ScrWidth-Rec.XRight) DIV 2,
                               3{HWND_TOP},Dlg);
         END;
         WM_PAINT:
         BEGIN
              r:=WinDefDlgProc(POINTER(para2),POINTER(para1),msg,Dlg);

              hp:=WinGetPs(Dlg);
              WinQueryWindowRect (rec,Dlg);
              GpiMove (POINTL(rec),hp);
              dec(Rec.xRight);
              dec(Rec.yTop);
              GpiBox (0,0,POINTL(rec.xright),2,hp);
              WinQueryWindowPos (_Swp,WinWindowFromID (2000,Dlg));
              Rec.xLeft:= _Swp.x-1;
              Rec.yBottom:= _Swp.y-1;
              Rec.xRight:= _Swp.x + _Swp.cx + 1;
              Rec.yTop:= _Swp.y + _Swp.cy + 1;
              WinDrawBorder($800,CLR_WHITE,CLR_DARKGRAY,
                            1,1,rec,hp);
              WinQueryWindowPos (_Swp,WinWindowFromID (2001,Dlg));
              Rec.xLeft:= _Swp.x-1;
              Rec.yBottom:= _Swp.y-1;
              Rec.xRight:= _Swp.x + _Swp.cx + 1;
              Rec.yTop:= _Swp.y + _Swp.cy + 1;
              WinDrawBorder($800,CLR_WHITE,CLR_DARKGRAY,
                            1,1,rec,hp);
              WinReleasePs(hp); {Canvas Handle free}
         END;
         WM_COMMAND:
         BEGIN
              command:=Word(Para1);
              IF command=2005 {Ok} THEN
              BEGIN
                   WinDisMissDlg(1,Dlg);
              END
              ELSE H:=FALSE;
         END;
         ELSE IF not Handled THEN H:=FALSE;
     END; {case}

     Handled:=H;
     DialogHandleEvent:=r;
END;

CONSTRUCTOR TSuccErrDialog.Init(Parent,Owner:HWND;hmod:HModule;idDlg:LONGWORD;
                           PCreateParams:Pointer);
BEGIN
     Inherited.Init(Parent,Owner,hmod,idDlg,PCreateParams);
END;

DESTRUCTOR TSuccErrDialog.Done;
BEGIN
END;

PROCEDURE Parse_line;
BEGIN
     CASE Commanditem OF
       __MENU:ParseMenu;
       __ICON,__POINTER:ParseIcon;
       __BITMAP:ParseBitMap;
       __CONST:ParseConst;
       __DLGTEMPLATE:ParseDialog;
       __ACCELTABLE:ParseAccel;
       __HELPTABLE:ParseHelpTable;
       __HELPSUBTABLE:ParseHelpSubTable;
       __END:;
       else error('Command '+command+' not found');
     END; {CASE}
END;

PROCEDURE Parse;
BEGIN
     WHILE not eof(quellf) DO
     BEGIN
          Read_line;
          Parse_line;
     END;
END;


PROCEDURE RunResComp;
VAR p:POINTER;
Label l;
BEGIN
     Quelline:=0;
     Dialogs:=NIL;
     Menus:=NIL;
     Icons:=NIL;
     Bitmaps:=NIL;
     Constants:=NIL;
     Accelerators:=NIL;
     HelpTables:=NIL;
     HelpSubTables:=NIL;
     DialogCount:=0;
     AccelCount:=0;
     HelptableCount:=0;
     HelpSubTableCount:=0;
     IconCount:=0;
     BitmapCount:=0;
     MenuCount:=0;
     Assign(quellf,quelldat);
     reset(quellf,1);
     if ioresult<>0 then error('Could not open sourcefile '+quelldat);
     Assign(zielf,zieldat);
     rewrite(zielf,1);
     if ioresult<>0 then error('Could not open destination file '+zieldat);
     {writeln('Compiling...');}
     Parse;
     close(quellf);
     if ioresult<>0 then error('Could not close sourcefile');
     {writeln('Successfull...');
     writeln('Generating '+zieldat);}

     WriteWord(BitmapCount); {Anzahl Bitmaps}
     WriteWord(IconCount);   {Anzahl Icons}
     WriteWord(MenuCount);   {Anzahl Menus}
     WriteWord(dialogcount); {Anzahl Dialoge}
     WriteWord(AccelCount);  {Anzahl Acceleratortabellen}
     WriteWord(HelptableCount);  {Anzahl Helptabletabellen}
     WriteWord(HelpSubtableCount);  {Anzahl HelpSubtabletabellen}

     ResLen:=0;

     TempIcon:=Bitmaps;
     while TempIcon<>NIL do
     begin
          ResLen:=ResLen+TempIcon^.subsize;
          TempIcon:=TempIcon^.next;
     end;

     TempIcon:=Icons;
     while TempIcon<>NIL do
     begin
          ResLen:=ResLen+TempIcon^.subsize;
          TempIcon:=TempIcon^.next;
     end;

     TempMenu:=Menus;
     while TempMenu<>NIL do
     begin
          ResLen:=ResLen+TempMenu^.subsize;
          TempMenu:=TempMenu^.next;
     end;

     TempDialog:=Dialogs;
     while TempDialog<>NIL do
     begin
          ResLen:=ResLen+TempDialog^.subsize;
          TempDialog:=TempDialog^.next;
     end;

     TempAccel:=Accelerators;
     while TempAccel<>NIL do
     begin
          ResLen:=ResLen+TempAccel^.subsize;
          TempAccel:=TempAccel^.next;
     end;

     TempHelptable:=HelpTables;
     while Temphelptable<>NIL do
     begin
          ResLen:=ResLen+TempHelptable^.subsize;
          TemphelpTable:=Temphelptable^.next;
     end;

     TempHelpSubtable:=HelpSubTables;
     while TemphelpSubtable<>NIL do
     begin
          ResLen:=ResLen+TempHelpSubtable^.subsize;
          TemphelpSubTable:=TemphelpSubtable^.next;
     end;

     Blockwrite(Zielf,ResLen,4);
     if ioresult<>0 then error('File write error');

     {Zuerst die Bitmaps}
     Write_Bitmaps;

     {jetzt die Icons}
     Write_Icons;

     {Jetzt die Menus}
     Write_Menus;

     {jetzt die Dialoge}
     Write_Dialogs;

     {Jetzt die Acceleratortabellen}
     Write_Accels;

     {Hifetabellen}
     Write_HelpTables;

     {Hilfesubtabellen}
     Write_HelpSubTables;

     {Die Daten der einzelnen Ressourcen}
     Write_Res_Icons(Bitmaps);
     Write_Res_Icons(Icons);
     Write_Res_Menus;
     Write_Res_Dialogs;
     Write_Res_Accels;
     Write_Res_Helptables;
     Write_Res_HelpSubTables;

     for temp:=1 to 10 do writeword(0);

     close(zielf);
     if ioresult<>0 then error('Could not close destination file');
     {writeln('Ressource file created !');}

     ErrorDetected:=FALSE;
     p:=NIL; {No error detected}
     WinPostMsg(NIL,p,WM_DISMISS,ResDlg); {Delete dialog window}
l:
     goto l;  {Thread is killed by parent process}
END;

BEGIN
     if Paramcount=0 Then
     BEGIN
           _About.Init(1,0,0,4000,NIL);
           _About.ExecDialog(___r);
           _About.Done;
           Halt(0);
     END;
     {writeln;
     writeln('Ressource compiler for OS/2 V0.1 BETA (1994)');
     writeln('(C) 1994 Rene Nrnberger');}
     QuellDat:=Paramstr(1);
     fsplit(Quelldat,d,n,e);
     if e='' then e:='.RC';
     if d='' then getdir(0,d);
     if d[length(d)]='\' then dec(d[0]);
     quelldat:=d+'\'+n+e;
     If Paramcount=2 Then ZielDat:=Paramstr(2)
     Else Zieldat:=d;
     IF Zieldat[length(zieldat)]='\' then dec(zieldat[0]);
     Zieldat:=Zieldat+'\'+n+'.RES';
     ErrorDetected:=FALSE;
     err:='';
     __D.Init(1,0,0,1005,NIL);  {load dialog}
     __D.GetDlg(ResDlg);
     DosCreateThread(32768,2,NIL,@RunResComp,ResTid);
     WinProcessDlg(ResDlg);  {Process the dialog}

     DosKillThread(ResTid);  {Kill the parent thread}
     WinDestroyWindow(ResDlg);
     {The program will return to here if main program is terminated}
     __D.Done;
     IF ErrorDetected THEN
     BEGIN
          _Err.Init(1,0,0,3001,NIL);
          _Err.GetDlg(ResDlg);
          Errstr:='Error detected in line:'+tostr(quelline);
          WinSetDlgItemText (Errstr,1007,ResDlg); {Main file:}
          Errstr:='"'+err+'"';
          WinSetDlgItemText(Errstr,1009,ResDlg);
          Errstr:='Work file:'+Quelldat;
          WinSetDlgItemText (ErrStr,1008,ResDlg)
          Beep(1200,300);
          _Err.ExecDialog(___r);
          _Err.Done;
    END
    ELSE
    BEGIN
         Beep(800,50);
         Beep(1000,30);
         Beep(1300,50);
         _Succ.Init(1,0,0,3000,NIL);
         _Succ.GetDlg(ResDlg);
         Errstr:='Work file:'+Quelldat;
         WinSetDlgItemText (ErrStr,1008,ResDlg)
         _Succ.ExecDialog(___r);
         _Succ.Done;
    END;
END.
