2 static define buildString = $"Ecere SDK v0.44.10 (Without MinGW) -- built on March 9th, 2014 ";
4 static define buildString = $"Ecere SDK v0.44.10 -- built on March 9th, 2014 ";
7 #define WIN32_LEAN_AND_MEAN
8 #define GetFreeSpace _GetFreeSpace
22 static LanguageOption dummy; // TOFIX
24 static bool IsAdministrator()
27 SID_IDENTIFIER_AUTHORITY NtAuthority = { SECURITY_NT_AUTHORITY };
28 PSID AdministratorsGroup;
29 b = AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &AdministratorsGroup);
32 if(!CheckTokenMembership(NULL, AdministratorsGroup, &b))
34 FreeSid(AdministratorsGroup);
44 char * OnGetString(char * tempString, void * fieldData, bool * needClass)
48 strcpy(tempString, name);
49 strcat(tempString, " (32)");
55 void OnDisplay(Surface surface, int x, int y, int width, void * fieldData, Alignment alignment, DataDisplayFlags displayFlags)
57 if(!displayFlags.active) { displayFlags.current = false; displayFlags.selected = false; }
58 class::OnDisplay(surface, x + 22, y, width - 22, fieldData, alignment, displayFlags);
62 //#define BUFFERSIZE 0x10000
63 #define BUFFERSIZE 0x1000
64 bool abortInstall = false;
66 void ExtractFileFromArchive(ProgressBar progressBar, char * path, char * outputFile)
68 char fileName[MAX_LOCATION];
69 FileAttribs exists = FileExists(path);
73 if(exists.isDirectory)
75 FileListing listing { path };
79 if(MakeDir(outputFile))
82 FileGetStats(path, &stats);
86 while(listing.Find() && !abortInstall)
88 strcpy(fileName, outputFile);
90 // Tweak file name if out
93 if(!strcmp(fileName, ".")) fileName[0] = '\0';
94 if(listing.name[0] == '/' || listing.name[0] == '\\')
96 char * afterSlash, rest[MAX_LOCATION];
97 for(afterSlash = fileName; *afterSlash == '/' || *afterSlash == '\\'; afterSlash++);
98 strcpy(rest, afterSlash);
99 PathCat(fileName, "_root");
100 PathCat(fileName, rest);
102 else if(listing.name[1] == ':')
105 sprintf(letter, "_%cdrive", toupper(listing.name[0]));
106 PathCat(fileName, letter);
107 PathCat(fileName, listing.name[2] ? (listing.name + 3) : (listing.name + 2));
110 PathCat(fileName, listing.name);
113 PathCat(fileName, listing.name);
114 if(!strcmp(fileName, "/") || !strcmp(fileName, "\\"))
115 strcpy(fileName, DIR_SEPS);
116 ExtractFileFromArchive(progressBar, listing.path, fileName);
122 File input = FileOpen(path, read);
125 File output = FileOpen(outputFile, write);
128 char fileName[MAX_FILENAME];
129 uint position = progressBar.progress;
132 byte buffer[BUFFERSIZE];
134 FileGetSize(path, &dataSize);
135 GetLastDirectory(outputFile, fileName);
137 ((GuiApplication)__thisModule).SignalEvent();
138 //((GuiApplication)__thisModule).ProcessInput();
139 //((GuiApplication)__thisModule).UpdateDisplay();
141 for(c = 0; c<dataSize && !abortInstall; c += BUFFERSIZE)
143 uint size = (dataSize > c + BUFFERSIZE) ? BUFFERSIZE : (dataSize - c);
145 ((GuiApplication)__thisModule).Unlock();
147 input.Read(buffer, 1, size);
148 output.Write(buffer, 1, size);
150 ((GuiApplication)__thisModule).Lock();
152 progressBar.progress = position + c + size;
153 ((GuiApplication)__thisModule).SignalEvent();
155 //((GuiApplication)__thisModule).ProcessInput();
156 //((GuiApplication)__thisModule).UpdateDisplay();
161 FileGetStats(path, &stats);
167 FileSetTime(outputFile, stats.created, 0, stats.modified);
170 public enum BitArch { none, bits32, bits64 };
176 char * defInstallPath;
177 Component * subComponents;
187 char installPath[MAX_LOCATION];
190 void GetFullPath(char * path, bool is32bit)
192 if(this != null && parent)
193 parent->GetFullPath(path, is32bit || (arch == bits32 && osIS64bit));
195 strcpy(path, (this && (is32bit || (arch == bits32 && osIS64bit))) ? installDir32 : installDir);
198 PathCat(path, installPath);
201 void Install(char * parentPath, char * parentPath32)
204 if(selected && (arch == none || arch == bits32 || osIS64bit))
206 char path64[MAX_LOCATION];
207 char path32[MAX_LOCATION];
208 strcpy(path64, parentPath);
209 PathCat(path64, installPath);
211 strcpy(path32, parentPath32);
212 PathCat(path32, installPath);
214 installProgress.installing.SetText($"Installing %s...", name);
215 ((GuiApplication)__thisModule).UpdateDisplay();
219 char * path = path64;
220 char source[MAX_LOCATION];
222 strcat(source, dataPath);
229 if(FileExists(source).isFile)
231 char name[MAX_FILENAME];
232 GetLastDirectory(source, name);
237 uint p = installProgress.progressBar.progress;
238 ExtractFileFromArchive(installProgress.progressBar, source, path);
243 for(c = 0; subComponents[c].name; c++)
244 subComponents[c].Install(path64, path32);
251 define minGWIncluded = true;
253 define minGWIncluded = false;
256 Array<Component> samples
258 { "Ecere Chess", "samples/chess", "chess", null, false, true, true, none },
259 { "Ecere Fractals", "samples/fractals", "fractals", null, false, true, true, none },
260 { "3D", "samples/3D", "3D", null, false, true, true, none },
261 { "Android", "samples/android", "android", null, false, true, true, none },
262 { $"Audio", "samples/audio", "audio", null, false, true, true, none },
263 { $"Database", "samples/db", "db", null, false, true, true, none },
264 { "eC", "samples/eC", "eC", null, false, true, true, none },
265 { $"Games", "samples/games", "games", null, false, true, true, none },
266 { $"GUI & Graphics", "samples/guiAndGfx", "guiAndGfx", null, false, true, true, none },
267 { $"Miscellaneous", "samples/misc", "misc", null, false, true, true, none },
268 { $"Networking", "samples/net", "net", null, false, true, true, none },
269 { $"WIA Scanning", "samples/scanning", "scanning", null, false, true, true, none },
270 { $"Threading", "samples/threads", "threads", null, false, true, true, none },
274 public enum CoreSDKID
276 ide, ide32, runtime, runtime32, ec, ec32,
277 gcc, gdb, mingw, binutils, make,
281 Array<Component> coreSDK
283 { "Ecere IDE", "ecere-sdk/ide", "bin", null, true, true, true, bits64 },
284 { "Ecere IDE", "ecere-sdk32/ide", "bin", null, true, true, true, bits32 },
285 { $"Runtime Library", "ecere-sdk/ecere.dll", "bin", null, true, true, true, bits64 },
286 { $"Runtime Library", "ecere-sdk32/ecere.dll", "bin", null, true, true, true, bits32 },
287 { $"eC Compiler", "ecere-sdk/compiler", "bin", null, true, true, true, bits64 },
288 { $"eC Compiler", "ecere-sdk32/compiler", "bin", null, true, true, true, bits32 },
289 { $"GNU C Compiler", "tdm/gcc/core", "tdm", null, true, true, minGWIncluded, none },
290 { $"GNU Debugger", "tdm/gdb", "tdm", null, true, true, minGWIncluded, none },
291 { $"MinGW-w64 Runtime", "tdm/mingwrt", "tdm", null, true, true, minGWIncluded, none },
292 { $"Binary Utils", "tdm/binutils", "tdm", null, true, true, minGWIncluded, none },
293 { $"GNU Make", "tdm/make", "tdm", null, true, true, minGWIncluded, none },
297 public enum AdditionalID
299 eda, eda32, vanilla, vanilla32, extras, upx, gnurx, gnurx32, /*pthreads, */cpp, /*w32api, gcci18n, gdbi18n, makei18n, binutilsi18n, */none
302 Array<Component> additional
304 { $"Data Access", "ecere-sdk/eda", "bin", null, false, true, true, bits64 },
305 { $"Data Access", "ecere-sdk32/eda", "bin", null, false, true, true, bits32 },
306 { $"Ecere Vanilla", "ecere-sdk/libecereVanilla.a", "lib", null, false, true, true, bits64 },
307 { $"Ecere Vanilla", "ecere-sdk32/libecereVanilla.a", "lib", null, false, true, true, bits32 },
308 { $"Ecere Extras", "extras", "extras", null, false, true, true, none },
309 { "UPX", "upx/bin", "upx/bin", null, false, true, true, none },
310 { $"GNU Regexp", "tdm/gnurx", "tdm", null, false, true, true, bits64 },
311 { $"GNU Regexp", "tdm/gnurx32", "tdm", null, false, true, true, bits32 },
312 // { "pthreads", "tdm/pthreads", "mingw", null, false, true, minGWIncluded, none },
313 { $"C++ Compiler", "tdm/gcc/c++", "tdm", null, false, true, minGWIncluded, none },
314 // { "Win32 APIs", "mingw/w32api", "mingw", null, false, true, minGWIncluded, none },
315 /* { "GCC I18n", "mingw/locale/gcc", "tdm", null, false, false, minGWIncluded, none },
316 { "GDB I18n", "mingw/locale/gdb", "tdm", null, false, false, minGWIncluded, none },
317 { "Make I18n", "mingw/locale/make", "tdm", null, false, false, minGWIncluded, none },
318 { "Binutils I18n", "mingw/locale/binutils", "tdm", null, false, false, minGWIncluded, none },
323 public enum DocumentationID
325 ecereBook, apiRef, tutorials, coursework,
326 gccDoc, gppDocs, gdbDocs, makeDocs, binDocs, mingwDocs, gnurxDocs, upxDocs,
330 Array<Component> documentation
332 { $"Ecere Book", "ecere-sdk/book", "doc", null, false, true, true, none },
333 { $"API Reference", "ecere-sdk/doc", "doc", null, false, true, true, none },
334 { $"Ecere Tutorials", "ecere-sdk/tutorials", "doc", null, false, true, true, none },
335 { $"Ecere Coursework", "ecere-sdk/coursework", "doc", null, false, true, true, none },
336 { $"GCC Docs", "tdm/doc/gcc", "tdm", null, false, false, minGWIncluded, none },
337 { $"G++ Docs", "tdm/doc/g++", "tdm", null, false, false, minGWIncluded, none },
338 { $"GDB Docs", "tdm/doc/gdb", "tdm", null, false, false, minGWIncluded, none },
339 { $"Make Docs", "tdm/doc/make", "tdm", null, false, false, minGWIncluded, none },
340 { $"Binutils Docs", "tdm/doc/binutils", "tdm", null, false, false, minGWIncluded, none },
341 { $"gnurx Docs", "tdm/doc/gnurx", "tdm", null, false, false, minGWIncluded, none },
342 { $"UPX Docs", "upx/doc", "upx/doc", null, false, false, minGWIncluded, none },
346 public enum ComponentID
355 Array<Component> components
357 { $"Core SDK Files", null, null, coreSDK.array, true, true, true, none },
358 { $"Additional Support", null, null, additional.array, false, true, true, none },
359 { $"Documentation", null /*"doc"*/, null /*"doc"*/, documentation.array, false, true, true, none },
360 { $"Samples", null, "samples", samples.array, false, true, true, none },
364 FileSize totalInstalled;
369 InstallOption * subOptions;
375 enum AssociateOptions
386 Array<InstallOption> associateOptions
388 { $"Associate with Ecere Project Files (*.epj)", null, true },
389 { $"Associate with eC Files (*.ec, *.eh)", null, true },
390 { $"Associate with C files (*.c, *.h)", null, false },
391 { $"Associate with C++ Files (*.cpp, *.hpp, *.cc, *.hh, *.cxx, *.hxx)", null, false },
392 { $"Associate with text files (*.txt)", null, false },
393 { $"Associate with 3D Studio Model Files (*.3ds)", null, true },
394 { $"Associate with Image Files (*.png, *.jpg, *.pcx, *.bmp, *.gif)", null, false },
400 AddECEREPaths, AddMinGWPaths
403 Array<InstallOption> pathOptions
405 { $"Add Ecere binaries location to the user environment path", null, true, true },
406 { $"Add MinGW to the user environment path", null, true, minGWIncluded },
417 Array<InstallOption> options
419 { $"Install for All Users", null, true, true },
420 { $"Start Menu Group", null, true, true },
421 { $"Desktop Icon", null, true, true },
422 { $"Quicklaunch Icon", null, true, true },
423 { $"Associate the Ecere IDE with Supported File Types", associateOptions.array, true, true },
424 { $"Add binaries location to the user environment paths", pathOptions.array, true, minGWIncluded },
428 char sourceDir[MAX_LOCATION] = ":";
429 char installDir[MAX_LOCATION];
430 char installDir32[MAX_LOCATION];
433 class Installer : Window
435 background = formColor;
440 clientSize = { 636, 476 };
441 icon = { ":icon.png" };
442 text = $"Ecere Software Development Kit Setup - v0.44.10 \"Ryōan-ji\" 64 Bit Edition";
444 // clientSize = { 796, 576 };
447 Picture back { image = BitmapResource { ":ryoanji.png" }, parent = this, position = { 0, 0 } };
448 FileDialog fileDialog
450 master = this, type = selectDir,
451 text = $"Select a new location"
455 master = this, autoCreate = false, inactive = true, text = "...";
457 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
459 DataRow row = componentsBox.currentRow;
460 Component * component = ((CheckItem *)row.GetData(componentField))->data;
461 component->GetFullPath(fileDialog.filePath, false);
462 StripLastDirectory(fileDialog.filePath, fileDialog.currentDirectory);
464 if(fileDialog.Modal() == ok)
466 componentsBox.StopEditing(false);
467 row.SetData(locationField, fileDialog.filePath);
468 componentsBox.NotifyChanged(this, componentsBox, row);
469 componentsBox.currentField = componentsBox.currentField;
474 CheckListBox componentsBox
476 this, size = { 460, 112 }, position = { 160, 160 }, hasHeader = true;
477 fullRowSelect = false, collapseControl = true, treeBranches = true, rootCollapseButton = true,
478 hasHorzScroll = true;
482 selectionColor = { 145, 150, 140 };
487 bool NotifyKeyDown(ListBox listBox, DataRow row, Key key, unichar ch)
489 if(key == f2 && browse.visible)
490 browse.NotifyClicked(this, browse, 0, 0, 0);
494 bool NotifyChanged(ListBox listBox, DataRow row)
496 Component * component = ((CheckItem *)listBox.GetData(componentField))->data;
497 char path[MAX_LOCATION], relative[MAX_LOCATION] = "", * newPath;
498 char fullPath[MAX_LOCATION];
500 component->parent->GetFullPath(path, false);
501 strcpy(fullPath, path);
503 newPath = row.GetData(locationField);
506 PathCat(fullPath, newPath);
507 if(IsPathInsideOf(fullPath, path))
508 MakePathRelative(fullPath, path, relative);
510 strcpy(relative, fullPath);
512 listBox.SetData(locationField, relative);
513 strcpy(component->installPath, relative);
515 //SetAvailableSpace(component, path);
518 install.disabled = false;
519 for(c = 0; components[c].name; c++)
521 SetAvailableSpace(components[c], installDir);
527 bool NotifyEditDone(ListBox listBox, DataRow row)
533 bool NotifyEdited(ListBox listBox, DataRow row)
536 browse.parent = listBox;
537 browse.position = { componentField.width + locationField.width + 18, (listBox.currentIndex+1) * listBox.rowHeight - 2 };
538 browse.size = { 30, listBox.rowHeight + 3 };
539 for(e = listBox.firstChild; e; e = e.next)
541 if(e._class == class(DataBox))
550 void NotifyChecked(CheckListBox listBox, DataRow row)
552 Component * component = ((CheckItem *)row.GetData(componentField))->data;
554 component->selected = listBox.IsChecked(row);
556 if(!component->parent) totalSize -= component->requiredSize;
557 component->requiredSize = 0;
558 if(component->selected)
560 component->requiredSize += component->size;
561 if(component->subComponents)
562 for(c = 0; component->subComponents[c].name; c++)
563 component->requiredSize += component->subComponents[c].requiredSize;
565 if(component->requiredSize)
567 uint requiredSize = component->requiredSize;
568 row.SetData(reqField, requiredSize);
571 row.UnsetData(reqField);
572 if(!component->parent)
574 totalSize += component->requiredSize;
576 char sizeString[100];
577 PrintSize(sizeString, totalSize, 2);
578 totalSpaceValue.text = sizeString;
583 Label agreementLbl { parent = this, text = $"By installing the Ecere SDK, you agree to the", font = { "Tahoma", 8.25f }, anchor = Anchor { right = 399, top = 448 } };
586 this, inactive = true, offset = false, bevel = false, foreground = blue, font = { "Tahoma", 8.25f, underline = true, bold = true },
587 // text = $"terms and conditions", anchor = Anchor { left = 241, top = 421 };
588 text = $"terms and conditions", anchor = Anchor { left = 235, top = 445 };
589 cursor = ((GuiApplication)__thisModule).GetCursor(hand);
591 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
593 // LicenseBox { master = this, sourceFile = ":ecere-sdk/doc/LICENSE" }.Modal();
594 LicensesForm { master = this }.Modal();
598 Label dotLbl { parent = this, text = ".", font = { "Tahoma", 8.25f }, anchor = Anchor { left = 372, top = 448 } };
599 CheckListBox optionsBox
601 this, size = { 460, 114 }, position = { 160, 284 };
602 fullRowSelect = false, collapseControl = true, treeBranches = true, rootCollapseButton = true,
607 void NotifyChecked(CheckListBox listBox, DataRow row)
609 CheckItem * item = row.GetData(optionField);
610 InstallOption * option = item->data;
611 option->selected = listBox.IsChecked(row);
612 // Update default samples/extras path whether we're installing for All Users or not
613 if(option == &options[0])
615 char appData[MAX_LOCATION];
617 options[5].name = options[0].selected ? $"Add binaries location to the system environment paths" : $"Add binaries location to the user environment paths";
619 ((CheckItem *)options[5].row.GetData(optionField))->name = options[5].name;
621 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";
622 if(pathOptions[PathOptions::AddECEREPaths].row)
623 ((CheckItem *)pathOptions[PathOptions::AddECEREPaths].row.GetData(optionField))->name = pathOptions[PathOptions::AddECEREPaths].name;
625 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";
626 if(pathOptions[PathOptions::AddMinGWPaths].row)
627 ((CheckItem *)pathOptions[PathOptions::AddMinGWPaths].row.GetData(optionField))->name = pathOptions[PathOptions::AddMinGWPaths].name;
629 GetEnvironment(options[0].selected ? "ALLUSERSPROFILE" : "APPDATA", appData, sizeof(appData));
630 if(appData && appData[0])
632 char defPath[MAX_LOCATION];
634 char * s = components[ComponentID::samples].installPath;
635 strcpy(defPath, installDir);
636 PathCat(defPath, components[ComponentID::samples].defInstallPath);
637 ChangeCh(defPath, '/', DIR_SEP);
638 if(!strcmp(defPath, components[ComponentID::samples].installPath))
640 static char defSamplesPath[MAX_LOCATION];
641 strcpy(defSamplesPath, appData);
642 PathCat(defSamplesPath, "Ecere SDK\\Samples");
643 components[ComponentID::samples].defInstallPath = defSamplesPath;
645 strcpy(components[ComponentID::samples].installPath, components[ComponentID::samples].defInstallPath);
646 ChangeCh(components[ComponentID::samples].installPath, '/', DIR_SEP);
647 components[ComponentID::samples].row.SetData(locationField, components[ComponentID::samples].installPath);
650 strcpy(defPath, installDir);
651 PathCat(defPath, additional[AdditionalID::extras].defInstallPath);
652 ChangeCh(defPath, '/', DIR_SEP);
653 if(!strcmp(additional[AdditionalID::extras].installPath, additional[AdditionalID::extras].installPath))
655 static char defExtrasPath[MAX_LOCATION];
656 strcpy(defExtrasPath, appData);
657 PathCat(defExtrasPath, "Ecere SDK\\extras");
658 additional[AdditionalID::extras].defInstallPath = defExtrasPath;
660 strcpy(additional[AdditionalID::extras].installPath, additional[AdditionalID::extras].defInstallPath);
661 ChangeCh(additional[AdditionalID::extras].installPath, '/', DIR_SEP);
662 additional[AdditionalID::extras].row.SetData(locationField, additional[AdditionalID::extras].installPath);
670 parent = this, text = $"Install", isDefault = true, size = { 75, 23 }, position = { 432, 440 };
672 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
674 installProgress.Create();
676 // installProgress.thread.Main();
677 installProgress.thread.Create();
681 Button button3 { parent = this, text = $"Cancel", hotKey = altX, size = Size { 75, 23 }, anchor = Anchor { left = 544, top = 440 }, NotifyClicked = ButtonCloseDialog };
684 this, position = { 14, 374 }, size = { 142, 0 }, caption = "Language:";
686 bool NotifySelect(DropBox dropBox, DataRow row, Modifiers mods)
688 LanguageOption * option = row.GetData(null);
689 // If the language is already set, we need to override it
691 IDESettings settings = null;
692 IDESettingsContainer settingsContainer
695 dataOwner = &settings;
696 dataClass = class(IDESettings);
697 allUsers = options[0].selected;
699 settingsContainer.Load();
700 if(settings.language)
702 settings.language = option->code;
703 settingsContainer.Save();
705 delete settingsContainer;
708 ((GuiApplication)__thisModule.application).desktop.Destroy(0);
709 LanguageRestart(option->code, __thisModule.application, null, null, null, null, false);
713 Label lblLanguageBox { this, position = { 14, 354 }, labeledWindow = languageBox };
714 Label label1 { labeledWindow = destBox, tabCycle = true, isGroupBox = true, parent = this, inactive = false, size = Size { 458, 50 }, anchor = Anchor { left = 160, top = 96 } };
717 parent = label1, master = this, text = $" Destination Folder", size = Size { 336, 22 }, anchor = Anchor { left = 12, top = 20, right = 12 };
718 typeExpected = directory;
719 browseDialog = fileDialog;
722 bool NotifyModified(PathBox pathBox)
725 strcpy(installDir, destBox.path);
726 install.disabled = false;
727 for(c = 0; components[c].name; c++)
729 SetAvailableSpace(components[c], installDir);
736 label1, this, $"Browse", altB, size = { 83, 24 }, position = { 360, 16 };
738 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
740 strcpy(fileDialog.filePath, installDir);
741 StripLastDirectory(installDir, fileDialog.currentDirectory);
742 if(fileDialog.Modal())
744 strcpy(installDir, fileDialog.filePath);
745 destBox.contents = installDir;
746 // TOCHECK: Should setting contents call NotifyModified?
747 destBox.NotifyModified(destBox.master, destBox);
754 this, multiLine = true,
755 opacity = 0, borderStyle = none, inactive = true, size = { 136, 53 }, position = { 14, 96 }, noSelect = true,
756 contents = $"Select the default root\n"
757 "folder where to install\n"
762 this, opacity = 0, borderStyle = none, inactive = true, size = { 136, 132 }, position = { 14, 152 }, noSelect = true,
764 contents = $"Select the optional\n"
765 "components you wish\n"
767 "You may customize the\n"
768 "install location for each\n"
769 "of them, or use the default\n"
770 "based on the main\n"
771 "destination folder."
775 this, opacity = 0, borderStyle = none, inactive = true, size = { 136, 83 }, position = { 14, 280 }, noSelect = true,
777 contents = $"Select icons to install, file\n"
778 "associations, and system\n"
779 "environment modifications:"
781 Label totalSpaceLabel
783 this, anchor = { right = 72, top = 404 }, text = $"Space Required: "
785 Label totalSpaceValue
787 this, anchor = { right = 14, top = 404 }, text = "0 mb"
791 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"
792 "of the SDK to install, as well as where to install program icons."
794 Label label2 { parent = this, text = buildString, position = { 16, 422 }, font = { "Tahoma", 10, true }, disabled = true, opacity = 0, background = activeBorder };
797 image = BitmapResource { ":ecere.png", alphaBlend = true }, filter = true, parent = label3, text = "picture1", anchor = Anchor { left = 16, top = 4 };
798 cursor = ((GuiApplication)__thisModule).GetCursor(hand);
800 bool OnLeftButtonDown(int x, int y, Modifiers mods)
802 ShellOpen("http://www.ecere.com/");
806 Label label4 { label3, font = { "Tahoma", 8.25f, bold = true }, /*size = { 326, 16 }, */position = { 248, 24 }, text = $"Choose Components, Locations and Install Options" };
807 DataField componentField { "CheckItem", width = 160, header = $"Component" };
808 DataField locationField { "char *", width = 108, header = $"Destination Folder", editable = true };
809 DataField reqField { "FileSize", width = 70, header = $"Req. Space", alignment = right };
810 DataField avField { "FileSize64", width = 70, header = $"Avail. Space", alignment = right };
811 DataField optionField { "CheckItem" };
813 DataField languageField { class(LanguageOption) };
815 void SetAvailableSpace(Component component, char * parentPath)
817 char path[MAX_LOCATION];
821 strcpy(path, parentPath);
822 PathCat(path, component.installPath);
824 if(component.subComponents)
825 for(c = 0; component.subComponents[c].name; c++)
826 SetAvailableSpace(component.subComponents[c], path);
828 while(!FileExists(path) && path[0])
829 StripLastDirectory(path, path);
832 GetFreeSpace(path, &size);
833 component.row.SetData(avField, size);
834 if(!size) install.disabled = true;
837 FileSize ComputeSize(char * path)
840 FileAttribs attribs = FileExists(path);
841 if(attribs.isDirectory)
843 FileListing listing { path };
844 while(listing.Find())
846 if(listing.stats.attribs.isDirectory)
847 size += ComputeSize(listing.path);
849 size += listing.stats.size;
853 FileGetSize(path, &size);
857 void AddComponent(Component component, Component parent, char * parentPath)
859 DataRow row = (parent != null) ? parent.row.AddRow() : componentsBox.AddRow();
861 FileSize64 avSize = 0;
862 char path[MAX_LOCATION];
865 strcpy(path, parentPath);
866 if(component.defInstallPath)
867 PathCat(path, component.defInstallPath);
868 component.parent = parent;
870 row.SetData(null, CheckItem { component.name, component, (component.arch == bits32 && osIS64bit) } );
872 if(component.defInstallPath)
874 strcpy(component.installPath, component.defInstallPath);
875 ChangeCh(component.installPath, '/', DIR_SEP);
876 row.SetData(locationField, component.installPath);
879 if(component.mandatory)
881 if(component.arch != bits32 || !osIS64bit) // || component == &coreSDK[gdb32])
882 componentsBox.SetDisabled(row, true);
884 component.selected = false;*/
886 else if(component.arch == bits32 && osIS64bit)
887 ; //component.selected = false;
889 componentsBox.SetCheck(row, component.selected);
891 if(component.dataPath)
893 char path[MAX_LOCATION];
895 PathCat(path, component.dataPath);
896 component.size = ComputeSize(path);
898 if(component.subComponents)
901 for(c = 0; component.subComponents[c].name; c++)
903 Component * sub = &component.subComponents[c];
904 if(sub->available && (osIS64bit || sub->arch == bits32 || sub->arch == none))
906 AddComponent(sub, component, path);
907 size += sub->requiredSize;
910 sub->selected = false;
914 component.requiredSize = component.selected ? (size + component.size) : 0;
915 if(component.requiredSize)
916 row.SetData(reqField, component.requiredSize);
918 while(!FileExists(path) && path[0])
919 StripLastDirectory(path, path);
922 GetFreeSpace(path, &avSize);
925 row.SetData(avField, avSize);
926 row.collapsed = true;
929 void AddOption(InstallOption option, InstallOption parent)
931 DataRow row = option.row = (parent != null) ? parent.row.AddRow() : optionsBox.AddRow();
932 row.SetData(null, CheckItem { option.name, option } );
933 optionsBox.SetCheck(row, option.selected);
934 if(option.subOptions)
937 for(c = 0; option.subOptions[c].name; c++)
939 AddOption(option.subOptions[c], option);
942 row.collapsed = true;
948 char programFilesDir[MAX_LOCATION];
949 char appData[MAX_LOCATION];
950 char homeDrive[MAX_LOCATION];
951 char winDir[MAX_LOCATION];
954 bool isAdministrator = IsAdministrator();
958 options[0].available = false;
959 options[0].selected = false;
962 // If the SDK is already installed, use currently selected language
964 IDESettings settings = null;
965 IDESettingsContainer settingsContainer
968 dataOwner = &settings;
969 dataClass = class(IDESettings);
970 allUsers = options[0].selected;
973 settingsContainer.Load();
975 if(settings.language)
977 String language = GetLanguageString();
978 if(settings.language.OnCompare(language))
980 // Relaunch the installer with previously selected language
981 LanguageRestart(settings.language, __thisModule.application, null, null, null, null, false);
985 delete settingsContainer;
989 GetEnvironment("HOMEDRIVE", homeDrive, sizeof(homeDrive));
990 GetEnvironment("windir", winDir, sizeof(winDir));
992 GetEnvironment(options[0].selected ? "ALLUSERSPROFILE" : "APPDATA", appData, sizeof(appData));
994 componentsBox.AddField(componentField);
995 componentsBox.AddField(locationField);
996 componentsBox.AddField(reqField);
997 componentsBox.AddField(avField);
999 optionsBox.AddField(optionField);
1001 languageBox.AddField(languageField);
1003 programFilesDir[0] = 0;
1004 if(GetEnvironment("ProgramFiles", programFilesDir, MAX_LOCATION))
1006 x86 = strstr(programFilesDir, " (x86)");
1011 if(isAdministrator && programFilesDir[0])
1015 strcpy(installDir32, programFilesDir);
1016 PathCat(installDir32, "Ecere SDK");
1018 strcpy(installDir, programFilesDir);
1019 PathCat(installDir, "Ecere SDK");
1023 strcpy(installDir, programFilesDir);
1024 PathCat(installDir, "Ecere SDK");
1025 strcpy(installDir32, installDir);
1028 else if(homeDrive && homeDrive[0])
1030 strcpy(installDir, homeDrive);
1031 PathCat(installDir, "Ecere SDK");
1032 strcpy(installDir32, installDir);
1033 strcat(installDir32, " (32)");
1035 else if(winDir && winDir[0])
1037 strcpy(installDir, winDir);
1038 PathCat(installDir, "..\\Ecere SDK");
1039 strcpy(installDir32, installDir);
1040 strcat(installDir32, " (32)");
1044 strcpy(installDir, "C:\\Ecere SDK");
1045 strcpy(installDir32, installDir);
1046 strcat(installDir32, " (32)");
1049 if(appData && appData[0])
1051 static char defSamplesPath[MAX_LOCATION];
1052 static char defExtrasPath[MAX_LOCATION];
1053 strcpy(defSamplesPath, appData);
1054 PathCat(defSamplesPath, "Ecere SDK\\Samples");
1055 components[ComponentID::samples].defInstallPath = defSamplesPath;
1057 strcpy(defExtrasPath, appData);
1058 PathCat(defExtrasPath, "Ecere SDK\\extras");
1059 additional[AdditionalID::extras].defInstallPath = defExtrasPath;
1062 destBox.path = installDir;
1066 for(c = 0; components[c].name; c++)
1067 AddComponent(components[c], null, installDir);
1070 // Compute size apart because ToggleCheck will change it
1074 for(c = 0; components[c].name; c++)
1075 totalSize += components[c].requiredSize;
1078 char sizeString[100];
1079 PrintSize(sizeString, totalSize, 2);
1080 totalSpaceValue.text = sizeString;
1082 for(c = 0; options[c].name; c++)
1084 if(options[c].available)
1085 AddOption(options[c], null);
1097 dotLbl.position.x = licenseButton.position.x + licenseButton.size.w - 4;
1103 // Constructor happens before Languages is instantiated...
1106 l.res = { l.bitmap, window = this };
1112 String language = GetLanguageString();
1116 // Try to find country-specific language first
1119 LanguageOption option = l;
1120 row = languageBox.AddRow();
1121 row.SetData(null, option); // TOFIX: l used directly here
1123 if(!found && (!strcmpi(l.code, language) || (!row.GetPrevRow() && !strcmpi("en", language))))
1125 languageBox.currentRow = row;
1130 // Try generalizing locale
1134 char genericLocale[256];
1135 strncpy(genericLocale, language, sizeof(genericLocale));
1136 genericLocale[sizeof(genericLocale)] = 0;
1138 under = strchr(genericLocale, '_');
1141 if(!strcmpi(genericLocale, "zh"))
1142 strcpy(genericLocale, "zh_CN");
1143 if(strcmp(genericLocale, language))
1145 row = languageBox.firstRow;
1148 if(!strcmpi(l.code, genericLocale) || (!row.GetPrevRow() && !strcmpi("en", genericLocale)))
1150 languageBox.currentRow = row;
1154 row = row.GetNextRow();
1160 languageBox.currentRow = languageBox.firstRow;
1168 void OnDrawOverChildren(Surface surface)
1170 int tw = label2.size.w;
1171 surface.SetForeground(Color { 128, 128, 128 });
1172 surface.HLine(label2.position.x + tw + 6, 620, 430);
1173 surface.SetForeground(white);
1174 surface.HLine(label2.position.x + tw + 6, 621, 431);
1175 surface.PutPixel(621, 400);
1179 parent = this, opacity = 0, borderStyle = deep, size = Size { 644, 93 }, anchor = Anchor { left = -8, top = -8 };
1183 class InstallProgress : Window
1185 text = $"Ecere Software Development Kit Setup - v0.44.10 \"Ryōan-ji\" 64 Bit Edition";
1186 background = activeBorder;
1187 borderStyle = fixed;
1191 // size = Size { 640, 480 };
1192 clientSize = { 636, 476 };
1193 //clientSize = { 796, 576 };
1194 icon = { ":icon.png" };
1196 Picture back { image = BitmapResource { ":ryoanji-progress.png" }, parent = this, position = { 0, 0 } };
1197 Label installing { this, position = { 32, 160 } };
1198 ProgressBar progressBar { parent = this, size = Size { 588, 24 }, anchor = Anchor { left = 24, top = 184 } };
1201 parent = this, text = $"Install", disabled = true, isDefault = true, size = Size { 75, 23 }, anchor = Anchor { left = 432, top = 440 };
1203 NotifyClicked = ButtonCloseDialog
1207 this, text = $"Cancel", hotKey = altX, size = Size { 75, 23 }, anchor = Anchor { left = 544, top = 440 };
1209 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
1211 abortInstall = true;
1217 inactive = true, noSelect = true,
1218 multiLine = true, parent = label3, opacity = 0, borderStyle = none, size = Size { 350, 35 }, anchor = Anchor { horz = 111, vert = 13 },
1219 contents = $"Please wait while the Ecere Software Development Kit is being installed."
1221 Label label2 { parent = this, text = buildString, position = { 16, 422 }, font = { "Tahoma", 10, true }, disabled = true, opacity = 0, background = activeBorder };
1224 image = BitmapResource { ":ecere.png", alphaBlend = true }, filter = true, parent = label3, anchor = Anchor { left = 16, top = 4 };
1225 cursor = ((GuiApplication)__thisModule).GetCursor(hand);
1227 bool OnLeftButtonDown(int x, int y, Modifiers mods)
1229 ShellOpen("http://www.ecere.com/");
1233 Label title { parent = label3, text = $"Installing the Ecere SDK", font = FontResource { "Tahoma", 8.25f, bold = true }, size = Size { 326, 16 }, anchor = Anchor { horz = 91, vert = -12 } };
1235 void OnDrawOverChildren(Surface surface)
1237 int tw = label2.size.w;
1238 surface.SetForeground(Color { 128, 128, 128 });
1239 surface.HLine(label2.position.x + tw + 6, 620, 430);
1240 surface.SetForeground(white);
1241 surface.HLine(label2.position.x + tw + 6, 621, 431);
1242 surface.PutPixel(621, 400);
1247 parent = this, opacity = 0, borderStyle = deep, size = Size { 644, 93 }, anchor = Anchor { left = -8, top = -8 };
1249 InstallThread thread
1254 Installer installer {};
1255 InstallProgress installProgress { autoCreate = false };
1257 static void AddPath(char * sysPaths[200], int sysCount, char * paths[200], int * count, char * oldPath, char * userPath, char * path)
1261 for(p = 0; p<sysCount; p++)
1262 if(!fstrcmp(sysPaths[p], path))
1267 for(p = 0; !found && p<*count; p++)
1268 if(!fstrcmp(paths[p], path))
1278 strcat(userPath, ";");
1279 start = paths[(*count)-1] + strlen(paths[(*count)-1])+1;
1284 strcpy(start, path);
1285 *(start + strlen(path)) = '\0';
1286 paths[(*count)++] = start;
1288 strcat(userPath, path);
1293 void ModifyPath(char * systemPath, char * userPath)
1295 char oldPath[8192], * paths[200], * sysPaths[200];
1296 int count, sysCount = 0;
1300 strcpy(oldPath, userPath);
1301 count = TokenizeWith(oldPath, sizeof(paths) / sizeof(char *), paths, ";", false);
1302 sysCount = TokenizeWith(systemPath, sizeof(sysPaths) / sizeof(char *), sysPaths, ";", false);
1306 strcpy(oldPath, systemPath);
1307 count = TokenizeWith(oldPath, sizeof(paths) / sizeof(char *), paths, ";", false);
1312 for(c = 0; coreSDK[c].name; c++)
1315 char path[MAX_LOCATION];
1316 if(!coreSDK[c].selected) continue;
1317 coreSDK[c].GetFullPath(path, false);
1318 if(c != ide && c != runtime && c != ec &&
1319 c != ide32 && c != runtime32 && c != ec32)
1321 if(!pathOptions[PathOptions::AddMinGWPaths].available || !pathOptions[PathOptions::AddMinGWPaths].selected)
1323 PathCat(path, "bin");
1325 else if(!pathOptions[PathOptions::AddECEREPaths].selected) continue;
1327 AddPath(sysPaths, sysCount, paths, &count, oldPath, userPath ? userPath : systemPath, path);
1333 for(c = 0; c <= cpp; c++)
1336 char path[MAX_LOCATION];
1337 if(!additional[c].selected || c == vanilla || c == vanilla32 || c == extras) continue;
1338 if((c != eda && c != eda32 && c != upx) && (!pathOptions[PathOptions::AddMinGWPaths].available || !pathOptions[PathOptions::AddMinGWPaths].selected))
1340 additional[c].GetFullPath(path, false);
1341 if(c != eda && c != eda32 && c != upx)
1342 PathCat(path, "bin");
1343 AddPath(sysPaths, sysCount, paths, &count, oldPath, userPath ? userPath : systemPath, path);
1348 void AssociateExtension(char * extension, char * description, char *name, char * action, char * path)
1354 RegCreateKeyEx(HKEY_CLASSES_ROOT, extension, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1355 RegSetValueEx(key, null, 0, REG_SZ, name, (uint)strlen(name)+1);
1358 RegCreateKeyEx(HKEY_CLASSES_ROOT, name, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1359 RegSetValueEx(key, null, 0, REG_SZ, description, (uint)strlen(description)+1);
1362 sprintf(keyName, "%s\\shell", extension);
1363 RegCreateKeyEx(HKEY_CLASSES_ROOT, keyName, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1364 RegSetValueEx(key, null, 0, REG_SZ, action, (uint)strlen(action)+1);
1367 sprintf(keyName, "%s\\shell\\%s", name, action);
1368 RegCreateKeyEx(HKEY_CLASSES_ROOT, keyName, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1371 sprintf(keyName, "%s\\shell\\%s\\command", name, action);
1372 RegCreateKeyEx(HKEY_CLASSES_ROOT, keyName, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1374 sprintf(keyName, path);
1375 strcat(keyName, " \"%L\"");
1377 uint16 wKeyName[2048];
1378 UTF8toUTF16Buffer(keyName, wKeyName, sizeof(wKeyName) / sizeof(uint16));
1379 RegSetValueExW(key, null, 0, REG_SZ, (byte *)wKeyName, (uint)(wcslen(wKeyName) + 1)*sizeof(uint16));
1384 class InstallThread : Thread
1389 ((GuiApplication)__thisModule).Lock();
1390 installProgress.progressBar.range = totalSize;
1393 strcpy(installDir32, installDir);
1395 for(c = 0; components[c].name && !abortInstall; c++)
1396 components[c].Install(installDir, installDir32);
1399 installProgress.progressBar.range = 0;
1400 installProgress.finish.Destroy(0);
1401 installProgress.cancel.text = $"Close";
1402 installProgress.cancel.isDefault = true;
1403 installProgress.cancel.disabled = false;
1404 installProgress.cancel.NotifyClicked = Window::ButtonCloseDialog;
1405 installProgress.installing.text = $"Installation Cancelled.";
1406 installProgress.title.text = $"Installation Cancelled";
1407 installProgress.titleInfo.contents = $"The installation was not completed.";
1411 char idePath[MAX_LOCATION];
1412 char userProfile[MAX_LOCATION];
1415 IDESettings settings = null; // Don't instantiate yet so we can pick up old settings
1417 IDESettingsContainer settingsContainer
1420 dataOwner = &settings;
1421 dataClass = class(IDESettings);
1422 allUsers = options[0].selected;
1424 CompilerConfig compiler;
1425 installProgress.installing.text = $"Configuring Ecere IDE...";
1426 ((GuiApplication)__thisModule).Unlock();
1427 ((GuiApplication)__thisModule).SignalEvent();
1429 settingsContainer.Load();
1430 compiler = settings.GetCompilerConfig(defaultCompilerName);
1435 for(c = 0; coreSDK[c].name; c++)
1437 char path[MAX_LOCATION];
1438 if(!coreSDK[c].selected || !coreSDK[c].available) continue;
1440 coreSDK[c].GetFullPath(path, false);
1441 if(c != ide && c != runtime && c != ec &&
1442 c != ide32 && c != runtime32 && c != ec32)
1443 PathCat(path, "bin");
1444 MakeSlashPath(path);
1445 if((c == ide && osIS64bit) || (c == ide32 && !osIS64bit))
1447 coreSDK[c].GetFullPath(idePath, false);
1448 PathCat(idePath, "ide.exe");
1451 if(c == runtime || c == runtime32)
1453 if(!compiler.libraryDirs.Find(path))
1454 compiler.libraryDirs.Add(CopyString(path));
1461 for(c = 0; c <= cpp; c++)
1463 char path[MAX_LOCATION];
1464 if(c == extras || !additional[c].selected || !additional[c].available) continue;
1465 additional[c].GetFullPath(path, false);
1466 if(c != upx && c != eda && c != vanilla && c != eda32 && c != vanilla32)
1467 PathCat(path, "bin");
1468 MakeSlashPath(path);
1469 if(c == vanilla || c == vanilla32)
1471 if(!compiler.libraryDirs.Find(path))
1472 compiler.libraryDirs.Add(CopyString(path));
1476 if(!compiler.executableDirs.Find(path))
1477 compiler.executableDirs.Add(CopyString(path));
1484 char path[MAX_LOCATION] = "";
1486 if(components[ComponentID::samples].selected)
1487 components[ComponentID::samples].GetFullPath(path, false);
1488 // IDE will now default to HOME for the default project/files locations
1490 if(!settings.ideProjectFileDialogLocation[0])
1491 settings.ideProjectFileDialogLocation = path;
1492 if(!settings.ideFileDialogLocation[0])
1493 settings.ideFileDialogLocation = path;
1495 if(documentation[DocumentationID::apiRef].selected)
1497 documentation[DocumentationID::apiRef].GetFullPath(path, false);
1498 if(!settings.docDir[0])
1499 settings.docDir = path;
1503 settings.language = GetLanguageString();
1505 // Set LANGUAGE environment variable
1508 uint16 wLanguage[256];
1512 if(options[0].selected)
1513 RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", 0, KEY_ALL_ACCESS, &key);
1515 RegCreateKeyEx(HKEY_CURRENT_USER, "Environment", 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1518 UTF8toUTF16Buffer(settings.language, wLanguage, sizeof(wLanguage) / sizeof(uint16));
1519 RegSetValueExW(key, L"ECERE_LANGUAGE", 0, REG_EXPAND_SZ, (byte *)wLanguage, (uint)(wcslen(wLanguage)+1) * 2);
1524 settingsContainer.Save();
1525 delete settingsContainer;
1528 // Set up Uninstaller
1529 ((GuiApplication)__thisModule).Lock();
1530 installProgress.installing.text = $"Registering uninstaller...";
1531 ((GuiApplication)__thisModule).Unlock();
1532 ((GuiApplication)__thisModule).SignalEvent();
1537 char * displayName = "Ecere SDK 0.44";
1538 char uninstaller[MAX_LOCATION];
1539 bool nomodify = true;
1541 strcpy(uninstaller, installDir);
1542 PathCat(uninstaller, "uninstall_ecere.exe");
1544 RegCreateKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Ecere SDK", 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1546 RegSetValueEx(key, "DisplayName", 0, REG_SZ, displayName, (uint)strlen(displayName)+1);
1547 RegSetValueEx(key, "UninstallString", 0, REG_SZ, uninstaller, (uint)strlen(uninstaller)+1);
1548 RegSetValueEx(key, "DisplayIcon", 0, REG_SZ, idePath, (uint)strlen(idePath)+1);
1549 //RegSetValueEx(key, "NoModify", 0, REG_DWORD, (byte *)&nomodify, sizeof(nomodify));
1550 //RegSetValueEx(key, "NoRepair", 0, REG_DWORD, (byte *)&nomodify, sizeof(nomodify));
1555 if(pathOptions[PathOptions::AddECEREPaths].selected
1557 || pathOptions[PathOptions::AddMinGWPaths].selected
1561 HKEY userKey = null, systemKey = null;
1563 char userPath[8192] = "";
1564 char systemPath[8192] = "";
1565 uint16 wUserPath[8192];
1566 uint16 wSystemPath[8192];
1571 ((GuiApplication)__thisModule).Lock();
1572 installProgress.installing.text = "Registering paths...";
1573 ((GuiApplication)__thisModule).Unlock();
1574 ((GuiApplication)__thisModule).SignalEvent();
1576 if(options[0].selected)
1578 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", 0, KEY_ALL_ACCESS, &systemKey) == ERROR_SUCCESS)
1580 size = sizeof(wSystemPath);
1581 RegQueryValueExW(systemKey, L"path", null, null, (byte *)wSystemPath, &size);
1582 UTF16toUTF8Buffer(wSystemPath, systemPath, sizeof(systemPath));
1583 ModifyPath(systemPath, null);
1585 UTF8toUTF16Buffer(systemPath, wSystemPath, sizeof(wSystemPath) / sizeof(uint16));
1586 RegSetValueExW(systemKey, L"path", 0, REG_EXPAND_SZ, (byte *)wSystemPath, (uint)(wcslen(wSystemPath)+1) * 2);
1587 RegCloseKey(systemKey);
1592 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", 0, KEY_QUERY_VALUE, &systemKey) == ERROR_SUCCESS)
1594 size = sizeof(wSystemPath);
1595 RegQueryValueExW(systemKey, L"path", null, null, (byte *)wSystemPath, &size);
1596 UTF16toUTF8Buffer(wSystemPath, systemPath, sizeof(systemPath));
1597 RegCloseKey(systemKey);
1600 RegCreateKeyEx(HKEY_CURRENT_USER, "Environment", 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &userKey, &status);
1601 if(status == REG_OPENED_EXISTING_KEY)
1603 size = sizeof(wUserPath);
1604 RegQueryValueExW(userKey, L"path", null, null, (byte *)wUserPath, &size);
1605 UTF16toUTF8Buffer(wUserPath, userPath, sizeof(userPath));
1607 ModifyPath(systemPath, userPath);
1608 UTF8toUTF16Buffer(userPath, wUserPath, sizeof(wUserPath) / sizeof(uint16));
1609 RegSetValueExW(userKey, L"path", 0, REG_EXPAND_SZ, (byte *)wUserPath, (uint)(wcslen(wUserPath)+1) * 2);
1610 RegCloseKey(userKey);
1612 // SendMessageTimeout (HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)"Environment", SMTO_NORMAL, 1000, NULL);
1615 // Install Program Group Icons
1616 GetEnvironment(options[0].selected ? "ALLUSERSPROFILE" : "USERPROFILE", userProfile, sizeof(userProfile));
1618 if(options[IconOptions::StartMenuIcon].selected)
1620 char destPath[MAX_LOCATION];
1621 char startMenuPath[MAX_LOCATION] = "";
1624 ((GuiApplication)__thisModule).Lock();
1625 installProgress.installing.text = $"Installing Start Menu Icons...";
1626 ((GuiApplication)__thisModule).Unlock();
1627 ((GuiApplication)__thisModule).SignalEvent();
1629 strcpy(destPath, userProfile);
1631 if(RegOpenKeyEx(options[0].selected ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
1632 "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", 0, KEY_QUERY_VALUE, &key) == ERROR_SUCCESS)
1634 uint16 wStartMenuPath[2048];
1635 uint size = sizeof(wStartMenuPath);
1636 // RegQueryValueEx(key, "Start Menu", null, null, startMenuPath, &size);
1637 RegQueryValueExW(key, options[0].selected ? L"Common Programs" : L"Programs", null, null, (byte *)wStartMenuPath, &size);
1638 UTF16toUTF8Buffer(wStartMenuPath, startMenuPath, sizeof(startMenuPath));
1641 if(!startMenuPath[0] && userProfile[0])
1643 strcpy(startMenuPath, userProfile);
1644 PathCat(startMenuPath, "Start Menu\\Programs");
1647 if(startMenuPath[0])
1649 strcpy(destPath, startMenuPath);
1650 PathCat(destPath, "Ecere SDK");
1653 strcpy(destPath, startMenuPath);
1654 PathCat(destPath, "Ecere SDK\\Ecere IDE.lnk");
1655 CreateLink(idePath, destPath, null); //"Ecere IDE");
1656 if(components[ComponentID::samples].selected)
1658 char samplesPath[MAX_LOCATION] = "";
1659 components[ComponentID::samples].GetFullPath(samplesPath, false);
1661 strcpy(destPath, startMenuPath);
1662 PathCat(destPath, "Ecere SDK\\Sample Projects.lnk");
1663 CreateLink(samplesPath, destPath, null);//"Sample Projects");
1665 if(components[ComponentID::documentation].selected && documentation[DocumentationID::ecereBook].selected)
1667 char docPath[MAX_LOCATION] = "";
1668 documentation[DocumentationID::ecereBook].GetFullPath(docPath, false);
1669 PathCat(docPath, "Ecere Tao of Programming [work in progress].pdf");
1672 char tao[MAX_LOCATION] ;
1673 documentation[DocumentationID::ecereBook].GetFullPath(tao, false);
1674 PathCat(tao, "tao.pdf");
1675 RenameFile(tao, docPath);
1678 strcpy(destPath, startMenuPath);
1679 PathCat(destPath, "Ecere SDK\\The Ecere Tao of Programming.lnk");
1680 CreateLink(docPath, destPath, null);
1685 // Install Desktop Icon
1686 if(options[IconOptions::DesktopIcon].selected)
1689 char desktopPath[MAX_LOCATION];
1691 if(RegOpenKeyEx(options[0].selected ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
1692 "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", 0, KEY_QUERY_VALUE, &key) == ERROR_SUCCESS)
1694 uint16 wDesktopPath[MAX_LOCATION];
1695 uint size = sizeof(wDesktopPath);
1696 RegQueryValueExW(key, options[0].selected ? L"Common Desktop" : L"Desktop", null, null, (byte *)wDesktopPath, &size);
1697 UTF16toUTF8Buffer(wDesktopPath, desktopPath, sizeof(desktopPath));
1700 if(!desktopPath[0] && userProfile[0])
1702 strcpy(desktopPath, userProfile);
1703 PathCat(desktopPath, "Desktop");
1708 PathCat(desktopPath, "Ecere IDE.lnk");
1710 ((GuiApplication)__thisModule).Lock();
1711 installProgress.installing.text = $"Installing Desktop Icon...";
1712 ((GuiApplication)__thisModule).Unlock();
1713 ((GuiApplication)__thisModule).SignalEvent();
1715 CreateLink(idePath, desktopPath, null);//"Ecere IDE");
1719 SendMessageTimeout (HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)"Environment", SMTO_NORMAL, 1000, NULL);
1721 // Install QuickLaunch Icon
1722 if(options[IconOptions::QuickLaunchIcon].selected)
1724 char appData[MAX_LOCATION];
1725 GetEnvironment("APPDATA", appData, sizeof(appData));
1728 char destPath[MAX_LOCATION];
1730 if(appData[0] && options[0].selected)
1732 char dir[MAX_FILENAME];
1733 GetLastDirectory(appData, dir);
1734 if(!strcmpi(dir, "Roaming"))
1735 PathCat(appData, "../../../Default/AppData/Roaming");
1737 PathCat(appData, "../Default");
1740 ((GuiApplication)__thisModule).Lock();
1741 installProgress.installing.text = $"Installing Quicklaunch Icon...";
1742 ((GuiApplication)__thisModule).Unlock();
1743 ((GuiApplication)__thisModule).SignalEvent();
1745 strcpy(destPath, appData);
1746 PathCat(destPath, "Microsoft\\Internet Explorer\\Quick Launch\\Ecere IDE.lnk");
1747 CreateLink(idePath, destPath, null);
1749 // Set it up on the dock for Windows 7 -- not working
1751 StripLastDirectory(destPath, destPath);
1752 PathCat(destPath, "User Pinned\\TaskBar");
1754 PathCat(destPath, "Ecere IDE.lnk");
1755 CreateLink(idePath, destPath, null);
1760 // Register File Types
1761 if(associateOptions[AssociateOptions::AssociateEPJ].selected ||
1762 associateOptions[AssociateOptions::AssociateEC].selected ||
1763 associateOptions[AssociateOptions::AssociateC].selected ||
1764 associateOptions[AssociateOptions::AssociateCPP].selected ||
1765 associateOptions[AssociateOptions::AssociateTXT].selected ||
1766 associateOptions[AssociateOptions::Associate3DS].selected ||
1767 associateOptions[AssociateOptions::AssociateIMG].selected)
1769 ((GuiApplication)__thisModule).Lock();
1770 installProgress.installing.text = $"Resgistering File Types...";
1771 ((GuiApplication)__thisModule).Unlock();
1772 ((GuiApplication)__thisModule).SignalEvent();
1774 if(associateOptions[AssociateOptions::AssociateEPJ].selected)
1776 AssociateExtension(".epj", "Ecere IDE Project", "epj_file", "Open", idePath);
1778 if(associateOptions[AssociateOptions::AssociateEC].selected)
1780 AssociateExtension(".ec", "eC Source File", "ec_file", "Open", idePath);
1781 AssociateExtension(".eh", "eC Header File", "eh_file", "Open", idePath);
1783 if(associateOptions[AssociateOptions::AssociateC].selected)
1785 AssociateExtension(".c", "C Source File", "c_file", "Open", idePath);
1786 AssociateExtension(".h", "C Header File", "h_file", "Open", idePath);
1788 if(associateOptions[AssociateOptions::AssociateCPP].selected)
1790 AssociateExtension(".cpp", "C++ Source File", "cpp_file", "Open", idePath);
1791 AssociateExtension(".cc", "C++ Source File", "cpp_file", "Open", idePath);
1792 AssociateExtension(".cxx", "C++ Source File", "cpp_file", "Open", idePath);
1793 AssociateExtension(".chh", "C++ Header File", "chh_file", "Open", idePath);
1794 AssociateExtension(".hh", "C++ Header File", "chh_file", "Open", idePath);
1795 AssociateExtension(".hxx", "C++ Header File", "chh_file", "Open", idePath);
1797 if(associateOptions[AssociateOptions::AssociateTXT].selected)
1799 AssociateExtension(".txt", "Text File", "txt_file", "Open", idePath);
1801 if(associateOptions[AssociateOptions::Associate3DS].selected)
1803 AssociateExtension(".3ds", "3D Studio Model", "3ds_file", "View", idePath);
1805 if(associateOptions[AssociateOptions::AssociateIMG].selected)
1807 AssociateExtension(".bmp", "BMP Image", "bmp_file", "View", idePath);
1808 AssociateExtension(".pcx", "PCX Image", "pcx_file", "View", idePath);
1809 AssociateExtension(".png", "PNG Image", "png_file", "View", idePath);
1810 AssociateExtension(".jpg", "JPEG Image", "jpg_file", "View", idePath);
1811 AssociateExtension(".jpeg", "JPEG Image", "jpg_file", "View", idePath);
1812 AssociateExtension(".gif", "GIF Image", "gif_file", "View", idePath);
1815 ((GuiApplication)__thisModule).Lock();
1817 installProgress.cancel.Destroy(0);
1818 installProgress.finish.text = $"Finish";
1819 installProgress.finish.disabled = false;
1820 installProgress.finish.Activate();
1821 installProgress.installing.text = $"Installation Complete.";
1822 installProgress.title.text = $"Installation Complete";
1823 installProgress.titleInfo.contents = $"Thank you for using the Ecere SDK.";
1825 ((GuiApplication)__thisModule).Unlock();