1 static define versionString = $"Ecere SDK v0.44.10";
2 static define dateString = $"July 12th, 2014";
3 static define builtOnString = $"built on ";
4 static define withoutMinGW = $" (Without MinGW)";
6 #define WIN32_LEAN_AND_MEAN
7 #define GetFreeSpace _GetFreeSpace
21 static void SetBuildString(Label label)
23 static const String addMinGW = "";
27 addMinGW = withoutMinGW;
30 s = PrintString(versionString, addMinGW, " -- ", builtOnString, dateString);
35 static bool IsAdministrator()
38 SID_IDENTIFIER_AUTHORITY NtAuthority = { SECURITY_NT_AUTHORITY };
39 PSID AdministratorsGroup;
40 b = AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &AdministratorsGroup);
43 if(!CheckTokenMembership(NULL, AdministratorsGroup, &b))
45 FreeSid(AdministratorsGroup);
55 const char * OnGetString(char * tempString, void * fieldData, bool * needClass)
59 strcpy(tempString, name);
60 strcat(tempString, " (32)");
66 void OnDisplay(Surface surface, int x, int y, int width, void * fieldData, Alignment alignment, DataDisplayFlags displayFlags)
68 if(!displayFlags.active) { displayFlags.current = false; displayFlags.selected = false; }
69 class::OnDisplay(surface, x + 22, y, width - 22, fieldData, alignment, displayFlags);
73 //#define BUFFERSIZE 0x10000
74 #define BUFFERSIZE 0x1000
75 bool abortInstall = false;
77 void ExtractFileFromArchive(ProgressBar progressBar, const char * path, const char * outputFile)
79 char fileName[MAX_LOCATION];
80 FileAttribs exists = FileExists(path);
84 if(exists.isDirectory)
86 FileListing listing { path };
90 if(MakeDir(outputFile))
93 FileGetStats(path, &stats);
97 while(listing.Find() && !abortInstall)
99 strcpy(fileName, outputFile);
101 // Tweak file name if out
104 if(!strcmp(fileName, ".")) fileName[0] = '\0';
105 if(listing.name[0] == '/' || listing.name[0] == '\\')
107 char * afterSlash, rest[MAX_LOCATION];
108 for(afterSlash = fileName; *afterSlash == '/' || *afterSlash == '\\'; afterSlash++);
109 strcpy(rest, afterSlash);
110 PathCat(fileName, "_root");
111 PathCat(fileName, rest);
113 else if(listing.name[1] == ':')
116 sprintf(letter, "_%cdrive", toupper(listing.name[0]));
117 PathCat(fileName, letter);
118 PathCat(fileName, listing.name[2] ? (listing.name + 3) : (listing.name + 2));
121 PathCat(fileName, listing.name);
124 PathCat(fileName, listing.name);
125 if(!strcmp(fileName, "/") || !strcmp(fileName, "\\"))
126 strcpy(fileName, DIR_SEPS);
127 ExtractFileFromArchive(progressBar, listing.path, fileName);
133 File input = FileOpen(path, read);
136 File output = FileOpen(outputFile, write);
139 char fileName[MAX_FILENAME];
140 uint position = progressBar.progress;
143 byte buffer[BUFFERSIZE];
145 FileGetSize(path, &dataSize);
146 GetLastDirectory(outputFile, fileName);
148 ((GuiApplication)__thisModule).SignalEvent();
149 //((GuiApplication)__thisModule).ProcessInput();
150 //((GuiApplication)__thisModule).UpdateDisplay();
152 for(c = 0; c<dataSize && !abortInstall; c += BUFFERSIZE)
154 uint size = (dataSize > c + BUFFERSIZE) ? BUFFERSIZE : (dataSize - c);
156 ((GuiApplication)__thisModule).Unlock();
158 input.Read(buffer, 1, size);
159 output.Write(buffer, 1, size);
161 ((GuiApplication)__thisModule).Lock();
163 progressBar.progress = position + c + size;
164 ((GuiApplication)__thisModule).SignalEvent();
166 //((GuiApplication)__thisModule).ProcessInput();
167 //((GuiApplication)__thisModule).UpdateDisplay();
172 FileGetStats(path, &stats);
178 FileSetTime(outputFile, stats.created, 0, stats.modified);
181 public enum BitArch { none, bits32, bits64 };
186 const char * dataPath;
187 const char * defInstallPath;
188 Component * subComponents;
198 char installPath[MAX_LOCATION];
201 void GetFullPath(char * path, bool is32bit)
203 if(this != null && parent)
204 parent->GetFullPath(path, is32bit || (arch == bits32 && osIS64bit));
206 strcpy(path, (this && (is32bit || (arch == bits32 && osIS64bit))) ? installDir32 : installDir);
209 PathCat(path, installPath);
212 void Install(char * parentPath, char * parentPath32)
215 if(selected && (arch == none || arch == bits32 || osIS64bit))
217 char path64[MAX_LOCATION];
218 char path32[MAX_LOCATION];
219 strcpy(path64, parentPath);
220 PathCat(path64, installPath);
222 strcpy(path32, parentPath32);
223 PathCat(path32, installPath);
225 installProgress.installing.SetText($"Installing %s...", name);
226 ((GuiApplication)__thisModule).UpdateDisplay();
230 char * path = path64;
231 char source[MAX_LOCATION];
233 strcat(source, dataPath);
240 if(FileExists(source).isFile)
242 char name[MAX_FILENAME];
243 GetLastDirectory(source, name);
247 ExtractFileFromArchive(installProgress.progressBar, source, path);
251 for(c = 0; subComponents[c].name; c++)
252 subComponents[c].Install(path64, path32);
259 define minGWIncluded = true;
261 define minGWIncluded = false;
264 Array<Component> samples
266 { "3D", "samples/3D", "3D", null, false, true, true, none },
267 { "Android", "samples/android", "android", null, false, true, true, none },
268 { $"Audio", "samples/audio", "audio", null, false, true, true, none },
269 { $"Database", "samples/db", "db", null, false, true, true, none },
270 { "eC", "samples/eC", "eC", null, false, true, true, none },
271 { $"Games", "samples/games", "games", null, false, true, true, none },
272 { $"GUI & Graphics", "samples/guiAndGfx", "guiAndGfx", null, false, true, true, none },
273 { $"Miscellaneous", "samples/misc", "misc", null, false, true, true, none },
274 { $"Networking", "samples/net", "net", null, false, true, true, none },
275 { $"WIA Scanning", "samples/scanning", "scanning", null, false, true, true, none },
276 { $"Threading", "samples/threads", "threads", null, false, true, true, none },
280 public enum CoreSDKID
282 ide, ide32, runtime, runtime32, ec, ec32,
283 gcc, gdb, mingw, binutils, make,
287 Array<Component> coreSDK
289 { "Ecere IDE", "ecere-sdk/ide", "bin", null, true, true, true, bits64 },
290 { "Ecere IDE", "ecere-sdk32/ide", "bin", null, true, true, true, bits32 },
291 { $"Runtime Library", "ecere-sdk/ecere.dll", "bin", null, true, true, true, bits64 },
292 { $"Runtime Library", "ecere-sdk32/ecere.dll", "bin", null, true, true, true, bits32 },
293 { $"eC Compiler", "ecere-sdk/compiler", "bin", null, true, true, true, bits64 },
294 { $"eC Compiler", "ecere-sdk32/compiler", "bin", null, true, true, true, bits32 },
295 { $"GNU C Compiler", "tdm/gcc/core", "tdm", null, true, true, minGWIncluded, none },
296 { $"GNU Debugger", "tdm/gdb", "tdm", null, true, true, minGWIncluded, none },
297 { $"MinGW-w64 Runtime", "tdm/mingwrt", "tdm", null, true, true, minGWIncluded, none },
298 { $"Binary Utils", "tdm/binutils", "tdm", null, true, true, minGWIncluded, none },
299 { $"GNU Make", "tdm/make", "tdm", null, true, true, minGWIncluded, none },
303 public enum AdditionalID
305 eda, eda32, vanilla, vanilla32, extras, upx, gnurx, gnurx32, /*pthreads, */cpp, /*w32api, gcci18n, gdbi18n, makei18n, binutilsi18n, */none
308 Array<Component> additional
310 { $"Data Access", "ecere-sdk/eda", "bin", null, false, true, true, bits64 },
311 { $"Data Access", "ecere-sdk32/eda", "bin", null, false, true, true, bits32 },
312 { $"Ecere Vanilla", "ecere-sdk/libecereVanilla.a", "lib", null, false, true, true, bits64 },
313 { $"Ecere Vanilla", "ecere-sdk32/libecereVanilla.a", "lib", null, false, true, true, bits32 },
314 { $"Ecere Extras", "extras", "extras", null, false, true, true, none },
315 { "UPX", "upx/bin", "upx/bin", null, false, true, true, none },
316 { $"GNU Regexp", "tdm/gnurx", "tdm", null, false, true, true, bits64 },
317 { $"GNU Regexp", "tdm/gnurx32", "tdm", null, false, true, true, bits32 },
318 // { "pthreads", "tdm/pthreads", "mingw", null, false, true, minGWIncluded, none },
319 { $"C++ Compiler", "tdm/gcc/c++", "tdm", null, false, true, minGWIncluded, none },
320 // { "Win32 APIs", "mingw/w32api", "mingw", null, false, true, minGWIncluded, none },
321 /* { "GCC I18n", "mingw/locale/gcc", "tdm", null, false, false, minGWIncluded, none },
322 { "GDB I18n", "mingw/locale/gdb", "tdm", null, false, false, minGWIncluded, none },
323 { "Make I18n", "mingw/locale/make", "tdm", null, false, false, minGWIncluded, none },
324 { "Binutils I18n", "mingw/locale/binutils", "tdm", null, false, false, minGWIncluded, none },
329 public enum DocumentationID
331 ecereBook, apiRef, coursework,
332 gccDoc, gppDocs, gdbDocs, makeDocs, binDocs, mingwDocs, gnurxDocs, upxDocs,
336 Array<Component> documentation
338 { $"Ecere Book", "ecere-sdk/book", "doc", null, false, true, true, none },
339 { $"API Reference", "ecere-sdk/doc", "doc", null, false, true, true, none },
340 { $"Ecere Coursework", "ecere-sdk/coursework", "doc", null, false, true, true, none },
341 { $"GCC Docs", "tdm/doc/gcc", "tdm", null, false, false, minGWIncluded, none },
342 { $"G++ Docs", "tdm/doc/g++", "tdm", null, false, false, minGWIncluded, none },
343 { $"GDB Docs", "tdm/doc/gdb", "tdm", null, false, false, minGWIncluded, none },
344 { $"Make Docs", "tdm/doc/make", "tdm", null, false, false, minGWIncluded, none },
345 { $"Binutils Docs", "tdm/doc/binutils", "tdm", null, false, false, minGWIncluded, none },
346 { $"gnurx Docs", "tdm/doc/gnurx", "tdm", null, false, false, minGWIncluded, none },
347 { $"UPX Docs", "upx/doc", "upx/doc", null, false, false, minGWIncluded, none },
351 public enum ComponentID
360 Array<Component> components
362 { $"Core SDK Files", null, null, coreSDK.array, true, true, true, none },
363 { $"Additional Support", null, null, additional.array, false, true, true, none },
364 { $"Documentation", null /*"doc"*/, null /*"doc"*/, documentation.array, false, true, true, none },
365 { $"Samples", null, "samples", samples.array, false, true, true, none },
369 FileSize totalInstalled;
374 InstallOption * subOptions;
380 enum AssociateOptions
391 Array<InstallOption> associateOptions
393 { $"Associate with Ecere Project Files (*.epj)", null, true },
394 { $"Associate with eC Files (*.ec, *.eh)", null, true },
395 { $"Associate with C files (*.c, *.h)", null, false },
396 { $"Associate with C++ Files (*.cpp, *.hpp, *.cc, *.hh, *.cxx, *.hxx)", null, false },
397 { $"Associate with text files (*.txt)", null, false },
398 { $"Associate with 3D Studio Model Files (*.3ds)", null, true },
399 { $"Associate with Image Files (*.png, *.jpg, *.pcx, *.bmp, *.gif)", null, false },
405 AddECEREPaths, AddMinGWPaths
408 Array<InstallOption> pathOptions
410 { $"Add Ecere binaries location to the user environment path", null, true, true },
411 { $"Add MinGW to the user environment path", null, true, minGWIncluded },
422 Array<InstallOption> options
424 { $"Install for All Users", null, true, true },
425 { $"Start Menu Group", null, true, true },
426 { $"Desktop Icon", null, true, true },
427 { $"Quicklaunch Icon", null, true, true },
428 { $"Associate the Ecere IDE with Supported File Types", associateOptions.array, true, true },
429 { $"Add binaries location to the user environment paths", pathOptions.array, true, minGWIncluded },
433 char sourceDir[MAX_LOCATION] = ":";
434 char installDir[MAX_LOCATION];
435 char installDir32[MAX_LOCATION];
438 class Installer : Window
440 background = formColor;
445 clientSize = { 636, 476 };
446 icon = { ":icon.png" };
447 caption = $"Ecere Software Development Kit Setup - v0.44.10 \"Ryōan-ji\" 64 Bit Edition";
449 // clientSize = { 796, 576 };
452 Picture back { image = BitmapResource { ":ryoanji.png" }, parent = this, position = { 0, 0 } };
453 FileDialog fileDialog
455 master = this, type = selectDir,
456 caption = $"Select a new location"
460 master = this, autoCreate = false, inactive = true, caption = "...";
462 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
464 DataRow row = componentsBox.currentRow;
465 Component * component = ((CheckItem *)row.GetData(componentField))->data;
466 char filePath[MAX_LOCATION];
467 component->GetFullPath(filePath, false);
468 fileDialog.filePath = filePath;
469 StripLastDirectory(filePath, filePath);
470 fileDialog.currentDirectory = filePath;
472 if(fileDialog.Modal() == ok)
474 componentsBox.StopEditing(false);
475 row.SetData(locationField, fileDialog.filePath);
476 componentsBox.NotifyChanged(this, componentsBox, row);
477 componentsBox.currentField = componentsBox.currentField;
482 CheckListBox componentsBox
484 this, size = { 460, 112 }, position = { 160, 160 }, hasHeader = true;
485 fullRowSelect = false, collapseControl = true, treeBranches = true, rootCollapseButton = true,
486 hasHorzScroll = true;
490 selectionColor = { 145, 150, 140 };
495 bool NotifyKeyDown(ListBox listBox, DataRow row, Key key, unichar ch)
497 if(key == f2 && browse.visible)
498 browse.NotifyClicked(this, browse, 0, 0, 0);
502 bool NotifyChanged(ListBox listBox, DataRow row)
504 Component * component = ((CheckItem *)listBox.GetData(componentField))->data;
505 char path[MAX_LOCATION], relative[MAX_LOCATION] = "", * newPath;
506 char fullPath[MAX_LOCATION];
508 component->parent->GetFullPath(path, false);
509 strcpy(fullPath, path);
511 newPath = row.GetData(locationField);
514 PathCat(fullPath, newPath);
515 if(IsPathInsideOf(fullPath, path))
516 MakePathRelative(fullPath, path, relative);
518 strcpy(relative, fullPath);
520 listBox.SetData(locationField, relative);
521 strcpy(component->installPath, relative);
523 //SetAvailableSpace(component, path);
526 install.disabled = false;
527 for(c = 0; components[c].name; c++)
529 SetAvailableSpace(components[c], installDir);
535 bool NotifyEditDone(ListBox listBox, DataRow row)
541 bool NotifyEdited(ListBox listBox, DataRow row)
544 browse.parent = listBox;
545 browse.position = { componentField.width + locationField.width + 18, (listBox.currentIndex+1) * listBox.rowHeight - 2 };
546 browse.size = { 30, listBox.rowHeight + 3 };
547 for(e = listBox.firstChild; e; e = e.next)
549 if(e._class == class(DataBox))
558 void NotifyChecked(CheckListBox listBox, DataRow row)
560 Component * component = ((CheckItem *)row.GetData(componentField))->data;
562 component->selected = listBox.IsChecked(row);
564 if(!component->parent) totalSize -= component->requiredSize;
565 component->requiredSize = 0;
566 if(component->selected)
568 component->requiredSize += component->size;
569 if(component->subComponents)
570 for(c = 0; component->subComponents[c].name; c++)
571 component->requiredSize += component->subComponents[c].requiredSize;
573 if(component->requiredSize)
575 uint requiredSize = component->requiredSize;
576 row.SetData(reqField, requiredSize);
579 row.UnsetData(reqField);
580 if(!component->parent)
582 totalSize += component->requiredSize;
584 char sizeString[100];
585 PrintSize(sizeString, totalSize, 2);
586 totalSpaceValue.caption = sizeString;
591 Label agreementLbl { parent = this, caption = $"By installing the Ecere SDK, you agree to the", font = { "Tahoma", 8.25f }, anchor = Anchor { right = 399, top = 448 } };
594 this, inactive = true, offset = false, bevel = false, foreground = blue, font = { "Tahoma", 8.25f, underline = true, bold = true },
595 // caption = $"terms and conditions", anchor = Anchor { left = 241, top = 421 };
596 caption = $"terms and conditions", anchor = Anchor { left = 235, top = 445 };
597 cursor = ((GuiApplication)__thisModule).GetCursor(hand);
599 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
601 // LicenseBox { master = this, sourceFile = ":ecere-sdk/doc/LICENSE" }.Modal();
602 LicensesForm { master = this }.Modal();
606 Label dotLbl { parent = this, caption = ".", font = { "Tahoma", 8.25f }, anchor = Anchor { left = 372, top = 448 } };
607 CheckListBox optionsBox
609 this, size = { 460, 114 }, position = { 160, 284 };
610 fullRowSelect = false, collapseControl = true, treeBranches = true, rootCollapseButton = true,
615 void NotifyChecked(CheckListBox listBox, DataRow row)
617 CheckItem * item = row.GetData(optionField);
618 InstallOption * option = item->data;
619 option->selected = listBox.IsChecked(row);
620 // Update default samples/extras path whether we're installing for All Users or not
621 if(option == &options[0])
623 char appData[MAX_LOCATION];
625 options[5].name = options[0].selected ? $"Add binaries location to the system environment paths" : $"Add binaries location to the user environment paths";
627 ((CheckItem *)options[5].row.GetData(optionField))->name = options[5].name;
629 pathOptions[PathOptions::AddECEREPaths].name = options[0].selected ? $"Add Ecere binaries location to the system environment path" : $"Add Ecere binaries location to the user environment path";
630 if(pathOptions[PathOptions::AddECEREPaths].row)
631 ((CheckItem *)pathOptions[PathOptions::AddECEREPaths].row.GetData(optionField))->name = pathOptions[PathOptions::AddECEREPaths].name;
633 pathOptions[PathOptions::AddMinGWPaths].name = options[0].selected ? $"Add TDM-GCC/MinGW-w64 to the system environment path" : $"Add TDM-GCC/MinGW-w64 to the user environment path";
634 if(pathOptions[PathOptions::AddMinGWPaths].row)
635 ((CheckItem *)pathOptions[PathOptions::AddMinGWPaths].row.GetData(optionField))->name = pathOptions[PathOptions::AddMinGWPaths].name;
637 GetEnvironment(options[0].selected ? "ALLUSERSPROFILE" : "APPDATA", appData, sizeof(appData));
640 char defPath[MAX_LOCATION];
642 strcpy(defPath, installDir);
643 PathCat(defPath, components[ComponentID::samples].defInstallPath);
644 ChangeCh(defPath, '/', DIR_SEP);
645 if(!strcmp(defPath, components[ComponentID::samples].installPath))
647 static char defSamplesPath[MAX_LOCATION];
648 strcpy(defSamplesPath, appData);
649 PathCat(defSamplesPath, "Ecere SDK\\Samples");
650 components[ComponentID::samples].defInstallPath = defSamplesPath;
652 strcpy(components[ComponentID::samples].installPath, components[ComponentID::samples].defInstallPath);
653 ChangeCh(components[ComponentID::samples].installPath, '/', DIR_SEP);
654 components[ComponentID::samples].row.SetData(locationField, components[ComponentID::samples].installPath);
657 strcpy(defPath, installDir);
658 PathCat(defPath, additional[AdditionalID::extras].defInstallPath);
659 ChangeCh(defPath, '/', DIR_SEP);
660 if(!strcmp(additional[AdditionalID::extras].installPath, additional[AdditionalID::extras].installPath))
662 static char defExtrasPath[MAX_LOCATION];
663 strcpy(defExtrasPath, appData);
664 PathCat(defExtrasPath, "Ecere SDK\\extras");
665 additional[AdditionalID::extras].defInstallPath = defExtrasPath;
667 strcpy(additional[AdditionalID::extras].installPath, additional[AdditionalID::extras].defInstallPath);
668 ChangeCh(additional[AdditionalID::extras].installPath, '/', DIR_SEP);
669 additional[AdditionalID::extras].row.SetData(locationField, additional[AdditionalID::extras].installPath);
672 listBox.Update(null);
678 parent = this, caption = $"Install", isDefault = true, size = { 75, 23 }, position = { 432, 440 };
680 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
682 installProgress.Create();
684 // installProgress.thread.Main();
685 installProgress.thread.Create();
689 Button button3 { parent = this, caption = $"Cancel", hotKey = altX, size = Size { 75, 23 }, anchor = Anchor { left = 544, top = 440 }, NotifyClicked = ButtonCloseDialog };
692 this, position = { 14, 374 }, size = { 142, 0 }, caption = "Language:";
694 bool NotifySelect(DropBox dropBox, DataRow row, Modifiers mods)
696 LanguageOption * option = row.GetData(null);
697 // If the language is already set, we need to override it
699 IDESettings settings = null;
700 IDESettingsContainer settingsContainer
703 dataOwner = &settings;
704 dataClass = class(IDESettings);
705 allUsers = options[0].selected;
707 settingsContainer.Load();
708 if(settings.language)
710 settings.language = option->code;
711 settingsContainer.Save();
713 delete settingsContainer;
716 ((GuiApplication)__thisModule.application).desktop.Destroy(0);
717 LanguageRestart(option->code, __thisModule.application, null, null, null, null, false);
721 Label lblLanguageBox { this, position = { 14, 354 }, labeledWindow = languageBox };
722 Label label1 { labeledWindow = destBox, tabCycle = true, isGroupBox = true, parent = this, inactive = false, size = Size { 458, 50 }, anchor = Anchor { left = 160, top = 96 } };
725 parent = label1, master = this, caption = $" Destination Folder", size = Size { 336, 22 }, anchor = Anchor { left = 12, top = 20, right = 12 };
726 typeExpected = directory;
727 browseDialog = fileDialog;
730 bool NotifyModified(PathBox pathBox)
733 strcpy(installDir, destBox.path);
734 install.disabled = false;
735 for(c = 0; components[c].name; c++)
737 SetAvailableSpace(components[c], installDir);
744 label1, this, $"Browse", altB, size = { 83, 24 }, position = { 360, 16 };
746 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
748 strcpy(fileDialog.filePath, installDir);
749 StripLastDirectory(installDir, fileDialog.currentDirectory);
750 if(fileDialog.Modal())
752 strcpy(installDir, fileDialog.filePath);
753 destBox.contents = installDir;
754 // TOCHECK: Should setting contents call NotifyModified?
755 destBox.NotifyModified(destBox.master, destBox);
762 this, multiLine = true,
763 opacity = 0, borderStyle = none, inactive = true, size = { 136, 53 }, position = { 14, 96 }, noSelect = true,
764 contents = $"Select the default root\n"
765 "folder where to install\n"
770 this, opacity = 0, borderStyle = none, inactive = true, size = { 136, 132 }, position = { 14, 152 }, noSelect = true,
772 contents = $"Select the optional\n"
773 "components you wish\n"
775 "You may customize the\n"
776 "install location for each\n"
777 "of them, or use the default\n"
778 "based on the main\n"
779 "destination folder."
783 this, opacity = 0, borderStyle = none, inactive = true, size = { 136, 83 }, position = { 14, 280 }, noSelect = true,
785 contents = $"Select icons to install, file\n"
786 "associations, and system\n"
787 "environment modifications:"
789 Label totalSpaceLabel
791 this, anchor = { right = 72, top = 404 }, caption = $"Space Required: "
793 Label totalSpaceValue
795 this, anchor = { right = 14, top = 404 }, caption = "0 mb"
799 label3, caption = "editBox1", opacity = 0, borderStyle = none, inactive = true, size = { 350, 35 }, position = { 256, 40 }, multiLine = true, noSelect = true, contents = $"Choose in which folder to install the Ecere SDK, which features\n"
800 "of the SDK to install, as well as where to install program icons."
802 Label label2 { parent = this, position = { 16, 422 }, font = { "Tahoma", 10, true }, disabled = true, opacity = 0, background = activeBorder };
805 image = BitmapResource { ":ecere.png", alphaBlend = true }, filter = true, parent = label3, caption = "picture1", anchor = Anchor { left = 16, top = 4 };
806 cursor = ((GuiApplication)__thisModule).GetCursor(hand);
808 bool OnLeftButtonDown(int x, int y, Modifiers mods)
810 ShellOpen("http://www.ecere.com/");
814 Label label4 { label3, font = { "Tahoma", 8.25f, bold = true }, /*size = { 326, 16 }, */position = { 248, 24 }, caption = $"Choose Components, Locations and Install Options" };
815 DataField componentField { "CheckItem", width = 160, header = $"Component" };
816 DataField locationField { "char *", width = 108, header = $"Destination Folder", editable = true };
817 DataField reqField { "FileSize", width = 70, header = $"Req. Space", alignment = right };
818 DataField avField { "FileSize64", width = 70, header = $"Avail. Space", alignment = right };
819 DataField optionField { "CheckItem" };
821 DataField languageField { class(LanguageOption) };
823 void SetAvailableSpace(Component component, const char * parentPath)
825 char path[MAX_LOCATION];
829 strcpy(path, parentPath);
830 PathCat(path, component.installPath);
832 if(component.subComponents)
833 for(c = 0; component.subComponents[c].name; c++)
834 SetAvailableSpace(component.subComponents[c], path);
836 while(!FileExists(path) && path[0])
837 StripLastDirectory(path, path);
840 GetFreeSpace(path, &size);
841 component.row.SetData(avField, size);
842 if(!size) install.disabled = true;
845 FileSize ComputeSize(const char * path)
848 FileAttribs attribs = FileExists(path);
849 if(attribs.isDirectory)
851 FileListing listing { path };
852 while(listing.Find())
854 if(listing.stats.attribs.isDirectory)
855 size += ComputeSize(listing.path);
857 size += listing.stats.size;
861 FileGetSize(path, &size);
865 void AddComponent(Component component, Component parent, const char * parentPath)
867 DataRow row = (parent != null) ? parent.row.AddRow() : componentsBox.AddRow();
869 FileSize64 avSize = 0;
870 char path[MAX_LOCATION];
873 strcpy(path, parentPath);
874 if(component.defInstallPath)
875 PathCat(path, component.defInstallPath);
876 component.parent = parent;
878 row.SetData(null, CheckItem { component.name, component, (component.arch == bits32 && osIS64bit) } );
880 if(component.defInstallPath)
882 strcpy(component.installPath, component.defInstallPath);
883 ChangeCh(component.installPath, '/', DIR_SEP);
884 row.SetData(locationField, component.installPath);
887 if(component.mandatory)
889 if(component.arch != bits32 || !osIS64bit) // || component == &coreSDK[gdb32])
890 componentsBox.SetDisabled(row, true);
892 component.selected = false;*/
894 else if(component.arch == bits32 && osIS64bit)
895 ; //component.selected = false;
897 componentsBox.SetCheck(row, component.selected);
899 if(component.dataPath)
901 char path[MAX_LOCATION];
903 PathCat(path, component.dataPath);
904 component.size = ComputeSize(path);
906 if(component.subComponents)
909 for(c = 0; component.subComponents[c].name; c++)
911 Component * sub = &component.subComponents[c];
912 if(sub->available && (osIS64bit || sub->arch == bits32 || sub->arch == none))
914 AddComponent(sub, component, path);
915 size += sub->requiredSize;
918 sub->selected = false;
922 component.requiredSize = component.selected ? (size + component.size) : 0;
923 if(component.requiredSize)
924 row.SetData(reqField, component.requiredSize);
926 while(!FileExists(path) && path[0])
927 StripLastDirectory(path, path);
930 GetFreeSpace(path, &avSize);
933 row.SetData(avField, avSize);
934 row.collapsed = true;
937 void AddOption(InstallOption option, InstallOption parent)
939 DataRow row = option.row = (parent != null) ? parent.row.AddRow() : optionsBox.AddRow();
940 row.SetData(null, CheckItem { option.name, option } );
941 optionsBox.SetCheck(row, option.selected);
942 if(option.subOptions)
945 for(c = 0; option.subOptions[c].name; c++)
947 AddOption(option.subOptions[c], option);
950 row.collapsed = true;
956 char programFilesDir[MAX_LOCATION];
957 char appData[MAX_LOCATION];
958 char homeDrive[MAX_LOCATION];
959 char winDir[MAX_LOCATION];
962 bool isAdministrator = IsAdministrator();
964 SetBuildString(label2);
968 options[0].available = false;
969 options[0].selected = false;
972 // If the SDK is already installed, use currently selected language
974 IDESettings settings = null;
975 IDESettingsContainer settingsContainer
978 dataOwner = &settings;
979 dataClass = class(IDESettings);
980 allUsers = options[0].selected;
983 settingsContainer.Load();
985 if(settings.language)
987 const String language = GetLanguageString();
988 if(settings.language.OnCompare(language))
990 // Relaunch the installer with previously selected language
991 LanguageRestart(settings.language, __thisModule.application, null, null, null, null, false);
995 delete settingsContainer;
999 GetEnvironment("HOMEDRIVE", homeDrive, sizeof(homeDrive));
1000 GetEnvironment("windir", winDir, sizeof(winDir));
1002 GetEnvironment(options[0].selected ? "ALLUSERSPROFILE" : "APPDATA", appData, sizeof(appData));
1004 componentsBox.AddField(componentField);
1005 componentsBox.AddField(locationField);
1006 componentsBox.AddField(reqField);
1007 componentsBox.AddField(avField);
1009 optionsBox.AddField(optionField);
1011 languageBox.AddField(languageField);
1013 programFilesDir[0] = 0;
1014 if(GetEnvironment("ProgramFiles", programFilesDir, MAX_LOCATION))
1016 x86 = strstr(programFilesDir, " (x86)");
1021 if(isAdministrator && programFilesDir[0])
1025 strcpy(installDir32, programFilesDir);
1026 PathCat(installDir32, "Ecere SDK");
1028 strcpy(installDir, programFilesDir);
1029 PathCat(installDir, "Ecere SDK");
1033 strcpy(installDir, programFilesDir);
1034 PathCat(installDir, "Ecere SDK");
1035 strcpy(installDir32, installDir);
1038 else if(homeDrive[0])
1040 strcpy(installDir, homeDrive);
1041 PathCat(installDir, "Ecere SDK");
1042 strcpy(installDir32, installDir);
1043 strcat(installDir32, " (32)");
1047 strcpy(installDir, winDir);
1048 PathCat(installDir, "..\\Ecere SDK");
1049 strcpy(installDir32, installDir);
1050 strcat(installDir32, " (32)");
1054 strcpy(installDir, "C:\\Ecere SDK");
1055 strcpy(installDir32, installDir);
1056 strcat(installDir32, " (32)");
1061 static char defSamplesPath[MAX_LOCATION];
1062 static char defExtrasPath[MAX_LOCATION];
1063 strcpy(defSamplesPath, appData);
1064 PathCat(defSamplesPath, "Ecere SDK\\Samples");
1065 components[ComponentID::samples].defInstallPath = defSamplesPath;
1067 strcpy(defExtrasPath, appData);
1068 PathCat(defExtrasPath, "Ecere SDK\\extras");
1069 additional[AdditionalID::extras].defInstallPath = defExtrasPath;
1072 destBox.path = installDir;
1076 for(c = 0; components[c].name; c++)
1077 AddComponent(components[c], null, installDir);
1080 // Compute size apart because ToggleCheck will change it
1084 for(c = 0; components[c].name; c++)
1085 totalSize += components[c].requiredSize;
1088 char sizeString[100];
1089 PrintSize(sizeString, totalSize, 2);
1090 totalSpaceValue.caption = sizeString;
1092 for(c = 0; options[c].name; c++)
1094 if(options[c].available)
1095 AddOption(options[c], null);
1107 dotLbl.position.x = licenseButton.position.x + licenseButton.size.w - 4;
1113 // Constructor happens before Languages is instantiated...
1116 l.res = { l.bitmap, window = this };
1122 const String language = GetLanguageString();
1126 // Try to find country-specific language first
1129 LanguageOption option = l;
1130 row = languageBox.AddRow();
1131 row.SetData(null, option); // TOFIX: l used directly here
1133 if(!found && (!strcmpi(l.code, language) || (!row.GetPrevRow() && !strcmpi("en", language))))
1135 languageBox.currentRow = row;
1140 // Try generalizing locale
1144 char genericLocale[256];
1145 strncpy(genericLocale, language, sizeof(genericLocale));
1146 genericLocale[sizeof(genericLocale)-1] = 0;
1148 under = strchr(genericLocale, '_');
1151 if(!strcmpi(genericLocale, "zh"))
1152 strcpy(genericLocale, "zh_CN");
1153 if(strcmp(genericLocale, language))
1155 row = languageBox.firstRow;
1158 if(!strcmpi(l.code, genericLocale) || (!row.GetPrevRow() && !strcmpi("en", genericLocale)))
1160 languageBox.currentRow = row;
1164 row = row.GetNextRow();
1170 languageBox.currentRow = languageBox.firstRow;
1178 void OnDrawOverChildren(Surface surface)
1180 int tw = label2.size.w;
1181 surface.SetForeground(Color { 128, 128, 128 });
1182 surface.HLine(label2.position.x + tw + 6, 620, 430);
1183 surface.SetForeground(white);
1184 surface.HLine(label2.position.x + tw + 6, 621, 431);
1185 surface.PutPixel(621, 400);
1189 parent = this, opacity = 0, borderStyle = deep, size = Size { 644, 93 }, anchor = Anchor { left = -8, top = -8 };
1193 class InstallProgress : Window
1195 caption = $"Ecere Software Development Kit Setup - v0.44.10 \"Ryōan-ji\" 64 Bit Edition";
1196 background = activeBorder;
1197 borderStyle = fixed;
1201 // size = Size { 640, 480 };
1202 clientSize = { 636, 476 };
1203 //clientSize = { 796, 576 };
1204 icon = { ":icon.png" };
1208 SetBuildString(label2);
1211 Picture back { image = BitmapResource { ":ryoanji-progress.png" }, parent = this, position = { 0, 0 } };
1212 Label installing { this, position = { 32, 160 } };
1213 ProgressBar progressBar { parent = this, size = Size { 588, 24 }, anchor = Anchor { left = 24, top = 184 } };
1216 parent = this, caption = $"Install", disabled = true, isDefault = true, size = Size { 75, 23 }, anchor = Anchor { left = 432, top = 440 };
1218 NotifyClicked = ButtonCloseDialog
1222 this, caption = $"Cancel", hotKey = altX, size = Size { 75, 23 }, anchor = Anchor { left = 544, top = 440 };
1224 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
1226 abortInstall = true;
1232 inactive = true, noSelect = true,
1233 multiLine = true, parent = label3, opacity = 0, borderStyle = none, size = Size { 350, 35 }, anchor = Anchor { horz = 111, vert = 13 },
1234 contents = $"Please wait while the Ecere Software Development Kit is being installed."
1236 Label label2 { parent = this, position = { 16, 422 }, font = { "Tahoma", 10, true }, disabled = true, opacity = 0, background = activeBorder };
1239 image = BitmapResource { ":ecere.png", alphaBlend = true }, filter = true, parent = label3, anchor = Anchor { left = 16, top = 4 };
1240 cursor = ((GuiApplication)__thisModule).GetCursor(hand);
1242 bool OnLeftButtonDown(int x, int y, Modifiers mods)
1244 ShellOpen("http://www.ecere.com/");
1248 Label title { parent = label3, caption = $"Installing the Ecere SDK", font = FontResource { "Tahoma", 8.25f, bold = true }, size = Size { 326, 16 }, anchor = Anchor { horz = 91, vert = -12 } };
1250 void OnDrawOverChildren(Surface surface)
1252 int tw = label2.size.w;
1253 surface.SetForeground(Color { 128, 128, 128 });
1254 surface.HLine(label2.position.x + tw + 6, 620, 430);
1255 surface.SetForeground(white);
1256 surface.HLine(label2.position.x + tw + 6, 621, 431);
1257 surface.PutPixel(621, 400);
1262 parent = this, opacity = 0, borderStyle = deep, size = Size { 644, 93 }, anchor = Anchor { left = -8, top = -8 };
1264 InstallThread thread
1269 Installer installer {};
1270 InstallProgress installProgress { autoCreate = false };
1272 static void AddPath(char * sysPaths[200], int sysCount, char * paths[200], int * count, char * oldPath, char * userPath, char * path)
1276 for(p = 0; p<sysCount; p++)
1277 if(!fstrcmp(sysPaths[p], path))
1282 for(p = 0; !found && p<*count; p++)
1283 if(!fstrcmp(paths[p], path))
1293 strcat(userPath, ";");
1294 start = paths[(*count)-1] + strlen(paths[(*count)-1])+1;
1299 strcpy(start, path);
1300 *(start + strlen(path)) = '\0';
1301 paths[(*count)++] = start;
1303 strcat(userPath, path);
1308 void ModifyPath(char * systemPath, char * userPath)
1310 char oldPath[8192], * paths[200], * sysPaths[200];
1311 int count, sysCount = 0;
1315 strcpy(oldPath, userPath);
1316 count = TokenizeWith(oldPath, sizeof(paths) / sizeof(char *), paths, ";", false);
1317 sysCount = TokenizeWith(systemPath, sizeof(sysPaths) / sizeof(char *), sysPaths, ";", false);
1321 strcpy(oldPath, systemPath);
1322 count = TokenizeWith(oldPath, sizeof(paths) / sizeof(char *), paths, ";", false);
1327 for(c = 0; coreSDK[c].name; c++)
1329 char path[MAX_LOCATION];
1330 if(!coreSDK[c].selected) continue;
1331 coreSDK[c].GetFullPath(path, false);
1332 if(c != ide && c != runtime && c != ec &&
1333 c != ide32 && c != runtime32 && c != ec32)
1335 if(!pathOptions[PathOptions::AddMinGWPaths].available || !pathOptions[PathOptions::AddMinGWPaths].selected)
1337 PathCat(path, "bin");
1339 else if(!pathOptions[PathOptions::AddECEREPaths].selected) continue;
1341 AddPath(sysPaths, sysCount, paths, &count, oldPath, userPath ? userPath : systemPath, path);
1347 for(c = 0; c <= cpp; c++)
1349 char path[MAX_LOCATION];
1350 if(!additional[c].selected || c == vanilla || c == vanilla32 || c == extras) continue;
1351 if((c != eda && c != eda32 && c != upx) && (!pathOptions[PathOptions::AddMinGWPaths].available || !pathOptions[PathOptions::AddMinGWPaths].selected))
1353 additional[c].GetFullPath(path, false);
1354 if(c != eda && c != eda32 && c != upx)
1355 PathCat(path, "bin");
1356 AddPath(sysPaths, sysCount, paths, &count, oldPath, userPath ? userPath : systemPath, path);
1361 void AssociateExtension(const char * extension, const char * description, const char *name, const char * action, const char * path)
1367 RegCreateKeyEx(HKEY_CLASSES_ROOT, extension, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1368 RegSetValueEx(key, null, 0, REG_SZ, (byte *)name, (uint)strlen(name)+1);
1371 RegCreateKeyEx(HKEY_CLASSES_ROOT, name, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1372 RegSetValueEx(key, null, 0, REG_SZ, (byte *)description, (uint)strlen(description)+1);
1375 sprintf(keyName, "%s\\shell", extension);
1376 RegCreateKeyEx(HKEY_CLASSES_ROOT, keyName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1377 RegSetValueEx(key, null, 0, REG_SZ, (byte *)action, (uint)strlen(action)+1);
1380 sprintf(keyName, "%s\\shell\\%s", name, action);
1381 RegCreateKeyEx(HKEY_CLASSES_ROOT, keyName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1384 sprintf(keyName, "%s\\shell\\%s\\command", name, action);
1385 RegCreateKeyEx(HKEY_CLASSES_ROOT, keyName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1387 sprintf(keyName, path);
1388 strcat(keyName, " \"%L\"");
1390 uint16 wKeyName[2048];
1391 UTF8toUTF16Buffer(keyName, wKeyName, sizeof(wKeyName) / sizeof(uint16));
1392 RegSetValueExW(key, null, 0, REG_SZ, (byte *)wKeyName, (uint)(wcslen(wKeyName) + 1)*sizeof(uint16));
1397 class InstallThread : Thread
1402 ((GuiApplication)__thisModule).Lock();
1403 installProgress.progressBar.range = totalSize;
1406 strcpy(installDir32, installDir);
1408 for(c = 0; components[c].name && !abortInstall; c++)
1409 components[c].Install(installDir, installDir32);
1412 installProgress.progressBar.range = 0;
1413 installProgress.finish.Destroy(0);
1414 installProgress.cancel.caption = $"Close";
1415 installProgress.cancel.isDefault = true;
1416 installProgress.cancel.disabled = false;
1417 installProgress.cancel.NotifyClicked = Window::ButtonCloseDialog;
1418 installProgress.installing.caption = $"Installation Cancelled.";
1419 installProgress.title.caption = $"Installation Cancelled";
1420 installProgress.titleInfo.contents = $"The installation was not completed.";
1424 char idePath[MAX_LOCATION];
1425 char userProfile[MAX_LOCATION];
1428 IDESettings settings = null; // Don't instantiate yet so we can pick up old settings
1430 IDESettingsContainer settingsContainer
1433 dataOwner = &settings;
1434 dataClass = class(IDESettings);
1435 allUsers = options[0].selected;
1437 CompilerConfig compiler;
1438 installProgress.installing.caption = $"Configuring Ecere IDE...";
1439 ((GuiApplication)__thisModule).Unlock();
1440 ((GuiApplication)__thisModule).SignalEvent();
1442 settingsContainer.Load();
1443 compiler = settings.GetCompilerConfig(defaultCompilerName);
1448 for(c = 0; coreSDK[c].name; c++)
1450 char path[MAX_LOCATION];
1451 if(!coreSDK[c].selected || !coreSDK[c].available) continue;
1453 coreSDK[c].GetFullPath(path, false);
1454 if(c != ide && c != runtime && c != ec &&
1455 c != ide32 && c != runtime32 && c != ec32)
1456 PathCat(path, "bin");
1457 MakeSlashPath(path);
1458 if((c == ide && osIS64bit) || (c == ide32 && !osIS64bit))
1460 coreSDK[c].GetFullPath(idePath, false);
1461 PathCat(idePath, "ide.exe");
1464 if(c == runtime || c == runtime32)
1466 if(!compiler.libraryDirs.Find(path))
1467 compiler.libraryDirs.Add(CopyString(path));
1474 for(c = 0; c <= cpp; c++)
1476 char path[MAX_LOCATION];
1477 if(c == extras || !additional[c].selected || !additional[c].available) continue;
1478 additional[c].GetFullPath(path, false);
1479 if(c != upx && c != eda && c != vanilla && c != eda32 && c != vanilla32)
1480 PathCat(path, "bin");
1481 MakeSlashPath(path);
1482 if(c == vanilla || c == vanilla32)
1484 if(!compiler.libraryDirs.Find(path))
1485 compiler.libraryDirs.Add(CopyString(path));
1489 if(!compiler.executableDirs.Find(path))
1490 compiler.executableDirs.Add(CopyString(path));
1497 char path[MAX_LOCATION] = "";
1499 if(components[ComponentID::samples].selected)
1500 components[ComponentID::samples].GetFullPath(path, false);
1501 // IDE will now default to HOME for the default project/files locations
1503 if(!settings.ideProjectFileDialogLocation[0])
1504 settings.ideProjectFileDialogLocation = path;
1505 if(!settings.ideFileDialogLocation[0])
1506 settings.ideFileDialogLocation = path;
1508 if(documentation[DocumentationID::apiRef].selected)
1510 documentation[DocumentationID::apiRef].GetFullPath(path, false);
1511 if(!settings.docDir[0])
1512 settings.docDir = path;
1516 settings.language = GetLanguageString();
1518 // Set LANGUAGE environment variable
1521 uint16 wLanguage[256];
1525 if(options[0].selected)
1526 RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", 0, KEY_ALL_ACCESS, &key);
1528 RegCreateKeyEx(HKEY_CURRENT_USER, "Environment", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1531 UTF8toUTF16Buffer(settings.language, wLanguage, sizeof(wLanguage) / sizeof(uint16));
1532 RegSetValueExW(key, L"ECERE_LANGUAGE", 0, REG_EXPAND_SZ, (byte *)wLanguage, (uint)(wcslen(wLanguage)+1) * 2);
1537 settingsContainer.Save();
1538 delete settingsContainer;
1541 // Set up Uninstaller
1542 ((GuiApplication)__thisModule).Lock();
1543 installProgress.installing.caption = $"Registering uninstaller...";
1544 ((GuiApplication)__thisModule).Unlock();
1545 ((GuiApplication)__thisModule).SignalEvent();
1550 const char * displayName = "Ecere SDK 0.44";
1551 char uninstaller[MAX_LOCATION];
1552 //bool nomodify = true;
1554 strcpy(uninstaller, installDir);
1555 PathCat(uninstaller, "uninstall_ecere.exe");
1557 RegCreateKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Ecere SDK", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1559 RegSetValueEx(key, "DisplayName", 0, REG_SZ, (byte *)displayName, (uint)strlen(displayName)+1);
1560 RegSetValueEx(key, "UninstallString", 0, REG_SZ, (byte *)uninstaller, (uint)strlen(uninstaller)+1);
1561 RegSetValueEx(key, "DisplayIcon", 0, REG_SZ, (byte *)idePath, (uint)strlen(idePath)+1);
1562 //RegSetValueEx(key, "NoModify", 0, REG_DWORD, (byte *)&nomodify, sizeof(nomodify));
1563 //RegSetValueEx(key, "NoRepair", 0, REG_DWORD, (byte *)&nomodify, sizeof(nomodify));
1568 if(pathOptions[PathOptions::AddECEREPaths].selected
1570 || pathOptions[PathOptions::AddMinGWPaths].selected
1574 HKEY userKey = null, systemKey = null;
1576 char userPath[8192] = "";
1577 char systemPath[8192] = "";
1578 uint16 wUserPath[8192];
1579 uint16 wSystemPath[8192];
1584 ((GuiApplication)__thisModule).Lock();
1585 installProgress.installing.caption = "Registering paths...";
1586 ((GuiApplication)__thisModule).Unlock();
1587 ((GuiApplication)__thisModule).SignalEvent();
1589 if(options[0].selected)
1591 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", 0, KEY_ALL_ACCESS, &systemKey) == ERROR_SUCCESS)
1593 size = sizeof(wSystemPath);
1594 RegQueryValueExW(systemKey, L"path", null, null, (byte *)wSystemPath, &size);
1595 UTF16toUTF8Buffer(wSystemPath, systemPath, sizeof(systemPath));
1596 ModifyPath(systemPath, null);
1598 UTF8toUTF16Buffer(systemPath, wSystemPath, sizeof(wSystemPath) / sizeof(uint16));
1599 RegSetValueExW(systemKey, L"path", 0, REG_EXPAND_SZ, (byte *)wSystemPath, (uint)(wcslen(wSystemPath)+1) * 2);
1600 RegCloseKey(systemKey);
1605 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", 0, KEY_QUERY_VALUE, &systemKey) == ERROR_SUCCESS)
1607 size = sizeof(wSystemPath);
1608 RegQueryValueExW(systemKey, L"path", null, null, (byte *)wSystemPath, &size);
1609 UTF16toUTF8Buffer(wSystemPath, systemPath, sizeof(systemPath));
1610 RegCloseKey(systemKey);
1613 RegCreateKeyEx(HKEY_CURRENT_USER, "Environment", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &userKey, &status);
1614 if(status == REG_OPENED_EXISTING_KEY)
1616 size = sizeof(wUserPath);
1617 RegQueryValueExW(userKey, L"path", null, null, (byte *)wUserPath, &size);
1618 UTF16toUTF8Buffer(wUserPath, userPath, sizeof(userPath));
1620 ModifyPath(systemPath, userPath);
1621 UTF8toUTF16Buffer(userPath, wUserPath, sizeof(wUserPath) / sizeof(uint16));
1622 RegSetValueExW(userKey, L"path", 0, REG_EXPAND_SZ, (byte *)wUserPath, (uint)(wcslen(wUserPath)+1) * 2);
1623 RegCloseKey(userKey);
1625 // SendMessageTimeout (HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)"Environment", SMTO_NORMAL, 1000, NULL);
1628 // Install Program Group Icons
1629 GetEnvironment(options[0].selected ? "ALLUSERSPROFILE" : "USERPROFILE", userProfile, sizeof(userProfile));
1631 if(options[IconOptions::StartMenuIcon].selected)
1633 char destPath[MAX_LOCATION];
1634 char startMenuPath[MAX_LOCATION] = "";
1637 ((GuiApplication)__thisModule).Lock();
1638 installProgress.installing.caption = $"Installing Start Menu Icons...";
1639 ((GuiApplication)__thisModule).Unlock();
1640 ((GuiApplication)__thisModule).SignalEvent();
1642 strcpy(destPath, userProfile);
1644 if(RegOpenKeyEx(options[0].selected ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
1645 "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", 0, KEY_QUERY_VALUE, &key) == ERROR_SUCCESS)
1647 uint16 wStartMenuPath[2048];
1648 DWORD size = sizeof(wStartMenuPath);
1649 // RegQueryValueEx(key, "Start Menu", null, null, startMenuPath, &size);
1650 RegQueryValueExW(key, options[0].selected ? L"Common Programs" : L"Programs", null, null, (byte *)wStartMenuPath, &size);
1651 UTF16toUTF8Buffer(wStartMenuPath, startMenuPath, sizeof(startMenuPath));
1654 if(!startMenuPath[0] && userProfile[0])
1656 strcpy(startMenuPath, userProfile);
1657 PathCat(startMenuPath, "Start Menu\\Programs");
1660 if(startMenuPath[0])
1662 strcpy(destPath, startMenuPath);
1663 PathCat(destPath, "Ecere SDK");
1666 strcpy(destPath, startMenuPath);
1667 PathCat(destPath, "Ecere SDK\\Ecere IDE.lnk");
1668 CreateLink(idePath, destPath, null); //"Ecere IDE");
1669 if(components[ComponentID::samples].selected)
1671 char samplesPath[MAX_LOCATION] = "";
1672 components[ComponentID::samples].GetFullPath(samplesPath, false);
1674 strcpy(destPath, startMenuPath);
1675 PathCat(destPath, "Ecere SDK\\Sample Projects.lnk");
1676 CreateLink(samplesPath, destPath, null);//"Sample Projects");
1678 if(components[ComponentID::documentation].selected && documentation[DocumentationID::ecereBook].selected)
1680 char docPath[MAX_LOCATION] = "";
1681 documentation[DocumentationID::ecereBook].GetFullPath(docPath, false);
1682 PathCat(docPath, "Ecere Tao of Programming [work in progress].pdf");
1685 char tao[MAX_LOCATION] ;
1686 documentation[DocumentationID::ecereBook].GetFullPath(tao, false);
1687 PathCat(tao, "tao.pdf");
1688 RenameFile(tao, docPath);
1691 strcpy(destPath, startMenuPath);
1692 PathCat(destPath, "Ecere SDK\\The Ecere Tao of Programming.lnk");
1693 CreateLink(docPath, destPath, null);
1698 // Install Desktop Icon
1699 if(options[IconOptions::DesktopIcon].selected)
1702 char desktopPath[MAX_LOCATION];
1704 if(RegOpenKeyEx(options[0].selected ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
1705 "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", 0, KEY_QUERY_VALUE, &key) == ERROR_SUCCESS)
1707 uint16 wDesktopPath[MAX_LOCATION];
1708 DWORD size = sizeof(wDesktopPath);
1709 RegQueryValueExW(key, options[0].selected ? L"Common Desktop" : L"Desktop", null, null, (byte *)wDesktopPath, &size);
1710 UTF16toUTF8Buffer(wDesktopPath, desktopPath, sizeof(desktopPath));
1713 if(!desktopPath[0] && userProfile[0])
1715 strcpy(desktopPath, userProfile);
1716 PathCat(desktopPath, "Desktop");
1721 PathCat(desktopPath, "Ecere IDE.lnk");
1723 ((GuiApplication)__thisModule).Lock();
1724 installProgress.installing.caption = $"Installing Desktop Icon...";
1725 ((GuiApplication)__thisModule).Unlock();
1726 ((GuiApplication)__thisModule).SignalEvent();
1728 CreateLink(idePath, desktopPath, null);//"Ecere IDE");
1732 SendMessageTimeout (HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)"Environment", SMTO_NORMAL, 1000, NULL);
1734 // Install QuickLaunch Icon
1735 if(options[IconOptions::QuickLaunchIcon].selected)
1737 char appData[MAX_LOCATION];
1738 GetEnvironment("APPDATA", appData, sizeof(appData));
1741 char destPath[MAX_LOCATION];
1743 if(appData[0] && options[0].selected)
1745 char dir[MAX_FILENAME];
1746 GetLastDirectory(appData, dir);
1747 if(!strcmpi(dir, "Roaming"))
1748 PathCat(appData, "../../../Default/AppData/Roaming");
1750 PathCat(appData, "../Default");
1753 ((GuiApplication)__thisModule).Lock();
1754 installProgress.installing.caption = $"Installing Quicklaunch Icon...";
1755 ((GuiApplication)__thisModule).Unlock();
1756 ((GuiApplication)__thisModule).SignalEvent();
1758 strcpy(destPath, appData);
1759 PathCat(destPath, "Microsoft\\Internet Explorer\\Quick Launch\\Ecere IDE.lnk");
1760 CreateLink(idePath, destPath, null);
1762 // Set it up on the dock for Windows 7 -- not working
1764 StripLastDirectory(destPath, destPath);
1765 PathCat(destPath, "User Pinned\\TaskBar");
1767 PathCat(destPath, "Ecere IDE.lnk");
1768 CreateLink(idePath, destPath, null);
1773 // Register File Types
1774 if(associateOptions[AssociateOptions::AssociateEPJ].selected ||
1775 associateOptions[AssociateOptions::AssociateEC].selected ||
1776 associateOptions[AssociateOptions::AssociateC].selected ||
1777 associateOptions[AssociateOptions::AssociateCPP].selected ||
1778 associateOptions[AssociateOptions::AssociateTXT].selected ||
1779 associateOptions[AssociateOptions::Associate3DS].selected ||
1780 associateOptions[AssociateOptions::AssociateIMG].selected)
1782 ((GuiApplication)__thisModule).Lock();
1783 installProgress.installing.caption = $"Resgistering File Types...";
1784 ((GuiApplication)__thisModule).Unlock();
1785 ((GuiApplication)__thisModule).SignalEvent();
1787 if(associateOptions[AssociateOptions::AssociateEPJ].selected)
1789 AssociateExtension(".epj", "Ecere IDE Project", "epj_file", "Open", idePath);
1791 if(associateOptions[AssociateOptions::AssociateEC].selected)
1793 AssociateExtension(".ec", "eC Source File", "ec_file", "Open", idePath);
1794 AssociateExtension(".eh", "eC Header File", "eh_file", "Open", idePath);
1796 if(associateOptions[AssociateOptions::AssociateC].selected)
1798 AssociateExtension(".c", "C Source File", "c_file", "Open", idePath);
1799 AssociateExtension(".h", "C Header File", "h_file", "Open", idePath);
1801 if(associateOptions[AssociateOptions::AssociateCPP].selected)
1803 AssociateExtension(".cpp", "C++ Source File", "cpp_file", "Open", idePath);
1804 AssociateExtension(".cc", "C++ Source File", "cpp_file", "Open", idePath);
1805 AssociateExtension(".cxx", "C++ Source File", "cpp_file", "Open", idePath);
1806 AssociateExtension(".chh", "C++ Header File", "chh_file", "Open", idePath);
1807 AssociateExtension(".hh", "C++ Header File", "chh_file", "Open", idePath);
1808 AssociateExtension(".hxx", "C++ Header File", "chh_file", "Open", idePath);
1810 if(associateOptions[AssociateOptions::AssociateTXT].selected)
1812 AssociateExtension(".txt", "Text File", "txt_file", "Open", idePath);
1814 if(associateOptions[AssociateOptions::Associate3DS].selected)
1816 AssociateExtension(".3ds", "3D Studio Model", "3ds_file", "View", idePath);
1818 if(associateOptions[AssociateOptions::AssociateIMG].selected)
1820 AssociateExtension(".bmp", "BMP Image", "bmp_file", "View", idePath);
1821 AssociateExtension(".pcx", "PCX Image", "pcx_file", "View", idePath);
1822 AssociateExtension(".png", "PNG Image", "png_file", "View", idePath);
1823 AssociateExtension(".jpg", "JPEG Image", "jpg_file", "View", idePath);
1824 AssociateExtension(".jpeg", "JPEG Image", "jpg_file", "View", idePath);
1825 AssociateExtension(".gif", "GIF Image", "gif_file", "View", idePath);
1828 ((GuiApplication)__thisModule).Lock();
1830 installProgress.cancel.Destroy(0);
1831 installProgress.finish.caption = $"Finish";
1832 installProgress.finish.disabled = false;
1833 installProgress.finish.Activate();
1834 installProgress.installing.caption = $"Installation Complete.";
1835 installProgress.title.caption = $"Installation Complete";
1836 installProgress.titleInfo.contents = $"Thank you for using the Ecere SDK.";
1838 ((GuiApplication)__thisModule).Unlock();