Version: 2.00.02 - last Update: Thursday, April 27, 2008, 23:53:00
This thread is all about how to get VFP’s syntax coloured code to an HTML-formatted Blog like this is.
Intro
Today we will talk about FoxPro's syntax colouring in detail. You will learn what kind of information VFP is storing and where all the colour data is coming from. You will learn which VFP syntax areas are mapping to which registry values and what RGB() colour pairs are mapping to what kind of RTF control words. Finally I will give you some code to read VFP's colour entries out of the Windows registry. Let's go...
FoxPro's Syntax Colouring
At the end of part 2 we talked about VFP's syntax colour settings. Figure #1 below shows my test configuration:
Figure #1: SyntaxColorText.Prg pasted into clipboard
VFP stores all colour settings under HKEY_CURRENT_USER registry's hive. Figure #2 shows my registry content under
Software\Microsoft\VisualFoxPro\9.0\Options
Figure #2: Corresponding editor entries in the registry
Resetting Syntax Colours to Defaults
If you click the default button (shown in Figure #2b below) you will reset all syntax colours to the internal defaults.
Figure #2b: Built-in syntax colour defaults
As we can see, there are always two entries reading Auto or NoAuto after the RGB() fore- and background colour pairs. As long as we select a colour other than Automatic the registry entry will be "NoAuto". All Automatic colour selections we've made within VFP's options dialogue will be reflected by an "Auto" registry entry accordingly. Figure 2b above shows us all built-in VFP default values (after a complete reset). The next table #1 below lists all "Automatic" values for all of VFP's syntax fore- and background colours. The listed RGB() values below are applied if we choose to reset VFP's colour values.
Area ID | Foreground | Background |
EditorCommentColor | RGB(0,128,0) | RGB(255,255,255) |
EditorKeywordColor | RGB(0,0,255) | RGB(255,255,255) |
EditorConstantColor | RGB(0,0,0) | RGB(255,255,255) |
EditorNormalColor | RGB(0,0,0) | RGB(255,255,255) |
EditorOperatorColor | RGB(0,0,0) | RGB(255,255,255) |
EditorStringColor | RGB(0,0,0) | RGB(255,255,255) |
EditorVariableColor | RGB(0,0,0) | RGB(255,255,255) |
Table #1: Default Syntax Colours after a RESET ALL
General Font Style Registry Mappings
The font style Automatic gets represented by the value -1 in the registry. Table #2 below shows all values possible:
Font Style | Registry value | Meaning |
Automatic | -1 | Use VFP'S internal "reset-all default" |
Normal | 0 | apply neither bold nor italic formatting |
Bold | 1 | apply bold formatting |
Italic | 2 | apply italic formatting |
Bold Italic | 3 | apply bold and italic formatting |
All about EditorNormalColor and Style
Firstly: The setting "EditorNormalColor" is used for background colouring only if you have syntax colouring turned ON, like shown in figure #3 below:
Figure #3: Background with syntax colouring ON
Secondly: The other settings of "Area Normal" are only used when you turn syntax colouring OFF - either for a single source code editor session via it's context menu, or generally via VFP's options->IDE settings. Figure #4 below shows the relation:
Figure #4: Disabling syntax colouring activates "Area-Normal" settings
Remember: you have to use VFP's option dialogue button Set As Default to flush your work back to the registry before our little tool can retrieve and apply these changed settings to the final HTML output!
BTW: Disabling syntax colouring stops VFP stuffing any RTF content into the Windows clipboard!! (After I had finished some - as I thought - cool RTF-Clipboard retrieval code block of code - GOSH, there it was: my next inspiration of the day!) As you might have guessed - we have to talk about this issue in detail later!
Additional Note about EditorNormalColor
It is good to know, that you are not limited to the internal colour palette VFP offers you when choosing a fore-or background colour in the Options dialogue. Go to the registry Software\Microsoft\VisualFoxPro\9.0\Options-hive instead and replace, let's say, the back-colour of the Normal area for instance like shown in figure #5 below:
Figure #5: An individual editor back-colour
The Automatic Syntax Colour Option
Finally it is good to know where the "automatic colours" are coming from. As we know by now VFP ignores all RGB() syntax colour values stored in the registry as long we've chosen Automatic in the Options dialogue. There are two different scenarios:
1st scenario: We have chosen an Automatic colour for VFP's Area Normal. In this case VFP retrieves the appropriate colour setting from Windows directly! Figure #5 below shows my German display settings where I changed the window background colour of the active window to green (GLOBALLY!). My running VFP instance immediately reflected the change, because my Area Normal background colouring was set to Automatic in that demo.
Figure #6: Automatic syntax colour for Area Normal
2nd scenario: We have chosen an Automatic colour for any other VFP Area but Normal. In these cases VFP reads the colour setting from it's own Area Normal settings like shown in Figure #7 below:
Figure #7: Automatic syntax colour for all other Areas
Wow, folks, that hurts ;-) I hope I could shed some light on that "colourful" chapter of VFP's Better-to-Forget internals...
RTF Colour Mappings
Let's have a look at our syntax colour test code and compare it's text colours with the the RTF colour table now:
Our SyntaxColorText.Prg ... |
* Lucy.prg USE fred TAG ethel m.nAmount = 1213.45 * 10 m.cName = "Ricky" |
... generates the following RTF colour table |
{\rtf1{\colortbl \red0\green128\blue0; \red0\green0\blue255; \red255\green0\blue0; \red0\green0\blue0; \red255\green0\blue255; \red255\green255\blue0; \red128\green0\blue128;}} |
Now we can relate the colour table entries of VFP's clipboard data to VFP's editor keyword mapping in the registry like listed in table #3 below:
Registry entry | RTF colour index | RTF control word |
EditorCommentColor | 0 | \cf0 |
EditorKeywordColor | 1 | \cf1 |
EditorConstantColor | 2 | \cf2 |
EditorNormalColor | 3 | \cf3 |
EditorOperatorColor | 4 | \cf4 |
EditorStringColor | 5 | \cf5 |
EditorVariableColor | 6 | \cf6 |
This is pretty cool, because we are able to retrieve the missing background colour information out of the Windows registry directly!
Background Colour Workaround
Since we know by now what RTF colour table index (control word) matches what VFP editor's registry entry, we can fetch the missing background colour information out of the Windows registry directly. Even better! We do not need to parse the entire colour table in the RTF header! The following steps have to be taken:
- Open Windows Registry
- Read VFP editor's syntax colour information
- Create a mapping array holding fore- and background colours
- Map colour-pairs to the corresponding RTF control words
Well, that sounds easy to do - almost! You already know that there are some more steps to be taken to achieve a final one-to-one looking result! Thus, the final implementation has to care about the Auto/NoAuto registry settings for each syntax colour area. It has to map those areas marked as an Automatic colour setting to the Area Normal. Even better, if VFP's Area Normal has an Automatic setting on it's own, we have to look up the corresponding Windows values first! Again, this can be done automatically reading the right registry values at program launch. Or we can implement some leaner solution by just using discrete setup variables that can be set through a configuration dialogue by the user.
Accessing the Registry
Of course we could utilize VFP's own registry class like shown in listing #1 below without problems:
Using VFP's FoxReg-Object |
regfile = HOME(2)+"classes\registry.prg" SET PROCEDURE TO (m.regfile) ADDITIVE oReg = CreateObject("FoxReg") |
Listing #1: accessing the Windows registry |
We only need read access by now. Using VFP's FoxReg object would be a little bit to much of a good thing. Let's implement our own registry reader based on one of Anatoliy Mogylevets's free API example you can find here.
Our own Registry Reader |
*\\ Function GetRegKey *\\ Don't forget to define these registry ; DECLARE INTEGER RegQueryValueEx IN advapi32; DECLARE INTEGER RegCloseKey IN advapi32; |
Listing #2: Function GetRegKey() |
Finally we need a method to fill an array like shown in listing #3 below:
Looping through VFP's Registry Entries |
*\\ InitColorArray() |
Listing #3: Procedure InitColorArray() |
Finally, we parse the retrieved colour pairs and split them into array fields like shown in listing #4 below:
Parsing the retrieved colour values |
LPARAMETERS tnColorIndex AS Integer LOCAL ARRAY aRGB[1,6] |
Listing #4: Procedure ParseColorExpression() |
Preview
That's all for now. In part 5 of this thread I will show you how to work around all quirks and oddities we've encountered so far.
No comments:
Post a Comment