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, 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 Coursework", "ecere-sdk/coursework", "doc", null, false, true, true, none },
335 { $"GCC Docs", "tdm/doc/gcc", "tdm", null, false, false, minGWIncluded, none },
336 { $"G++ Docs", "tdm/doc/g++", "tdm", null, false, false, minGWIncluded, none },
337 { $"GDB Docs", "tdm/doc/gdb", "tdm", null, false, false, minGWIncluded, none },
338 { $"Make Docs", "tdm/doc/make", "tdm", null, false, false, minGWIncluded, none },
339 { $"Binutils Docs", "tdm/doc/binutils", "tdm", null, false, false, minGWIncluded, none },
340 { $"gnurx Docs", "tdm/doc/gnurx", "tdm", null, false, false, minGWIncluded, none },
341 { $"UPX Docs", "upx/doc", "upx/doc", null, false, false, minGWIncluded, none },
345 public enum ComponentID
354 Array<Component> components
356 { $"Core SDK Files", null, null, coreSDK.array, true, true, true, none },
357 { $"Additional Support", null, null, additional.array, false, true, true, none },
358 { $"Documentation", null /*"doc"*/, null /*"doc"*/, documentation.array, false, true, true, none },
359 { $"Samples", null, "samples", samples.array, false, true, true, none },
363 FileSize totalInstalled;
368 InstallOption * subOptions;
374 enum AssociateOptions
385 Array<InstallOption> associateOptions
387 { $"Associate with Ecere Project Files (*.epj)", null, true },
388 { $"Associate with eC Files (*.ec, *.eh)", null, true },
389 { $"Associate with C files (*.c, *.h)", null, false },
390 { $"Associate with C++ Files (*.cpp, *.hpp, *.cc, *.hh, *.cxx, *.hxx)", null, false },
391 { $"Associate with text files (*.txt)", null, false },
392 { $"Associate with 3D Studio Model Files (*.3ds)", null, true },
393 { $"Associate with Image Files (*.png, *.jpg, *.pcx, *.bmp, *.gif)", null, false },
399 AddECEREPaths, AddMinGWPaths
402 Array<InstallOption> pathOptions
404 { $"Add Ecere binaries location to the user environment path", null, true, true },
405 { $"Add MinGW to the user environment path", null, true, minGWIncluded },
416 Array<InstallOption> options
418 { $"Install for All Users", null, true, true },
419 { $"Start Menu Group", null, true, true },
420 { $"Desktop Icon", null, true, true },
421 { $"Quicklaunch Icon", null, true, true },
422 { $"Associate the Ecere IDE with Supported File Types", associateOptions.array, true, true },
423 { $"Add binaries location to the user environment paths", pathOptions.array, true, minGWIncluded },
427 char sourceDir[MAX_LOCATION] = ":";
428 char installDir[MAX_LOCATION];
429 char installDir32[MAX_LOCATION];
432 class Installer : Window
434 background = formColor;
439 clientSize = { 636, 476 };
440 icon = { ":icon.png" };
441 text = $"Ecere Software Development Kit Setup - v0.44.10 \"Ryōan-ji\" 64 Bit Edition";
443 // clientSize = { 796, 576 };
446 Picture back { image = BitmapResource { ":ryoanji.png" }, parent = this, position = { 0, 0 } };
447 FileDialog fileDialog
449 master = this, type = selectDir,
450 text = $"Select a new location"
454 master = this, autoCreate = false, inactive = true, text = "...";
456 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
458 DataRow row = componentsBox.currentRow;
459 Component * component = ((CheckItem *)row.GetData(componentField))->data;
460 component->GetFullPath(fileDialog.filePath, false);
461 StripLastDirectory(fileDialog.filePath, fileDialog.currentDirectory);
463 if(fileDialog.Modal() == ok)
465 componentsBox.StopEditing(false);
466 row.SetData(locationField, fileDialog.filePath);
467 componentsBox.NotifyChanged(this, componentsBox, row);
468 componentsBox.currentField = componentsBox.currentField;
473 CheckListBox componentsBox
475 this, size = { 460, 112 }, position = { 160, 160 }, hasHeader = true;
476 fullRowSelect = false, collapseControl = true, treeBranches = true, rootCollapseButton = true,
477 hasHorzScroll = true;
481 selectionColor = { 145, 150, 140 };
486 bool NotifyKeyDown(ListBox listBox, DataRow row, Key key, unichar ch)
488 if(key == f2 && browse.visible)
489 browse.NotifyClicked(this, browse, 0, 0, 0);
493 bool NotifyChanged(ListBox listBox, DataRow row)
495 Component * component = ((CheckItem *)listBox.GetData(componentField))->data;
496 char path[MAX_LOCATION], relative[MAX_LOCATION] = "", * newPath;
497 char fullPath[MAX_LOCATION];
499 component->parent->GetFullPath(path, false);
500 strcpy(fullPath, path);
502 newPath = row.GetData(locationField);
505 PathCat(fullPath, newPath);
506 if(IsPathInsideOf(fullPath, path))
507 MakePathRelative(fullPath, path, relative);
509 strcpy(relative, fullPath);
511 listBox.SetData(locationField, relative);
512 strcpy(component->installPath, relative);
514 //SetAvailableSpace(component, path);
517 install.disabled = false;
518 for(c = 0; components[c].name; c++)
520 SetAvailableSpace(components[c], installDir);
526 bool NotifyEditDone(ListBox listBox, DataRow row)
532 bool NotifyEdited(ListBox listBox, DataRow row)
535 browse.parent = listBox;
536 browse.position = { componentField.width + locationField.width + 18, (listBox.currentIndex+1) * listBox.rowHeight - 2 };
537 browse.size = { 30, listBox.rowHeight + 3 };
538 for(e = listBox.firstChild; e; e = e.next)
540 if(e._class == class(DataBox))
549 void NotifyChecked(CheckListBox listBox, DataRow row)
551 Component * component = ((CheckItem *)row.GetData(componentField))->data;
553 component->selected = listBox.IsChecked(row);
555 if(!component->parent) totalSize -= component->requiredSize;
556 component->requiredSize = 0;
557 if(component->selected)
559 component->requiredSize += component->size;
560 if(component->subComponents)
561 for(c = 0; component->subComponents[c].name; c++)
562 component->requiredSize += component->subComponents[c].requiredSize;
564 if(component->requiredSize)
566 uint requiredSize = component->requiredSize;
567 row.SetData(reqField, requiredSize);
570 row.UnsetData(reqField);
571 if(!component->parent)
573 totalSize += component->requiredSize;
575 char sizeString[100];
576 PrintSize(sizeString, totalSize, 2);
577 totalSpaceValue.text = sizeString;
582 Label agreementLbl { parent = this, text = $"By installing the Ecere SDK, you agree to the", font = { "Tahoma", 8.25f }, anchor = Anchor { right = 399, top = 448 } };
585 this, inactive = true, offset = false, bevel = false, foreground = blue, font = { "Tahoma", 8.25f, underline = true, bold = true },
586 // text = $"terms and conditions", anchor = Anchor { left = 241, top = 421 };
587 text = $"terms and conditions", anchor = Anchor { left = 235, top = 445 };
588 cursor = ((GuiApplication)__thisModule).GetCursor(hand);
590 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
592 // LicenseBox { master = this, sourceFile = ":ecere-sdk/doc/LICENSE" }.Modal();
593 LicensesForm { master = this }.Modal();
597 Label dotLbl { parent = this, text = ".", font = { "Tahoma", 8.25f }, anchor = Anchor { left = 372, top = 448 } };
598 CheckListBox optionsBox
600 this, size = { 460, 114 }, position = { 160, 284 };
601 fullRowSelect = false, collapseControl = true, treeBranches = true, rootCollapseButton = true,
606 void NotifyChecked(CheckListBox listBox, DataRow row)
608 CheckItem * item = row.GetData(optionField);
609 InstallOption * option = item->data;
610 option->selected = listBox.IsChecked(row);
611 // Update default samples/extras path whether we're installing for All Users or not
612 if(option == &options[0])
614 char appData[MAX_LOCATION];
616 options[5].name = options[0].selected ? $"Add binaries location to the system environment paths" : $"Add binaries location to the user environment paths";
618 ((CheckItem *)options[5].row.GetData(optionField))->name = options[5].name;
620 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";
621 if(pathOptions[PathOptions::AddECEREPaths].row)
622 ((CheckItem *)pathOptions[PathOptions::AddECEREPaths].row.GetData(optionField))->name = pathOptions[PathOptions::AddECEREPaths].name;
624 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";
625 if(pathOptions[PathOptions::AddMinGWPaths].row)
626 ((CheckItem *)pathOptions[PathOptions::AddMinGWPaths].row.GetData(optionField))->name = pathOptions[PathOptions::AddMinGWPaths].name;
628 GetEnvironment(options[0].selected ? "ALLUSERSPROFILE" : "APPDATA", appData, sizeof(appData));
629 if(appData && appData[0])
631 char defPath[MAX_LOCATION];
633 char * s = components[ComponentID::samples].installPath;
634 strcpy(defPath, installDir);
635 PathCat(defPath, components[ComponentID::samples].defInstallPath);
636 ChangeCh(defPath, '/', DIR_SEP);
637 if(!strcmp(defPath, components[ComponentID::samples].installPath))
639 static char defSamplesPath[MAX_LOCATION];
640 strcpy(defSamplesPath, appData);
641 PathCat(defSamplesPath, "Ecere SDK\\Samples");
642 components[ComponentID::samples].defInstallPath = defSamplesPath;
644 strcpy(components[ComponentID::samples].installPath, components[ComponentID::samples].defInstallPath);
645 ChangeCh(components[ComponentID::samples].installPath, '/', DIR_SEP);
646 components[ComponentID::samples].row.SetData(locationField, components[ComponentID::samples].installPath);
649 strcpy(defPath, installDir);
650 PathCat(defPath, additional[AdditionalID::extras].defInstallPath);
651 ChangeCh(defPath, '/', DIR_SEP);
652 if(!strcmp(additional[AdditionalID::extras].installPath, additional[AdditionalID::extras].installPath))
654 static char defExtrasPath[MAX_LOCATION];
655 strcpy(defExtrasPath, appData);
656 PathCat(defExtrasPath, "Ecere SDK\\extras");
657 additional[AdditionalID::extras].defInstallPath = defExtrasPath;
659 strcpy(additional[AdditionalID::extras].installPath, additional[AdditionalID::extras].defInstallPath);
660 ChangeCh(additional[AdditionalID::extras].installPath, '/', DIR_SEP);
661 additional[AdditionalID::extras].row.SetData(locationField, additional[AdditionalID::extras].installPath);
669 parent = this, text = $"Install", isDefault = true, size = { 75, 23 }, position = { 432, 440 };
671 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
673 installProgress.Create();
675 // installProgress.thread.Main();
676 installProgress.thread.Create();
680 Button button3 { parent = this, text = $"Cancel", hotKey = altX, size = Size { 75, 23 }, anchor = Anchor { left = 544, top = 440 }, NotifyClicked = ButtonCloseDialog };
683 this, position = { 14, 374 }, size = { 142, 0 }, caption = "Language:";
685 bool NotifySelect(DropBox dropBox, DataRow row, Modifiers mods)
687 LanguageOption * option = row.GetData(null);
688 // If the language is already set, we need to override it
690 IDESettings settings = null;
691 IDESettingsContainer settingsContainer
694 dataOwner = &settings;
695 dataClass = class(IDESettings);
696 allUsers = options[0].selected;
698 settingsContainer.Load();
699 if(settings.language)
701 settings.language = option->code;
702 settingsContainer.Save();
704 delete settingsContainer;
707 ((GuiApplication)__thisModule.application).desktop.Destroy(0);
708 LanguageRestart(option->code, __thisModule.application, null, null, null, null, false);
712 Label lblLanguageBox { this, position = { 14, 354 }, labeledWindow = languageBox };
713 Label label1 { labeledWindow = destBox, tabCycle = true, isGroupBox = true, parent = this, inactive = false, size = Size { 458, 50 }, anchor = Anchor { left = 160, top = 96 } };
716 parent = label1, master = this, text = $" Destination Folder", size = Size { 336, 22 }, anchor = Anchor { left = 12, top = 20, right = 12 };
717 typeExpected = directory;
718 browseDialog = fileDialog;
721 bool NotifyModified(PathBox pathBox)
724 strcpy(installDir, destBox.path);
725 install.disabled = false;
726 for(c = 0; components[c].name; c++)
728 SetAvailableSpace(components[c], installDir);
735 label1, this, $"Browse", altB, size = { 83, 24 }, position = { 360, 16 };
737 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
739 strcpy(fileDialog.filePath, installDir);
740 StripLastDirectory(installDir, fileDialog.currentDirectory);
741 if(fileDialog.Modal())
743 strcpy(installDir, fileDialog.filePath);
744 destBox.contents = installDir;
745 // TOCHECK: Should setting contents call NotifyModified?
746 destBox.NotifyModified(destBox.master, destBox);
753 this, multiLine = true,
754 opacity = 0, borderStyle = none, inactive = true, size = { 136, 53 }, position = { 14, 96 }, noSelect = true,
755 contents = $"Select the default root\n"
756 "folder where to install\n"
761 this, opacity = 0, borderStyle = none, inactive = true, size = { 136, 132 }, position = { 14, 152 }, noSelect = true,
763 contents = $"Select the optional\n"
764 "components you wish\n"
766 "You may customize the\n"
767 "install location for each\n"
768 "of them, or use the default\n"
769 "based on the main\n"
770 "destination folder."
774 this, opacity = 0, borderStyle = none, inactive = true, size = { 136, 83 }, position = { 14, 280 }, noSelect = true,
776 contents = $"Select icons to install, file\n"
777 "associations, and system\n"
778 "environment modifications:"
780 Label totalSpaceLabel
782 this, anchor = { right = 72, top = 404 }, text = $"Space Required: "
784 Label totalSpaceValue
786 this, anchor = { right = 14, top = 404 }, text = "0 mb"
790 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"
791 "of the SDK to install, as well as where to install program icons."
793 Label label2 { parent = this, text = buildString, position = { 16, 422 }, font = { "Tahoma", 10, true }, disabled = true, opacity = 0, background = activeBorder };
796 image = BitmapResource { ":ecere.png", alphaBlend = true }, filter = true, parent = label3, text = "picture1", anchor = Anchor { left = 16, top = 4 };
797 cursor = ((GuiApplication)__thisModule).GetCursor(hand);
799 bool OnLeftButtonDown(int x, int y, Modifiers mods)
801 ShellOpen("http://www.ecere.com/");
805 Label label4 { label3, font = { "Tahoma", 8.25f, bold = true }, /*size = { 326, 16 }, */position = { 248, 24 }, text = $"Choose Components, Locations and Install Options" };
806 DataField componentField { "CheckItem", width = 160, header = $"Component" };
807 DataField locationField { "char *", width = 108, header = $"Destination Folder", editable = true };
808 DataField reqField { "FileSize", width = 70, header = $"Req. Space", alignment = right };
809 DataField avField { "FileSize64", width = 70, header = $"Avail. Space", alignment = right };
810 DataField optionField { "CheckItem" };
812 DataField languageField { class(LanguageOption) };
814 void SetAvailableSpace(Component component, char * parentPath)
816 char path[MAX_LOCATION];
820 strcpy(path, parentPath);
821 PathCat(path, component.installPath);
823 if(component.subComponents)
824 for(c = 0; component.subComponents[c].name; c++)
825 SetAvailableSpace(component.subComponents[c], path);
827 while(!FileExists(path) && path[0])
828 StripLastDirectory(path, path);
831 GetFreeSpace(path, &size);
832 component.row.SetData(avField, size);
833 if(!size) install.disabled = true;
836 FileSize ComputeSize(char * path)
839 FileAttribs attribs = FileExists(path);
840 if(attribs.isDirectory)
842 FileListing listing { path };
843 while(listing.Find())
845 if(listing.stats.attribs.isDirectory)
846 size += ComputeSize(listing.path);
848 size += listing.stats.size;
852 FileGetSize(path, &size);
856 void AddComponent(Component component, Component parent, char * parentPath)
858 DataRow row = (parent != null) ? parent.row.AddRow() : componentsBox.AddRow();
860 FileSize64 avSize = 0;
861 char path[MAX_LOCATION];
864 strcpy(path, parentPath);
865 if(component.defInstallPath)
866 PathCat(path, component.defInstallPath);
867 component.parent = parent;
869 row.SetData(null, CheckItem { component.name, component, (component.arch == bits32 && osIS64bit) } );
871 if(component.defInstallPath)
873 strcpy(component.installPath, component.defInstallPath);
874 ChangeCh(component.installPath, '/', DIR_SEP);
875 row.SetData(locationField, component.installPath);
878 if(component.mandatory)
880 if(component.arch != bits32 || !osIS64bit) // || component == &coreSDK[gdb32])
881 componentsBox.SetDisabled(row, true);
883 component.selected = false;*/
885 else if(component.arch == bits32 && osIS64bit)
886 ; //component.selected = false;
888 componentsBox.SetCheck(row, component.selected);
890 if(component.dataPath)
892 char path[MAX_LOCATION];
894 PathCat(path, component.dataPath);
895 component.size = ComputeSize(path);
897 if(component.subComponents)
900 for(c = 0; component.subComponents[c].name; c++)
902 Component * sub = &component.subComponents[c];
903 if(sub->available && (osIS64bit || sub->arch == bits32 || sub->arch == none))
905 AddComponent(sub, component, path);
906 size += sub->requiredSize;
909 sub->selected = false;
913 component.requiredSize = component.selected ? (size + component.size) : 0;
914 if(component.requiredSize)
915 row.SetData(reqField, component.requiredSize);
917 while(!FileExists(path) && path[0])
918 StripLastDirectory(path, path);
921 GetFreeSpace(path, &avSize);
924 row.SetData(avField, avSize);
925 row.collapsed = true;
928 void AddOption(InstallOption option, InstallOption parent)
930 DataRow row = option.row = (parent != null) ? parent.row.AddRow() : optionsBox.AddRow();
931 row.SetData(null, CheckItem { option.name, option } );
932 optionsBox.SetCheck(row, option.selected);
933 if(option.subOptions)
936 for(c = 0; option.subOptions[c].name; c++)
938 AddOption(option.subOptions[c], option);
941 row.collapsed = true;
947 char programFilesDir[MAX_LOCATION];
948 char appData[MAX_LOCATION];
949 char homeDrive[MAX_LOCATION];
950 char winDir[MAX_LOCATION];
953 bool isAdministrator = IsAdministrator();
957 options[0].available = false;
958 options[0].selected = false;
961 // If the SDK is already installed, use currently selected language
963 IDESettings settings = null;
964 IDESettingsContainer settingsContainer
967 dataOwner = &settings;
968 dataClass = class(IDESettings);
969 allUsers = options[0].selected;
972 settingsContainer.Load();
974 if(settings.language)
976 String language = GetLanguageString();
977 if(settings.language.OnCompare(language))
979 // Relaunch the installer with previously selected language
980 LanguageRestart(settings.language, __thisModule.application, null, null, null, null, false);
984 delete settingsContainer;
988 GetEnvironment("HOMEDRIVE", homeDrive, sizeof(homeDrive));
989 GetEnvironment("windir", winDir, sizeof(winDir));
991 GetEnvironment(options[0].selected ? "ALLUSERSPROFILE" : "APPDATA", appData, sizeof(appData));
993 componentsBox.AddField(componentField);
994 componentsBox.AddField(locationField);
995 componentsBox.AddField(reqField);
996 componentsBox.AddField(avField);
998 optionsBox.AddField(optionField);
1000 languageBox.AddField(languageField);
1002 programFilesDir[0] = 0;
1003 if(GetEnvironment("ProgramFiles", programFilesDir, MAX_LOCATION))
1005 x86 = strstr(programFilesDir, " (x86)");
1010 if(isAdministrator && programFilesDir[0])
1014 strcpy(installDir32, programFilesDir);
1015 PathCat(installDir32, "Ecere SDK");
1017 strcpy(installDir, programFilesDir);
1018 PathCat(installDir, "Ecere SDK");
1022 strcpy(installDir, programFilesDir);
1023 PathCat(installDir, "Ecere SDK");
1024 strcpy(installDir32, installDir);
1027 else if(homeDrive && homeDrive[0])
1029 strcpy(installDir, homeDrive);
1030 PathCat(installDir, "Ecere SDK");
1031 strcpy(installDir32, installDir);
1032 strcat(installDir32, " (32)");
1034 else if(winDir && winDir[0])
1036 strcpy(installDir, winDir);
1037 PathCat(installDir, "..\\Ecere SDK");
1038 strcpy(installDir32, installDir);
1039 strcat(installDir32, " (32)");
1043 strcpy(installDir, "C:\\Ecere SDK");
1044 strcpy(installDir32, installDir);
1045 strcat(installDir32, " (32)");
1048 if(appData && appData[0])
1050 static char defSamplesPath[MAX_LOCATION];
1051 static char defExtrasPath[MAX_LOCATION];
1052 strcpy(defSamplesPath, appData);
1053 PathCat(defSamplesPath, "Ecere SDK\\Samples");
1054 components[ComponentID::samples].defInstallPath = defSamplesPath;
1056 strcpy(defExtrasPath, appData);
1057 PathCat(defExtrasPath, "Ecere SDK\\extras");
1058 additional[AdditionalID::extras].defInstallPath = defExtrasPath;
1061 destBox.path = installDir;
1065 for(c = 0; components[c].name; c++)
1066 AddComponent(components[c], null, installDir);
1069 // Compute size apart because ToggleCheck will change it
1073 for(c = 0; components[c].name; c++)
1074 totalSize += components[c].requiredSize;
1077 char sizeString[100];
1078 PrintSize(sizeString, totalSize, 2);
1079 totalSpaceValue.text = sizeString;
1081 for(c = 0; options[c].name; c++)
1083 if(options[c].available)
1084 AddOption(options[c], null);
1096 dotLbl.position.x = licenseButton.position.x + licenseButton.size.w - 4;
1102 // Constructor happens before Languages is instantiated...
1105 l.res = { l.bitmap, window = this };
1111 String language = GetLanguageString();
1115 // Try to find country-specific language first
1118 LanguageOption option = l;
1119 row = languageBox.AddRow();
1120 row.SetData(null, option); // TOFIX: l used directly here
1122 if(!found && (!strcmpi(l.code, language) || (!row.GetPrevRow() && !strcmpi("en", language))))
1124 languageBox.currentRow = row;
1129 // Try generalizing locale
1133 char genericLocale[256];
1134 strncpy(genericLocale, language, sizeof(genericLocale));
1135 genericLocale[sizeof(genericLocale)] = 0;
1137 under = strchr(genericLocale, '_');
1140 if(!strcmpi(genericLocale, "zh"))
1141 strcpy(genericLocale, "zh_CN");
1142 if(strcmp(genericLocale, language))
1144 row = languageBox.firstRow;
1147 if(!strcmpi(l.code, genericLocale) || (!row.GetPrevRow() && !strcmpi("en", genericLocale)))
1149 languageBox.currentRow = row;
1153 row = row.GetNextRow();
1159 languageBox.currentRow = languageBox.firstRow;
1167 void OnDrawOverChildren(Surface surface)
1169 int tw = label2.size.w;
1170 surface.SetForeground(Color { 128, 128, 128 });
1171 surface.HLine(label2.position.x + tw + 6, 620, 430);
1172 surface.SetForeground(white);
1173 surface.HLine(label2.position.x + tw + 6, 621, 431);
1174 surface.PutPixel(621, 400);
1178 parent = this, opacity = 0, borderStyle = deep, size = Size { 644, 93 }, anchor = Anchor { left = -8, top = -8 };
1182 class InstallProgress : Window
1184 text = $"Ecere Software Development Kit Setup - v0.44.10 \"Ryōan-ji\" 64 Bit Edition";
1185 background = activeBorder;
1186 borderStyle = fixed;
1190 // size = Size { 640, 480 };
1191 clientSize = { 636, 476 };
1192 //clientSize = { 796, 576 };
1193 icon = { ":icon.png" };
1195 Picture back { image = BitmapResource { ":ryoanji-progress.png" }, parent = this, position = { 0, 0 } };
1196 Label installing { this, position = { 32, 160 } };
1197 ProgressBar progressBar { parent = this, size = Size { 588, 24 }, anchor = Anchor { left = 24, top = 184 } };
1200 parent = this, text = $"Install", disabled = true, isDefault = true, size = Size { 75, 23 }, anchor = Anchor { left = 432, top = 440 };
1202 NotifyClicked = ButtonCloseDialog
1206 this, text = $"Cancel", hotKey = altX, size = Size { 75, 23 }, anchor = Anchor { left = 544, top = 440 };
1208 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
1210 abortInstall = true;
1216 inactive = true, noSelect = true,
1217 multiLine = true, parent = label3, opacity = 0, borderStyle = none, size = Size { 350, 35 }, anchor = Anchor { horz = 111, vert = 13 },
1218 contents = $"Please wait while the Ecere Software Development Kit is being installed."
1220 Label label2 { parent = this, text = buildString, position = { 16, 422 }, font = { "Tahoma", 10, true }, disabled = true, opacity = 0, background = activeBorder };
1223 image = BitmapResource { ":ecere.png", alphaBlend = true }, filter = true, parent = label3, anchor = Anchor { left = 16, top = 4 };
1224 cursor = ((GuiApplication)__thisModule).GetCursor(hand);
1226 bool OnLeftButtonDown(int x, int y, Modifiers mods)
1228 ShellOpen("http://www.ecere.com/");
1232 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 } };
1234 void OnDrawOverChildren(Surface surface)
1236 int tw = label2.size.w;
1237 surface.SetForeground(Color { 128, 128, 128 });
1238 surface.HLine(label2.position.x + tw + 6, 620, 430);
1239 surface.SetForeground(white);
1240 surface.HLine(label2.position.x + tw + 6, 621, 431);
1241 surface.PutPixel(621, 400);
1246 parent = this, opacity = 0, borderStyle = deep, size = Size { 644, 93 }, anchor = Anchor { left = -8, top = -8 };
1248 InstallThread thread
1253 Installer installer {};
1254 InstallProgress installProgress { autoCreate = false };
1256 static void AddPath(char * sysPaths[200], int sysCount, char * paths[200], int * count, char * oldPath, char * userPath, char * path)
1260 for(p = 0; p<sysCount; p++)
1261 if(!fstrcmp(sysPaths[p], path))
1266 for(p = 0; !found && p<*count; p++)
1267 if(!fstrcmp(paths[p], path))
1277 strcat(userPath, ";");
1278 start = paths[(*count)-1] + strlen(paths[(*count)-1])+1;
1283 strcpy(start, path);
1284 *(start + strlen(path)) = '\0';
1285 paths[(*count)++] = start;
1287 strcat(userPath, path);
1292 void ModifyPath(char * systemPath, char * userPath)
1294 char oldPath[8192], * paths[200], * sysPaths[200];
1295 int count, sysCount = 0;
1299 strcpy(oldPath, userPath);
1300 count = TokenizeWith(oldPath, sizeof(paths) / sizeof(char *), paths, ";", false);
1301 sysCount = TokenizeWith(systemPath, sizeof(sysPaths) / sizeof(char *), sysPaths, ";", false);
1305 strcpy(oldPath, systemPath);
1306 count = TokenizeWith(oldPath, sizeof(paths) / sizeof(char *), paths, ";", false);
1311 for(c = 0; coreSDK[c].name; c++)
1314 char path[MAX_LOCATION];
1315 if(!coreSDK[c].selected) continue;
1316 coreSDK[c].GetFullPath(path, false);
1317 if(c != ide && c != runtime && c != ec &&
1318 c != ide32 && c != runtime32 && c != ec32)
1320 if(!pathOptions[PathOptions::AddMinGWPaths].available || !pathOptions[PathOptions::AddMinGWPaths].selected)
1322 PathCat(path, "bin");
1324 else if(!pathOptions[PathOptions::AddECEREPaths].selected) continue;
1326 AddPath(sysPaths, sysCount, paths, &count, oldPath, userPath ? userPath : systemPath, path);
1332 for(c = 0; c <= cpp; c++)
1335 char path[MAX_LOCATION];
1336 if(!additional[c].selected || c == vanilla || c == vanilla32 || c == extras) continue;
1337 if((c != eda && c != eda32 && c != upx) && (!pathOptions[PathOptions::AddMinGWPaths].available || !pathOptions[PathOptions::AddMinGWPaths].selected))
1339 additional[c].GetFullPath(path, false);
1340 if(c != eda && c != eda32 && c != upx)
1341 PathCat(path, "bin");
1342 AddPath(sysPaths, sysCount, paths, &count, oldPath, userPath ? userPath : systemPath, path);
1347 void AssociateExtension(char * extension, char * description, char *name, char * action, char * path)
1353 RegCreateKeyEx(HKEY_CLASSES_ROOT, extension, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1354 RegSetValueEx(key, null, 0, REG_SZ, name, (uint)strlen(name)+1);
1357 RegCreateKeyEx(HKEY_CLASSES_ROOT, name, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1358 RegSetValueEx(key, null, 0, REG_SZ, description, (uint)strlen(description)+1);
1361 sprintf(keyName, "%s\\shell", extension);
1362 RegCreateKeyEx(HKEY_CLASSES_ROOT, keyName, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1363 RegSetValueEx(key, null, 0, REG_SZ, action, (uint)strlen(action)+1);
1366 sprintf(keyName, "%s\\shell\\%s", name, action);
1367 RegCreateKeyEx(HKEY_CLASSES_ROOT, keyName, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1370 sprintf(keyName, "%s\\shell\\%s\\command", name, action);
1371 RegCreateKeyEx(HKEY_CLASSES_ROOT, keyName, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1373 sprintf(keyName, path);
1374 strcat(keyName, " \"%L\"");
1376 uint16 wKeyName[2048];
1377 UTF8toUTF16Buffer(keyName, wKeyName, sizeof(wKeyName) / sizeof(uint16));
1378 RegSetValueExW(key, null, 0, REG_SZ, (byte *)wKeyName, (uint)(wcslen(wKeyName) + 1)*sizeof(uint16));
1383 class InstallThread : Thread
1388 ((GuiApplication)__thisModule).Lock();
1389 installProgress.progressBar.range = totalSize;
1392 strcpy(installDir32, installDir);
1394 for(c = 0; components[c].name && !abortInstall; c++)
1395 components[c].Install(installDir, installDir32);
1398 installProgress.progressBar.range = 0;
1399 installProgress.finish.Destroy(0);
1400 installProgress.cancel.text = $"Close";
1401 installProgress.cancel.isDefault = true;
1402 installProgress.cancel.disabled = false;
1403 installProgress.cancel.NotifyClicked = Window::ButtonCloseDialog;
1404 installProgress.installing.text = $"Installation Cancelled.";
1405 installProgress.title.text = $"Installation Cancelled";
1406 installProgress.titleInfo.contents = $"The installation was not completed.";
1410 char idePath[MAX_LOCATION];
1411 char userProfile[MAX_LOCATION];
1414 IDESettings settings = null; // Don't instantiate yet so we can pick up old settings
1416 IDESettingsContainer settingsContainer
1419 dataOwner = &settings;
1420 dataClass = class(IDESettings);
1421 allUsers = options[0].selected;
1423 CompilerConfig compiler;
1424 installProgress.installing.text = $"Configuring Ecere IDE...";
1425 ((GuiApplication)__thisModule).Unlock();
1426 ((GuiApplication)__thisModule).SignalEvent();
1428 settingsContainer.Load();
1429 compiler = settings.GetCompilerConfig(defaultCompilerName);
1434 for(c = 0; coreSDK[c].name; c++)
1436 char path[MAX_LOCATION];
1437 if(!coreSDK[c].selected || !coreSDK[c].available) continue;
1439 coreSDK[c].GetFullPath(path, false);
1440 if(c != ide && c != runtime && c != ec &&
1441 c != ide32 && c != runtime32 && c != ec32)
1442 PathCat(path, "bin");
1443 MakeSlashPath(path);
1444 if((c == ide && osIS64bit) || (c == ide32 && !osIS64bit))
1446 coreSDK[c].GetFullPath(idePath, false);
1447 PathCat(idePath, "ide.exe");
1450 if(c == runtime || c == runtime32)
1452 if(!compiler.libraryDirs.Find(path))
1453 compiler.libraryDirs.Add(CopyString(path));
1460 for(c = 0; c <= cpp; c++)
1462 char path[MAX_LOCATION];
1463 if(c == extras || !additional[c].selected || !additional[c].available) continue;
1464 additional[c].GetFullPath(path, false);
1465 if(c != upx && c != eda && c != vanilla && c != eda32 && c != vanilla32)
1466 PathCat(path, "bin");
1467 MakeSlashPath(path);
1468 if(c == vanilla || c == vanilla32)
1470 if(!compiler.libraryDirs.Find(path))
1471 compiler.libraryDirs.Add(CopyString(path));
1475 if(!compiler.executableDirs.Find(path))
1476 compiler.executableDirs.Add(CopyString(path));
1483 char path[MAX_LOCATION] = "";
1485 if(components[ComponentID::samples].selected)
1486 components[ComponentID::samples].GetFullPath(path, false);
1487 // IDE will now default to HOME for the default project/files locations
1489 if(!settings.ideProjectFileDialogLocation[0])
1490 settings.ideProjectFileDialogLocation = path;
1491 if(!settings.ideFileDialogLocation[0])
1492 settings.ideFileDialogLocation = path;
1494 if(documentation[DocumentationID::apiRef].selected)
1496 documentation[DocumentationID::apiRef].GetFullPath(path, false);
1497 if(!settings.docDir[0])
1498 settings.docDir = path;
1502 settings.language = GetLanguageString();
1504 // Set LANGUAGE environment variable
1507 uint16 wLanguage[256];
1511 if(options[0].selected)
1512 RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", 0, KEY_ALL_ACCESS, &key);
1514 RegCreateKeyEx(HKEY_CURRENT_USER, "Environment", 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1517 UTF8toUTF16Buffer(settings.language, wLanguage, sizeof(wLanguage) / sizeof(uint16));
1518 RegSetValueExW(key, L"ECERE_LANGUAGE", 0, REG_EXPAND_SZ, (byte *)wLanguage, (uint)(wcslen(wLanguage)+1) * 2);
1523 settingsContainer.Save();
1524 delete settingsContainer;
1527 // Set up Uninstaller
1528 ((GuiApplication)__thisModule).Lock();
1529 installProgress.installing.text = $"Registering uninstaller...";
1530 ((GuiApplication)__thisModule).Unlock();
1531 ((GuiApplication)__thisModule).SignalEvent();
1536 char * displayName = "Ecere SDK 0.44";
1537 char uninstaller[MAX_LOCATION];
1538 bool nomodify = true;
1540 strcpy(uninstaller, installDir);
1541 PathCat(uninstaller, "uninstall_ecere.exe");
1543 RegCreateKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Ecere SDK", 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1545 RegSetValueEx(key, "DisplayName", 0, REG_SZ, displayName, (uint)strlen(displayName)+1);
1546 RegSetValueEx(key, "UninstallString", 0, REG_SZ, uninstaller, (uint)strlen(uninstaller)+1);
1547 RegSetValueEx(key, "DisplayIcon", 0, REG_SZ, idePath, (uint)strlen(idePath)+1);
1548 //RegSetValueEx(key, "NoModify", 0, REG_DWORD, (byte *)&nomodify, sizeof(nomodify));
1549 //RegSetValueEx(key, "NoRepair", 0, REG_DWORD, (byte *)&nomodify, sizeof(nomodify));
1554 if(pathOptions[PathOptions::AddECEREPaths].selected
1556 || pathOptions[PathOptions::AddMinGWPaths].selected
1560 HKEY userKey = null, systemKey = null;
1562 char userPath[8192] = "";
1563 char systemPath[8192] = "";
1564 uint16 wUserPath[8192];
1565 uint16 wSystemPath[8192];
1570 ((GuiApplication)__thisModule).Lock();
1571 installProgress.installing.text = "Registering paths...";
1572 ((GuiApplication)__thisModule).Unlock();
1573 ((GuiApplication)__thisModule).SignalEvent();
1575 if(options[0].selected)
1577 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", 0, KEY_ALL_ACCESS, &systemKey) == ERROR_SUCCESS)
1579 size = sizeof(wSystemPath);
1580 RegQueryValueExW(systemKey, L"path", null, null, (byte *)wSystemPath, &size);
1581 UTF16toUTF8Buffer(wSystemPath, systemPath, sizeof(systemPath));
1582 ModifyPath(systemPath, null);
1584 UTF8toUTF16Buffer(systemPath, wSystemPath, sizeof(wSystemPath) / sizeof(uint16));
1585 RegSetValueExW(systemKey, L"path", 0, REG_EXPAND_SZ, (byte *)wSystemPath, (uint)(wcslen(wSystemPath)+1) * 2);
1586 RegCloseKey(systemKey);
1591 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", 0, KEY_QUERY_VALUE, &systemKey) == ERROR_SUCCESS)
1593 size = sizeof(wSystemPath);
1594 RegQueryValueExW(systemKey, L"path", null, null, (byte *)wSystemPath, &size);
1595 UTF16toUTF8Buffer(wSystemPath, systemPath, sizeof(systemPath));
1596 RegCloseKey(systemKey);
1599 RegCreateKeyEx(HKEY_CURRENT_USER, "Environment", 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &userKey, &status);
1600 if(status == REG_OPENED_EXISTING_KEY)
1602 size = sizeof(wUserPath);
1603 RegQueryValueExW(userKey, L"path", null, null, (byte *)wUserPath, &size);
1604 UTF16toUTF8Buffer(wUserPath, userPath, sizeof(userPath));
1606 ModifyPath(systemPath, userPath);
1607 UTF8toUTF16Buffer(userPath, wUserPath, sizeof(wUserPath) / sizeof(uint16));
1608 RegSetValueExW(userKey, L"path", 0, REG_EXPAND_SZ, (byte *)wUserPath, (uint)(wcslen(wUserPath)+1) * 2);
1609 RegCloseKey(userKey);
1611 // SendMessageTimeout (HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)"Environment", SMTO_NORMAL, 1000, NULL);
1614 // Install Program Group Icons
1615 GetEnvironment(options[0].selected ? "ALLUSERSPROFILE" : "USERPROFILE", userProfile, sizeof(userProfile));
1617 if(options[IconOptions::StartMenuIcon].selected)
1619 char destPath[MAX_LOCATION];
1620 char startMenuPath[MAX_LOCATION] = "";
1623 ((GuiApplication)__thisModule).Lock();
1624 installProgress.installing.text = $"Installing Start Menu Icons...";
1625 ((GuiApplication)__thisModule).Unlock();
1626 ((GuiApplication)__thisModule).SignalEvent();
1628 strcpy(destPath, userProfile);
1630 if(RegOpenKeyEx(options[0].selected ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
1631 "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", 0, KEY_QUERY_VALUE, &key) == ERROR_SUCCESS)
1633 uint16 wStartMenuPath[2048];
1634 uint size = sizeof(wStartMenuPath);
1635 // RegQueryValueEx(key, "Start Menu", null, null, startMenuPath, &size);
1636 RegQueryValueExW(key, options[0].selected ? L"Common Programs" : L"Programs", null, null, (byte *)wStartMenuPath, &size);
1637 UTF16toUTF8Buffer(wStartMenuPath, startMenuPath, sizeof(startMenuPath));
1640 if(!startMenuPath[0] && userProfile[0])
1642 strcpy(startMenuPath, userProfile);
1643 PathCat(startMenuPath, "Start Menu\\Programs");
1646 if(startMenuPath[0])
1648 strcpy(destPath, startMenuPath);
1649 PathCat(destPath, "Ecere SDK");
1652 strcpy(destPath, startMenuPath);
1653 PathCat(destPath, "Ecere SDK\\Ecere IDE.lnk");
1654 CreateLink(idePath, destPath, null); //"Ecere IDE");
1655 if(components[ComponentID::samples].selected)
1657 char samplesPath[MAX_LOCATION] = "";
1658 components[ComponentID::samples].GetFullPath(samplesPath, false);
1660 strcpy(destPath, startMenuPath);
1661 PathCat(destPath, "Ecere SDK\\Sample Projects.lnk");
1662 CreateLink(samplesPath, destPath, null);//"Sample Projects");
1664 if(components[ComponentID::documentation].selected && documentation[DocumentationID::ecereBook].selected)
1666 char docPath[MAX_LOCATION] = "";
1667 documentation[DocumentationID::ecereBook].GetFullPath(docPath, false);
1668 PathCat(docPath, "Ecere Tao of Programming [work in progress].pdf");
1671 char tao[MAX_LOCATION] ;
1672 documentation[DocumentationID::ecereBook].GetFullPath(tao, false);
1673 PathCat(tao, "tao.pdf");
1674 RenameFile(tao, docPath);
1677 strcpy(destPath, startMenuPath);
1678 PathCat(destPath, "Ecere SDK\\The Ecere Tao of Programming.lnk");
1679 CreateLink(docPath, destPath, null);
1684 // Install Desktop Icon
1685 if(options[IconOptions::DesktopIcon].selected)
1688 char desktopPath[MAX_LOCATION];
1690 if(RegOpenKeyEx(options[0].selected ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
1691 "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", 0, KEY_QUERY_VALUE, &key) == ERROR_SUCCESS)
1693 uint16 wDesktopPath[MAX_LOCATION];
1694 uint size = sizeof(wDesktopPath);
1695 RegQueryValueExW(key, options[0].selected ? L"Common Desktop" : L"Desktop", null, null, (byte *)wDesktopPath, &size);
1696 UTF16toUTF8Buffer(wDesktopPath, desktopPath, sizeof(desktopPath));
1699 if(!desktopPath[0] && userProfile[0])
1701 strcpy(desktopPath, userProfile);
1702 PathCat(desktopPath, "Desktop");
1707 PathCat(desktopPath, "Ecere IDE.lnk");
1709 ((GuiApplication)__thisModule).Lock();
1710 installProgress.installing.text = $"Installing Desktop Icon...";
1711 ((GuiApplication)__thisModule).Unlock();
1712 ((GuiApplication)__thisModule).SignalEvent();
1714 CreateLink(idePath, desktopPath, null);//"Ecere IDE");
1718 SendMessageTimeout (HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)"Environment", SMTO_NORMAL, 1000, NULL);
1720 // Install QuickLaunch Icon
1721 if(options[IconOptions::QuickLaunchIcon].selected)
1723 char appData[MAX_LOCATION];
1724 GetEnvironment("APPDATA", appData, sizeof(appData));
1727 char destPath[MAX_LOCATION];
1729 if(appData[0] && options[0].selected)
1731 char dir[MAX_FILENAME];
1732 GetLastDirectory(appData, dir);
1733 if(!strcmpi(dir, "Roaming"))
1734 PathCat(appData, "../../../Default/AppData/Roaming");
1736 PathCat(appData, "../Default");
1739 ((GuiApplication)__thisModule).Lock();
1740 installProgress.installing.text = $"Installing Quicklaunch Icon...";
1741 ((GuiApplication)__thisModule).Unlock();
1742 ((GuiApplication)__thisModule).SignalEvent();
1744 strcpy(destPath, appData);
1745 PathCat(destPath, "Microsoft\\Internet Explorer\\Quick Launch\\Ecere IDE.lnk");
1746 CreateLink(idePath, destPath, null);
1748 // Set it up on the dock for Windows 7 -- not working
1750 StripLastDirectory(destPath, destPath);
1751 PathCat(destPath, "User Pinned\\TaskBar");
1753 PathCat(destPath, "Ecere IDE.lnk");
1754 CreateLink(idePath, destPath, null);
1759 // Register File Types
1760 if(associateOptions[AssociateOptions::AssociateEPJ].selected ||
1761 associateOptions[AssociateOptions::AssociateEC].selected ||
1762 associateOptions[AssociateOptions::AssociateC].selected ||
1763 associateOptions[AssociateOptions::AssociateCPP].selected ||
1764 associateOptions[AssociateOptions::AssociateTXT].selected ||
1765 associateOptions[AssociateOptions::Associate3DS].selected ||
1766 associateOptions[AssociateOptions::AssociateIMG].selected)
1768 ((GuiApplication)__thisModule).Lock();
1769 installProgress.installing.text = $"Resgistering File Types...";
1770 ((GuiApplication)__thisModule).Unlock();
1771 ((GuiApplication)__thisModule).SignalEvent();
1773 if(associateOptions[AssociateOptions::AssociateEPJ].selected)
1775 AssociateExtension(".epj", "Ecere IDE Project", "epj_file", "Open", idePath);
1777 if(associateOptions[AssociateOptions::AssociateEC].selected)
1779 AssociateExtension(".ec", "eC Source File", "ec_file", "Open", idePath);
1780 AssociateExtension(".eh", "eC Header File", "eh_file", "Open", idePath);
1782 if(associateOptions[AssociateOptions::AssociateC].selected)
1784 AssociateExtension(".c", "C Source File", "c_file", "Open", idePath);
1785 AssociateExtension(".h", "C Header File", "h_file", "Open", idePath);
1787 if(associateOptions[AssociateOptions::AssociateCPP].selected)
1789 AssociateExtension(".cpp", "C++ Source File", "cpp_file", "Open", idePath);
1790 AssociateExtension(".cc", "C++ Source File", "cpp_file", "Open", idePath);
1791 AssociateExtension(".cxx", "C++ Source File", "cpp_file", "Open", idePath);
1792 AssociateExtension(".chh", "C++ Header File", "chh_file", "Open", idePath);
1793 AssociateExtension(".hh", "C++ Header File", "chh_file", "Open", idePath);
1794 AssociateExtension(".hxx", "C++ Header File", "chh_file", "Open", idePath);
1796 if(associateOptions[AssociateOptions::AssociateTXT].selected)
1798 AssociateExtension(".txt", "Text File", "txt_file", "Open", idePath);
1800 if(associateOptions[AssociateOptions::Associate3DS].selected)
1802 AssociateExtension(".3ds", "3D Studio Model", "3ds_file", "View", idePath);
1804 if(associateOptions[AssociateOptions::AssociateIMG].selected)
1806 AssociateExtension(".bmp", "BMP Image", "bmp_file", "View", idePath);
1807 AssociateExtension(".pcx", "PCX Image", "pcx_file", "View", idePath);
1808 AssociateExtension(".png", "PNG Image", "png_file", "View", idePath);
1809 AssociateExtension(".jpg", "JPEG Image", "jpg_file", "View", idePath);
1810 AssociateExtension(".jpeg", "JPEG Image", "jpg_file", "View", idePath);
1811 AssociateExtension(".gif", "GIF Image", "gif_file", "View", idePath);
1814 ((GuiApplication)__thisModule).Lock();
1816 installProgress.cancel.Destroy(0);
1817 installProgress.finish.text = $"Finish";
1818 installProgress.finish.disabled = false;
1819 installProgress.finish.Activate();
1820 installProgress.installing.text = $"Installation Complete.";
1821 installProgress.title.text = $"Installation Complete";
1822 installProgress.titleInfo.contents = $"Thank you for using the Ecere SDK.";
1824 ((GuiApplication)__thisModule).Unlock();