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,
480 selectionColor = { 145, 150, 140 };
485 bool NotifyKeyDown(ListBox listBox, DataRow row, Key key, unichar ch)
487 if(key == f2 && browse.visible)
488 browse.NotifyClicked(this, browse, 0, 0, 0);
492 bool NotifyChanged(ListBox listBox, DataRow row)
494 Component * component = ((CheckItem *)listBox.GetData(componentField))->data;
495 char path[MAX_LOCATION], relative[MAX_LOCATION] = "", * newPath;
496 char fullPath[MAX_LOCATION];
498 component->parent->GetFullPath(path, false);
499 strcpy(fullPath, path);
501 newPath = row.GetData(locationField);
504 PathCat(fullPath, newPath);
505 if(IsPathInsideOf(fullPath, path))
506 MakePathRelative(fullPath, path, relative);
508 strcpy(relative, fullPath);
510 listBox.SetData(locationField, relative);
511 strcpy(component->installPath, relative);
513 //SetAvailableSpace(component, path);
516 install.disabled = false;
517 for(c = 0; components[c].name; c++)
519 SetAvailableSpace(components[c], installDir);
525 bool NotifyEditDone(ListBox listBox, DataRow row)
531 bool NotifyEdited(ListBox listBox, DataRow row)
534 browse.parent = listBox;
535 browse.position = { componentField.width + locationField.width + 18, (listBox.currentIndex+1) * listBox.rowHeight - 2 };
536 browse.size = { 30, listBox.rowHeight + 3 };
537 for(e = listBox.firstChild; e; e = e.next)
539 if(e._class == class(DataBox))
548 void NotifyChecked(CheckListBox listBox, DataRow row)
550 Component * component = ((CheckItem *)row.GetData(componentField))->data;
552 component->selected = listBox.IsChecked(row);
554 if(!component->parent) totalSize -= component->requiredSize;
555 component->requiredSize = 0;
556 if(component->selected)
558 component->requiredSize += component->size;
559 if(component->subComponents)
560 for(c = 0; component->subComponents[c].name; c++)
561 component->requiredSize += component->subComponents[c].requiredSize;
563 if(component->requiredSize)
565 uint requiredSize = component->requiredSize;
566 row.SetData(reqField, requiredSize);
569 row.UnsetData(reqField);
570 if(!component->parent)
572 totalSize += component->requiredSize;
574 char sizeString[100];
575 PrintSize(sizeString, totalSize, 2);
576 totalSpaceValue.text = sizeString;
581 Label agreementLbl { parent = this, text = $"By installing the Ecere SDK, you agree to the", font = { "Tahoma", 8.25f }, anchor = Anchor { right = 399, top = 448 } };
584 this, inactive = true, offset = false, bevel = false, foreground = blue, font = { "Tahoma", 8.25f, underline = true, bold = true },
585 // text = $"terms and conditions", anchor = Anchor { left = 241, top = 421 };
586 text = $"terms and conditions", anchor = Anchor { left = 235, top = 445 };
587 cursor = ((GuiApplication)__thisModule).GetCursor(hand);
589 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
591 // LicenseBox { master = this, sourceFile = ":ecere-sdk/doc/LICENSE" }.Modal();
592 LicensesForm { master = this }.Modal();
596 Label dotLbl { parent = this, text = ".", font = { "Tahoma", 8.25f }, anchor = Anchor { left = 372, top = 448 } };
597 CheckListBox optionsBox
599 this, size = { 460, 114 }, position = { 160, 284 };
600 fullRowSelect = false, collapseControl = true, treeBranches = true, rootCollapseButton = true,
605 void NotifyChecked(CheckListBox listBox, DataRow row)
607 CheckItem * item = row.GetData(optionField);
608 InstallOption * option = item->data;
609 option->selected = listBox.IsChecked(row);
610 // Update default samples/extras path whether we're installing for All Users or not
611 if(option == &options[0])
613 char appData[MAX_LOCATION];
615 options[5].name = options[0].selected ? $"Add binaries location to the system environment paths" : $"Add binaries location to the user environment paths";
617 ((CheckItem *)options[5].row.GetData(optionField))->name = options[5].name;
619 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";
620 if(pathOptions[PathOptions::AddECEREPaths].row)
621 ((CheckItem *)pathOptions[PathOptions::AddECEREPaths].row.GetData(optionField))->name = pathOptions[PathOptions::AddECEREPaths].name;
623 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";
624 if(pathOptions[PathOptions::AddMinGWPaths].row)
625 ((CheckItem *)pathOptions[PathOptions::AddMinGWPaths].row.GetData(optionField))->name = pathOptions[PathOptions::AddMinGWPaths].name;
627 GetEnvironment(options[0].selected ? "ALLUSERSPROFILE" : "APPDATA", appData, sizeof(appData));
628 if(appData && appData[0])
630 char defPath[MAX_LOCATION];
632 char * s = components[ComponentID::samples].installPath;
633 strcpy(defPath, installDir);
634 PathCat(defPath, components[ComponentID::samples].defInstallPath);
635 ChangeCh(defPath, '/', DIR_SEP);
636 if(!strcmp(defPath, components[ComponentID::samples].installPath))
638 static char defSamplesPath[MAX_LOCATION];
639 strcpy(defSamplesPath, appData);
640 PathCat(defSamplesPath, "Ecere SDK\\Samples");
641 components[ComponentID::samples].defInstallPath = defSamplesPath;
643 strcpy(components[ComponentID::samples].installPath, components[ComponentID::samples].defInstallPath);
644 ChangeCh(components[ComponentID::samples].installPath, '/', DIR_SEP);
645 components[ComponentID::samples].row.SetData(locationField, components[ComponentID::samples].installPath);
648 strcpy(defPath, installDir);
649 PathCat(defPath, additional[AdditionalID::extras].defInstallPath);
650 ChangeCh(defPath, '/', DIR_SEP);
651 if(!strcmp(additional[AdditionalID::extras].installPath, additional[AdditionalID::extras].installPath))
653 static char defExtrasPath[MAX_LOCATION];
654 strcpy(defExtrasPath, appData);
655 PathCat(defExtrasPath, "Ecere SDK\\extras");
656 additional[AdditionalID::extras].defInstallPath = defExtrasPath;
658 strcpy(additional[AdditionalID::extras].installPath, additional[AdditionalID::extras].defInstallPath);
659 ChangeCh(additional[AdditionalID::extras].installPath, '/', DIR_SEP);
660 additional[AdditionalID::extras].row.SetData(locationField, additional[AdditionalID::extras].installPath);
668 parent = this, text = $"Install", isDefault = true, size = { 75, 23 }, position = { 432, 440 };
670 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
672 installProgress.Create();
674 // installProgress.thread.Main();
675 installProgress.thread.Create();
679 Button button3 { parent = this, text = $"Cancel", hotKey = altX, size = Size { 75, 23 }, anchor = Anchor { left = 544, top = 440 }, NotifyClicked = ButtonCloseDialog };
682 this, position = { 14, 374 }, size = { 142, 0 }, caption = "Language:";
684 bool NotifySelect(DropBox dropBox, DataRow row, Modifiers mods)
686 LanguageOption * option = row.GetData(null);
687 // If the language is already set, we need to override it
689 IDESettings settings = null;
690 IDESettingsContainer settingsContainer
693 dataOwner = &settings;
694 dataClass = class(IDESettings);
695 allUsers = options[0].selected;
697 settingsContainer.Load();
698 if(settings.language)
700 settings.language = option->code;
701 settingsContainer.Save();
703 delete settingsContainer;
706 ((GuiApplication)__thisModule.application).desktop.Destroy(0);
707 LanguageRestart(option->code, __thisModule.application, null, null, null, null, false);
711 Label lblLanguageBox { this, position = { 14, 354 }, labeledWindow = languageBox };
712 Label label1 { labeledWindow = destBox, tabCycle = true, isGroupBox = true, parent = this, inactive = false, size = Size { 458, 50 }, anchor = Anchor { left = 160, top = 96 } };
715 parent = label1, master = this, text = $" Destination Folder", size = Size { 336, 22 }, anchor = Anchor { left = 12, top = 20, right = 12 };
716 typeExpected = directory;
717 browseDialog = fileDialog;
720 bool NotifyModified(PathBox pathBox)
723 strcpy(installDir, destBox.path);
724 install.disabled = false;
725 for(c = 0; components[c].name; c++)
727 SetAvailableSpace(components[c], installDir);
734 label1, this, $"Browse", altB, size = { 83, 24 }, position = { 360, 16 };
736 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
738 strcpy(fileDialog.filePath, installDir);
739 StripLastDirectory(installDir, fileDialog.currentDirectory);
740 if(fileDialog.Modal())
742 strcpy(installDir, fileDialog.filePath);
743 destBox.contents = installDir;
744 // TOCHECK: Should setting contents call NotifyModified?
745 destBox.NotifyModified(destBox.master, destBox);
752 this, multiLine = true,
753 opacity = 0, borderStyle = none, inactive = true, size = { 136, 53 }, position = { 14, 96 }, noSelect = true,
754 contents = $"Select the default root\n"
755 "folder where to install\n"
760 this, opacity = 0, borderStyle = none, inactive = true, size = { 136, 132 }, position = { 14, 152 }, noSelect = true,
762 contents = $"Select the optional\n"
763 "components you wish\n"
765 "You may customize the\n"
766 "install location for each\n"
767 "of them, or use the default\n"
768 "based on the main\n"
769 "destination folder."
773 this, opacity = 0, borderStyle = none, inactive = true, size = { 136, 83 }, position = { 14, 280 }, noSelect = true,
775 contents = $"Select icons to install, file\n"
776 "associations, and system\n"
777 "environment modifications:"
779 Label totalSpaceLabel
781 this, anchor = { right = 72, top = 404 }, text = $"Space Required: "
783 Label totalSpaceValue
785 this, anchor = { right = 14, top = 404 }, text = "0 mb"
789 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"
790 "of the SDK to install, as well as where to install program icons."
792 Label label2 { parent = this, text = buildString, position = { 16, 422 }, font = { "Tahoma", 10, true }, disabled = true, opacity = 0, background = activeBorder };
795 image = BitmapResource { ":ecere.png", alphaBlend = true }, filter = true, parent = label3, text = "picture1", anchor = Anchor { left = 16, top = 4 };
796 cursor = ((GuiApplication)__thisModule).GetCursor(hand);
798 bool OnLeftButtonDown(int x, int y, Modifiers mods)
800 ShellOpen("http://www.ecere.com/");
804 Label label4 { label3, font = { "Tahoma", 8.25f, bold = true }, /*size = { 326, 16 }, */position = { 248, 24 }, text = $"Choose Components, Locations and Install Options" };
805 DataField componentField { "CheckItem", width = 160, header = $"Component" };
806 DataField locationField { "char *", width = 108, header = $"Destination Folder", editable = true };
807 DataField reqField { "FileSize", width = 70, header = $"Req. Space", alignment = right };
808 DataField avField { "FileSize64", width = 70, header = $"Avail. Space", alignment = right };
809 DataField optionField { "CheckItem" };
811 DataField languageField { class(LanguageOption) };
813 void SetAvailableSpace(Component component, char * parentPath)
815 char path[MAX_LOCATION];
819 strcpy(path, parentPath);
820 PathCat(path, component.installPath);
822 if(component.subComponents)
823 for(c = 0; component.subComponents[c].name; c++)
824 SetAvailableSpace(component.subComponents[c], path);
826 while(!FileExists(path) && path[0])
827 StripLastDirectory(path, path);
830 GetFreeSpace(path, &size);
831 component.row.SetData(avField, size);
832 if(!size) install.disabled = true;
835 FileSize ComputeSize(char * path)
838 FileAttribs attribs = FileExists(path);
839 if(attribs.isDirectory)
841 FileListing listing { path };
842 while(listing.Find())
844 if(listing.stats.attribs.isDirectory)
845 size += ComputeSize(listing.path);
847 size += listing.stats.size;
851 FileGetSize(path, &size);
855 void AddComponent(Component component, Component parent, char * parentPath)
857 DataRow row = (parent != null) ? parent.row.AddRow() : componentsBox.AddRow();
859 FileSize64 avSize = 0;
860 char path[MAX_LOCATION];
863 strcpy(path, parentPath);
864 if(component.defInstallPath)
865 PathCat(path, component.defInstallPath);
866 component.parent = parent;
868 row.SetData(null, CheckItem { component.name, component, (component.arch == bits32 && osIS64bit) } );
870 if(component.defInstallPath)
872 strcpy(component.installPath, component.defInstallPath);
873 ChangeCh(component.installPath, '/', DIR_SEP);
874 row.SetData(locationField, component.installPath);
877 if(component.mandatory)
879 if(component.arch != bits32 || !osIS64bit) // || component == &coreSDK[gdb32])
880 componentsBox.SetDisabled(row, true);
882 component.selected = false;*/
884 else if(component.arch == bits32 && osIS64bit)
885 ; //component.selected = false;
887 componentsBox.SetCheck(row, component.selected);
889 if(component.dataPath)
891 char path[MAX_LOCATION];
893 PathCat(path, component.dataPath);
894 component.size = ComputeSize(path);
896 if(component.subComponents)
899 for(c = 0; component.subComponents[c].name; c++)
901 Component * sub = &component.subComponents[c];
902 if(sub->available && (osIS64bit || sub->arch == bits32 || sub->arch == none))
904 AddComponent(sub, component, path);
905 size += sub->requiredSize;
908 sub->selected = false;
912 component.requiredSize = component.selected ? (size + component.size) : 0;
913 if(component.requiredSize)
914 row.SetData(reqField, component.requiredSize);
916 while(!FileExists(path) && path[0])
917 StripLastDirectory(path, path);
920 GetFreeSpace(path, &avSize);
923 row.SetData(avField, avSize);
924 row.collapsed = true;
927 void AddOption(InstallOption option, InstallOption parent)
929 DataRow row = option.row = (parent != null) ? parent.row.AddRow() : optionsBox.AddRow();
930 row.SetData(null, CheckItem { option.name, option } );
931 optionsBox.SetCheck(row, option.selected);
932 if(option.subOptions)
935 for(c = 0; option.subOptions[c].name; c++)
937 AddOption(option.subOptions[c], option);
940 row.collapsed = true;
946 char programFilesDir[MAX_LOCATION];
947 char appData[MAX_LOCATION];
948 char homeDrive[MAX_LOCATION];
949 char winDir[MAX_LOCATION];
952 bool isAdministrator = IsAdministrator();
956 options[0].available = false;
957 options[0].selected = false;
960 // If the SDK is already installed, use currently selected language
962 IDESettings settings = null;
963 IDESettingsContainer settingsContainer
966 dataOwner = &settings;
967 dataClass = class(IDESettings);
968 allUsers = options[0].selected;
971 settingsContainer.Load();
973 if(settings.language)
975 String language = GetLanguageString();
976 if(settings.language.OnCompare(language))
978 // Relaunch the installer with previously selected language
979 LanguageRestart(settings.language, __thisModule.application, null, null, null, null, false);
983 delete settingsContainer;
987 GetEnvironment("HOMEDRIVE", homeDrive, sizeof(homeDrive));
988 GetEnvironment("windir", winDir, sizeof(winDir));
990 GetEnvironment(options[0].selected ? "ALLUSERSPROFILE" : "APPDATA", appData, sizeof(appData));
992 componentsBox.AddField(componentField);
993 componentsBox.AddField(locationField);
994 componentsBox.AddField(reqField);
995 componentsBox.AddField(avField);
997 optionsBox.AddField(optionField);
999 languageBox.AddField(languageField);
1001 programFilesDir[0] = 0;
1002 if(GetEnvironment("ProgramFiles", programFilesDir, MAX_LOCATION))
1004 x86 = strstr(programFilesDir, " (x86)");
1009 if(isAdministrator && programFilesDir[0])
1013 strcpy(installDir32, programFilesDir);
1014 PathCat(installDir32, "Ecere SDK");
1016 strcpy(installDir, programFilesDir);
1017 PathCat(installDir, "Ecere SDK");
1021 strcpy(installDir, programFilesDir);
1022 PathCat(installDir, "Ecere SDK");
1023 strcpy(installDir32, installDir);
1026 else if(homeDrive && homeDrive[0])
1028 strcpy(installDir, homeDrive);
1029 PathCat(installDir, "Ecere SDK");
1030 strcpy(installDir32, installDir);
1031 strcat(installDir32, " (32)");
1033 else if(winDir && winDir[0])
1035 strcpy(installDir, winDir);
1036 PathCat(installDir, "..\\Ecere SDK");
1037 strcpy(installDir32, installDir);
1038 strcat(installDir32, " (32)");
1042 strcpy(installDir, "C:\\Ecere SDK");
1043 strcpy(installDir32, installDir);
1044 strcat(installDir32, " (32)");
1047 if(appData && appData[0])
1049 static char defSamplesPath[MAX_LOCATION];
1050 static char defExtrasPath[MAX_LOCATION];
1051 strcpy(defSamplesPath, appData);
1052 PathCat(defSamplesPath, "Ecere SDK\\Samples");
1053 components[ComponentID::samples].defInstallPath = defSamplesPath;
1055 strcpy(defExtrasPath, appData);
1056 PathCat(defExtrasPath, "Ecere SDK\\extras");
1057 additional[AdditionalID::extras].defInstallPath = defExtrasPath;
1060 destBox.path = installDir;
1064 for(c = 0; components[c].name; c++)
1065 AddComponent(components[c], null, installDir);
1068 // Compute size apart because ToggleCheck will change it
1072 for(c = 0; components[c].name; c++)
1073 totalSize += components[c].requiredSize;
1076 char sizeString[100];
1077 PrintSize(sizeString, totalSize, 2);
1078 totalSpaceValue.text = sizeString;
1080 for(c = 0; options[c].name; c++)
1082 if(options[c].available)
1083 AddOption(options[c], null);
1095 dotLbl.position.x = licenseButton.position.x + licenseButton.size.w - 4;
1101 // Constructor happens before Languages is instantiated...
1104 l.res = { l.bitmap, window = this };
1110 String language = GetLanguageString();
1113 LanguageOption option = l;
1114 DataRow row = languageBox.AddRow();
1115 row.SetData(null, option); // TOFIX: l used directly here
1116 if(!language.OnCompare(l.code))
1117 languageBox.currentRow = row;
1119 if(!languageBox.currentRow)
1120 languageBox.currentRow = languageBox.firstRow;
1128 void OnDrawOverChildren(Surface surface)
1130 int tw = label2.size.w;
1131 surface.SetForeground(Color { 128, 128, 128 });
1132 surface.HLine(label2.position.x + tw + 6, 620, 430);
1133 surface.SetForeground(white);
1134 surface.HLine(label2.position.x + tw + 6, 621, 431);
1135 surface.PutPixel(621, 400);
1139 parent = this, opacity = 0, borderStyle = deep, size = Size { 644, 93 }, anchor = Anchor { left = -8, top = -8 };
1143 class InstallProgress : Window
1145 text = $"Ecere Software Development Kit Setup - v0.44.10 \"Ryōan-ji\" 64 Bit Edition";
1146 background = activeBorder;
1147 borderStyle = fixed;
1151 // size = Size { 640, 480 };
1152 clientSize = { 636, 476 };
1153 //clientSize = { 796, 576 };
1154 icon = { ":icon.png" };
1156 Picture back { image = BitmapResource { ":ryoanji-progress.png" }, parent = this, position = { 0, 0 } };
1157 Label installing { this, position = { 32, 160 } };
1158 ProgressBar progressBar { parent = this, size = Size { 588, 24 }, anchor = Anchor { left = 24, top = 184 } };
1161 parent = this, text = $"Install", disabled = true, isDefault = true, size = Size { 75, 23 }, anchor = Anchor { left = 432, top = 440 };
1163 NotifyClicked = ButtonCloseDialog
1167 this, text = $"Cancel", hotKey = altX, size = Size { 75, 23 }, anchor = Anchor { left = 544, top = 440 };
1169 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
1171 abortInstall = true;
1177 inactive = true, noSelect = true,
1178 multiLine = true, parent = label3, opacity = 0, borderStyle = none, size = Size { 350, 35 }, anchor = Anchor { horz = 111, vert = 13 },
1179 contents = $"Please wait while the Ecere Software Development Kit is being installed."
1181 Label label2 { parent = this, text = buildString, position = { 16, 422 }, font = { "Tahoma", 10, true }, disabled = true, opacity = 0, background = activeBorder };
1184 image = BitmapResource { ":ecere.png", alphaBlend = true }, filter = true, parent = label3, anchor = Anchor { left = 16, top = 4 };
1185 cursor = ((GuiApplication)__thisModule).GetCursor(hand);
1187 bool OnLeftButtonDown(int x, int y, Modifiers mods)
1189 ShellOpen("http://www.ecere.com/");
1193 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 } };
1195 void OnDrawOverChildren(Surface surface)
1197 int tw = label2.size.w;
1198 surface.SetForeground(Color { 128, 128, 128 });
1199 surface.HLine(label2.position.x + tw + 6, 620, 430);
1200 surface.SetForeground(white);
1201 surface.HLine(label2.position.x + tw + 6, 621, 431);
1202 surface.PutPixel(621, 400);
1207 parent = this, opacity = 0, borderStyle = deep, size = Size { 644, 93 }, anchor = Anchor { left = -8, top = -8 };
1209 InstallThread thread
1214 Installer installer {};
1215 InstallProgress installProgress { autoCreate = false };
1217 static void AddPath(char * sysPaths[200], int sysCount, char * paths[200], int * count, char * oldPath, char * userPath, char * path)
1221 for(p = 0; p<sysCount; p++)
1222 if(!fstrcmp(sysPaths[p], path))
1227 for(p = 0; !found && p<*count; p++)
1228 if(!fstrcmp(paths[p], path))
1238 strcat(userPath, ";");
1239 start = paths[(*count)-1] + strlen(paths[(*count)-1])+1;
1244 strcpy(start, path);
1245 *(start + strlen(path)) = '\0';
1246 paths[(*count)++] = start;
1248 strcat(userPath, path);
1253 void ModifyPath(char * systemPath, char * userPath)
1255 char oldPath[8192], * paths[200], * sysPaths[200];
1256 int count, sysCount = 0;
1260 strcpy(oldPath, userPath);
1261 count = TokenizeWith(oldPath, sizeof(paths) / sizeof(char *), paths, ";", false);
1262 sysCount = TokenizeWith(systemPath, sizeof(sysPaths) / sizeof(char *), sysPaths, ";", false);
1266 strcpy(oldPath, systemPath);
1267 count = TokenizeWith(oldPath, sizeof(paths) / sizeof(char *), paths, ";", false);
1272 for(c = 0; coreSDK[c].name; c++)
1275 char path[MAX_LOCATION];
1276 if(!coreSDK[c].selected) continue;
1277 coreSDK[c].GetFullPath(path, false);
1278 if(c != ide && c != runtime && c != ec &&
1279 c != ide32 && c != runtime32 && c != ec32)
1281 if(!pathOptions[PathOptions::AddMinGWPaths].available || !pathOptions[PathOptions::AddMinGWPaths].selected)
1283 PathCat(path, "bin");
1285 else if(!pathOptions[PathOptions::AddECEREPaths].selected) continue;
1287 AddPath(sysPaths, sysCount, paths, &count, oldPath, userPath ? userPath : systemPath, path);
1293 for(c = 0; c <= cpp; c++)
1296 char path[MAX_LOCATION];
1297 if(!additional[c].selected || c == vanilla || c == vanilla32 || c == extras) continue;
1298 if((c != eda && c != eda32 && c != upx) && (!pathOptions[PathOptions::AddMinGWPaths].available || !pathOptions[PathOptions::AddMinGWPaths].selected))
1300 additional[c].GetFullPath(path, false);
1301 if(c != eda && c != eda32 && c != upx)
1302 PathCat(path, "bin");
1303 AddPath(sysPaths, sysCount, paths, &count, oldPath, userPath ? userPath : systemPath, path);
1308 void AssociateExtension(char * extension, char * description, char *name, char * action, char * path)
1314 RegCreateKeyEx(HKEY_CLASSES_ROOT, extension, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1315 RegSetValueEx(key, null, 0, REG_SZ, name, (uint)strlen(name)+1);
1318 RegCreateKeyEx(HKEY_CLASSES_ROOT, name, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1319 RegSetValueEx(key, null, 0, REG_SZ, description, (uint)strlen(description)+1);
1322 sprintf(keyName, "%s\\shell", extension);
1323 RegCreateKeyEx(HKEY_CLASSES_ROOT, keyName, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1324 RegSetValueEx(key, null, 0, REG_SZ, action, (uint)strlen(action)+1);
1327 sprintf(keyName, "%s\\shell\\%s", name, action);
1328 RegCreateKeyEx(HKEY_CLASSES_ROOT, keyName, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1331 sprintf(keyName, "%s\\shell\\%s\\command", name, action);
1332 RegCreateKeyEx(HKEY_CLASSES_ROOT, keyName, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1334 sprintf(keyName, path);
1335 strcat(keyName, " \"%L\"");
1337 uint16 wKeyName[2048];
1338 UTF8toUTF16Buffer(keyName, wKeyName, sizeof(wKeyName) / sizeof(uint16));
1339 RegSetValueExW(key, null, 0, REG_SZ, (byte *)wKeyName, (uint)(wcslen(wKeyName) + 1)*sizeof(uint16));
1344 class InstallThread : Thread
1349 ((GuiApplication)__thisModule).Lock();
1350 installProgress.progressBar.range = totalSize;
1353 strcpy(installDir32, installDir);
1355 for(c = 0; components[c].name && !abortInstall; c++)
1356 components[c].Install(installDir, installDir32);
1359 installProgress.progressBar.range = 0;
1360 installProgress.finish.Destroy(0);
1361 installProgress.cancel.text = $"Close";
1362 installProgress.cancel.isDefault = true;
1363 installProgress.cancel.disabled = false;
1364 installProgress.cancel.NotifyClicked = Window::ButtonCloseDialog;
1365 installProgress.installing.text = $"Installation Cancelled.";
1366 installProgress.title.text = $"Installation Cancelled";
1367 installProgress.titleInfo.contents = $"The installation was not completed.";
1371 char idePath[MAX_LOCATION];
1372 char userProfile[MAX_LOCATION];
1375 IDESettings settings = null; // Don't instantiate yet so we can pick up old settings
1377 IDESettingsContainer settingsContainer
1380 dataOwner = &settings;
1381 dataClass = class(IDESettings);
1382 allUsers = options[0].selected;
1384 CompilerConfig compiler;
1385 installProgress.installing.text = $"Configuring Ecere IDE...";
1386 ((GuiApplication)__thisModule).Unlock();
1387 ((GuiApplication)__thisModule).SignalEvent();
1389 settingsContainer.Load();
1390 compiler = settings.GetCompilerConfig(defaultCompilerName);
1395 for(c = 0; coreSDK[c].name; c++)
1397 char path[MAX_LOCATION];
1398 if(!coreSDK[c].selected || !coreSDK[c].available) continue;
1400 coreSDK[c].GetFullPath(path, false);
1401 if(c != ide && c != runtime && c != ec &&
1402 c != ide32 && c != runtime32 && c != ec32)
1403 PathCat(path, "bin");
1404 MakeSlashPath(path);
1405 if((c == ide && osIS64bit) || (c == ide32 && !osIS64bit))
1407 coreSDK[c].GetFullPath(idePath, false);
1408 PathCat(idePath, "ide.exe");
1411 if(c == runtime || c == runtime32)
1413 if(!compiler.libraryDirs.Find(path))
1414 compiler.libraryDirs.Add(CopyString(path));
1421 for(c = 0; c <= cpp; c++)
1423 char path[MAX_LOCATION];
1424 if(c == extras || !additional[c].selected || !additional[c].available) continue;
1425 additional[c].GetFullPath(path, false);
1426 if(c != upx && c != eda && c != vanilla && c != eda32 && c != vanilla32)
1427 PathCat(path, "bin");
1428 MakeSlashPath(path);
1429 if(c == vanilla || c == vanilla32)
1431 if(!compiler.libraryDirs.Find(path))
1432 compiler.libraryDirs.Add(CopyString(path));
1436 if(!compiler.executableDirs.Find(path))
1437 compiler.executableDirs.Add(CopyString(path));
1444 char path[MAX_LOCATION] = "";
1446 if(components[ComponentID::samples].selected)
1447 components[ComponentID::samples].GetFullPath(path, false);
1448 // IDE will now default to HOME for the default project/files locations
1450 if(!settings.ideProjectFileDialogLocation[0])
1451 settings.ideProjectFileDialogLocation = path;
1452 if(!settings.ideFileDialogLocation[0])
1453 settings.ideFileDialogLocation = path;
1455 if(documentation[DocumentationID::apiRef].selected)
1457 documentation[DocumentationID::apiRef].GetFullPath(path, false);
1458 if(!settings.docDir[0])
1459 settings.docDir = path;
1463 settings.language = GetLanguageString();
1465 settingsContainer.Save();
1466 delete settingsContainer;
1469 // Set up Uninstaller
1470 ((GuiApplication)__thisModule).Lock();
1471 installProgress.installing.text = $"Registering uninstaller...";
1472 ((GuiApplication)__thisModule).Unlock();
1473 ((GuiApplication)__thisModule).SignalEvent();
1478 char * displayName = "Ecere SDK 0.44";
1479 char uninstaller[MAX_LOCATION];
1480 bool nomodify = true;
1482 strcpy(uninstaller, installDir);
1483 PathCat(uninstaller, "uninstall_ecere.exe");
1485 RegCreateKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Ecere SDK", 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1487 RegSetValueEx(key, "DisplayName", 0, REG_SZ, displayName, (uint)strlen(displayName)+1);
1488 RegSetValueEx(key, "UninstallString", 0, REG_SZ, uninstaller, (uint)strlen(uninstaller)+1);
1489 RegSetValueEx(key, "DisplayIcon", 0, REG_SZ, idePath, (uint)strlen(idePath)+1);
1490 //RegSetValueEx(key, "NoModify", 0, REG_DWORD, (byte *)&nomodify, sizeof(nomodify));
1491 //RegSetValueEx(key, "NoRepair", 0, REG_DWORD, (byte *)&nomodify, sizeof(nomodify));
1496 if(pathOptions[PathOptions::AddECEREPaths].selected
1498 || pathOptions[PathOptions::AddMinGWPaths].selected
1502 HKEY userKey = null, systemKey = null;
1504 char userPath[8192] = "";
1505 char systemPath[8192] = "";
1506 uint16 wUserPath[8192];
1507 uint16 wSystemPath[8192];
1512 ((GuiApplication)__thisModule).Lock();
1513 installProgress.installing.text = "Registering paths...";
1514 ((GuiApplication)__thisModule).Unlock();
1515 ((GuiApplication)__thisModule).SignalEvent();
1517 if(options[0].selected)
1519 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", 0, KEY_ALL_ACCESS, &systemKey) == ERROR_SUCCESS)
1521 size = sizeof(wSystemPath);
1522 RegQueryValueExW(systemKey, L"path", null, null, (byte *)wSystemPath, &size);
1523 UTF16toUTF8Buffer(wSystemPath, systemPath, sizeof(systemPath));
1524 ModifyPath(systemPath, null);
1526 UTF8toUTF16Buffer(systemPath, wSystemPath, sizeof(wSystemPath) / sizeof(uint16));
1527 RegSetValueExW(systemKey, L"path", 0, REG_EXPAND_SZ, (byte *)wSystemPath, (uint)(wcslen(wSystemPath)+1) * 2);
1528 RegCloseKey(systemKey);
1533 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", 0, KEY_QUERY_VALUE, &systemKey) == ERROR_SUCCESS)
1535 size = sizeof(wSystemPath);
1536 RegQueryValueExW(systemKey, L"path", null, null, (byte *)wSystemPath, &size);
1537 UTF16toUTF8Buffer(wSystemPath, systemPath, sizeof(systemPath));
1538 RegCloseKey(systemKey);
1541 RegCreateKeyEx(HKEY_CURRENT_USER, "Environment", 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &userKey, &status);
1542 if(status == REG_OPENED_EXISTING_KEY)
1544 size = sizeof(wUserPath);
1545 RegQueryValueExW(userKey, L"path", null, null, (byte *)wUserPath, &size);
1546 UTF16toUTF8Buffer(wUserPath, userPath, sizeof(userPath));
1548 ModifyPath(systemPath, userPath);
1549 UTF8toUTF16Buffer(userPath, wUserPath, sizeof(wUserPath) / sizeof(uint16));
1550 RegSetValueExW(userKey, L"path", 0, REG_EXPAND_SZ, (byte *)wUserPath, (uint)(wcslen(wUserPath)+1) * 2);
1551 RegCloseKey(userKey);
1553 SendMessageTimeout (HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)"Environment", SMTO_NORMAL, 1000, NULL);
1556 // Install Program Group Icons
1557 GetEnvironment(options[0].selected ? "ALLUSERSPROFILE" : "USERPROFILE", userProfile, sizeof(userProfile));
1559 if(options[IconOptions::StartMenuIcon].selected)
1561 char destPath[MAX_LOCATION];
1562 char startMenuPath[MAX_LOCATION] = "";
1565 ((GuiApplication)__thisModule).Lock();
1566 installProgress.installing.text = $"Installing Start Menu Icons...";
1567 ((GuiApplication)__thisModule).Unlock();
1568 ((GuiApplication)__thisModule).SignalEvent();
1570 strcpy(destPath, userProfile);
1572 if(RegOpenKeyEx(options[0].selected ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
1573 "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", 0, KEY_QUERY_VALUE, &key) == ERROR_SUCCESS)
1575 uint16 wStartMenuPath[2048];
1576 uint size = sizeof(wStartMenuPath);
1577 // RegQueryValueEx(key, "Start Menu", null, null, startMenuPath, &size);
1578 RegQueryValueExW(key, options[0].selected ? L"Common Programs" : L"Programs", null, null, (byte *)wStartMenuPath, &size);
1579 UTF16toUTF8Buffer(wStartMenuPath, startMenuPath, sizeof(startMenuPath));
1582 if(!startMenuPath[0] && userProfile[0])
1584 strcpy(startMenuPath, userProfile);
1585 PathCat(startMenuPath, "Start Menu\\Programs");
1588 if(startMenuPath[0])
1590 strcpy(destPath, startMenuPath);
1591 PathCat(destPath, "Ecere SDK");
1594 strcpy(destPath, startMenuPath);
1595 PathCat(destPath, "Ecere SDK\\Ecere IDE.lnk");
1596 CreateLink(idePath, destPath, null); //"Ecere IDE");
1597 if(components[ComponentID::samples].selected)
1599 char samplesPath[MAX_LOCATION] = "";
1600 components[ComponentID::samples].GetFullPath(samplesPath, false);
1602 strcpy(destPath, startMenuPath);
1603 PathCat(destPath, "Ecere SDK\\Sample Projects.lnk");
1604 CreateLink(samplesPath, destPath, null);//"Sample Projects");
1606 if(components[ComponentID::documentation].selected && documentation[DocumentationID::ecereBook].selected)
1608 char docPath[MAX_LOCATION] = "";
1609 documentation[DocumentationID::ecereBook].GetFullPath(docPath, false);
1610 PathCat(docPath, "Ecere Tao of Programming [work in progress].pdf");
1613 char tao[MAX_LOCATION] ;
1614 documentation[DocumentationID::ecereBook].GetFullPath(tao, false);
1615 PathCat(tao, "tao.pdf");
1616 RenameFile(tao, docPath);
1619 strcpy(destPath, startMenuPath);
1620 PathCat(destPath, "Ecere SDK\\The Ecere Tao of Programming.lnk");
1621 CreateLink(docPath, destPath, null);
1626 // Install Desktop Icon
1627 if(options[IconOptions::DesktopIcon].selected)
1630 char desktopPath[MAX_LOCATION];
1632 if(RegOpenKeyEx(options[0].selected ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
1633 "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", 0, KEY_QUERY_VALUE, &key) == ERROR_SUCCESS)
1635 uint16 wDesktopPath[MAX_LOCATION];
1636 uint size = sizeof(wDesktopPath);
1637 RegQueryValueExW(key, options[0].selected ? L"Common Desktop" : L"Desktop", null, null, (byte *)wDesktopPath, &size);
1638 UTF16toUTF8Buffer(wDesktopPath, desktopPath, sizeof(desktopPath));
1641 if(!desktopPath[0] && userProfile[0])
1643 strcpy(desktopPath, userProfile);
1644 PathCat(desktopPath, "Desktop");
1649 PathCat(desktopPath, "Ecere IDE.lnk");
1651 ((GuiApplication)__thisModule).Lock();
1652 installProgress.installing.text = $"Installing Desktop Icon...";
1653 ((GuiApplication)__thisModule).Unlock();
1654 ((GuiApplication)__thisModule).SignalEvent();
1656 CreateLink(idePath, desktopPath, null);//"Ecere IDE");
1660 // Install QuickLaunch Icon
1661 if(options[IconOptions::QuickLaunchIcon].selected)
1663 char appData[MAX_LOCATION];
1664 GetEnvironment("APPDATA", appData, sizeof(appData));
1667 char destPath[MAX_LOCATION];
1669 if(appData[0] && options[0].selected)
1671 char dir[MAX_FILENAME];
1672 GetLastDirectory(appData, dir);
1673 if(!strcmpi(dir, "Roaming"))
1674 PathCat(appData, "../../../Default/AppData/Roaming");
1676 PathCat(appData, "../Default");
1679 ((GuiApplication)__thisModule).Lock();
1680 installProgress.installing.text = $"Installing Quicklaunch Icon...";
1681 ((GuiApplication)__thisModule).Unlock();
1682 ((GuiApplication)__thisModule).SignalEvent();
1684 strcpy(destPath, appData);
1685 PathCat(destPath, "Microsoft\\Internet Explorer\\Quick Launch\\Ecere IDE.lnk");
1686 CreateLink(idePath, destPath, null);
1688 // Set it up on the dock for Windows 7 -- not working
1690 StripLastDirectory(destPath, destPath);
1691 PathCat(destPath, "User Pinned\\TaskBar");
1693 PathCat(destPath, "Ecere IDE.lnk");
1694 CreateLink(idePath, destPath, null);
1699 // Register File Types
1700 if(associateOptions[AssociateOptions::AssociateEPJ].selected ||
1701 associateOptions[AssociateOptions::AssociateEC].selected ||
1702 associateOptions[AssociateOptions::AssociateC].selected ||
1703 associateOptions[AssociateOptions::AssociateCPP].selected ||
1704 associateOptions[AssociateOptions::AssociateTXT].selected ||
1705 associateOptions[AssociateOptions::Associate3DS].selected ||
1706 associateOptions[AssociateOptions::AssociateIMG].selected)
1708 ((GuiApplication)__thisModule).Lock();
1709 installProgress.installing.text = $"Resgistering File Types...";
1710 ((GuiApplication)__thisModule).Unlock();
1711 ((GuiApplication)__thisModule).SignalEvent();
1713 if(associateOptions[AssociateOptions::AssociateEPJ].selected)
1715 AssociateExtension(".epj", "Ecere IDE Project", "epj_file", "Open", idePath);
1717 if(associateOptions[AssociateOptions::AssociateEC].selected)
1719 AssociateExtension(".ec", "eC Source File", "ec_file", "Open", idePath);
1720 AssociateExtension(".eh", "eC Header File", "eh_file", "Open", idePath);
1722 if(associateOptions[AssociateOptions::AssociateC].selected)
1724 AssociateExtension(".c", "C Source File", "c_file", "Open", idePath);
1725 AssociateExtension(".h", "C Header File", "h_file", "Open", idePath);
1727 if(associateOptions[AssociateOptions::AssociateCPP].selected)
1729 AssociateExtension(".cpp", "C++ Source File", "cpp_file", "Open", idePath);
1730 AssociateExtension(".cc", "C++ Source File", "cpp_file", "Open", idePath);
1731 AssociateExtension(".cxx", "C++ Source File", "cpp_file", "Open", idePath);
1732 AssociateExtension(".chh", "C++ Header File", "chh_file", "Open", idePath);
1733 AssociateExtension(".hh", "C++ Header File", "chh_file", "Open", idePath);
1734 AssociateExtension(".hxx", "C++ Header File", "chh_file", "Open", idePath);
1736 if(associateOptions[AssociateOptions::AssociateTXT].selected)
1738 AssociateExtension(".txt", "Text File", "txt_file", "Open", idePath);
1740 if(associateOptions[AssociateOptions::Associate3DS].selected)
1742 AssociateExtension(".3ds", "3D Studio Model", "3ds_file", "View", idePath);
1744 if(associateOptions[AssociateOptions::AssociateIMG].selected)
1746 AssociateExtension(".bmp", "BMP Image", "bmp_file", "View", idePath);
1747 AssociateExtension(".pcx", "PCX Image", "pcx_file", "View", idePath);
1748 AssociateExtension(".png", "PNG Image", "png_file", "View", idePath);
1749 AssociateExtension(".jpg", "JPEG Image", "jpg_file", "View", idePath);
1750 AssociateExtension(".jpeg", "JPEG Image", "jpg_file", "View", idePath);
1751 AssociateExtension(".gif", "GIF Image", "gif_file", "View", idePath);
1754 ((GuiApplication)__thisModule).Lock();
1756 installProgress.cancel.Destroy(0);
1757 installProgress.finish.text = $"Finish";
1758 installProgress.finish.disabled = false;
1759 installProgress.finish.Activate();
1760 installProgress.installing.text = $"Installation Complete.";
1761 installProgress.title.text = $"Installation Complete";
1762 installProgress.titleInfo.contents = $"Thank you for using the Ecere SDK.";
1764 ((GuiApplication)__thisModule).Unlock();