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