1 static define versionString = "Ecere SDK v0.44.13";
2 static define dateString = $"December 22, 2015";
3 static define builtOnString = $"built on ";
4 static define withoutMinGW = $" (Without MinGW)";
6 #define WIN32_LEAN_AND_MEAN
7 #define GetFreeSpace _GetFreeSpace
21 static void SetBuildString(Label label)
23 static const String addMinGW = "";
27 addMinGW = withoutMinGW;
30 s = PrintString(versionString, addMinGW, " -- ", builtOnString, dateString);
35 static bool IsAdministrator()
38 SID_IDENTIFIER_AUTHORITY NtAuthority = { SECURITY_NT_AUTHORITY };
39 PSID AdministratorsGroup;
40 b = AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &AdministratorsGroup);
43 if(!CheckTokenMembership(NULL, AdministratorsGroup, &b))
45 FreeSid(AdministratorsGroup);
55 const char * OnGetString(char * tempString, void * fieldData, bool * needClass)
59 strcpy(tempString, name);
60 strcat(tempString, " (32)");
66 void OnDisplay(Surface surface, int x, int y, int width, void * fieldData, Alignment alignment, DataDisplayFlags displayFlags)
68 if(!displayFlags.active) { displayFlags.current = false; displayFlags.selected = false; }
69 class::OnDisplay(surface, x + 22, y, width - 22, fieldData, alignment, displayFlags);
73 //#define BUFFERSIZE 0x10000
74 #define BUFFERSIZE 0x1000
75 bool abortInstall = false;
77 void ExtractFileFromArchive(ProgressBar progressBar, const char * path, const char * outputFile)
79 char fileName[MAX_LOCATION];
80 FileAttribs exists = FileExists(path);
84 if(exists.isDirectory)
86 FileListing listing { path };
90 if(MakeDir(outputFile))
93 FileGetStats(path, &stats);
97 while(listing.Find() && !abortInstall)
99 strcpy(fileName, outputFile);
101 // Tweak file name if out
104 if(!strcmp(fileName, ".")) fileName[0] = '\0';
105 if(listing.name[0] == '/' || listing.name[0] == '\\')
107 char * afterSlash, rest[MAX_LOCATION];
108 for(afterSlash = fileName; *afterSlash == '/' || *afterSlash == '\\'; afterSlash++);
109 strcpy(rest, afterSlash);
110 PathCat(fileName, "_root");
111 PathCat(fileName, rest);
113 else if(listing.name[1] == ':')
116 sprintf(letter, "_%cdrive", toupper(listing.name[0]));
117 PathCat(fileName, letter);
118 PathCat(fileName, listing.name[2] ? (listing.name + 3) : (listing.name + 2));
121 PathCat(fileName, listing.name);
124 PathCat(fileName, listing.name);
125 if(!strcmp(fileName, "/") || !strcmp(fileName, "\\"))
126 strcpy(fileName, DIR_SEPS);
127 ExtractFileFromArchive(progressBar, listing.path, fileName);
133 File input = FileOpen(path, read);
136 File output = FileOpen(outputFile, write);
139 char fileName[MAX_FILENAME];
140 uint position = progressBar.progress;
143 byte buffer[BUFFERSIZE];
145 FileGetSize(path, &dataSize);
146 GetLastDirectory(outputFile, fileName);
148 ((GuiApplication)__thisModule).SignalEvent();
149 //((GuiApplication)__thisModule).ProcessInput();
150 //((GuiApplication)__thisModule).UpdateDisplay();
152 for(c = 0; c<dataSize && !abortInstall; c += BUFFERSIZE)
154 uint size = (dataSize > c + BUFFERSIZE) ? BUFFERSIZE : (dataSize - c);
156 ((GuiApplication)__thisModule).Unlock();
158 input.Read(buffer, 1, size);
159 output.Write(buffer, 1, size);
161 ((GuiApplication)__thisModule).Lock();
163 progressBar.progress = position + c + size;
164 ((GuiApplication)__thisModule).SignalEvent();
166 //((GuiApplication)__thisModule).ProcessInput();
167 //((GuiApplication)__thisModule).UpdateDisplay();
172 FileGetStats(path, &stats);
178 FileSetTime(outputFile, stats.created, 0, stats.modified);
181 public enum BitArch { none, bits32, bits64 };
186 const char * dataPath;
187 const char * defInstallPath;
188 Component * subComponents;
198 char installPath[MAX_LOCATION];
201 void GetFullPath(char * path, bool is32bit)
203 if(this != null && parent)
204 parent->GetFullPath(path, is32bit || (arch == bits32 && osIS64bit));
206 strcpy(path, (this && (is32bit || (arch == bits32 && osIS64bit))) ? installDir32 : installDir);
209 PathCat(path, installPath);
212 void Install(char * parentPath, char * parentPath32)
215 if(selected && (arch == none || arch == bits32 || osIS64bit))
217 char path64[MAX_LOCATION];
218 char path32[MAX_LOCATION];
219 strcpy(path64, parentPath);
220 PathCat(path64, installPath);
222 strcpy(path32, parentPath32);
223 PathCat(path32, installPath);
225 installProgress.installing.SetText($"Installing %s...", name);
226 ((GuiApplication)__thisModule).UpdateDisplay();
230 char * path = path64;
231 char source[MAX_LOCATION];
233 strcat(source, dataPath);
240 if(FileExists(source).isFile)
242 char name[MAX_FILENAME];
243 GetLastDirectory(source, name);
247 ExtractFileFromArchive(installProgress.progressBar, source, path);
251 for(c = 0; subComponents[c].name; c++)
252 subComponents[c].Install(path64, path32);
259 define minGWIncluded = true;
261 define minGWIncluded = false;
264 Array<Component> samples
266 { "3D", "samples/3D", "3D", null, false, true, true, none },
267 { "Android", "samples/android", "android", null, false, true, true, none },
268 { $"Audio", "samples/audio", "audio", null, false, true, true, none },
269 { $"Database", "samples/db", "db", null, false, true, true, none },
270 { "eC", "samples/eC", "eC", null, false, true, true, none },
271 { $"Games", "samples/games", "games", null, false, true, true, none },
272 { $"GUI & Graphics", "samples/guiAndGfx", "guiAndGfx", null, false, true, true, none },
273 { $"Miscellaneous", "samples/misc", "misc", null, false, true, true, none },
274 { $"Networking", "samples/net", "net", null, false, true, true, none },
275 { $"WIA Scanning", "samples/scanning", "scanning", null, false, true, true, none },
276 { $"Threading", "samples/threads", "threads", null, false, true, true, none },
280 public enum CoreSDKID
282 ide, ide32, runtime, runtime32, ec, ec32,
283 gcc, gdb, mingw, binutils, make,
287 Array<Component> coreSDK
289 { "Ecere IDE", "ecere-sdk/ide", "bin", null, true, true, true, bits64 },
290 { "Ecere IDE", "ecere-sdk32/ide", "bin", null, true, true, true, bits32 },
291 { $"Runtime Library", "ecere-sdk/ecere.dll", "bin", null, true, true, true, bits64 },
292 { $"Runtime Library", "ecere-sdk32/ecere.dll", "bin", null, true, true, true, bits32 },
293 { $"eC Compiler", "ecere-sdk/compiler", "bin", null, true, true, true, bits64 },
294 { $"eC Compiler", "ecere-sdk32/compiler", "bin", null, true, true, true, bits32 },
295 { $"GNU C Compiler", "tdm/gcc/core", "tdm", null, true, true, minGWIncluded, none },
296 { $"GNU Debugger", "tdm/gdb", "tdm", null, true, true, minGWIncluded, none },
297 { $"MinGW-w64 Runtime", "tdm/mingwrt", "tdm", null, true, true, minGWIncluded, none },
298 { $"Binary Utils", "tdm/binutils", "tdm", null, true, true, minGWIncluded, none },
299 { $"GNU Make", "tdm/make", "tdm", null, true, true, minGWIncluded, none },
303 public enum AdditionalID
305 eda, eda32, audio, audio32, vanilla, vanilla32, extras, upx, gnurx, gnurx32, /*pthreads, */cpp, /*w32api, gcci18n, gdbi18n, makei18n, binutilsi18n, */none
308 Array<Component> additional
310 { $"Data Access", "ecere-sdk/eda", "bin", null, false, true, true, bits64 },
311 { $"Data Access", "ecere-sdk32/eda", "bin", null, false, true, true, bits32 },
312 { $"Ecere Audio", "ecere-sdk/EcereAudio.dll", "bin", null, false, true, true, bits64 },
313 { $"Ecere Audio", "ecere-sdk32/EcereAudio.dll", "bin", null, false, true, true, bits32 },
314 { $"Ecere Vanilla", "ecere-sdk/libecereVanilla.a", "lib", null, false, true, true, bits64 },
315 { $"Ecere Vanilla", "ecere-sdk32/libecereVanilla.a", "lib", null, false, true, true, bits32 },
316 { $"Ecere Extras", "extras", "extras", null, false, true, true, none },
317 { "UPX", "upx/bin", "upx/bin", null, false, true, true, none },
318 { $"GNU Regexp", "tdm/gnurx", "tdm", null, false, true, true, bits64 },
319 { $"GNU Regexp", "tdm/gnurx32", "tdm", null, false, true, true, bits32 },
320 // { "pthreads", "tdm/pthreads", "mingw", null, false, true, minGWIncluded, none },
321 { $"C++ Compiler", "tdm/gcc/c++", "tdm", null, false, true, minGWIncluded, none },
322 // { "Win32 APIs", "mingw/w32api", "mingw", null, false, true, minGWIncluded, none },
323 /* { "GCC I18n", "mingw/locale/gcc", "tdm", null, false, false, minGWIncluded, none },
324 { "GDB I18n", "mingw/locale/gdb", "tdm", null, false, false, minGWIncluded, none },
325 { "Make I18n", "mingw/locale/make", "tdm", null, false, false, minGWIncluded, none },
326 { "Binutils I18n", "mingw/locale/binutils", "tdm", null, false, false, minGWIncluded, none },
331 public enum DocumentationID
333 ecereBook, apiRef, coursework,
334 gccDoc, gppDocs, gdbDocs, makeDocs, binDocs, mingwDocs, gnurxDocs, upxDocs,
338 Array<Component> documentation
340 { $"Ecere Book", "ecere-sdk/book", "doc", null, false, true, true, none },
341 { $"API Reference", "ecere-sdk/doc", "doc", null, false, true, true, none },
342 { $"Ecere Coursework", "ecere-sdk/coursework", "doc", null, false, true, true, none },
343 { $"GCC Docs", "tdm/doc/gcc", "tdm", null, false, false, minGWIncluded, none },
344 { $"G++ Docs", "tdm/doc/g++", "tdm", null, false, false, minGWIncluded, none },
345 { $"GDB Docs", "tdm/doc/gdb", "tdm", null, false, false, minGWIncluded, none },
346 { $"Make Docs", "tdm/doc/make", "tdm", null, false, false, minGWIncluded, none },
347 { $"Binutils Docs", "tdm/doc/binutils", "tdm", null, false, false, minGWIncluded, none },
348 { $"gnurx Docs", "tdm/doc/gnurx", "tdm", null, false, false, minGWIncluded, none },
349 { $"UPX Docs", "upx/doc", "upx/doc", null, false, false, minGWIncluded, none },
353 public enum ComponentID
362 Array<Component> components
364 { $"Core SDK Files", null, null, coreSDK.array, true, true, true, none },
365 { $"Additional Support", null, null, additional.array, false, true, true, none },
366 { $"Documentation", null /*"doc"*/, null /*"doc"*/, documentation.array, false, true, true, none },
367 { $"Samples", null, "samples", samples.array, false, true, true, none },
371 FileSize totalInstalled;
376 InstallOption * subOptions;
382 enum AssociateOptions
393 Array<InstallOption> associateOptions
395 { $"Associate with Ecere Project Files (*.epj)", null, true },
396 { $"Associate with eC Files (*.ec, *.eh)", null, true },
397 { $"Associate with C files (*.c, *.h)", null, false },
398 { $"Associate with C++ Files (*.cpp, *.hpp, *.cc, *.hh, *.cxx, *.hxx)", null, false },
399 { $"Associate with text files (*.txt)", null, false },
400 { $"Associate with 3D Studio Model Files (*.3ds)", null, true },
401 { $"Associate with Image Files (*.png, *.jpg, *.pcx, *.bmp, *.gif)", null, false },
407 AddECEREPaths, AddMinGWPaths
410 Array<InstallOption> pathOptions
412 { $"Add Ecere binaries location to the user environment path", null, true, true },
413 { $"Add MinGW to the user environment path", null, true, minGWIncluded },
424 Array<InstallOption> options
426 { $"Install for All Users", null, true, true },
427 { $"Start Menu Group", null, true, true },
428 { $"Desktop Icon", null, true, true },
429 { $"Quicklaunch Icon", null, true, true },
430 { $"Associate the Ecere IDE with Supported File Types", associateOptions.array, true, true },
431 { $"Add binaries location to the user environment paths", pathOptions.array, true, minGWIncluded },
435 char sourceDir[MAX_LOCATION] = ":";
436 char installDir[MAX_LOCATION];
437 char installDir32[MAX_LOCATION];
440 class Installer : Window
442 background = formColor;
447 clientSize = { 636, 476 };
448 icon = { ":icon.png" };
449 caption = $"Ecere Software Development Kit Setup - v0.44.13 \"Ryōan-ji\" 64 Bit Edition";
451 // clientSize = { 796, 576 };
454 Picture back { image = BitmapResource { ":ryoanji.png" }, parent = this, position = { 0, 0 } };
455 FileDialog fileDialog
457 master = this, type = selectDir,
458 caption = $"Select a new location"
462 master = this, autoCreate = false, inactive = true, caption = "...";
464 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
466 DataRow row = componentsBox.currentRow;
467 Component * component = ((CheckItem *)row.GetData(componentField))->data;
468 char filePath[MAX_LOCATION];
469 component->GetFullPath(filePath, false);
470 fileDialog.filePath = filePath;
471 StripLastDirectory(filePath, filePath);
472 fileDialog.currentDirectory = filePath;
474 if(fileDialog.Modal() == ok)
476 componentsBox.StopEditing(false);
477 row.SetData(locationField, fileDialog.filePath);
478 componentsBox.NotifyChanged(this, componentsBox, row);
479 componentsBox.currentField = componentsBox.currentField;
484 CheckListBox componentsBox
486 this, size = { 460, 112 }, position = { 160, 160 }, hasHeader = true;
487 fullRowSelect = false, collapseControl = true, treeBranches = true, rootCollapseButton = true,
488 hasHorzScroll = true;
492 selectionColor = { 145, 150, 140 };
497 bool NotifyKeyDown(ListBox listBox, DataRow row, Key key, unichar ch)
499 if(key == f2 && browse.visible)
500 browse.NotifyClicked(this, browse, 0, 0, 0);
504 bool NotifyChanged(ListBox listBox, DataRow row)
506 Component * component = ((CheckItem *)listBox.GetData(componentField))->data;
507 char path[MAX_LOCATION], relative[MAX_LOCATION] = "", * newPath;
508 char fullPath[MAX_LOCATION];
510 component->parent->GetFullPath(path, false);
511 strcpy(fullPath, path);
513 newPath = row.GetData(locationField);
516 PathCat(fullPath, newPath);
517 if(IsPathInsideOf(fullPath, path))
518 MakePathRelative(fullPath, path, relative);
520 strcpy(relative, fullPath);
522 listBox.SetData(locationField, relative);
523 strcpy(component->installPath, relative);
525 //SetAvailableSpace(component, path);
528 install.disabled = false;
529 for(c = 0; components[c].name; c++)
531 SetAvailableSpace(components[c], installDir);
537 bool NotifyEditDone(ListBox listBox, DataRow row)
543 bool NotifyEdited(ListBox listBox, DataRow row)
546 browse.parent = listBox;
547 browse.position = { componentField.width + locationField.width + 18, (listBox.currentIndex+1) * listBox.rowHeight - 2 };
548 browse.size = { 30, listBox.rowHeight + 3 };
549 for(e = listBox.firstChild; e; e = e.next)
551 if(e._class == class(DataBox))
560 void NotifyChecked(CheckListBox listBox, DataRow row)
562 Component * component = ((CheckItem *)row.GetData(componentField))->data;
564 component->selected = listBox.IsChecked(row);
566 if(!component->parent) totalSize -= component->requiredSize;
567 component->requiredSize = 0;
568 if(component->selected)
570 component->requiredSize += component->size;
571 if(component->subComponents)
572 for(c = 0; component->subComponents[c].name; c++)
573 component->requiredSize += component->subComponents[c].requiredSize;
575 if(component->requiredSize)
577 uint requiredSize = component->requiredSize;
578 row.SetData(reqField, requiredSize);
581 row.UnsetData(reqField);
582 if(!component->parent)
584 totalSize += component->requiredSize;
586 char sizeString[100];
587 PrintSize(sizeString, totalSize, 2);
588 totalSpaceValue.caption = sizeString;
593 Label agreementLbl { parent = this, caption = $"By installing the Ecere SDK, you agree to the", font = { "Tahoma", 8.25f }, anchor = Anchor { right = 399, top = 448 } };
596 this, inactive = true, offset = false, bevel = false, foreground = blue, font = { "Tahoma", 8.25f, underline = true, bold = true },
597 // caption = $"terms and conditions", anchor = Anchor { left = 241, top = 421 };
598 caption = $"terms and conditions", anchor = Anchor { left = 235, top = 445 };
599 cursor = ((GuiApplication)__thisModule).GetCursor(hand);
601 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
603 // LicenseBox { master = this, sourceFile = ":ecere-sdk/doc/LICENSE" }.Modal();
604 LicensesForm { master = this }.Modal();
608 Label dotLbl { parent = this, caption = ".", font = { "Tahoma", 8.25f }, anchor = Anchor { left = 372, top = 448 } };
609 CheckListBox optionsBox
611 this, size = { 460, 114 }, position = { 160, 284 };
612 fullRowSelect = false, collapseControl = true, treeBranches = true, rootCollapseButton = true,
617 void NotifyChecked(CheckListBox listBox, DataRow row)
619 CheckItem * item = row.GetData(optionField);
620 InstallOption * option = item->data;
621 option->selected = listBox.IsChecked(row);
622 // Update default samples/extras path whether we're installing for All Users or not
623 if(option == &options[0])
625 char appData[MAX_LOCATION];
627 options[5].name = options[0].selected ? $"Add binaries location to the system environment paths" : $"Add binaries location to the user environment paths";
629 ((CheckItem *)options[5].row.GetData(optionField))->name = options[5].name;
631 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";
632 if(pathOptions[PathOptions::AddECEREPaths].row)
633 ((CheckItem *)pathOptions[PathOptions::AddECEREPaths].row.GetData(optionField))->name = pathOptions[PathOptions::AddECEREPaths].name;
635 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";
636 if(pathOptions[PathOptions::AddMinGWPaths].row)
637 ((CheckItem *)pathOptions[PathOptions::AddMinGWPaths].row.GetData(optionField))->name = pathOptions[PathOptions::AddMinGWPaths].name;
639 GetEnvironment(options[0].selected ? "ALLUSERSPROFILE" : "APPDATA", appData, sizeof(appData));
642 char defPath[MAX_LOCATION];
644 strcpy(defPath, installDir);
645 PathCat(defPath, components[ComponentID::samples].defInstallPath);
646 ChangeCh(defPath, '/', DIR_SEP);
647 if(!strcmp(defPath, components[ComponentID::samples].installPath))
649 static char defSamplesPath[MAX_LOCATION];
650 strcpy(defSamplesPath, appData);
651 PathCat(defSamplesPath, "Ecere SDK\\Samples");
652 components[ComponentID::samples].defInstallPath = defSamplesPath;
654 strcpy(components[ComponentID::samples].installPath, components[ComponentID::samples].defInstallPath);
655 ChangeCh(components[ComponentID::samples].installPath, '/', DIR_SEP);
656 components[ComponentID::samples].row.SetData(locationField, components[ComponentID::samples].installPath);
659 strcpy(defPath, installDir);
660 PathCat(defPath, additional[AdditionalID::extras].defInstallPath);
661 ChangeCh(defPath, '/', DIR_SEP);
662 if(!strcmp(additional[AdditionalID::extras].installPath, additional[AdditionalID::extras].installPath))
664 static char defExtrasPath[MAX_LOCATION];
665 strcpy(defExtrasPath, appData);
666 PathCat(defExtrasPath, "Ecere SDK\\extras");
667 additional[AdditionalID::extras].defInstallPath = defExtrasPath;
669 strcpy(additional[AdditionalID::extras].installPath, additional[AdditionalID::extras].defInstallPath);
670 ChangeCh(additional[AdditionalID::extras].installPath, '/', DIR_SEP);
671 additional[AdditionalID::extras].row.SetData(locationField, additional[AdditionalID::extras].installPath);
674 listBox.Update(null);
680 parent = this, caption = $"Install", isDefault = true, size = { 75, 23 }, position = { 432, 440 };
682 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
684 installProgress.Create();
686 // installProgress.thread.Main();
687 installProgress.thread.Create();
691 Button button3 { parent = this, caption = $"Cancel", hotKey = altX, size = Size { 75, 23 }, anchor = Anchor { left = 544, top = 440 }, NotifyClicked = ButtonCloseDialog };
694 this, position = { 14, 374 }, size = { 142, 0 }, caption = "Language:";
696 bool NotifySelect(DropBox dropBox, DataRow row, Modifiers mods)
698 LanguageOption * option = row.GetData(null);
699 // If the language is already set, we need to override it
701 IDESettings settings = null;
702 IDESettingsContainer settingsContainer
705 dataOwner = &settings;
706 dataClass = class(IDESettings);
707 allUsers = options[0].selected;
709 settingsContainer.Load();
710 if(settings.language)
712 settings.language = option->code;
713 settingsContainer.Save();
715 delete settingsContainer;
718 ((GuiApplication)__thisModule.application).desktop.Destroy(0);
719 LanguageRestart(option->code, __thisModule.application, null, null, null, null, false);
723 Label lblLanguageBox { this, position = { 14, 354 }, labeledWindow = languageBox };
724 Label label1 { labeledWindow = destBox, tabCycle = true, isGroupBox = true, parent = this, inactive = false, size = Size { 458, 50 }, anchor = Anchor { left = 160, top = 96 } };
727 parent = label1, master = this, caption = $" Destination Folder", size = Size { 336, 22 }, anchor = Anchor { left = 12, top = 20, right = 12 };
728 typeExpected = directory;
729 browseDialog = fileDialog;
732 bool NotifyModified(PathBox pathBox)
735 strcpy(installDir, destBox.path);
736 install.disabled = false;
737 for(c = 0; components[c].name; c++)
739 SetAvailableSpace(components[c], installDir);
746 label1, this, $"Browse", altB, size = { 83, 24 }, position = { 360, 16 };
748 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
750 strcpy(fileDialog.filePath, installDir);
751 StripLastDirectory(installDir, fileDialog.currentDirectory);
752 if(fileDialog.Modal())
754 strcpy(installDir, fileDialog.filePath);
755 destBox.contents = installDir;
756 // TOCHECK: Should setting contents call NotifyModified?
757 destBox.NotifyModified(destBox.master, destBox);
764 this, multiLine = true,
765 opacity = 0, borderStyle = none, inactive = true, size = { 136, 53 }, position = { 14, 96 }, noSelect = true,
766 contents = $"Select the default root\n"
767 "folder where to install\n"
772 this, opacity = 0, borderStyle = none, inactive = true, size = { 136, 132 }, position = { 14, 152 }, noSelect = true,
774 contents = $"Select the optional\n"
775 "components you wish\n"
777 "You may customize the\n"
778 "install location for each\n"
779 "of them, or use the default\n"
780 "based on the main\n"
781 "destination folder."
785 this, opacity = 0, borderStyle = none, inactive = true, size = { 136, 83 }, position = { 14, 280 }, noSelect = true,
787 contents = $"Select icons to install, file\n"
788 "associations, and system\n"
789 "environment modifications:"
791 Label totalSpaceLabel
793 this, anchor = { right = 72, top = 404 }, caption = $"Space Required: "
795 Label totalSpaceValue
797 this, anchor = { right = 14, top = 404 }, caption = "0 mb"
801 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"
802 "of the SDK to install, as well as where to install program icons."
804 Label label2 { parent = this, position = { 16, 422 }, font = { "Tahoma", 10, true }, disabled = true, opacity = 0, background = activeBorder };
807 image = BitmapResource { ":ecere.png", alphaBlend = true }, filter = true, parent = label3, caption = "picture1", anchor = Anchor { left = 16, top = 4 };
808 cursor = ((GuiApplication)__thisModule).GetCursor(hand);
810 bool OnLeftButtonDown(int x, int y, Modifiers mods)
812 ShellOpen("http://www.ecere.com/");
816 Label label4 { label3, font = { "Tahoma", 8.25f, bold = true }, /*size = { 326, 16 }, */position = { 248, 24 }, caption = $"Choose Components, Locations and Install Options" };
817 DataField componentField { "CheckItem", width = 160, header = $"Component" };
818 DataField locationField { "char *", width = 108, header = $"Destination Folder", editable = true };
819 DataField reqField { "FileSize", width = 70, header = $"Req. Space", alignment = right };
820 DataField avField { "FileSize64", width = 70, header = $"Avail. Space", alignment = right };
821 DataField optionField { "CheckItem" };
823 DataField languageField { class(LanguageOption) };
825 void SetAvailableSpace(Component component, const char * parentPath)
827 char path[MAX_LOCATION];
831 strcpy(path, parentPath);
832 PathCat(path, component.installPath);
834 if(component.subComponents)
835 for(c = 0; component.subComponents[c].name; c++)
836 SetAvailableSpace(component.subComponents[c], path);
838 while(!FileExists(path) && path[0])
839 StripLastDirectory(path, path);
842 GetFreeSpace(path, &size);
843 component.row.SetData(avField, size);
844 if(!size) install.disabled = true;
847 FileSize ComputeSize(const char * path)
850 FileAttribs attribs = FileExists(path);
851 if(attribs.isDirectory)
853 FileListing listing { path };
854 while(listing.Find())
856 if(listing.stats.attribs.isDirectory)
857 size += ComputeSize(listing.path);
859 size += listing.stats.size;
863 FileGetSize(path, &size);
867 void AddComponent(Component component, Component parent, const char * parentPath)
869 DataRow row = (parent != null) ? parent.row.AddRow() : componentsBox.AddRow();
871 FileSize64 avSize = 0;
872 char path[MAX_LOCATION];
875 strcpy(path, parentPath);
876 if(component.defInstallPath)
877 PathCat(path, component.defInstallPath);
878 component.parent = parent;
880 row.SetData(null, CheckItem { component.name, component, (component.arch == bits32 && osIS64bit) } );
882 if(component.defInstallPath)
884 strcpy(component.installPath, component.defInstallPath);
885 ChangeCh(component.installPath, '/', DIR_SEP);
886 row.SetData(locationField, component.installPath);
889 if(component.mandatory)
891 if(component.arch != bits32 || !osIS64bit) // || component == &coreSDK[gdb32])
892 componentsBox.SetDisabled(row, true);
894 component.selected = false;*/
896 else if(component.arch == bits32 && osIS64bit)
897 ; //component.selected = false;
899 componentsBox.SetCheck(row, component.selected);
901 if(component.dataPath)
903 char path[MAX_LOCATION];
905 PathCat(path, component.dataPath);
906 component.size = ComputeSize(path);
908 if(component.subComponents)
911 for(c = 0; component.subComponents[c].name; c++)
913 Component * sub = &component.subComponents[c];
914 if(sub->available && (osIS64bit || sub->arch == bits32 || sub->arch == none))
916 AddComponent(sub, component, path);
917 size += sub->requiredSize;
920 sub->selected = false;
924 component.requiredSize = component.selected ? (size + component.size) : 0;
925 if(component.requiredSize)
926 row.SetData(reqField, component.requiredSize);
928 while(!FileExists(path) && path[0])
929 StripLastDirectory(path, path);
932 GetFreeSpace(path, &avSize);
935 row.SetData(avField, avSize);
936 row.collapsed = true;
939 void AddOption(InstallOption option, InstallOption parent)
941 DataRow row = option.row = (parent != null) ? parent.row.AddRow() : optionsBox.AddRow();
942 row.SetData(null, CheckItem { option.name, option } );
943 optionsBox.SetCheck(row, option.selected);
944 if(option.subOptions)
947 for(c = 0; option.subOptions[c].name; c++)
949 AddOption(option.subOptions[c], option);
952 row.collapsed = true;
958 char programFilesDir[MAX_LOCATION];
959 char appData[MAX_LOCATION];
960 char homeDrive[MAX_LOCATION];
961 char winDir[MAX_LOCATION];
964 bool isAdministrator = IsAdministrator();
966 SetBuildString(label2);
970 options[0].available = false;
971 options[0].selected = false;
974 // If the SDK is already installed, use currently selected language
976 IDESettings settings = null;
977 IDESettingsContainer settingsContainer
980 dataOwner = &settings;
981 dataClass = class(IDESettings);
982 allUsers = options[0].selected;
985 settingsContainer.Load();
987 if(settings.language)
989 const String language = GetLanguageString();
990 if(settings.language.OnCompare(language))
992 // Relaunch the installer with previously selected language
993 LanguageRestart(settings.language, __thisModule.application, null, null, null, null, false);
997 delete settingsContainer;
1001 GetEnvironment("HOMEDRIVE", homeDrive, sizeof(homeDrive));
1002 GetEnvironment("windir", winDir, sizeof(winDir));
1004 GetEnvironment(options[0].selected ? "ALLUSERSPROFILE" : "APPDATA", appData, sizeof(appData));
1006 componentsBox.AddField(componentField);
1007 componentsBox.AddField(locationField);
1008 componentsBox.AddField(reqField);
1009 componentsBox.AddField(avField);
1011 optionsBox.AddField(optionField);
1013 languageBox.AddField(languageField);
1015 programFilesDir[0] = 0;
1016 if(GetEnvironment("ProgramFiles", programFilesDir, MAX_LOCATION))
1018 x86 = strstr(programFilesDir, " (x86)");
1023 if(isAdministrator && programFilesDir[0])
1027 strcpy(installDir32, programFilesDir);
1028 PathCat(installDir32, "Ecere SDK");
1030 strcpy(installDir, programFilesDir);
1031 PathCat(installDir, "Ecere SDK");
1035 strcpy(installDir, programFilesDir);
1036 PathCat(installDir, "Ecere SDK");
1037 strcpy(installDir32, installDir);
1040 else if(homeDrive[0])
1042 strcpy(installDir, homeDrive);
1043 PathCat(installDir, "Ecere SDK");
1044 strcpy(installDir32, installDir);
1045 strcat(installDir32, " (32)");
1049 strcpy(installDir, winDir);
1050 PathCat(installDir, "..\\Ecere SDK");
1051 strcpy(installDir32, installDir);
1052 strcat(installDir32, " (32)");
1056 strcpy(installDir, "C:\\Ecere SDK");
1057 strcpy(installDir32, installDir);
1058 strcat(installDir32, " (32)");
1063 static char defSamplesPath[MAX_LOCATION];
1064 static char defExtrasPath[MAX_LOCATION];
1065 strcpy(defSamplesPath, appData);
1066 PathCat(defSamplesPath, "Ecere SDK\\Samples");
1067 components[ComponentID::samples].defInstallPath = defSamplesPath;
1069 strcpy(defExtrasPath, appData);
1070 PathCat(defExtrasPath, "Ecere SDK\\extras");
1071 additional[AdditionalID::extras].defInstallPath = defExtrasPath;
1074 destBox.path = installDir;
1078 for(c = 0; components[c].name; c++)
1079 AddComponent(components[c], null, installDir);
1082 // Compute size apart because ToggleCheck will change it
1086 for(c = 0; components[c].name; c++)
1087 totalSize += components[c].requiredSize;
1090 char sizeString[100];
1091 PrintSize(sizeString, totalSize, 2);
1092 totalSpaceValue.caption = sizeString;
1094 for(c = 0; options[c].name; c++)
1096 if(options[c].available)
1097 AddOption(options[c], null);
1109 dotLbl.position.x = licenseButton.position.x + licenseButton.size.w - 4;
1115 // Constructor happens before Languages is instantiated...
1118 l.res = { l.bitmap, window = this };
1124 const String language = GetLanguageString();
1128 // Try to find country-specific language first
1131 LanguageOption option = l;
1132 row = languageBox.AddRow();
1133 row.SetData(null, option); // TOFIX: l used directly here
1135 if(!found && (!strcmpi(l.code, language) || (!row.GetPrevRow() && !strcmpi("en", language))))
1137 languageBox.currentRow = row;
1142 // Try generalizing locale
1146 char genericLocale[256];
1147 strncpy(genericLocale, language, sizeof(genericLocale));
1148 genericLocale[sizeof(genericLocale)-1] = 0;
1150 under = strchr(genericLocale, '_');
1153 if(!strcmpi(genericLocale, "zh"))
1154 strcpy(genericLocale, "zh_CN");
1155 if(strcmp(genericLocale, language))
1157 row = languageBox.firstRow;
1160 if(!strcmpi(l.code, genericLocale) || (!row.GetPrevRow() && !strcmpi("en", genericLocale)))
1162 languageBox.currentRow = row;
1166 row = row.GetNextRow();
1172 languageBox.currentRow = languageBox.firstRow;
1180 void OnDrawOverChildren(Surface surface)
1182 int tw = label2.size.w;
1183 surface.SetForeground(Color { 128, 128, 128 });
1184 surface.HLine(label2.position.x + tw + 6, 620, 430);
1185 surface.SetForeground(white);
1186 surface.HLine(label2.position.x + tw + 6, 621, 431);
1187 surface.PutPixel(621, 400);
1191 parent = this, opacity = 0, borderStyle = deep, size = Size { 644, 93 }, anchor = Anchor { left = -8, top = -8 };
1195 class InstallProgress : Window
1197 caption = $"Ecere Software Development Kit Setup - v0.44.13 \"Ryōan-ji\" 64 Bit Edition";
1198 background = activeBorder;
1199 borderStyle = fixed;
1203 // size = Size { 640, 480 };
1204 clientSize = { 636, 476 };
1205 //clientSize = { 796, 576 };
1206 icon = { ":icon.png" };
1210 SetBuildString(label2);
1213 Picture back { image = BitmapResource { ":ryoanji-progress.png" }, parent = this, position = { 0, 0 } };
1214 Label installing { this, position = { 32, 160 } };
1215 ProgressBar progressBar { parent = this, size = Size { 588, 24 }, anchor = Anchor { left = 24, top = 184 } };
1218 parent = this, caption = $"Install", disabled = true, isDefault = true, size = Size { 75, 23 }, anchor = Anchor { left = 432, top = 440 };
1220 NotifyClicked = ButtonCloseDialog
1224 this, caption = $"Cancel", hotKey = altX, size = Size { 75, 23 }, anchor = Anchor { left = 544, top = 440 };
1226 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
1228 abortInstall = true;
1234 inactive = true, noSelect = true,
1235 multiLine = true, parent = label3, opacity = 0, borderStyle = none, size = Size { 350, 35 }, anchor = Anchor { horz = 111, vert = 13 },
1236 contents = $"Please wait while the Ecere Software Development Kit is being installed."
1238 Label label2 { parent = this, position = { 16, 422 }, font = { "Tahoma", 10, true }, disabled = true, opacity = 0, background = activeBorder };
1241 image = BitmapResource { ":ecere.png", alphaBlend = true }, filter = true, parent = label3, anchor = Anchor { left = 16, top = 4 };
1242 cursor = ((GuiApplication)__thisModule).GetCursor(hand);
1244 bool OnLeftButtonDown(int x, int y, Modifiers mods)
1246 ShellOpen("http://www.ecere.com/");
1250 Label title { parent = label3, caption = $"Installing the Ecere SDK", font = FontResource { "Tahoma", 8.25f, bold = true }, size = Size { 326, 16 }, anchor = Anchor { horz = 91, vert = -12 } };
1252 void OnDrawOverChildren(Surface surface)
1254 int tw = label2.size.w;
1255 surface.SetForeground(Color { 128, 128, 128 });
1256 surface.HLine(label2.position.x + tw + 6, 620, 430);
1257 surface.SetForeground(white);
1258 surface.HLine(label2.position.x + tw + 6, 621, 431);
1259 surface.PutPixel(621, 400);
1264 parent = this, opacity = 0, borderStyle = deep, size = Size { 644, 93 }, anchor = Anchor { left = -8, top = -8 };
1266 InstallThread thread
1271 Installer installer {};
1272 InstallProgress installProgress { autoCreate = false };
1274 static void AddPath(char * sysPaths[200], int sysCount, char * paths[200], int * count, char * oldPath, char * userPath, char * path)
1278 for(p = 0; p<sysCount; p++)
1279 if(!fstrcmp(sysPaths[p], path))
1284 for(p = 0; !found && p<*count; p++)
1285 if(!fstrcmp(paths[p], path))
1295 strcat(userPath, ";");
1296 start = paths[(*count)-1] + strlen(paths[(*count)-1])+1;
1301 strcpy(start, path);
1302 *(start + strlen(path)) = '\0';
1303 paths[(*count)++] = start;
1305 strcat(userPath, path);
1310 void ModifyPath(char * systemPath, char * userPath)
1312 char oldPath[8192], * paths[200], * sysPaths[200];
1313 int count, sysCount = 0;
1317 strcpy(oldPath, userPath);
1318 count = TokenizeWith(oldPath, sizeof(paths) / sizeof(char *), paths, ";", false);
1319 sysCount = TokenizeWith(systemPath, sizeof(sysPaths) / sizeof(char *), sysPaths, ";", false);
1323 strcpy(oldPath, systemPath);
1324 count = TokenizeWith(oldPath, sizeof(paths) / sizeof(char *), paths, ";", false);
1329 for(c = 0; coreSDK[c].name; c++)
1331 char path[MAX_LOCATION];
1332 if(!coreSDK[c].selected) continue;
1333 coreSDK[c].GetFullPath(path, false);
1334 if(c != ide && c != runtime && c != ec &&
1335 c != ide32 && c != runtime32 && c != ec32)
1337 if(!pathOptions[PathOptions::AddMinGWPaths].available || !pathOptions[PathOptions::AddMinGWPaths].selected)
1339 PathCat(path, "bin");
1341 else if(!pathOptions[PathOptions::AddECEREPaths].selected) continue;
1343 AddPath(sysPaths, sysCount, paths, &count, oldPath, userPath ? userPath : systemPath, path);
1349 for(c = 0; c <= cpp; c++)
1351 char path[MAX_LOCATION];
1352 if(!additional[c].selected || c == vanilla || c == vanilla32 || c == extras) continue;
1353 if((c != eda && c != eda32 && c != upx) && (!pathOptions[PathOptions::AddMinGWPaths].available || !pathOptions[PathOptions::AddMinGWPaths].selected))
1355 additional[c].GetFullPath(path, false);
1356 if(c != eda && c != eda32 && c != upx && c != audio && c != audio32)
1357 PathCat(path, "bin");
1358 AddPath(sysPaths, sysCount, paths, &count, oldPath, userPath ? userPath : systemPath, path);
1363 void AssociateExtension(const char * extension, const char * description, const char *name, const char * action, const char * path)
1369 RegCreateKeyEx(HKEY_CLASSES_ROOT, extension, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1370 RegSetValueEx(key, null, 0, REG_SZ, (byte *)name, (uint)strlen(name)+1);
1373 RegCreateKeyEx(HKEY_CLASSES_ROOT, name, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1374 RegSetValueEx(key, null, 0, REG_SZ, (byte *)description, (uint)strlen(description)+1);
1377 sprintf(keyName, "%s\\shell", extension);
1378 RegCreateKeyEx(HKEY_CLASSES_ROOT, keyName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1379 RegSetValueEx(key, null, 0, REG_SZ, (byte *)action, (uint)strlen(action)+1);
1382 sprintf(keyName, "%s\\shell\\%s", name, action);
1383 RegCreateKeyEx(HKEY_CLASSES_ROOT, keyName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1386 sprintf(keyName, "%s\\shell\\%s\\command", name, action);
1387 RegCreateKeyEx(HKEY_CLASSES_ROOT, keyName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1389 sprintf(keyName, path);
1390 strcat(keyName, " \"%L\"");
1392 uint16 wKeyName[2048];
1393 UTF8toUTF16Buffer(keyName, wKeyName, sizeof(wKeyName) / sizeof(uint16));
1394 RegSetValueExW(key, null, 0, REG_SZ, (byte *)wKeyName, (uint)(wcslen(wKeyName) + 1)*sizeof(uint16));
1399 class InstallThread : Thread
1404 ((GuiApplication)__thisModule).Lock();
1405 installProgress.progressBar.range = totalSize;
1408 strcpy(installDir32, installDir);
1410 for(c = 0; components[c].name && !abortInstall; c++)
1411 components[c].Install(installDir, installDir32);
1414 installProgress.progressBar.range = 0;
1415 installProgress.finish.Destroy(0);
1416 installProgress.cancel.caption = $"Close";
1417 installProgress.cancel.isDefault = true;
1418 installProgress.cancel.disabled = false;
1419 installProgress.cancel.NotifyClicked = Window::ButtonCloseDialog;
1420 installProgress.installing.caption = $"Installation Cancelled.";
1421 installProgress.title.caption = $"Installation Cancelled";
1422 installProgress.titleInfo.contents = $"The installation was not completed.";
1426 char idePath[MAX_LOCATION];
1427 char userProfile[MAX_LOCATION];
1430 IDESettings settings = null; // Don't instantiate yet so we can pick up old settings
1432 IDESettingsContainer settingsContainer
1435 dataOwner = &settings;
1436 dataClass = class(IDESettings);
1437 allUsers = options[0].selected;
1439 CompilerConfig compiler;
1440 installProgress.installing.caption = $"Configuring Ecere IDE...";
1441 ((GuiApplication)__thisModule).Unlock();
1442 ((GuiApplication)__thisModule).SignalEvent();
1444 settingsContainer.Load();
1445 compiler = settings.GetCompilerConfig(defaultCompilerName);
1450 for(c = 0; coreSDK[c].name; c++)
1452 char path[MAX_LOCATION];
1453 if(!coreSDK[c].selected || !coreSDK[c].available) continue;
1455 coreSDK[c].GetFullPath(path, false);
1456 if(c != ide && c != runtime && c != ec &&
1457 c != ide32 && c != runtime32 && c != ec32)
1458 PathCat(path, "bin");
1459 MakeSlashPath(path);
1460 if((c == ide && osIS64bit) || (c == ide32 && !osIS64bit))
1462 coreSDK[c].GetFullPath(idePath, false);
1463 PathCat(idePath, "ide.exe");
1466 if(c == runtime || c == runtime32)
1468 if(!compiler.libraryDirs.Find(path))
1469 compiler.libraryDirs.Add(CopyString(path));
1476 for(c = 0; c <= cpp; c++)
1478 char path[MAX_LOCATION];
1479 if(c == extras || !additional[c].selected || !additional[c].available) continue;
1480 additional[c].GetFullPath(path, false);
1481 if(c != upx && c != eda && c != vanilla && c != eda32 && c != vanilla32)
1482 PathCat(path, "bin");
1483 MakeSlashPath(path);
1484 if(c == vanilla || c == vanilla32)
1486 if(!compiler.libraryDirs.Find(path))
1487 compiler.libraryDirs.Add(CopyString(path));
1491 if(!compiler.executableDirs.Find(path))
1492 compiler.executableDirs.Add(CopyString(path));
1499 char path[MAX_LOCATION] = "";
1501 if(components[ComponentID::samples].selected)
1502 components[ComponentID::samples].GetFullPath(path, false);
1503 // IDE will now default to HOME for the default project/files locations
1505 if(!settings.ideProjectFileDialogLocation[0])
1506 settings.ideProjectFileDialogLocation = path;
1507 if(!settings.ideFileDialogLocation[0])
1508 settings.ideFileDialogLocation = path;
1510 if(documentation[DocumentationID::apiRef].selected)
1512 documentation[DocumentationID::apiRef].GetFullPath(path, false);
1513 if(!settings.docDir[0])
1514 settings.docDir = path;
1518 settings.language = GetLanguageString();
1520 // Set LANGUAGE environment variable
1523 uint16 wLanguage[256];
1527 if(options[0].selected)
1528 RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", 0, KEY_ALL_ACCESS, &key);
1530 RegCreateKeyEx(HKEY_CURRENT_USER, "Environment", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1533 UTF8toUTF16Buffer(settings.language, wLanguage, sizeof(wLanguage) / sizeof(uint16));
1534 RegSetValueExW(key, L"ECERE_LANGUAGE", 0, REG_EXPAND_SZ, (byte *)wLanguage, (uint)(wcslen(wLanguage)+1) * 2);
1539 settingsContainer.Save();
1540 delete settingsContainer;
1543 // Set up Uninstaller
1544 ((GuiApplication)__thisModule).Lock();
1545 installProgress.installing.caption = $"Registering uninstaller...";
1546 ((GuiApplication)__thisModule).Unlock();
1547 ((GuiApplication)__thisModule).SignalEvent();
1552 const char * displayName = "Ecere SDK 0.44";
1553 char uninstaller[MAX_LOCATION];
1554 //bool nomodify = true;
1556 strcpy(uninstaller, installDir);
1557 PathCat(uninstaller, "uninstall_ecere.exe");
1559 RegCreateKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Ecere SDK", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1561 RegSetValueEx(key, "DisplayName", 0, REG_SZ, (byte *)displayName, (uint)strlen(displayName)+1);
1562 RegSetValueEx(key, "UninstallString", 0, REG_SZ, (byte *)uninstaller, (uint)strlen(uninstaller)+1);
1563 RegSetValueEx(key, "DisplayIcon", 0, REG_SZ, (byte *)idePath, (uint)strlen(idePath)+1);
1564 //RegSetValueEx(key, "NoModify", 0, REG_DWORD, (byte *)&nomodify, sizeof(nomodify));
1565 //RegSetValueEx(key, "NoRepair", 0, REG_DWORD, (byte *)&nomodify, sizeof(nomodify));
1570 if(pathOptions[PathOptions::AddECEREPaths].selected
1572 || pathOptions[PathOptions::AddMinGWPaths].selected
1576 HKEY userKey = null, systemKey = null;
1578 char userPath[8192] = "";
1579 char systemPath[8192] = "";
1580 uint16 wUserPath[8192];
1581 uint16 wSystemPath[8192];
1586 ((GuiApplication)__thisModule).Lock();
1587 installProgress.installing.caption = "Registering paths...";
1588 ((GuiApplication)__thisModule).Unlock();
1589 ((GuiApplication)__thisModule).SignalEvent();
1591 if(options[0].selected)
1593 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", 0, KEY_ALL_ACCESS, &systemKey) == ERROR_SUCCESS)
1595 size = sizeof(wSystemPath);
1596 RegQueryValueExW(systemKey, L"path", null, null, (byte *)wSystemPath, &size);
1597 UTF16toUTF8Buffer(wSystemPath, systemPath, sizeof(systemPath));
1598 ModifyPath(systemPath, null);
1600 UTF8toUTF16Buffer(systemPath, wSystemPath, sizeof(wSystemPath) / sizeof(uint16));
1601 RegSetValueExW(systemKey, L"path", 0, REG_EXPAND_SZ, (byte *)wSystemPath, (uint)(wcslen(wSystemPath)+1) * 2);
1602 RegCloseKey(systemKey);
1607 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", 0, KEY_QUERY_VALUE, &systemKey) == ERROR_SUCCESS)
1609 size = sizeof(wSystemPath);
1610 RegQueryValueExW(systemKey, L"path", null, null, (byte *)wSystemPath, &size);
1611 UTF16toUTF8Buffer(wSystemPath, systemPath, sizeof(systemPath));
1612 RegCloseKey(systemKey);
1615 RegCreateKeyEx(HKEY_CURRENT_USER, "Environment", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &userKey, &status);
1616 if(status == REG_OPENED_EXISTING_KEY)
1618 size = sizeof(wUserPath);
1619 RegQueryValueExW(userKey, L"path", null, null, (byte *)wUserPath, &size);
1620 UTF16toUTF8Buffer(wUserPath, userPath, sizeof(userPath));
1622 ModifyPath(systemPath, userPath);
1623 UTF8toUTF16Buffer(userPath, wUserPath, sizeof(wUserPath) / sizeof(uint16));
1624 RegSetValueExW(userKey, L"path", 0, REG_EXPAND_SZ, (byte *)wUserPath, (uint)(wcslen(wUserPath)+1) * 2);
1625 RegCloseKey(userKey);
1627 // SendMessageTimeout (HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)"Environment", SMTO_NORMAL, 1000, NULL);
1630 // Install Program Group Icons
1631 GetEnvironment(options[0].selected ? "ALLUSERSPROFILE" : "USERPROFILE", userProfile, sizeof(userProfile));
1633 if(options[IconOptions::StartMenuIcon].selected)
1635 char destPath[MAX_LOCATION];
1636 char startMenuPath[MAX_LOCATION] = "";
1639 ((GuiApplication)__thisModule).Lock();
1640 installProgress.installing.caption = $"Installing Start Menu Icons...";
1641 ((GuiApplication)__thisModule).Unlock();
1642 ((GuiApplication)__thisModule).SignalEvent();
1644 strcpy(destPath, userProfile);
1646 if(RegOpenKeyEx(options[0].selected ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
1647 "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", 0, KEY_QUERY_VALUE, &key) == ERROR_SUCCESS)
1649 uint16 wStartMenuPath[2048];
1650 DWORD size = sizeof(wStartMenuPath);
1651 // RegQueryValueEx(key, "Start Menu", null, null, startMenuPath, &size);
1652 RegQueryValueExW(key, options[0].selected ? L"Common Programs" : L"Programs", null, null, (byte *)wStartMenuPath, &size);
1653 UTF16toUTF8Buffer(wStartMenuPath, startMenuPath, sizeof(startMenuPath));
1656 if(!startMenuPath[0] && userProfile[0])
1658 strcpy(startMenuPath, userProfile);
1659 PathCat(startMenuPath, "Start Menu\\Programs");
1662 if(startMenuPath[0])
1664 strcpy(destPath, startMenuPath);
1665 PathCat(destPath, "Ecere SDK");
1668 strcpy(destPath, startMenuPath);
1669 PathCat(destPath, "Ecere SDK\\Ecere IDE.lnk");
1670 CreateLink(idePath, destPath, null); //"Ecere IDE");
1671 if(components[ComponentID::samples].selected)
1673 char samplesPath[MAX_LOCATION] = "";
1674 components[ComponentID::samples].GetFullPath(samplesPath, false);
1676 strcpy(destPath, startMenuPath);
1677 PathCat(destPath, "Ecere SDK\\Sample Projects.lnk");
1678 CreateLink(samplesPath, destPath, null);//"Sample Projects");
1680 if(components[ComponentID::documentation].selected && documentation[DocumentationID::ecereBook].selected)
1682 char docPath[MAX_LOCATION] = "";
1683 documentation[DocumentationID::ecereBook].GetFullPath(docPath, false);
1684 PathCat(docPath, "Ecere Tao of Programming [work in progress].pdf");
1687 char tao[MAX_LOCATION] ;
1688 documentation[DocumentationID::ecereBook].GetFullPath(tao, false);
1689 PathCat(tao, "tao.pdf");
1690 RenameFile(tao, docPath);
1693 strcpy(destPath, startMenuPath);
1694 PathCat(destPath, "Ecere SDK\\The Ecere Tao of Programming.lnk");
1695 CreateLink(docPath, destPath, null);
1700 // Install Desktop Icon
1701 if(options[IconOptions::DesktopIcon].selected)
1704 char desktopPath[MAX_LOCATION];
1706 if(RegOpenKeyEx(options[0].selected ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
1707 "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", 0, KEY_QUERY_VALUE, &key) == ERROR_SUCCESS)
1709 uint16 wDesktopPath[MAX_LOCATION];
1710 DWORD size = sizeof(wDesktopPath);
1711 RegQueryValueExW(key, options[0].selected ? L"Common Desktop" : L"Desktop", null, null, (byte *)wDesktopPath, &size);
1712 UTF16toUTF8Buffer(wDesktopPath, desktopPath, sizeof(desktopPath));
1715 if(!desktopPath[0] && userProfile[0])
1717 strcpy(desktopPath, userProfile);
1718 PathCat(desktopPath, "Desktop");
1723 PathCat(desktopPath, "Ecere IDE.lnk");
1725 ((GuiApplication)__thisModule).Lock();
1726 installProgress.installing.caption = $"Installing Desktop Icon...";
1727 ((GuiApplication)__thisModule).Unlock();
1728 ((GuiApplication)__thisModule).SignalEvent();
1730 CreateLink(idePath, desktopPath, null);//"Ecere IDE");
1734 SendMessageTimeout (HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)"Environment", SMTO_NORMAL, 1000, NULL);
1736 // Install QuickLaunch Icon
1737 if(options[IconOptions::QuickLaunchIcon].selected)
1739 char appData[MAX_LOCATION];
1740 GetEnvironment("APPDATA", appData, sizeof(appData));
1743 char destPath[MAX_LOCATION];
1745 if(appData[0] && options[0].selected)
1747 char dir[MAX_FILENAME];
1748 GetLastDirectory(appData, dir);
1749 if(!strcmpi(dir, "Roaming"))
1750 PathCat(appData, "../../../Default/AppData/Roaming");
1752 PathCat(appData, "../Default");
1755 ((GuiApplication)__thisModule).Lock();
1756 installProgress.installing.caption = $"Installing Quicklaunch Icon...";
1757 ((GuiApplication)__thisModule).Unlock();
1758 ((GuiApplication)__thisModule).SignalEvent();
1760 strcpy(destPath, appData);
1761 PathCat(destPath, "Microsoft\\Internet Explorer\\Quick Launch\\Ecere IDE.lnk");
1762 CreateLink(idePath, destPath, null);
1764 // Set it up on the dock for Windows 7 -- not working
1766 StripLastDirectory(destPath, destPath);
1767 PathCat(destPath, "User Pinned\\TaskBar");
1769 PathCat(destPath, "Ecere IDE.lnk");
1770 CreateLink(idePath, destPath, null);
1775 // Register File Types
1776 if(associateOptions[AssociateOptions::AssociateEPJ].selected ||
1777 associateOptions[AssociateOptions::AssociateEC].selected ||
1778 associateOptions[AssociateOptions::AssociateC].selected ||
1779 associateOptions[AssociateOptions::AssociateCPP].selected ||
1780 associateOptions[AssociateOptions::AssociateTXT].selected ||
1781 associateOptions[AssociateOptions::Associate3DS].selected ||
1782 associateOptions[AssociateOptions::AssociateIMG].selected)
1784 ((GuiApplication)__thisModule).Lock();
1785 installProgress.installing.caption = $"Registering File Types...";
1786 ((GuiApplication)__thisModule).Unlock();
1787 ((GuiApplication)__thisModule).SignalEvent();
1789 if(associateOptions[AssociateOptions::AssociateEPJ].selected)
1791 AssociateExtension(".epj", "Ecere IDE Project", "epj_file", "Open", idePath);
1793 if(associateOptions[AssociateOptions::AssociateEC].selected)
1795 AssociateExtension(".ec", "eC Source File", "ec_file", "Open", idePath);
1796 AssociateExtension(".eh", "eC Header File", "eh_file", "Open", idePath);
1798 if(associateOptions[AssociateOptions::AssociateC].selected)
1800 AssociateExtension(".c", "C Source File", "c_file", "Open", idePath);
1801 AssociateExtension(".h", "C Header File", "h_file", "Open", idePath);
1803 if(associateOptions[AssociateOptions::AssociateCPP].selected)
1805 AssociateExtension(".cpp", "C++ Source File", "cpp_file", "Open", idePath);
1806 AssociateExtension(".cc", "C++ Source File", "cpp_file", "Open", idePath);
1807 AssociateExtension(".cxx", "C++ Source File", "cpp_file", "Open", idePath);
1808 AssociateExtension(".chh", "C++ Header File", "chh_file", "Open", idePath);
1809 AssociateExtension(".hh", "C++ Header File", "chh_file", "Open", idePath);
1810 AssociateExtension(".hxx", "C++ Header File", "chh_file", "Open", idePath);
1812 if(associateOptions[AssociateOptions::AssociateTXT].selected)
1814 AssociateExtension(".txt", "Text File", "txt_file", "Open", idePath);
1816 if(associateOptions[AssociateOptions::Associate3DS].selected)
1818 AssociateExtension(".3ds", "3D Studio Model", "3ds_file", "View", idePath);
1820 if(associateOptions[AssociateOptions::AssociateIMG].selected)
1822 AssociateExtension(".bmp", "BMP Image", "bmp_file", "View", idePath);
1823 AssociateExtension(".pcx", "PCX Image", "pcx_file", "View", idePath);
1824 AssociateExtension(".png", "PNG Image", "png_file", "View", idePath);
1825 AssociateExtension(".jpg", "JPEG Image", "jpg_file", "View", idePath);
1826 AssociateExtension(".jpeg", "JPEG Image", "jpg_file", "View", idePath);
1827 AssociateExtension(".gif", "GIF Image", "gif_file", "View", idePath);
1830 ((GuiApplication)__thisModule).Lock();
1832 installProgress.cancel.Destroy(0);
1833 installProgress.finish.caption = $"Finish";
1834 installProgress.finish.disabled = false;
1835 installProgress.finish.Activate();
1836 installProgress.installing.caption = $"Installation Complete.";
1837 installProgress.title.caption = $"Installation Complete";
1838 installProgress.titleInfo.contents = $"Thank you for using the Ecere SDK.";
1840 ((GuiApplication)__thisModule).Unlock();