kia1349
یک شنبه 10 تیر 1386, 17:09 عصر
Recently I was trying to make ProfilSmart translatable. In other words all program texts on forms, classes, messageboxes, reports etc. must be in the language that the user prefers. I have to admit that this is a very very boring procedure. If you ever have tried something like that you understand what I mean. Even I have downloaded Steven's INTL Toolkit I preferred to do the job manually.
At first, program forms have all the captions in greek. I was lucky enough to have used only sublclassed labels. So I created a Message_id property in my base label class. After that I created a table LangText (REC_ID Integer, GR_Text , EN_Text, FR_Text ...) in order to keep there every string of the program. My thought was to have a table with the messages and in each control a message_id number that corresponds to the appropriate record. The translation will take place "on the fly" in the SetCaption method after label's Init Event.
Moving the label captions from controls into LangText table one by one very soon I realised that this procedure will take months! So I decided to spend a couple of hours to create this routine:
*================================================= =====================
*| Purpose...... Sets the correct message_id to all Labels of the class/form
*| Author....... Vaggelakos
*| Created...... August 18, 2006
*| About........
*| Mod List.....
*================================================= =====================
LOCAL lcClassName, lcProp, lnMsgLine, lnCaptionLine, lnCaptionStart, lnCountOfFiles, lnCounter
LOCAL ARRAY laPropLines[1]
lcClassName = "Form1.Scx"
STORE 0 TO lnMsgLine, lnCaptionLine, lnCaptionStart, lnCountOfFiles
IF NOT USED("LangText")
USE langText IN 0
ENDIF
IF NOT USED(JUSTFNAME(lcClassName))
USE (lcClassName) IN 0
ENDIF
SELECT (lcClassName)
GO top
SCAN
IF ALLTRIM(baseclass)="label"
lcProp = Properties
lnCaptionStart = AT("Caption",lcProp)
STORE 0 TO lnMsgLine, lnCaptionLine
IF lnCaptionStart > 0 THEN
*We have a Caption
lnCountofLines = GetWordCount(Properties,CHR(10))
DIMENSION laPropLines[lnCountofLines]
laPropLines[1] = GetwordNum(properties,1,CHR(13))
IF SUBSTR(laPropLines[1],1,7) = "Caption"
lnCaptionLine = 1
ENDIF
FOR lnCounter = 2 TO lnCountofLines
laPropLines[lnCounter] = CHR(13) + GetwordNum(properties,lnCounter,CHR(13))
IF SUBSTR(laPropLines[lnCounter],1,7) = "Caption"
lnCaptionLine = lnCounter
ENDIF
IF SUBSTR(laPropLines[lnCounter],3,7) = "Caption"
lnCaptionLine = lnCounter
ENDIF
IF SUBSTR(laPropLines[lnCounter],3,10) = "message_id"
lnMsgLine = lnCounter
ENDIF
ENDFOR
IF lnCaptionLine > 0 THEN
lcString = SUBSTR(laPropLines[lnCaptionLine],AT("=",laPropLines[lnCaptionLine])+1)
lcString2Find = GETWORDNUM(&lcString,1,["])
SELECT LangText
LOCATE FOR ALLTRIM(Gr_Text) == ALLTRIM(lcString2Find)
IF FOUND()
lnMessage_id = Record_id
ELSE
APPEND BLANK
Replace Record_id WITH RECNO()
Replace gr_Text WITH lcString2Find
lnMessage_id = Record_id
ENDIF
IF lnMsgLine > 0 THEN
lcString = SUBSTR(laPropLines[lnMsgLine],AT("=",laPropLines[lnMsgLine])+1)
laPropLines[lnMsgLine] = SUBSTR(laPropLines[lnMsgLine],1,AT("=",laPropLines[lnMsgLine]))+ " " + ALLTRIM(STR(lnMessage_id))
***Update Properties Field
lcProp = ""
FOR lnCounter = 1 TO lnCountofLines
lcProp = lcProp +laPropLines[lnCounter]
ENDFOR
SELECT (lcClassName)
Replace Properties WITH lcProp
ELSE
lcNewLine = CHR(13)+CHR(10) + "message_id = "+ ALLTRIM(STR(lnMessage_id))
***Update Properties Field
lcProp = ""
FOR lnCounter = 1 TO lnCountofLines - 1
lcProp = lcProp +laPropLines[lnCounter]
ENDFOR
lcProp = lcProp + lcNewLine
lcProp = lcProp + laPropLines[lnCountofLines]
SELECT (lcClassName)
Replace Properties WITH lcProp
ENDIF
ENDIF
ENDIF
ENDIF
SELECT (lcClassName)
ENDSCAN
Wait Window "Done!"
CLOSE DATABASES
That's It! what I wanted all the texts from every control are transferred into langtext table in seconds! Keep in mind that the routine checks if the text string is already in the table and updates the message_id property correctly.
After that it was a matter of minutes to create a wrapper method that finds all the forms (and all the classes) of the project and calls this routine for every form or class.
All of my visual controls are now translatable!
Thanks to the nature of the Visual Foxpro source files this routine saved me months of work!
Important: Since this procedure dives into your form/class file keep a BACKUP copy before you run it!
VFP can do anything you can imagine!
At first, program forms have all the captions in greek. I was lucky enough to have used only sublclassed labels. So I created a Message_id property in my base label class. After that I created a table LangText (REC_ID Integer, GR_Text , EN_Text, FR_Text ...) in order to keep there every string of the program. My thought was to have a table with the messages and in each control a message_id number that corresponds to the appropriate record. The translation will take place "on the fly" in the SetCaption method after label's Init Event.
Moving the label captions from controls into LangText table one by one very soon I realised that this procedure will take months! So I decided to spend a couple of hours to create this routine:
*================================================= =====================
*| Purpose...... Sets the correct message_id to all Labels of the class/form
*| Author....... Vaggelakos
*| Created...... August 18, 2006
*| About........
*| Mod List.....
*================================================= =====================
LOCAL lcClassName, lcProp, lnMsgLine, lnCaptionLine, lnCaptionStart, lnCountOfFiles, lnCounter
LOCAL ARRAY laPropLines[1]
lcClassName = "Form1.Scx"
STORE 0 TO lnMsgLine, lnCaptionLine, lnCaptionStart, lnCountOfFiles
IF NOT USED("LangText")
USE langText IN 0
ENDIF
IF NOT USED(JUSTFNAME(lcClassName))
USE (lcClassName) IN 0
ENDIF
SELECT (lcClassName)
GO top
SCAN
IF ALLTRIM(baseclass)="label"
lcProp = Properties
lnCaptionStart = AT("Caption",lcProp)
STORE 0 TO lnMsgLine, lnCaptionLine
IF lnCaptionStart > 0 THEN
*We have a Caption
lnCountofLines = GetWordCount(Properties,CHR(10))
DIMENSION laPropLines[lnCountofLines]
laPropLines[1] = GetwordNum(properties,1,CHR(13))
IF SUBSTR(laPropLines[1],1,7) = "Caption"
lnCaptionLine = 1
ENDIF
FOR lnCounter = 2 TO lnCountofLines
laPropLines[lnCounter] = CHR(13) + GetwordNum(properties,lnCounter,CHR(13))
IF SUBSTR(laPropLines[lnCounter],1,7) = "Caption"
lnCaptionLine = lnCounter
ENDIF
IF SUBSTR(laPropLines[lnCounter],3,7) = "Caption"
lnCaptionLine = lnCounter
ENDIF
IF SUBSTR(laPropLines[lnCounter],3,10) = "message_id"
lnMsgLine = lnCounter
ENDIF
ENDFOR
IF lnCaptionLine > 0 THEN
lcString = SUBSTR(laPropLines[lnCaptionLine],AT("=",laPropLines[lnCaptionLine])+1)
lcString2Find = GETWORDNUM(&lcString,1,["])
SELECT LangText
LOCATE FOR ALLTRIM(Gr_Text) == ALLTRIM(lcString2Find)
IF FOUND()
lnMessage_id = Record_id
ELSE
APPEND BLANK
Replace Record_id WITH RECNO()
Replace gr_Text WITH lcString2Find
lnMessage_id = Record_id
ENDIF
IF lnMsgLine > 0 THEN
lcString = SUBSTR(laPropLines[lnMsgLine],AT("=",laPropLines[lnMsgLine])+1)
laPropLines[lnMsgLine] = SUBSTR(laPropLines[lnMsgLine],1,AT("=",laPropLines[lnMsgLine]))+ " " + ALLTRIM(STR(lnMessage_id))
***Update Properties Field
lcProp = ""
FOR lnCounter = 1 TO lnCountofLines
lcProp = lcProp +laPropLines[lnCounter]
ENDFOR
SELECT (lcClassName)
Replace Properties WITH lcProp
ELSE
lcNewLine = CHR(13)+CHR(10) + "message_id = "+ ALLTRIM(STR(lnMessage_id))
***Update Properties Field
lcProp = ""
FOR lnCounter = 1 TO lnCountofLines - 1
lcProp = lcProp +laPropLines[lnCounter]
ENDFOR
lcProp = lcProp + lcNewLine
lcProp = lcProp + laPropLines[lnCountofLines]
SELECT (lcClassName)
Replace Properties WITH lcProp
ENDIF
ENDIF
ENDIF
ENDIF
SELECT (lcClassName)
ENDSCAN
Wait Window "Done!"
CLOSE DATABASES
That's It! what I wanted all the texts from every control are transferred into langtext table in seconds! Keep in mind that the routine checks if the text string is already in the table and updates the message_id property correctly.
After that it was a matter of minutes to create a wrapper method that finds all the forms (and all the classes) of the project and calls this routine for every form or class.
All of my visual controls are now translatable!
Thanks to the nature of the Visual Foxpro source files this routine saved me months of work!
Important: Since this procedure dives into your form/class file keep a BACKUP copy before you run it!
VFP can do anything you can imagine!