RC to PRG generator

Re: RC to PRG generator

Postby Giovany Vecchi » Mon Feb 12, 2024 11:12 pm

Antonio.

I've already done some tests and I couldn't identify the GoupBox control.
The control is assigned to the BUTTON type.
I needed a way to identify the BS_GROUPBOX too.

Code: Select all  Expand view
 CONTROL "Guias Anteriores", 1101, "Button", BS_GROUPBOX, 2, 13, 135, 22
  CONTROL "Atualizar para", 1102, "Button", BS_GROUPBOX, 2, 35, 135, 22
 
User avatar
Giovany Vecchi
 
Posts: 223
Joined: Mon Jun 05, 2006 9:39 pm
Location: Brasil

Re: RC to PRG generator

Postby TimStone » Mon Feb 12, 2024 11:27 pm

Antonio,

One small thought. You are using oDlg each time. I realize it is LOCAL and that should be OK, but over the years, I find in my experience, sometimes I still have issues arise. In my case, I often give the dialogs unique names, especially if I will have multiple ones on the same screen. For example, when using folders, I have a master dialog, and each folder has its own dialog.

So, you may wish to include an option to assign a name for the dialog that will be used by the program when it creates each control.

Tim
Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
User avatar
TimStone
 
Posts: 2944
Joined: Fri Oct 07, 2005 1:45 pm
Location: Trabuco Canyon, CA USA

Re: RC to PRG generator

Postby Marcelo Via Giglio » Tue Feb 13, 2024 2:59 am

Hola Antonio,

Interesting work, I think it can be the start to another aproach to start a visual form builder, rc and prg source generator

Saludos cordiales

Marcelo Via
Marcelo Via Giglio
 
Posts: 1064
Joined: Fri Oct 07, 2005 3:33 pm
Location: Cochabamba - Bolivia

Re: RC to PRG generator

Postby Antonio Linares » Tue Feb 13, 2024 8:19 am

Enhanced version:
Code: Select all  Expand view
#include "FiveWin.ch"

#define GWL_STYLE         -16

static nButtons := 0, nLbxs := 0, nGets := 0, nTrackBars := 0, nXBrowses := 0, nMeterExs := 0
static nGroups := 0, nRadios := 0

function Main()

   local oDlg

   TMeterEx():Register()
   TXBrowse():Register()

   DEFINE DIALOG oDlg RESOURCE "test"

   ACTIVATE DIALOG oDlg CENTERED ;
      ON RIGHT CLICK WritePrg( oDlg )

return nil

function WritePrg( oDlg )

   local cPrg := "", n, cVars := ""

   EnumChildWindows( oDlg:hWnd, { | hCtrl | cPrg += GenCode( hCtrl ) } )
   
   if nButtons > 0
      cVars += "local "
      for n = 1 to nButtons
        cVars += If( n > 1, ", ", "" ) + "oBtn" + AllTrim( Str( n ) )
      next    
      cVars += CRLF    
   endif
   if nLbxs > 0
      cVars += "local "
      for n = 1 to nLbxs
         cVars += If( n > 1, ", ", "" ) + "oLbx" + AllTrim( Str( n ) )
      next
      cVars += CRLF    
    endif          
    if nGets > 0
       cVars += "local "
       for n = 1 to nGets
          cVars += If( n > 1, ", ", "" ) + "oGet" + AllTrim( Str( n ) )
       next
       cVars += CRLF    
    endif          
    if nTrackBars > 0
       cVars += "local "
       for n = 1 to nTrackBars
          cVars += If( n > 1, ", ", "" ) + "oTrb" + AllTrim( Str( n ) )
       next
       cVars += CRLF    
    endif          
    if nXBrowses > 0
      cVars += "local "
      for n = 1 to nXBrowses
         cVars += If( n > 1, ", ", "" ) + "oXbrw" + AllTrim( Str( n ) )
      next
      cVars += CRLF    
   endif          
   if nMeterExs > 0
      cVars += "local "
      for n = 1 to nMeterExs
         cVars += If( n > 1, ", ", "" ) + "oMtr" + AllTrim( Str( n ) )
      next
      cVars += CRLF    
   endif          
   if nGroups > 0
      cVars += "local "
      for n = 1 to nGroups
         cVars += If( n > 1, ", ", "" ) + "oGrp" + AllTrim( Str( n ) )
      next
      cVars += CRLF    
   endif          
   if nRadios > 0
      cVars += "local "
      for n = 1 to nGroups
         cVars += If( n > 1, ", ", "" ) + "oRad" + AllTrim( Str( n ) )
      next
      cVars += CRLF    
   endif          
 
   FW_memoEdit( cVars + CRLF + 'DEFINE DIALOG oDlg RESOURCE "' + oDlg:cResName + '"' + ;
                CRLF + CRLF + cPrg + "ACTIVATE DIALOG oDlg CENTERED" )

return nil  

function GenCode( hCtrl )

   local cCode := "REDEFINE "
   local cClass := Upper( GetClassName( hCtrl ) )
   
   static hPrevCtrl

   do case
      case cClass == "BUTTON"
         if nAnd( GetWindowLong( hCtrl, GWL_STYLE ), BS_AUTORADIOBUTTON ) == BS_AUTORADIOBUTTON
            cCode += "RADIO oRad" + AllTrim( Str( ++nRadios ) ) + " ID " + AllTrim( Str( GetDlgCtrlId( hCtrl ) ) ) + ;
               " OF oDlg ON CLICK ''" + " // " + LTrim( GetWindowText( hCtrl ) )
         elseif nAnd( GetWindowLong( hCtrl, GWL_STYLE ), BS_GROUPBOX ) == BS_GROUPBOX
            cCode += "GROUP oGrp" + AllTrim( Str( ++nGroups ) ) + " ID " + AllTrim( Str( GetDlgCtrlId( hCtrl ) ) ) + ;
               " OF oDlg"+ " // " + LTrim( GetWindowText( hCtrl ) )
         else  
            cCode += "BUTTON oBtn" + AllTrim( Str( ++nButtons ) ) + " ID " + AllTrim( Str( GetDlgCtrlId( hCtrl ) ) ) + ;
               " OF oDlg ACTION ''"
         endif  

      case cClass == "EDIT"
         cCode += "GET oGet" + AllTrim( Str( ++nGets ) ) + " ID " + AllTrim( Str( GetDlgCtrlId( hCtrl ) ) ) + ;
                  " OF oDlg" + If( lAnd( GetWindowLong( hCtrl, GWL_STYLE ), ES_MULTILINE ), " MULTILINE", "" ) + ;
                  " // " + If( ! Empty( hPrevCtrl ) .and. ;
                  Upper( GetClassName( hPrevCtrl ) ) == "STATIC", GetWindowText( hPrevCtrl ), "" )  
   
      case cClass == "LISTBOX"
         cCode += "LISTBOX oLbx" + AllTrim( Str( ++nLbxs ) ) + " ID " + AllTrim( Str( GetDlgCtrlId( hCtrl ) ) ) + ;
                  " OF oDlg ON CHANGE ''"

      case cClass == "MSCTLS_TRACKBAR32"  
         cCode += "TRACKBAR oTrb" + AllTrim( Str( ++nTrackBars ) ) + " ID " + AllTrim( Str( GetDlgCtrlId( hCtrl ) ) ) + ;
            " OF oDlg ON CHANGE ''"

      case cClass == "TXBROWSE"
         cCode += "XBROWSE oBrw" + AllTrim( Str( ++nXBrowses ) ) + " ID " + AllTrim( Str( GetDlgCtrlId( hCtrl ) ) ) + ;
            " OF oDlg"

      case cClass == "STATIC"
         cCode = ""  

      case cClass == "TMETEREX"
         cCode += "METEREX oMtr" + AllTrim( Str( ++nMeterExs ) ) + " ID " + AllTrim( Str( GetDlgCtrlId( hCtrl ) ) ) + ;
            " OF oDlg"

      otherwise
         MsgInfo( cClass )  
    endcase
   
    hPrevCtrl = hCtrl

return cCode + If( ! Empty( cCode ), CRLF + CRLF, "" )

Image
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42099
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: RC to PRG generator

Postby Antonio Linares » Tue Feb 13, 2024 9:11 am

Simplifying the code:
Code: Select all  Expand view
#include "FiveWin.ch"

#define GWL_STYLE         -16

static hVars := { "oBtn" => 0, "oLbx" => 0, "oGet" => 0, "oTbr" => 0,;
                  "oBrw" => 0, "oMtr" => 0, "oGrp" => 0, "oRad" => 0 }

function Main()

   local oDlg

   TMeterEx():Register()
   TXBrowse():Register()

   DEFINE DIALOG oDlg RESOURCE "test"

   ACTIVATE DIALOG oDlg CENTERED ;
      ON RIGHT CLICK WritePrg( oDlg )

return nil

function WritePrg( oDlg )

   local cPrg := "", n, cVars := "", cKey

   EnumChildWindows( oDlg:hWnd, { | hCtrl | cPrg += GenCode( hCtrl ) } )
   
   for each cKey in hb_HKeys( hVars )
      if hVars[ cKey ] != 0
         cVars += "local "
         for n = 1 to hVars[ cKey ]
            cVars += If( n > 1, ", ", "" ) + cKey + AllTrim( Str( n ) )    
         next
         cVars += CRLF
      endif
   next
 
   FW_memoEdit( cVars + CRLF + 'DEFINE DIALOG oDlg RESOURCE "' + oDlg:cResName + '"' + ;
                CRLF + CRLF + cPrg + "ACTIVATE DIALOG oDlg CENTERED" )

return nil  

function GenCode( hCtrl )

   local cCode := "REDEFINE "
   local cClass := Upper( GetClassName( hCtrl ) )
   
   static hPrevCtrl

   do case
      case cClass == "BUTTON"
         if nAnd( GetWindowLong( hCtrl, GWL_STYLE ), BS_AUTORADIOBUTTON ) == BS_AUTORADIOBUTTON
            cCode += "RADIO oRad" + AllTrim( Str( ++hVars[ "oRad" ] ) ) + " ID " + AllTrim( Str( GetDlgCtrlId( hCtrl ) ) ) + ;
               " OF oDlg ON CLICK ''" + " // " + LTrim( GetWindowText( hCtrl ) )
         elseif nAnd( GetWindowLong( hCtrl, GWL_STYLE ), BS_GROUPBOX ) == BS_GROUPBOX
            cCode += "GROUP oGrp" + AllTrim( Str( ++hVars[ "oGrp" ] ) ) + " ID " + AllTrim( Str( GetDlgCtrlId( hCtrl ) ) ) + ;
               " OF oDlg"+ " // " + LTrim( GetWindowText( hCtrl ) )
         else  
            cCode += "BUTTON oBtn" + AllTrim( Str( ++hVars[ "oBtn" ] ) ) + " ID " + AllTrim( Str( GetDlgCtrlId( hCtrl ) ) ) + ;
               " OF oDlg ACTION ''"
         endif  

      case cClass == "EDIT"
         cCode += "GET oGet" + AllTrim( Str( ++hVars[ "oGet" ] ) ) + " ID " + AllTrim( Str( GetDlgCtrlId( hCtrl ) ) ) + ;
                  " OF oDlg" + If( lAnd( GetWindowLong( hCtrl, GWL_STYLE ), ES_MULTILINE ), " MULTILINE", "" ) + ;
                  " // " + If( ! Empty( hPrevCtrl ) .and. ;
                  Upper( GetClassName( hPrevCtrl ) ) == "STATIC", GetWindowText( hPrevCtrl ), "" )  
   
      case cClass == "LISTBOX"
         cCode += "LISTBOX oLbx" + AllTrim( Str( ++hVars[ "oLbx" ] ) ) + " ID " + AllTrim( Str( GetDlgCtrlId( hCtrl ) ) ) + ;
                  " OF oDlg ON CHANGE ''"

      case cClass == "MSCTLS_TRACKBAR32"  
         cCode += "TRACKBAR oTrb" + AllTrim( Str( ++hVars[ "oTrb"] ) ) + " ID " + AllTrim( Str( GetDlgCtrlId( hCtrl ) ) ) + ;
            " OF oDlg ON CHANGE ''"

      case cClass == "TXBROWSE"
         cCode += "XBROWSE oBrw" + AllTrim( Str( ++hVars[ "oBrw" ] ) ) + " ID " + AllTrim( Str( GetDlgCtrlId( hCtrl ) ) ) + ;
            " OF oDlg"

      case cClass == "STATIC"
         cCode = ""  

      case cClass == "TMETEREX"
         cCode += "METEREX oMtr" + AllTrim( Str( ++hVars[ "oMtr" ] ) ) + " ID " + AllTrim( Str( GetDlgCtrlId( hCtrl ) ) ) + ;
            " OF oDlg"

      otherwise
         MsgInfo( cClass )  
    endcase
   
    hPrevCtrl = hCtrl

return cCode + If( ! Empty( cCode ), CRLF + CRLF, "" )
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42099
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: RC to PRG generator

Postby Antonio Linares » Tue Feb 13, 2024 11:20 am

Now we list all the dialogs that are available in the embedded RES inside the EXE and allows you to select one and generate the code for it:
simply rename your RC file as rctoprg.rc and build rctoprg.prg

If you keep your dialogs inside a DLL then replace GetInstance() for LoadLibrary( "yourdll.dll" )

This example and the new C code listed at the bottom will be included in next FWH build.

rctoprg.prg
Code: Select all  Expand view
#include "FiveWin.ch"

#define GWL_STYLE   -16
#define RT_DIALOG   MakeIntResource( 5 )

static hVars := { "oBtn" => 0, "oLbx" => 0, "oGet" => 0, "oTbr" => 0,;
                  "oBrw" => 0, "oMtr" => 0, "oGrp" => 0, "oRad" => 0 }

function Main()

   local oDlg, cDlgName, aDlgNames := {}, oLbx, oGetCode, cCode := Space( 800 ), oDlgNew

   TMeterEx():Register()
   TXBrowse():Register()
   TFolderEx():Register()

   EnumResourceNames( GetInstance(), RT_DIALOG, { | cDlgName | AAdd( aDlgNames, cDlgName ), .T. } )

   DEFINE DIALOG oDlg TITLE "RC dialogs to PRG" SIZE 720, 500

   @ 0, 1.5 SAY "Select a dialog" OF oDlg

   @ 1, 1 LISTBOX oLbx VAR cDlgName ITEMS aDlgNames OF oDlg SIZE 100, 200

   @ 12, 5 BUTTON "Generate" OF oDlg ACTION oDlgNew := BuildDialog( cDlgName, oGetCode )

   @ 12, 16 BUTTON "End" OF oDlg ACTION oDlgNew:End()

   @ 1.1, 14 GET oGetCode VAR cCode OF oDlg MULTILINE SIZE 240, 188

   ACTIVATE DIALOG oDlg ON INIT oDlg:SetPos( 300, 100 )

return nil

function BuildDialog( cDlgName, oGetCode )

   local oDlg

   DEFINE DIALOG oDlg RESOURCE ( cDlgName )

   ACTIVATE DIALOG oDlg NOWAIT ON INIT ( oDlg:SetPos( 300, 900 ), WritePrg( oDlg, oGetCode ) )

return oDlg

function WritePrg( oDlg, oGetCode )

   local cPrg := "", n, cVars := "", cKey

   EnumChildWindows( oDlg:hWnd, { | hCtrl | cPrg += GenCode( hCtrl ) } )
   
   for each cKey in hb_HKeys( hVars )
      if hVars[ cKey ] != 0
         cVars += "local "
         for n = 1 to hVars[ cKey ]
            cVars += If( n > 1, ", ", "" ) + cKey + AllTrim( Str( n ) )    
         next
         cVars += CRLF
      endif
   next
 
   oGetCode:SetText( cVars + CRLF + 'DEFINE DIALOG oDlg RESOURCE "' + oDlg:cResName + '"' + ;
                     CRLF + CRLF + cPrg + "ACTIVATE DIALOG oDlg CENTERED" )

return nil  

function GenCode( hCtrl )

   local cCode := "REDEFINE "
   local cClass := Upper( GetClassName( hCtrl ) )
   
   static hPrevCtrl

   do case
      case cClass == "BUTTON"
         if nAnd( GetWindowLong( hCtrl, GWL_STYLE ), BS_AUTORADIOBUTTON ) == BS_AUTORADIOBUTTON
            cCode += "RADIO oRad" + AllTrim( Str( ++hVars[ "oRad" ] ) ) + " ID " + AllTrim( Str( GetDlgCtrlId( hCtrl ) ) ) + ;
               " OF oDlg ON CLICK ''" + " // " + LTrim( GetWindowText( hCtrl ) )
         elseif nAnd( GetWindowLong( hCtrl, GWL_STYLE ), BS_GROUPBOX ) == BS_GROUPBOX
            cCode += "GROUP oGrp" + AllTrim( Str( ++hVars[ "oGrp" ] ) ) + " ID " + AllTrim( Str( GetDlgCtrlId( hCtrl ) ) ) + ;
               " OF oDlg"+ " // " + LTrim( GetWindowText( hCtrl ) )
         else  
            cCode += "BUTTON oBtn" + AllTrim( Str( ++hVars[ "oBtn" ] ) ) + " ID " + AllTrim( Str( GetDlgCtrlId( hCtrl ) ) ) + ;
               " OF oDlg ACTION ''"
         endif  

      case cClass == "EDIT"
         cCode += "GET oGet" + AllTrim( Str( ++hVars[ "oGet" ] ) ) + " ID " + AllTrim( Str( GetDlgCtrlId( hCtrl ) ) ) + ;
                  " OF oDlg" + If( lAnd( GetWindowLong( hCtrl, GWL_STYLE ), ES_MULTILINE ), " MULTILINE", "" ) + ;
                  " // " + If( ! Empty( hPrevCtrl ) .and. ;
                  Upper( GetClassName( hPrevCtrl ) ) == "STATIC", GetWindowText( hPrevCtrl ), "" )  
   
      case cClass == "LISTBOX"
         cCode += "LISTBOX oLbx" + AllTrim( Str( ++hVars[ "oLbx" ] ) ) + " ID " + AllTrim( Str( GetDlgCtrlId( hCtrl ) ) ) + ;
                  " OF oDlg ON CHANGE ''"

      case cClass == "MSCTLS_TRACKBAR32"  
         cCode += "TRACKBAR oTrb" + AllTrim( Str( ++hVars[ "oTrb"] ) ) + " ID " + AllTrim( Str( GetDlgCtrlId( hCtrl ) ) ) + ;
            " OF oDlg ON CHANGE ''"

      case cClass == "TXBROWSE"
         cCode += "XBROWSE oBrw" + AllTrim( Str( ++hVars[ "oBrw" ] ) ) + " ID " + AllTrim( Str( GetDlgCtrlId( hCtrl ) ) ) + ;
            " OF oDlg"

      case cClass == "STATIC"
         cCode = ""  

      case cClass == "TMETEREX"
         cCode += "METEREX oMtr" + AllTrim( Str( ++hVars[ "oMtr" ] ) ) + " ID " + AllTrim( Str( GetDlgCtrlId( hCtrl ) ) ) + ;
            " OF oDlg"

      otherwise
         MsgInfo( cClass )  
    endcase
   
    hPrevCtrl = hCtrl

return cCode + If( ! Empty( cCode ), CRLF + CRLF, "" )

#pragma BEGINCODE

#include <Windows.h>
#include <hbapi.h>
#include <hbapiitm.h>

//---------------------------------------------------------------------------//  

static BOOL CALLBACK EnumResourceNamesCallback( HMODULE hModule, LPSTR lpszType, LPSTR lpszName, LONG_PTR lParam )
{
   ( void ) hModule;

   if( lpszType == RT_DIALOG )
   {
      PHB_ITEM pStrName = hb_itemPutC( NULL, lpszName );
      hb_evalBlock1( ( PHB_ITEM ) lParam, pStrName );
      hb_itemRelease( pStrName );
   }
   return hb_parl( -1 ); // .T. continue enumeration
}

//---------------------------------------------------------------------------//  

HB_FUNC( ENUMRESOURCENAMES )
{
   #ifndef _WIN64
      EnumResourceNames( ( HMODULE ) hb_parnl( 1 ), ( const signed char * ) hb_parnl( 2 ),
         ( ENUMRESNAMEPROC ) EnumResourceNamesCallback, ( LONG_PTR ) hb_param( 3, HB_IT_BLOCK ) );
   #else
      EnumResourceNames( ( HMODULE ) hb_parnll( 1 ), ( const signed char * ) hb_parnl( 2 ),
         ( ENUMRESNAMEPROC ) EnumResourceNamesCallback, ( LONG_PTR ) hb_param( 3, HB_IT_BLOCK ) );
   #endif
}

//---------------------------------------------------------------------------//
#pragma ENDCODE

https://github.com/FiveTechSoft/screenshots/blob/master/rctoprg3.png?raw=true
Image
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42099
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: RC to PRG generator

Postby vilian » Thu Feb 15, 2024 1:27 pm

Where could i find file windows.h ?
Sds,
Vilian F. Arraes
vilian@vfatec.com.br
Belém-Pa-Brazil
User avatar
vilian
 
Posts: 977
Joined: Wed Nov 09, 2005 2:17 am
Location: Brazil

Re: RC to PRG generator

Postby Antonio Linares » Thu Feb 15, 2024 1:31 pm

vilian wrote:Where could i find file windows.h ?


The C compiler provides it
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42099
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: RC to PRG generator

Postby vilian » Thu Feb 15, 2024 1:54 pm

Thank you ;)
Sds,
Vilian F. Arraes
vilian@vfatec.com.br
Belém-Pa-Brazil
User avatar
vilian
 
Posts: 977
Joined: Wed Nov 09, 2005 2:17 am
Location: Brazil

Previous

Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: No registered users and 86 guests