Skip to content

Commit 7be999d

Browse files
author
joachim.marder
committed
Added PowerShell script which performs all necessary steps in one: It converts the XML file to the binary BML-file using UICC.exe, converts the .h file to a .PAS file and generates the .RES file that includes all the needed resources.
1 parent 5d0639f commit 7be999d

File tree

1 file changed

+196
-0
lines changed

1 file changed

+196
-0
lines changed

Lib/Generate.Ribbon.Markup.pas.ps1

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
# Stop on errors
2+
$ErrorActionPreference = "Stop"
3+
4+
$xmlFilePath = $args[0]
5+
6+
# Determine the current working directory from the given xml file path
7+
$workingDir = ([System.IO.Path]::GetDirectoryName($xmlFilePath))
8+
if ([string]::IsNullOrEmpty($workingDir))
9+
{
10+
$workingDir = "."
11+
}
12+
$workingDir = $workingDir + ([System.IO.Path]::DirectorySeparatorChar)
13+
14+
# Prepare file paths for the files that we want to create
15+
$pasFilePath = $workingDir + ([System.IO.Path]::GetFileNameWithoutExtension($xmlFilePath) + ".pas")
16+
$bmlFilePath = $workingDir + ([System.IO.Path]::GetFileNameWithoutExtension($xmlFilePath) + ".bml")
17+
$rcFilePath = $workingDir + ([System.IO.Path]::GetFileNameWithoutExtension($xmlFilePath) + ".rc")
18+
$headerFilePath = $workingDir + ([System.IO.Path]::GetFileNameWithoutExtension($xmlFilePath) + ".h")
19+
$resFileName = ([System.IO.Path]::GetFileNameWithoutExtension($xmlFilePath) + ".res")
20+
$unitName = ([System.IO.Path]::GetFileNameWithoutExtension($xmlFilePath))
21+
22+
$ResourceName = $args[1]
23+
$UICCDir = $args[2]
24+
25+
# Checks if a file exists under a given location. If yes, the path to this file is returned. If not, we lookup several known locations and return those, if the file is found.
26+
function FindFileInLocation($pLocation, $pFileName)
27+
{
28+
# First check if a valid path was passed via the command line
29+
$lPath = $pLocation + "\" +$pFileName
30+
if (Test-Path $lPath)
31+
{
32+
return $lPath
33+
}
34+
# Check if the file exists under %PATH%
35+
if (Get-Command $pFileName -ErrorAction SilentlyContinue)
36+
{
37+
return "$pFileName"
38+
}
39+
# If not, check a few known locations for uicc.exe
40+
elseif (Test-Path "${env:ProgramFiles(x86)}\Microsoft SDKs\Windows\v7.1A\Bin\$pFileName")
41+
{
42+
return "${env:ProgramFiles(x86)}\Microsoft SDKs\Windows\v7.1A\Bin\$pFileName"
43+
}
44+
elseif (Test-Path "${env:ProgramFiles(x86)}\Windows Kits\8.0\bin\x86\$pFileName")
45+
{
46+
return "${env:ProgramFiles(x86)}\Windows Kits\8.0\bin\x86\$pFileName"
47+
}
48+
elseif (Test-Path "${env:ProgramFiles(x86)}\Windows Kits\8.1\bin\$pFileName")
49+
{
50+
return "${env:ProgramFiles(x86)}\Windows Kits\8.1\bin\x86\$pFileName"
51+
}
52+
else
53+
{
54+
# Nothing found -> exit
55+
write "Cannot find $pFileName. Aborting execution."
56+
exit
57+
}
58+
}
59+
60+
# Find UICC.exe
61+
$UICCCmd = FindFileInLocation -pLocation $UICCDir -pFileName "UICC.exe"
62+
write-host "UICC.exe found: Using $UICCCmd"
63+
64+
# Use the provided xml file to Create the .bml, .h and .rc file
65+
& $UICCCmd "/W0" "$xmlFilePath" "$bmlFilePath" "/header:$headerFilePath" "/res:$rcFilePath" "/name:$ResourceName"
66+
67+
# Find rc.exe (Use the same locations as UICC.exe)
68+
$RCCmd = FindFileInLocation -pLocation $UICCDir -pFileName "rc.exe"
69+
write-host "RC.exe found: Using $RCCmd"
70+
71+
# Create the .RES resource file
72+
rc "$rcFilePath"
73+
74+
# Create a new Markup .pas file that will contain the Ribbon command constants.
75+
76+
[System.Collections.ArrayList]$markupContent = New-Object([System.Collections.ArrayList])
77+
78+
$FileTopPart = @"
79+
unit $unitName;
80+
81+
// *****************************************************************************
82+
// * This is an automatically generated source file for UI Element definition *
83+
// * resource symbols and values. Please do not modify manually. *
84+
// *****************************************************************************
85+
86+
interface
87+
88+
{`$R '$resFileName'}
89+
90+
uses
91+
Generics.Collections, SysUtils, UIRibbon;
92+
93+
const
94+
"@
95+
96+
write-host "Setting content to " + $pasFilePath
97+
Set-Content -Path "$pasFilePath" -Value $FileTopPart
98+
99+
# Get content of the header file (e.g. TreeSize.Ribbon.Markup.h).
100+
$data = Get-Content "$headerFilePath"
101+
102+
foreach ($line in $data)
103+
{
104+
if ($line.Contains("#define"))
105+
{
106+
$line = $line.TrimStart("#define")
107+
$commandId = ([regex]"\b\d{1,5}\b").match($line).groups[0].value
108+
$commandName = ([regex]"\b\w+\b").match($line).groups[0].value
109+
$appendLine = " $commandName = $commandId;"
110+
Add-Content "$pasFilePath" "$appendLine"
111+
$dummy = $markupContent.Add($appendLine);
112+
}
113+
}
114+
115+
# Add some additional predefined text.
116+
$FileMiddlePart = @"
117+
118+
implementation
119+
120+
function RegisterRibbonElements(): TRibbonMarkupElementList;
121+
begin
122+
Result := TRibbonMarkupElementList.Create('$ResourceName');
123+
"@
124+
125+
Add-Content "$pasFilePath" $FileMiddlePart
126+
127+
128+
# Add the mapping by using the previously generated markup content
129+
130+
# Initialization
131+
$commandName = ""
132+
$LabelTitleResourceID = -1
133+
$LabelDescriptionResourceID = -1
134+
$TooltipTitleResourceID = -1
135+
$TooltipDescriptionResourceID = -1
136+
137+
#RegEx for resource IDs
138+
$resourceIdRegexPattern = "\b\d{1,5}\b"
139+
140+
foreach ($line in $markupContent)
141+
{
142+
if (!($line.Contains("RESID")))
143+
{
144+
if (($commandName) -and ($commandID))
145+
{
146+
$appendLine = " Result.Add(TRibbonMarkupElement.Create('$commandName', $commandId, $LabelTitleResourceID, $LabelDescriptionResourceID, $TooltipTitleResourceID, $TooltipDescriptionResourceID));"
147+
Add-Content "$pasFilePath" "$appendLine"
148+
$LabelTitleResourceID = -1
149+
$LabelDescriptionResourceID = -1
150+
$TooltipTitleResourceID = -1
151+
$TooltipDescriptionResourceID = -1
152+
}
153+
154+
$commandName = ([regex]"\b\w+\b").match($line).groups[0].value
155+
$commandId = ([regex]$resourceIdRegexPattern).match($line).groups[0].value
156+
continue
157+
}
158+
if ($commandName -and $line.Contains($commandName))
159+
{
160+
if ($line.Contains("LabelTitle"))
161+
{
162+
$LabelTitleResourceID = ([regex]$resourceIdRegexPattern).match($line).groups[0].value
163+
}
164+
elseif ($line.Contains("LabelDescription"))
165+
{
166+
$LabelDescriptionResourceID = ([regex]$resourceIdRegexPattern).match($line).groups[0].value
167+
}
168+
elseif ($line.Contains("TooltipTitle"))
169+
{
170+
$TooltipTitleResourceID = ([regex]$resourceIdRegexPattern).match($line).groups[0].value
171+
}
172+
elseif ($line.Contains("TooltipDescription"))
173+
{
174+
$TooltipDescriptionResourceID = ([regex]$resourceIdRegexPattern).match($line).groups[0].value
175+
}
176+
}
177+
}
178+
179+
if (($commandName) -and ($commandID))
180+
{
181+
$appendLine = " Result.Add(TRibbonMarkupElement.Create('$commandName', $commandId, $LabelTitleResourceID, $TooltipTitleResourceID));"
182+
Add-Content "$pasFilePath" "$appendLine"
183+
}
184+
185+
# Add the ending part
186+
$FileEndPart = @"
187+
end;
188+
initialization
189+
190+
RegisterRibbonElements();
191+
192+
end.
193+
"@
194+
195+
Add-Content "$pasFilePath" $FileEndPart
196+
write-host "Ribbon pascal markup file generation successful: '$pasFilePath'"

0 commit comments

Comments
 (0)