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 { "3D", "samples/3D", "3D", null, false, true, true, none },
259 { "Android", "samples/android", "android", null, false, true, true, none },
260 { $"Audio", "samples/audio", "audio", null, false, true, true, none },
261 { $"Database", "samples/db", "db", null, false, true, true, none },
262 { "eC", "samples/eC", "eC", null, false, true, true, none },
263 { $"Games", "samples/games", "games", null, false, true, true, none },
264 { $"GUI & Graphics", "samples/guiAndGfx", "guiAndGfx", null, false, true, true, none },
265 { $"Miscellaneous", "samples/misc", "misc", null, false, true, true, none },
266 { $"Networking", "samples/net", "net", null, false, true, true, none },
267 { $"WIA Scanning", "samples/scanning", "scanning", null, false, true, true, none },
268 { $"Threading", "samples/threads", "threads", null, false, true, true, none },
272 public enum CoreSDKID
274 ide, ide32, runtime, runtime32, ec, ec32,
275 gcc, gdb, mingw, binutils, make,
279 Array<Component> coreSDK
281 { "Ecere IDE", "ecere-sdk/ide", "bin", null, true, true, true, bits64 },
282 { "Ecere IDE", "ecere-sdk32/ide", "bin", null, true, true, true, bits32 },
283 { $"Runtime Library", "ecere-sdk/ecere.dll", "bin", null, true, true, true, bits64 },
284 { $"Runtime Library", "ecere-sdk32/ecere.dll", "bin", null, true, true, true, bits32 },
285 { $"eC Compiler", "ecere-sdk/compiler", "bin", null, true, true, true, bits64 },
286 { $"eC Compiler", "ecere-sdk32/compiler", "bin", null, true, true, true, bits32 },
287 { $"GNU C Compiler", "tdm/gcc/core", "tdm", null, true, true, minGWIncluded, none },
288 { $"GNU Debugger", "tdm/gdb", "tdm", null, true, true, minGWIncluded, none },
289 { $"MinGW-w64 Runtime", "tdm/mingwrt", "tdm", null, true, true, minGWIncluded, none },
290 { $"Binary Utils", "tdm/binutils", "tdm", null, true, true, minGWIncluded, none },
291 { $"GNU Make", "tdm/make", "tdm", null, true, true, minGWIncluded, none },
295 public enum AdditionalID
297 eda, eda32, vanilla, vanilla32, extras, upx, gnurx, gnurx32, /*pthreads, */cpp, /*w32api, gcci18n, gdbi18n, makei18n, binutilsi18n, */none
300 Array<Component> additional
302 { $"Data Access", "ecere-sdk/eda", "bin", null, false, true, true, bits64 },
303 { $"Data Access", "ecere-sdk32/eda", "bin", null, false, true, true, bits32 },
304 { $"Ecere Vanilla", "ecere-sdk/libecereVanilla.a", "lib", null, false, true, true, bits64 },
305 { $"Ecere Vanilla", "ecere-sdk32/libecereVanilla.a", "lib", null, false, true, true, bits32 },
306 { $"Ecere Extras", "extras", "extras", null, false, true, true, none },
307 { "UPX", "upx/bin", "upx/bin", null, false, true, true, none },
308 { $"GNU Regexp", "tdm/gnurx", "tdm", null, false, true, true, bits64 },
309 { $"GNU Regexp", "tdm/gnurx32", "tdm", null, false, true, true, bits32 },
310 // { "pthreads", "tdm/pthreads", "mingw", null, false, true, minGWIncluded, none },
311 { $"C++ Compiler", "tdm/gcc/c++", "tdm", null, false, true, minGWIncluded, none },
312 // { "Win32 APIs", "mingw/w32api", "mingw", null, false, true, minGWIncluded, none },
313 /* { "GCC I18n", "mingw/locale/gcc", "tdm", null, false, false, minGWIncluded, none },
314 { "GDB I18n", "mingw/locale/gdb", "tdm", null, false, false, minGWIncluded, none },
315 { "Make I18n", "mingw/locale/make", "tdm", null, false, false, minGWIncluded, none },
316 { "Binutils I18n", "mingw/locale/binutils", "tdm", null, false, false, minGWIncluded, none },
321 public enum DocumentationID
323 ecereBook, apiRef, coursework,
324 gccDoc, gppDocs, gdbDocs, makeDocs, binDocs, mingwDocs, gnurxDocs, upxDocs,
328 Array<Component> documentation
330 { $"Ecere Book", "ecere-sdk/book", "doc", null, false, true, true, none },
331 { $"API Reference", "ecere-sdk/doc", "doc", null, false, true, true, none },
332 { $"Ecere Coursework", "ecere-sdk/coursework", "doc", null, false, true, true, none },
333 { $"GCC Docs", "tdm/doc/gcc", "tdm", null, false, false, minGWIncluded, none },
334 { $"G++ Docs", "tdm/doc/g++", "tdm", null, false, false, minGWIncluded, none },
335 { $"GDB Docs", "tdm/doc/gdb", "tdm", null, false, false, minGWIncluded, none },
336 { $"Make Docs", "tdm/doc/make", "tdm", null, false, false, minGWIncluded, none },
337 { $"Binutils Docs", "tdm/doc/binutils", "tdm", null, false, false, minGWIncluded, none },
338 { $"gnurx Docs", "tdm/doc/gnurx", "tdm", null, false, false, minGWIncluded, none },
339 { $"UPX Docs", "upx/doc", "upx/doc", null, false, false, minGWIncluded, none },
343 public enum ComponentID
352 Array<Component> components
354 { $"Core SDK Files", null, null, coreSDK.array, true, true, true, none },
355 { $"Additional Support", null, null, additional.array, false, true, true, none },
356 { $"Documentation", null /*"doc"*/, null /*"doc"*/, documentation.array, false, true, true, none },
357 { $"Samples", null, "samples", samples.array, false, true, true, none },
361 FileSize totalInstalled;
366 InstallOption * subOptions;
372 enum AssociateOptions
383 Array<InstallOption> associateOptions
385 { $"Associate with Ecere Project Files (*.epj)", null, true },
386 { $"Associate with eC Files (*.ec, *.eh)", null, true },
387 { $"Associate with C files (*.c, *.h)", null, false },
388 { $"Associate with C++ Files (*.cpp, *.hpp, *.cc, *.hh, *.cxx, *.hxx)", null, false },
389 { $"Associate with text files (*.txt)", null, false },
390 { $"Associate with 3D Studio Model Files (*.3ds)", null, true },
391 { $"Associate with Image Files (*.png, *.jpg, *.pcx, *.bmp, *.gif)", null, false },
397 AddECEREPaths, AddMinGWPaths
400 Array<InstallOption> pathOptions
402 { $"Add Ecere binaries location to the user environment path", null, true, true },
403 { $"Add MinGW to the user environment path", null, true, minGWIncluded },
414 Array<InstallOption> options
416 { $"Install for All Users", null, true, true },
417 { $"Start Menu Group", null, true, true },
418 { $"Desktop Icon", null, true, true },
419 { $"Quicklaunch Icon", null, true, true },
420 { $"Associate the Ecere IDE with Supported File Types", associateOptions.array, true, true },
421 { $"Add binaries location to the user environment paths", pathOptions.array, true, minGWIncluded },
425 char sourceDir[MAX_LOCATION] = ":";
426 char installDir[MAX_LOCATION];
427 char installDir32[MAX_LOCATION];
430 class Installer : Window
432 background = formColor;
437 clientSize = { 636, 476 };
438 icon = { ":icon.png" };
439 text = $"Ecere Software Development Kit Setup - v0.44.10 \"Ryōan-ji\" 64 Bit Edition";
441 // clientSize = { 796, 576 };
444 Picture back { image = BitmapResource { ":ryoanji.png" }, parent = this, position = { 0, 0 } };
445 FileDialog fileDialog
447 master = this, type = selectDir,
448 text = $"Select a new location"
452 master = this, autoCreate = false, inactive = true, text = "...";
454 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
456 DataRow row = componentsBox.currentRow;
457 Component * component = ((CheckItem *)row.GetData(componentField))->data;
458 component->GetFullPath(fileDialog.filePath, false);
459 StripLastDirectory(fileDialog.filePath, fileDialog.currentDirectory);
461 if(fileDialog.Modal() == ok)
463 componentsBox.StopEditing(false);
464 row.SetData(locationField, fileDialog.filePath);
465 componentsBox.NotifyChanged(this, componentsBox, row);
466 componentsBox.currentField = componentsBox.currentField;
471 CheckListBox componentsBox
473 this, size = { 460, 112 }, position = { 160, 160 }, hasHeader = true;
474 fullRowSelect = false, collapseControl = true, treeBranches = true, rootCollapseButton = true,
475 hasHorzScroll = true;
479 selectionColor = { 145, 150, 140 };
484 bool NotifyKeyDown(ListBox listBox, DataRow row, Key key, unichar ch)
486 if(key == f2 && browse.visible)
487 browse.NotifyClicked(this, browse, 0, 0, 0);
491 bool NotifyChanged(ListBox listBox, DataRow row)
493 Component * component = ((CheckItem *)listBox.GetData(componentField))->data;
494 char path[MAX_LOCATION], relative[MAX_LOCATION] = "", * newPath;
495 char fullPath[MAX_LOCATION];
497 component->parent->GetFullPath(path, false);
498 strcpy(fullPath, path);
500 newPath = row.GetData(locationField);
503 PathCat(fullPath, newPath);
504 if(IsPathInsideOf(fullPath, path))
505 MakePathRelative(fullPath, path, relative);
507 strcpy(relative, fullPath);
509 listBox.SetData(locationField, relative);
510 strcpy(component->installPath, relative);
512 //SetAvailableSpace(component, path);
515 install.disabled = false;
516 for(c = 0; components[c].name; c++)
518 SetAvailableSpace(components[c], installDir);
524 bool NotifyEditDone(ListBox listBox, DataRow row)
530 bool NotifyEdited(ListBox listBox, DataRow row)
533 browse.parent = listBox;
534 browse.position = { componentField.width + locationField.width + 18, (listBox.currentIndex+1) * listBox.rowHeight - 2 };
535 browse.size = { 30, listBox.rowHeight + 3 };
536 for(e = listBox.firstChild; e; e = e.next)
538 if(e._class == class(DataBox))
547 void NotifyChecked(CheckListBox listBox, DataRow row)
549 Component * component = ((CheckItem *)row.GetData(componentField))->data;
551 component->selected = listBox.IsChecked(row);
553 if(!component->parent) totalSize -= component->requiredSize;
554 component->requiredSize = 0;
555 if(component->selected)
557 component->requiredSize += component->size;
558 if(component->subComponents)
559 for(c = 0; component->subComponents[c].name; c++)
560 component->requiredSize += component->subComponents[c].requiredSize;
562 if(component->requiredSize)
564 uint requiredSize = component->requiredSize;
565 row.SetData(reqField, requiredSize);
568 row.UnsetData(reqField);
569 if(!component->parent)
571 totalSize += component->requiredSize;
573 char sizeString[100];
574 PrintSize(sizeString, totalSize, 2);
575 totalSpaceValue.text = sizeString;
580 Label agreementLbl { parent = this, text = $"By installing the Ecere SDK, you agree to the", font = { "Tahoma", 8.25f }, anchor = Anchor { right = 399, top = 448 } };
583 this, inactive = true, offset = false, bevel = false, foreground = blue, font = { "Tahoma", 8.25f, underline = true, bold = true },
584 // text = $"terms and conditions", anchor = Anchor { left = 241, top = 421 };
585 text = $"terms and conditions", anchor = Anchor { left = 235, top = 445 };
586 cursor = ((GuiApplication)__thisModule).GetCursor(hand);
588 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
590 // LicenseBox { master = this, sourceFile = ":ecere-sdk/doc/LICENSE" }.Modal();
591 LicensesForm { master = this }.Modal();
595 Label dotLbl { parent = this, text = ".", font = { "Tahoma", 8.25f }, anchor = Anchor { left = 372, top = 448 } };
596 CheckListBox optionsBox
598 this, size = { 460, 114 }, position = { 160, 284 };
599 fullRowSelect = false, collapseControl = true, treeBranches = true, rootCollapseButton = true,
604 void NotifyChecked(CheckListBox listBox, DataRow row)
606 CheckItem * item = row.GetData(optionField);
607 InstallOption * option = item->data;
608 option->selected = listBox.IsChecked(row);
609 // Update default samples/extras path whether we're installing for All Users or not
610 if(option == &options[0])
612 char appData[MAX_LOCATION];
614 options[5].name = options[0].selected ? $"Add binaries location to the system environment paths" : $"Add binaries location to the user environment paths";
616 ((CheckItem *)options[5].row.GetData(optionField))->name = options[5].name;
618 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";
619 if(pathOptions[PathOptions::AddECEREPaths].row)
620 ((CheckItem *)pathOptions[PathOptions::AddECEREPaths].row.GetData(optionField))->name = pathOptions[PathOptions::AddECEREPaths].name;
622 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";
623 if(pathOptions[PathOptions::AddMinGWPaths].row)
624 ((CheckItem *)pathOptions[PathOptions::AddMinGWPaths].row.GetData(optionField))->name = pathOptions[PathOptions::AddMinGWPaths].name;
626 GetEnvironment(options[0].selected ? "ALLUSERSPROFILE" : "APPDATA", appData, sizeof(appData));
627 if(appData && appData[0])
629 char defPath[MAX_LOCATION];
631 char * s = components[ComponentID::samples].installPath;
632 strcpy(defPath, installDir);
633 PathCat(defPath, components[ComponentID::samples].defInstallPath);
634 ChangeCh(defPath, '/', DIR_SEP);
635 if(!strcmp(defPath, components[ComponentID::samples].installPath))
637 static char defSamplesPath[MAX_LOCATION];
638 strcpy(defSamplesPath, appData);
639 PathCat(defSamplesPath, "Ecere SDK\\Samples");
640 components[ComponentID::samples].defInstallPath = defSamplesPath;
642 strcpy(components[ComponentID::samples].installPath, components[ComponentID::samples].defInstallPath);
643 ChangeCh(components[ComponentID::samples].installPath, '/', DIR_SEP);
644 components[ComponentID::samples].row.SetData(locationField, components[ComponentID::samples].installPath);
647 strcpy(defPath, installDir);
648 PathCat(defPath, additional[AdditionalID::extras].defInstallPath);
649 ChangeCh(defPath, '/', DIR_SEP);
650 if(!strcmp(additional[AdditionalID::extras].installPath, additional[AdditionalID::extras].installPath))
652 static char defExtrasPath[MAX_LOCATION];
653 strcpy(defExtrasPath, appData);
654 PathCat(defExtrasPath, "Ecere SDK\\extras");
655 additional[AdditionalID::extras].defInstallPath = defExtrasPath;
657 strcpy(additional[AdditionalID::extras].installPath, additional[AdditionalID::extras].defInstallPath);
658 ChangeCh(additional[AdditionalID::extras].installPath, '/', DIR_SEP);
659 additional[AdditionalID::extras].row.SetData(locationField, additional[AdditionalID::extras].installPath);
667 parent = this, text = $"Install", isDefault = true, size = { 75, 23 }, position = { 432, 440 };
669 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
671 installProgress.Create();
673 // installProgress.thread.Main();
674 installProgress.thread.Create();
678 Button button3 { parent = this, text = $"Cancel", hotKey = altX, size = Size { 75, 23 }, anchor = Anchor { left = 544, top = 440 }, NotifyClicked = ButtonCloseDialog };
681 this, position = { 14, 374 }, size = { 142, 0 }, caption = "Language:";
683 bool NotifySelect(DropBox dropBox, DataRow row, Modifiers mods)
685 LanguageOption * option = row.GetData(null);
686 // If the language is already set, we need to override it
688 IDESettings settings = null;
689 IDESettingsContainer settingsContainer
692 dataOwner = &settings;
693 dataClass = class(IDESettings);
694 allUsers = options[0].selected;
696 settingsContainer.Load();
697 if(settings.language)
699 settings.language = option->code;
700 settingsContainer.Save();
702 delete settingsContainer;
705 ((GuiApplication)__thisModule.application).desktop.Destroy(0);
706 LanguageRestart(option->code, __thisModule.application, null, null, null, null, false);
710 Label lblLanguageBox { this, position = { 14, 354 }, labeledWindow = languageBox };
711 Label label1 { labeledWindow = destBox, tabCycle = true, isGroupBox = true, parent = this, inactive = false, size = Size { 458, 50 }, anchor = Anchor { left = 160, top = 96 } };
714 parent = label1, master = this, text = $" Destination Folder", size = Size { 336, 22 }, anchor = Anchor { left = 12, top = 20, right = 12 };
715 typeExpected = directory;
716 browseDialog = fileDialog;
719 bool NotifyModified(PathBox pathBox)
722 strcpy(installDir, destBox.path);
723 install.disabled = false;
724 for(c = 0; components[c].name; c++)
726 SetAvailableSpace(components[c], installDir);
733 label1, this, $"Browse", altB, size = { 83, 24 }, position = { 360, 16 };
735 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
737 strcpy(fileDialog.filePath, installDir);
738 StripLastDirectory(installDir, fileDialog.currentDirectory);
739 if(fileDialog.Modal())
741 strcpy(installDir, fileDialog.filePath);
742 destBox.contents = installDir;
743 // TOCHECK: Should setting contents call NotifyModified?
744 destBox.NotifyModified(destBox.master, destBox);
751 this, multiLine = true,
752 opacity = 0, borderStyle = none, inactive = true, size = { 136, 53 }, position = { 14, 96 }, noSelect = true,
753 contents = $"Select the default root\n"
754 "folder where to install\n"
759 this, opacity = 0, borderStyle = none, inactive = true, size = { 136, 132 }, position = { 14, 152 }, noSelect = true,
761 contents = $"Select the optional\n"
762 "components you wish\n"
764 "You may customize the\n"
765 "install location for each\n"
766 "of them, or use the default\n"
767 "based on the main\n"
768 "destination folder."
772 this, opacity = 0, borderStyle = none, inactive = true, size = { 136, 83 }, position = { 14, 280 }, noSelect = true,
774 contents = $"Select icons to install, file\n"
775 "associations, and system\n"
776 "environment modifications:"
778 Label totalSpaceLabel
780 this, anchor = { right = 72, top = 404 }, text = $"Space Required: "
782 Label totalSpaceValue
784 this, anchor = { right = 14, top = 404 }, text = "0 mb"
788 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"
789 "of the SDK to install, as well as where to install program icons."
791 Label label2 { parent = this, text = buildString, position = { 16, 422 }, font = { "Tahoma", 10, true }, disabled = true, opacity = 0, background = activeBorder };
794 image = BitmapResource { ":ecere.png", alphaBlend = true }, filter = true, parent = label3, text = "picture1", anchor = Anchor { left = 16, top = 4 };
795 cursor = ((GuiApplication)__thisModule).GetCursor(hand);
797 bool OnLeftButtonDown(int x, int y, Modifiers mods)
799 ShellOpen("http://www.ecere.com/");
803 Label label4 { label3, font = { "Tahoma", 8.25f, bold = true }, /*size = { 326, 16 }, */position = { 248, 24 }, text = $"Choose Components, Locations and Install Options" };
804 DataField componentField { "CheckItem", width = 160, header = $"Component" };
805 DataField locationField { "char *", width = 108, header = $"Destination Folder", editable = true };
806 DataField reqField { "FileSize", width = 70, header = $"Req. Space", alignment = right };
807 DataField avField { "FileSize64", width = 70, header = $"Avail. Space", alignment = right };
808 DataField optionField { "CheckItem" };
810 DataField languageField { class(LanguageOption) };
812 void SetAvailableSpace(Component component, char * parentPath)
814 char path[MAX_LOCATION];
818 strcpy(path, parentPath);
819 PathCat(path, component.installPath);
821 if(component.subComponents)
822 for(c = 0; component.subComponents[c].name; c++)
823 SetAvailableSpace(component.subComponents[c], path);
825 while(!FileExists(path) && path[0])
826 StripLastDirectory(path, path);
829 GetFreeSpace(path, &size);
830 component.row.SetData(avField, size);
831 if(!size) install.disabled = true;
834 FileSize ComputeSize(char * path)
837 FileAttribs attribs = FileExists(path);
838 if(attribs.isDirectory)
840 FileListing listing { path };
841 while(listing.Find())
843 if(listing.stats.attribs.isDirectory)
844 size += ComputeSize(listing.path);
846 size += listing.stats.size;
850 FileGetSize(path, &size);
854 void AddComponent(Component component, Component parent, char * parentPath)
856 DataRow row = (parent != null) ? parent.row.AddRow() : componentsBox.AddRow();
858 FileSize64 avSize = 0;
859 char path[MAX_LOCATION];
862 strcpy(path, parentPath);
863 if(component.defInstallPath)
864 PathCat(path, component.defInstallPath);
865 component.parent = parent;
867 row.SetData(null, CheckItem { component.name, component, (component.arch == bits32 && osIS64bit) } );
869 if(component.defInstallPath)
871 strcpy(component.installPath, component.defInstallPath);
872 ChangeCh(component.installPath, '/', DIR_SEP);
873 row.SetData(locationField, component.installPath);
876 if(component.mandatory)
878 if(component.arch != bits32 || !osIS64bit) // || component == &coreSDK[gdb32])
879 componentsBox.SetDisabled(row, true);
881 component.selected = false;*/
883 else if(component.arch == bits32 && osIS64bit)
884 ; //component.selected = false;
886 componentsBox.SetCheck(row, component.selected);
888 if(component.dataPath)
890 char path[MAX_LOCATION];
892 PathCat(path, component.dataPath);
893 component.size = ComputeSize(path);
895 if(component.subComponents)
898 for(c = 0; component.subComponents[c].name; c++)
900 Component * sub = &component.subComponents[c];
901 if(sub->available && (osIS64bit || sub->arch == bits32 || sub->arch == none))
903 AddComponent(sub, component, path);
904 size += sub->requiredSize;
907 sub->selected = false;
911 component.requiredSize = component.selected ? (size + component.size) : 0;
912 if(component.requiredSize)
913 row.SetData(reqField, component.requiredSize);
915 while(!FileExists(path) && path[0])
916 StripLastDirectory(path, path);
919 GetFreeSpace(path, &avSize);
922 row.SetData(avField, avSize);
923 row.collapsed = true;
926 void AddOption(InstallOption option, InstallOption parent)
928 DataRow row = option.row = (parent != null) ? parent.row.AddRow() : optionsBox.AddRow();
929 row.SetData(null, CheckItem { option.name, option } );
930 optionsBox.SetCheck(row, option.selected);
931 if(option.subOptions)
934 for(c = 0; option.subOptions[c].name; c++)
936 AddOption(option.subOptions[c], option);
939 row.collapsed = true;
945 char programFilesDir[MAX_LOCATION];
946 char appData[MAX_LOCATION];
947 char homeDrive[MAX_LOCATION];
948 char winDir[MAX_LOCATION];
951 bool isAdministrator = IsAdministrator();
955 options[0].available = false;
956 options[0].selected = false;
959 // If the SDK is already installed, use currently selected language
961 IDESettings settings = null;
962 IDESettingsContainer settingsContainer
965 dataOwner = &settings;
966 dataClass = class(IDESettings);
967 allUsers = options[0].selected;
970 settingsContainer.Load();
972 if(settings.language)
974 String language = GetLanguageString();
975 if(settings.language.OnCompare(language))
977 // Relaunch the installer with previously selected language
978 LanguageRestart(settings.language, __thisModule.application, null, null, null, null, false);
982 delete settingsContainer;
986 GetEnvironment("HOMEDRIVE", homeDrive, sizeof(homeDrive));
987 GetEnvironment("windir", winDir, sizeof(winDir));
989 GetEnvironment(options[0].selected ? "ALLUSERSPROFILE" : "APPDATA", appData, sizeof(appData));
991 componentsBox.AddField(componentField);
992 componentsBox.AddField(locationField);
993 componentsBox.AddField(reqField);
994 componentsBox.AddField(avField);
996 optionsBox.AddField(optionField);
998 languageBox.AddField(languageField);
1000 programFilesDir[0] = 0;
1001 if(GetEnvironment("ProgramFiles", programFilesDir, MAX_LOCATION))
1003 x86 = strstr(programFilesDir, " (x86)");
1008 if(isAdministrator && programFilesDir[0])
1012 strcpy(installDir32, programFilesDir);
1013 PathCat(installDir32, "Ecere SDK");
1015 strcpy(installDir, programFilesDir);
1016 PathCat(installDir, "Ecere SDK");
1020 strcpy(installDir, programFilesDir);
1021 PathCat(installDir, "Ecere SDK");
1022 strcpy(installDir32, installDir);
1025 else if(homeDrive && homeDrive[0])
1027 strcpy(installDir, homeDrive);
1028 PathCat(installDir, "Ecere SDK");
1029 strcpy(installDir32, installDir);
1030 strcat(installDir32, " (32)");
1032 else if(winDir && winDir[0])
1034 strcpy(installDir, winDir);
1035 PathCat(installDir, "..\\Ecere SDK");
1036 strcpy(installDir32, installDir);
1037 strcat(installDir32, " (32)");
1041 strcpy(installDir, "C:\\Ecere SDK");
1042 strcpy(installDir32, installDir);
1043 strcat(installDir32, " (32)");
1046 if(appData && appData[0])
1048 static char defSamplesPath[MAX_LOCATION];
1049 static char defExtrasPath[MAX_LOCATION];
1050 strcpy(defSamplesPath, appData);
1051 PathCat(defSamplesPath, "Ecere SDK\\Samples");
1052 components[ComponentID::samples].defInstallPath = defSamplesPath;
1054 strcpy(defExtrasPath, appData);
1055 PathCat(defExtrasPath, "Ecere SDK\\extras");
1056 additional[AdditionalID::extras].defInstallPath = defExtrasPath;
1059 destBox.path = installDir;
1063 for(c = 0; components[c].name; c++)
1064 AddComponent(components[c], null, installDir);
1067 // Compute size apart because ToggleCheck will change it
1071 for(c = 0; components[c].name; c++)
1072 totalSize += components[c].requiredSize;
1075 char sizeString[100];
1076 PrintSize(sizeString, totalSize, 2);
1077 totalSpaceValue.text = sizeString;
1079 for(c = 0; options[c].name; c++)
1081 if(options[c].available)
1082 AddOption(options[c], null);
1094 dotLbl.position.x = licenseButton.position.x + licenseButton.size.w - 4;
1100 // Constructor happens before Languages is instantiated...
1103 l.res = { l.bitmap, window = this };
1109 String language = GetLanguageString();
1113 // Try to find country-specific language first
1116 LanguageOption option = l;
1117 row = languageBox.AddRow();
1118 row.SetData(null, option); // TOFIX: l used directly here
1120 if(!found && (!strcmpi(l.code, language) || (!row.GetPrevRow() && !strcmpi("en", language))))
1122 languageBox.currentRow = row;
1127 // Try generalizing locale
1131 char genericLocale[256];
1132 strncpy(genericLocale, language, sizeof(genericLocale));
1133 genericLocale[sizeof(genericLocale)-1] = 0;
1135 under = strchr(genericLocale, '_');
1138 if(!strcmpi(genericLocale, "zh"))
1139 strcpy(genericLocale, "zh_CN");
1140 if(strcmp(genericLocale, language))
1142 row = languageBox.firstRow;
1145 if(!strcmpi(l.code, genericLocale) || (!row.GetPrevRow() && !strcmpi("en", genericLocale)))
1147 languageBox.currentRow = row;
1151 row = row.GetNextRow();
1157 languageBox.currentRow = languageBox.firstRow;
1165 void OnDrawOverChildren(Surface surface)
1167 int tw = label2.size.w;
1168 surface.SetForeground(Color { 128, 128, 128 });
1169 surface.HLine(label2.position.x + tw + 6, 620, 430);
1170 surface.SetForeground(white);
1171 surface.HLine(label2.position.x + tw + 6, 621, 431);
1172 surface.PutPixel(621, 400);
1176 parent = this, opacity = 0, borderStyle = deep, size = Size { 644, 93 }, anchor = Anchor { left = -8, top = -8 };
1180 class InstallProgress : Window
1182 text = $"Ecere Software Development Kit Setup - v0.44.10 \"Ryōan-ji\" 64 Bit Edition";
1183 background = activeBorder;
1184 borderStyle = fixed;
1188 // size = Size { 640, 480 };
1189 clientSize = { 636, 476 };
1190 //clientSize = { 796, 576 };
1191 icon = { ":icon.png" };
1193 Picture back { image = BitmapResource { ":ryoanji-progress.png" }, parent = this, position = { 0, 0 } };
1194 Label installing { this, position = { 32, 160 } };
1195 ProgressBar progressBar { parent = this, size = Size { 588, 24 }, anchor = Anchor { left = 24, top = 184 } };
1198 parent = this, text = $"Install", disabled = true, isDefault = true, size = Size { 75, 23 }, anchor = Anchor { left = 432, top = 440 };
1200 NotifyClicked = ButtonCloseDialog
1204 this, text = $"Cancel", hotKey = altX, size = Size { 75, 23 }, anchor = Anchor { left = 544, top = 440 };
1206 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
1208 abortInstall = true;
1214 inactive = true, noSelect = true,
1215 multiLine = true, parent = label3, opacity = 0, borderStyle = none, size = Size { 350, 35 }, anchor = Anchor { horz = 111, vert = 13 },
1216 contents = $"Please wait while the Ecere Software Development Kit is being installed."
1218 Label label2 { parent = this, text = buildString, position = { 16, 422 }, font = { "Tahoma", 10, true }, disabled = true, opacity = 0, background = activeBorder };
1221 image = BitmapResource { ":ecere.png", alphaBlend = true }, filter = true, parent = label3, anchor = Anchor { left = 16, top = 4 };
1222 cursor = ((GuiApplication)__thisModule).GetCursor(hand);
1224 bool OnLeftButtonDown(int x, int y, Modifiers mods)
1226 ShellOpen("http://www.ecere.com/");
1230 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 } };
1232 void OnDrawOverChildren(Surface surface)
1234 int tw = label2.size.w;
1235 surface.SetForeground(Color { 128, 128, 128 });
1236 surface.HLine(label2.position.x + tw + 6, 620, 430);
1237 surface.SetForeground(white);
1238 surface.HLine(label2.position.x + tw + 6, 621, 431);
1239 surface.PutPixel(621, 400);
1244 parent = this, opacity = 0, borderStyle = deep, size = Size { 644, 93 }, anchor = Anchor { left = -8, top = -8 };
1246 InstallThread thread
1251 Installer installer {};
1252 InstallProgress installProgress { autoCreate = false };
1254 static void AddPath(char * sysPaths[200], int sysCount, char * paths[200], int * count, char * oldPath, char * userPath, char * path)
1258 for(p = 0; p<sysCount; p++)
1259 if(!fstrcmp(sysPaths[p], path))
1264 for(p = 0; !found && p<*count; p++)
1265 if(!fstrcmp(paths[p], path))
1275 strcat(userPath, ";");
1276 start = paths[(*count)-1] + strlen(paths[(*count)-1])+1;
1281 strcpy(start, path);
1282 *(start + strlen(path)) = '\0';
1283 paths[(*count)++] = start;
1285 strcat(userPath, path);
1290 void ModifyPath(char * systemPath, char * userPath)
1292 char oldPath[8192], * paths[200], * sysPaths[200];
1293 int count, sysCount = 0;
1297 strcpy(oldPath, userPath);
1298 count = TokenizeWith(oldPath, sizeof(paths) / sizeof(char *), paths, ";", false);
1299 sysCount = TokenizeWith(systemPath, sizeof(sysPaths) / sizeof(char *), sysPaths, ";", false);
1303 strcpy(oldPath, systemPath);
1304 count = TokenizeWith(oldPath, sizeof(paths) / sizeof(char *), paths, ";", false);
1309 for(c = 0; coreSDK[c].name; c++)
1312 char path[MAX_LOCATION];
1313 if(!coreSDK[c].selected) continue;
1314 coreSDK[c].GetFullPath(path, false);
1315 if(c != ide && c != runtime && c != ec &&
1316 c != ide32 && c != runtime32 && c != ec32)
1318 if(!pathOptions[PathOptions::AddMinGWPaths].available || !pathOptions[PathOptions::AddMinGWPaths].selected)
1320 PathCat(path, "bin");
1322 else if(!pathOptions[PathOptions::AddECEREPaths].selected) continue;
1324 AddPath(sysPaths, sysCount, paths, &count, oldPath, userPath ? userPath : systemPath, path);
1330 for(c = 0; c <= cpp; c++)
1333 char path[MAX_LOCATION];
1334 if(!additional[c].selected || c == vanilla || c == vanilla32 || c == extras) continue;
1335 if((c != eda && c != eda32 && c != upx) && (!pathOptions[PathOptions::AddMinGWPaths].available || !pathOptions[PathOptions::AddMinGWPaths].selected))
1337 additional[c].GetFullPath(path, false);
1338 if(c != eda && c != eda32 && c != upx)
1339 PathCat(path, "bin");
1340 AddPath(sysPaths, sysCount, paths, &count, oldPath, userPath ? userPath : systemPath, path);
1345 void AssociateExtension(char * extension, char * description, char *name, char * action, char * path)
1351 RegCreateKeyEx(HKEY_CLASSES_ROOT, extension, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1352 RegSetValueEx(key, null, 0, REG_SZ, name, (uint)strlen(name)+1);
1355 RegCreateKeyEx(HKEY_CLASSES_ROOT, name, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1356 RegSetValueEx(key, null, 0, REG_SZ, description, (uint)strlen(description)+1);
1359 sprintf(keyName, "%s\\shell", extension);
1360 RegCreateKeyEx(HKEY_CLASSES_ROOT, keyName, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1361 RegSetValueEx(key, null, 0, REG_SZ, action, (uint)strlen(action)+1);
1364 sprintf(keyName, "%s\\shell\\%s", name, action);
1365 RegCreateKeyEx(HKEY_CLASSES_ROOT, keyName, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1368 sprintf(keyName, "%s\\shell\\%s\\command", name, action);
1369 RegCreateKeyEx(HKEY_CLASSES_ROOT, keyName, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1371 sprintf(keyName, path);
1372 strcat(keyName, " \"%L\"");
1374 uint16 wKeyName[2048];
1375 UTF8toUTF16Buffer(keyName, wKeyName, sizeof(wKeyName) / sizeof(uint16));
1376 RegSetValueExW(key, null, 0, REG_SZ, (byte *)wKeyName, (uint)(wcslen(wKeyName) + 1)*sizeof(uint16));
1381 class InstallThread : Thread
1386 ((GuiApplication)__thisModule).Lock();
1387 installProgress.progressBar.range = totalSize;
1390 strcpy(installDir32, installDir);
1392 for(c = 0; components[c].name && !abortInstall; c++)
1393 components[c].Install(installDir, installDir32);
1396 installProgress.progressBar.range = 0;
1397 installProgress.finish.Destroy(0);
1398 installProgress.cancel.text = $"Close";
1399 installProgress.cancel.isDefault = true;
1400 installProgress.cancel.disabled = false;
1401 installProgress.cancel.NotifyClicked = Window::ButtonCloseDialog;
1402 installProgress.installing.text = $"Installation Cancelled.";
1403 installProgress.title.text = $"Installation Cancelled";
1404 installProgress.titleInfo.contents = $"The installation was not completed.";
1408 char idePath[MAX_LOCATION];
1409 char userProfile[MAX_LOCATION];
1412 IDESettings settings = null; // Don't instantiate yet so we can pick up old settings
1414 IDESettingsContainer settingsContainer
1417 dataOwner = &settings;
1418 dataClass = class(IDESettings);
1419 allUsers = options[0].selected;
1421 CompilerConfig compiler;
1422 installProgress.installing.text = $"Configuring Ecere IDE...";
1423 ((GuiApplication)__thisModule).Unlock();
1424 ((GuiApplication)__thisModule).SignalEvent();
1426 settingsContainer.Load();
1427 compiler = settings.GetCompilerConfig(defaultCompilerName);
1432 for(c = 0; coreSDK[c].name; c++)
1434 char path[MAX_LOCATION];
1435 if(!coreSDK[c].selected || !coreSDK[c].available) continue;
1437 coreSDK[c].GetFullPath(path, false);
1438 if(c != ide && c != runtime && c != ec &&
1439 c != ide32 && c != runtime32 && c != ec32)
1440 PathCat(path, "bin");
1441 MakeSlashPath(path);
1442 if((c == ide && osIS64bit) || (c == ide32 && !osIS64bit))
1444 coreSDK[c].GetFullPath(idePath, false);
1445 PathCat(idePath, "ide.exe");
1448 if(c == runtime || c == runtime32)
1450 if(!compiler.libraryDirs.Find(path))
1451 compiler.libraryDirs.Add(CopyString(path));
1458 for(c = 0; c <= cpp; c++)
1460 char path[MAX_LOCATION];
1461 if(c == extras || !additional[c].selected || !additional[c].available) continue;
1462 additional[c].GetFullPath(path, false);
1463 if(c != upx && c != eda && c != vanilla && c != eda32 && c != vanilla32)
1464 PathCat(path, "bin");
1465 MakeSlashPath(path);
1466 if(c == vanilla || c == vanilla32)
1468 if(!compiler.libraryDirs.Find(path))
1469 compiler.libraryDirs.Add(CopyString(path));
1473 if(!compiler.executableDirs.Find(path))
1474 compiler.executableDirs.Add(CopyString(path));
1481 char path[MAX_LOCATION] = "";
1483 if(components[ComponentID::samples].selected)
1484 components[ComponentID::samples].GetFullPath(path, false);
1485 // IDE will now default to HOME for the default project/files locations
1487 if(!settings.ideProjectFileDialogLocation[0])
1488 settings.ideProjectFileDialogLocation = path;
1489 if(!settings.ideFileDialogLocation[0])
1490 settings.ideFileDialogLocation = path;
1492 if(documentation[DocumentationID::apiRef].selected)
1494 documentation[DocumentationID::apiRef].GetFullPath(path, false);
1495 if(!settings.docDir[0])
1496 settings.docDir = path;
1500 settings.language = GetLanguageString();
1502 // Set LANGUAGE environment variable
1505 uint16 wLanguage[256];
1509 if(options[0].selected)
1510 RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", 0, KEY_ALL_ACCESS, &key);
1512 RegCreateKeyEx(HKEY_CURRENT_USER, "Environment", 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1515 UTF8toUTF16Buffer(settings.language, wLanguage, sizeof(wLanguage) / sizeof(uint16));
1516 RegSetValueExW(key, L"ECERE_LANGUAGE", 0, REG_EXPAND_SZ, (byte *)wLanguage, (uint)(wcslen(wLanguage)+1) * 2);
1521 settingsContainer.Save();
1522 delete settingsContainer;
1525 // Set up Uninstaller
1526 ((GuiApplication)__thisModule).Lock();
1527 installProgress.installing.text = $"Registering uninstaller...";
1528 ((GuiApplication)__thisModule).Unlock();
1529 ((GuiApplication)__thisModule).SignalEvent();
1534 char * displayName = "Ecere SDK 0.44";
1535 char uninstaller[MAX_LOCATION];
1536 bool nomodify = true;
1538 strcpy(uninstaller, installDir);
1539 PathCat(uninstaller, "uninstall_ecere.exe");
1541 RegCreateKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Ecere SDK", 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1543 RegSetValueEx(key, "DisplayName", 0, REG_SZ, displayName, (uint)strlen(displayName)+1);
1544 RegSetValueEx(key, "UninstallString", 0, REG_SZ, uninstaller, (uint)strlen(uninstaller)+1);
1545 RegSetValueEx(key, "DisplayIcon", 0, REG_SZ, idePath, (uint)strlen(idePath)+1);
1546 //RegSetValueEx(key, "NoModify", 0, REG_DWORD, (byte *)&nomodify, sizeof(nomodify));
1547 //RegSetValueEx(key, "NoRepair", 0, REG_DWORD, (byte *)&nomodify, sizeof(nomodify));
1552 if(pathOptions[PathOptions::AddECEREPaths].selected
1554 || pathOptions[PathOptions::AddMinGWPaths].selected
1558 HKEY userKey = null, systemKey = null;
1560 char userPath[8192] = "";
1561 char systemPath[8192] = "";
1562 uint16 wUserPath[8192];
1563 uint16 wSystemPath[8192];
1568 ((GuiApplication)__thisModule).Lock();
1569 installProgress.installing.text = "Registering paths...";
1570 ((GuiApplication)__thisModule).Unlock();
1571 ((GuiApplication)__thisModule).SignalEvent();
1573 if(options[0].selected)
1575 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", 0, KEY_ALL_ACCESS, &systemKey) == ERROR_SUCCESS)
1577 size = sizeof(wSystemPath);
1578 RegQueryValueExW(systemKey, L"path", null, null, (byte *)wSystemPath, &size);
1579 UTF16toUTF8Buffer(wSystemPath, systemPath, sizeof(systemPath));
1580 ModifyPath(systemPath, null);
1582 UTF8toUTF16Buffer(systemPath, wSystemPath, sizeof(wSystemPath) / sizeof(uint16));
1583 RegSetValueExW(systemKey, L"path", 0, REG_EXPAND_SZ, (byte *)wSystemPath, (uint)(wcslen(wSystemPath)+1) * 2);
1584 RegCloseKey(systemKey);
1589 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", 0, KEY_QUERY_VALUE, &systemKey) == ERROR_SUCCESS)
1591 size = sizeof(wSystemPath);
1592 RegQueryValueExW(systemKey, L"path", null, null, (byte *)wSystemPath, &size);
1593 UTF16toUTF8Buffer(wSystemPath, systemPath, sizeof(systemPath));
1594 RegCloseKey(systemKey);
1597 RegCreateKeyEx(HKEY_CURRENT_USER, "Environment", 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &userKey, &status);
1598 if(status == REG_OPENED_EXISTING_KEY)
1600 size = sizeof(wUserPath);
1601 RegQueryValueExW(userKey, L"path", null, null, (byte *)wUserPath, &size);
1602 UTF16toUTF8Buffer(wUserPath, userPath, sizeof(userPath));
1604 ModifyPath(systemPath, userPath);
1605 UTF8toUTF16Buffer(userPath, wUserPath, sizeof(wUserPath) / sizeof(uint16));
1606 RegSetValueExW(userKey, L"path", 0, REG_EXPAND_SZ, (byte *)wUserPath, (uint)(wcslen(wUserPath)+1) * 2);
1607 RegCloseKey(userKey);
1609 // SendMessageTimeout (HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)"Environment", SMTO_NORMAL, 1000, NULL);
1612 // Install Program Group Icons
1613 GetEnvironment(options[0].selected ? "ALLUSERSPROFILE" : "USERPROFILE", userProfile, sizeof(userProfile));
1615 if(options[IconOptions::StartMenuIcon].selected)
1617 char destPath[MAX_LOCATION];
1618 char startMenuPath[MAX_LOCATION] = "";
1621 ((GuiApplication)__thisModule).Lock();
1622 installProgress.installing.text = $"Installing Start Menu Icons...";
1623 ((GuiApplication)__thisModule).Unlock();
1624 ((GuiApplication)__thisModule).SignalEvent();
1626 strcpy(destPath, userProfile);
1628 if(RegOpenKeyEx(options[0].selected ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
1629 "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", 0, KEY_QUERY_VALUE, &key) == ERROR_SUCCESS)
1631 uint16 wStartMenuPath[2048];
1632 uint size = sizeof(wStartMenuPath);
1633 // RegQueryValueEx(key, "Start Menu", null, null, startMenuPath, &size);
1634 RegQueryValueExW(key, options[0].selected ? L"Common Programs" : L"Programs", null, null, (byte *)wStartMenuPath, &size);
1635 UTF16toUTF8Buffer(wStartMenuPath, startMenuPath, sizeof(startMenuPath));
1638 if(!startMenuPath[0] && userProfile[0])
1640 strcpy(startMenuPath, userProfile);
1641 PathCat(startMenuPath, "Start Menu\\Programs");
1644 if(startMenuPath[0])
1646 strcpy(destPath, startMenuPath);
1647 PathCat(destPath, "Ecere SDK");
1650 strcpy(destPath, startMenuPath);
1651 PathCat(destPath, "Ecere SDK\\Ecere IDE.lnk");
1652 CreateLink(idePath, destPath, null); //"Ecere IDE");
1653 if(components[ComponentID::samples].selected)
1655 char samplesPath[MAX_LOCATION] = "";
1656 components[ComponentID::samples].GetFullPath(samplesPath, false);
1658 strcpy(destPath, startMenuPath);
1659 PathCat(destPath, "Ecere SDK\\Sample Projects.lnk");
1660 CreateLink(samplesPath, destPath, null);//"Sample Projects");
1662 if(components[ComponentID::documentation].selected && documentation[DocumentationID::ecereBook].selected)
1664 char docPath[MAX_LOCATION] = "";
1665 documentation[DocumentationID::ecereBook].GetFullPath(docPath, false);
1666 PathCat(docPath, "Ecere Tao of Programming [work in progress].pdf");
1669 char tao[MAX_LOCATION] ;
1670 documentation[DocumentationID::ecereBook].GetFullPath(tao, false);
1671 PathCat(tao, "tao.pdf");
1672 RenameFile(tao, docPath);
1675 strcpy(destPath, startMenuPath);
1676 PathCat(destPath, "Ecere SDK\\The Ecere Tao of Programming.lnk");
1677 CreateLink(docPath, destPath, null);
1682 // Install Desktop Icon
1683 if(options[IconOptions::DesktopIcon].selected)
1686 char desktopPath[MAX_LOCATION];
1688 if(RegOpenKeyEx(options[0].selected ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
1689 "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", 0, KEY_QUERY_VALUE, &key) == ERROR_SUCCESS)
1691 uint16 wDesktopPath[MAX_LOCATION];
1692 uint size = sizeof(wDesktopPath);
1693 RegQueryValueExW(key, options[0].selected ? L"Common Desktop" : L"Desktop", null, null, (byte *)wDesktopPath, &size);
1694 UTF16toUTF8Buffer(wDesktopPath, desktopPath, sizeof(desktopPath));
1697 if(!desktopPath[0] && userProfile[0])
1699 strcpy(desktopPath, userProfile);
1700 PathCat(desktopPath, "Desktop");
1705 PathCat(desktopPath, "Ecere IDE.lnk");
1707 ((GuiApplication)__thisModule).Lock();
1708 installProgress.installing.text = $"Installing Desktop Icon...";
1709 ((GuiApplication)__thisModule).Unlock();
1710 ((GuiApplication)__thisModule).SignalEvent();
1712 CreateLink(idePath, desktopPath, null);//"Ecere IDE");
1716 SendMessageTimeout (HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)"Environment", SMTO_NORMAL, 1000, NULL);
1718 // Install QuickLaunch Icon
1719 if(options[IconOptions::QuickLaunchIcon].selected)
1721 char appData[MAX_LOCATION];
1722 GetEnvironment("APPDATA", appData, sizeof(appData));
1725 char destPath[MAX_LOCATION];
1727 if(appData[0] && options[0].selected)
1729 char dir[MAX_FILENAME];
1730 GetLastDirectory(appData, dir);
1731 if(!strcmpi(dir, "Roaming"))
1732 PathCat(appData, "../../../Default/AppData/Roaming");
1734 PathCat(appData, "../Default");
1737 ((GuiApplication)__thisModule).Lock();
1738 installProgress.installing.text = $"Installing Quicklaunch Icon...";
1739 ((GuiApplication)__thisModule).Unlock();
1740 ((GuiApplication)__thisModule).SignalEvent();
1742 strcpy(destPath, appData);
1743 PathCat(destPath, "Microsoft\\Internet Explorer\\Quick Launch\\Ecere IDE.lnk");
1744 CreateLink(idePath, destPath, null);
1746 // Set it up on the dock for Windows 7 -- not working
1748 StripLastDirectory(destPath, destPath);
1749 PathCat(destPath, "User Pinned\\TaskBar");
1751 PathCat(destPath, "Ecere IDE.lnk");
1752 CreateLink(idePath, destPath, null);
1757 // Register File Types
1758 if(associateOptions[AssociateOptions::AssociateEPJ].selected ||
1759 associateOptions[AssociateOptions::AssociateEC].selected ||
1760 associateOptions[AssociateOptions::AssociateC].selected ||
1761 associateOptions[AssociateOptions::AssociateCPP].selected ||
1762 associateOptions[AssociateOptions::AssociateTXT].selected ||
1763 associateOptions[AssociateOptions::Associate3DS].selected ||
1764 associateOptions[AssociateOptions::AssociateIMG].selected)
1766 ((GuiApplication)__thisModule).Lock();
1767 installProgress.installing.text = $"Resgistering File Types...";
1768 ((GuiApplication)__thisModule).Unlock();
1769 ((GuiApplication)__thisModule).SignalEvent();
1771 if(associateOptions[AssociateOptions::AssociateEPJ].selected)
1773 AssociateExtension(".epj", "Ecere IDE Project", "epj_file", "Open", idePath);
1775 if(associateOptions[AssociateOptions::AssociateEC].selected)
1777 AssociateExtension(".ec", "eC Source File", "ec_file", "Open", idePath);
1778 AssociateExtension(".eh", "eC Header File", "eh_file", "Open", idePath);
1780 if(associateOptions[AssociateOptions::AssociateC].selected)
1782 AssociateExtension(".c", "C Source File", "c_file", "Open", idePath);
1783 AssociateExtension(".h", "C Header File", "h_file", "Open", idePath);
1785 if(associateOptions[AssociateOptions::AssociateCPP].selected)
1787 AssociateExtension(".cpp", "C++ Source File", "cpp_file", "Open", idePath);
1788 AssociateExtension(".cc", "C++ Source File", "cpp_file", "Open", idePath);
1789 AssociateExtension(".cxx", "C++ Source File", "cpp_file", "Open", idePath);
1790 AssociateExtension(".chh", "C++ Header File", "chh_file", "Open", idePath);
1791 AssociateExtension(".hh", "C++ Header File", "chh_file", "Open", idePath);
1792 AssociateExtension(".hxx", "C++ Header File", "chh_file", "Open", idePath);
1794 if(associateOptions[AssociateOptions::AssociateTXT].selected)
1796 AssociateExtension(".txt", "Text File", "txt_file", "Open", idePath);
1798 if(associateOptions[AssociateOptions::Associate3DS].selected)
1800 AssociateExtension(".3ds", "3D Studio Model", "3ds_file", "View", idePath);
1802 if(associateOptions[AssociateOptions::AssociateIMG].selected)
1804 AssociateExtension(".bmp", "BMP Image", "bmp_file", "View", idePath);
1805 AssociateExtension(".pcx", "PCX Image", "pcx_file", "View", idePath);
1806 AssociateExtension(".png", "PNG Image", "png_file", "View", idePath);
1807 AssociateExtension(".jpg", "JPEG Image", "jpg_file", "View", idePath);
1808 AssociateExtension(".jpeg", "JPEG Image", "jpg_file", "View", idePath);
1809 AssociateExtension(".gif", "GIF Image", "gif_file", "View", idePath);
1812 ((GuiApplication)__thisModule).Lock();
1814 installProgress.cancel.Destroy(0);
1815 installProgress.finish.text = $"Finish";
1816 installProgress.finish.disabled = false;
1817 installProgress.finish.Activate();
1818 installProgress.installing.text = $"Installation Complete.";
1819 installProgress.title.text = $"Installation Complete";
1820 installProgress.titleInfo.contents = $"Thank you for using the Ecere SDK.";
1822 ((GuiApplication)__thisModule).Unlock();