2 static define buildString = $"Ecere SDK v0.44.08 (Without MinGW) -- built on August 8, 2013 ";
4 static define buildString = $"Ecere SDK v0.44.08 -- built on August 8, 2013 ";
7 #define WIN32_LEAN_AND_MEAN
8 #define GetFreeSpace _GetFreeSpace
26 char * OnGetString(char * tempString, void * fieldData, bool * needClass)
31 void OnDisplay(Surface surface, int x, int y, int width, void * fieldData, Alignment alignment, DataDisplayFlags displayFlags)
33 if(!displayFlags.active) { displayFlags.current = false; displayFlags.selected = false; }
34 class::OnDisplay(surface, x + 22, y, width - 22, fieldData, alignment, displayFlags);
38 //#define BUFFERSIZE 0x10000
39 #define BUFFERSIZE 0x1000
40 bool abortInstall = false;
42 void ExtractFileFromArchive(ProgressBar progressBar, char * path, char * outputFile)
44 char fileName[MAX_LOCATION];
45 FileAttribs exists = FileExists(path);
49 if(exists.isDirectory)
51 FileListing listing { path };
55 if(MakeDir(outputFile))
58 FileGetStats(path, &stats);
62 while(listing.Find() && !abortInstall)
64 strcpy(fileName, outputFile);
66 // Tweak file name if out
69 if(!strcmp(fileName, ".")) fileName[0] = '\0';
70 if(listing.name[0] == '/' || listing.name[0] == '\\')
72 char * afterSlash, rest[MAX_LOCATION];
73 for(afterSlash = fileName; *afterSlash == '/' || *afterSlash == '\\'; afterSlash++);
74 strcpy(rest, afterSlash);
75 PathCat(fileName, "_root");
76 PathCat(fileName, rest);
78 else if(listing.name[1] == ':')
81 sprintf(letter, "_%cdrive", toupper(listing.name[0]));
82 PathCat(fileName, letter);
83 PathCat(fileName, listing.name[2] ? (listing.name + 3) : (listing.name + 2));
86 PathCat(fileName, listing.name);
89 PathCat(fileName, listing.name);
90 if(!strcmp(fileName, "/") || !strcmp(fileName, "\\"))
91 strcpy(fileName, DIR_SEPS);
92 ExtractFileFromArchive(progressBar, listing.path, fileName);
98 File input = FileOpen(path, read);
101 File output = FileOpen(outputFile, write);
104 char fileName[MAX_FILENAME];
105 uint position = progressBar.progress;
108 byte buffer[BUFFERSIZE];
110 FileGetSize(path, &dataSize);
111 GetLastDirectory(outputFile, fileName);
113 ((GuiApplication)__thisModule).SignalEvent();
114 //((GuiApplication)__thisModule).ProcessInput();
115 //((GuiApplication)__thisModule).UpdateDisplay();
117 for(c = 0; c<dataSize && !abortInstall; c += BUFFERSIZE)
119 uint size = (dataSize > c + BUFFERSIZE) ? BUFFERSIZE : (dataSize - c);
121 ((GuiApplication)__thisModule).Unlock();
123 input.Read(buffer, 1, size);
124 output.Write(buffer, 1, size);
126 ((GuiApplication)__thisModule).Lock();
128 progressBar.progress = position + c + size;
129 ((GuiApplication)__thisModule).SignalEvent();
131 //((GuiApplication)__thisModule).ProcessInput();
132 //((GuiApplication)__thisModule).UpdateDisplay();
137 FileGetStats(path, &stats);
143 FileSetTime(outputFile, stats.created, 0, stats.modified);
150 char * defInstallPath;
151 Component * subComponents;
158 char installPath[MAX_LOCATION];
161 void GetFullPath(char * path)
163 if(this != null && parent)
164 parent->GetFullPath(path);
166 strcpy(path, installDir);
169 PathCat(path, installPath);
172 void Install(char * parentPath)
177 char path[MAX_LOCATION];
178 strcpy(path, parentPath);
179 PathCat(path, installPath);
181 installProgress.installing.SetText($"Installing %s...", name);
182 ((GuiApplication)__thisModule).UpdateDisplay();
186 char source[MAX_LOCATION];
188 strcat(source, dataPath);
192 if(FileExists(source).isFile)
194 char name[MAX_FILENAME];
195 GetLastDirectory(source, name);
200 uint p = installProgress.progressBar.progress;
201 ExtractFileFromArchive(installProgress.progressBar, source, path);
206 for(c = 0; subComponents[c].name; c++)
207 subComponents[c].Install(path);
212 Component samples[] =
214 { "Ecere Chess", "samples/chess", "chess", null, false, true },
215 { "Ecere Fractals", "samples/fractals", "fractals", null, false, true },
216 { "3D", "samples/3D", "3D", null, false, true },
217 { "Audio", "samples/audio", "audio", null, false, true },
218 { "Database", "samples/db", "db", null, false, true },
219 { "eC", "samples/eC", "eC", null, false, true },
220 { "Games", "samples/games", "games", null, false, true },
221 { "GUI & Graphics", "samples/guiAndGfx", "guiAndGfx", null, false, true },
222 { "Miscellaneous", "samples/misc", "misc", null, false, true },
223 { "Networking", "samples/net", "net", null, false, true },
224 { "WIA Scanning", "samples/scanning", "scanning", null, false, true },
225 { "Threading", "samples/threads", "threads", null, false, true }
229 public enum CoreSDKID
231 ide, runtime, ec, eda, vanilla, extras,
233 gcc, gdb, mingw, binutils, make,
238 Component coreSDK[CoreSDKID] =
240 { "Ecere IDE", "ecere-sdk/ide", "bin", null, true, true },
241 { "Runtime Library", "ecere-sdk/ecere.dll", "bin", null, true, true },
242 { "eC Compiler", "ecere-sdk/compiler", "bin", null, true, true },
244 { "GNU C Compiler", "mingw/gcc/core", "mingw", null, true, true },
245 { "GNU Debugger", "mingw/gdb", "mingw", null, true, true },
246 { "MinGW Runtime", "mingw/mingwrt", "mingw", null, true, true },
247 { "Binary Utils", "mingw/binutils", "mingw", null, true, true },
248 { "GNU Make", "mingw/make", "mingw", null, true, true },
254 Component additional[] =
256 { "Data Access", "ecere-sdk/eda", "bin", null, false, true },
257 { "Ecere Vanilla", "ecere-sdk/libecereVanilla.a", "lib", null, false, true },
258 { "Ecere Extras", "extras", "extras", null, false, true },
259 { "UPX", "upx/bin", "mingw/bin",null, false, true },
260 { "GNU Regexp", "mingw/gnurx", "mingw", null, false, true },
261 { "pthreads", "mingw/pthreads", "mingw", null, false, true },
262 { "C++ Compiler", "mingw/gcc/c++", "mingw", null, false, true },
263 { "Win32 APIs", "mingw/w32api", "mingw", null, false, true },
264 { "GCC I18n", "mingw/locale/gcc", "mingw", null, false, false },
265 { "GDB I18n", "mingw/locale/gdb", "mingw", null, false, false },
266 { "Make I18n", "mingw/locale/make", "mingw", null, false, false },
267 { "Binutils I18n", "mingw/locale/binutils", "mingw", null, false, false },
272 public enum DocumentationID
274 ecereBook, apiRef, tutorials, coursework,
276 gccDoc, gppDocs, gdbDocs, makeDocs, binDocs, mingwDocs, gnurxDocs, upxDocs,
281 Component documentation[DocumentationID] =
283 { "Ecere Book", "ecere-sdk/book", "doc", null, false, true },
284 { "API Reference", "ecere-sdk/doc", "doc", null, false, true },
285 { "Ecere Tutorials", "ecere-sdk/tutorials", "doc", null, false, true },
286 { "Ecere Coursework", "ecere-sdk/coursework", "doc", null, false, true },
288 { "GCC Docs", "mingw/doc/gcc", "mingw", null, false, false },
289 { "G++ Docs", "mingw/doc/g++", "mingw", null, false, false },
290 { "GDB Docs", "mingw/doc/gdb", "mingw", null, false, false },
291 { "Make Docs", "mingw/doc/make", "mingw", null, false, false },
292 { "Binutils Docs", "mingw/doc/binutils", "mingw", null, false, false },
293 { "MinGW Docs", "mingw/doc/mingwrt", "mingw", null, false, false },
294 { "gnurx Docs", "mingw/doc/gnurx", "mingw", null, false, false },
295 { "UPX Docs", "upx/doc", "mingw/doc/upx", null, false, false },
300 public enum ComponentID
311 Component components[ComponentID] =
313 { "Core SDK Files", null, null, coreSDK, true, true },
315 { "Additional Support", null, null, additional, false, true },
317 { "Documentation", null /*"doc"*/, null /*"doc"*/, documentation, false, true },
318 { "Samples", null, "samples", samples, false, true },
322 FileSize totalInstalled;
327 InstallOption * subOptions;
332 enum AssociateOptions
343 InstallOption associateOptions[] =
345 { "Associate with Ecere Project Files (*.epj)", null, true },
346 { "Associate with eC Files (*.ec, *.eh)", null, true },
347 { "Associate with C files (*.c, *.h)", null, false },
348 { "Associate with C++ Files (*.cpp, *.hpp, *.cc, *.hh, *.cxx, *.hxx)", null, false },
349 { "Associate with text files (*.txt)", null, false },
350 { "Associate with 3D Studio Model Files (*.3ds)", null, true },
351 { "Associate with Image Files (*.png, *.jpg, *.pcx, *.bmp, *.gif)", null, false },
363 InstallOption pathOptions[] =
365 { "Add Ecere binaries location to the system path", null, true },
366 { "Add MinGW to the system path", null, true }
377 InstallOption options[] =
379 { "Start Menu Group", null, true },
380 { "Desktop Icon", null, true },
381 { "Quicklaunch Icon", null, true },
382 { "Associate the ECERE IDE with Supported File Types", associateOptions, true },
384 { "Add binaries location to the system paths", pathOptions, true },
389 char sourceDir[MAX_LOCATION] = ":";
390 char installDir[MAX_LOCATION];
392 class Installer : Window
394 text = $"Ecere Software Development Kit Setup - v0.44.08 \"Ryōan-ji\"";
395 background = activeBorder;
400 clientSize = { 636, 456 };
401 // clientSize = { 796, 576 };
402 icon = { ":icon.png" };
404 Picture back { image = BitmapResource { ":ryoanji.png" }, parent = this, position = { 0, 0 } };
405 FileDialog fileDialog
407 master = this, type = selectDir,
408 text = $"Select a new location"
412 master = this, autoCreate = false, inactive = true, text = "...";
414 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
416 DataRow row = componentsBox.currentRow;
417 Component * component = ((CheckItem *)row.GetData(componentField))->data;
418 component->GetFullPath(fileDialog.filePath);
419 StripLastDirectory(fileDialog.filePath, fileDialog.currentDirectory);
421 if(fileDialog.Modal() == ok)
423 componentsBox.StopEditing(false);
424 row.SetData(locationField, fileDialog.filePath);
425 componentsBox.NotifyChanged(this, componentsBox, row);
426 componentsBox.currentField = componentsBox.currentField;
431 CheckListBox componentsBox
433 this, size = { 460, 112 }, position = { 160, 160 }, hasHeader = true;
434 fullRowSelect = false, collapseControl = true, treeBranches = true, rootCollapseButton = true,
437 selectionColor = { 145, 150, 140 };
442 bool NotifyKeyDown(ListBox listBox, DataRow row, Key key, unichar ch)
444 if(key == f2 && browse.visible)
445 browse.NotifyClicked(this, browse, 0, 0, 0);
449 bool NotifyChanged(ListBox listBox, DataRow row)
451 Component * component = ((CheckItem *)listBox.GetData(componentField))->data;
452 char path[MAX_LOCATION], relative[MAX_LOCATION] = "", * newPath;
453 char fullPath[MAX_LOCATION];
455 component->parent->GetFullPath(path);
456 strcpy(fullPath, path);
458 newPath = row.GetData(locationField);
461 PathCat(fullPath, newPath);
462 MakePathRelative(fullPath, path, relative);
464 listBox.SetData(locationField, relative);
465 strcpy(component->installPath, relative);
467 //SetAvailableSpace(component, path);
470 install.disabled = false;
471 for(c = 0; components[c].name; c++)
473 SetAvailableSpace(components[c], installDir);
479 bool NotifyEditDone(ListBox listBox, DataRow row)
485 bool NotifyEdited(ListBox listBox, DataRow row)
488 browse.parent = listBox;
489 browse.position = { componentField.width + locationField.width + 18, (listBox.currentIndex+1) * listBox.rowHeight - 2 };
490 browse.size = { 30, listBox.rowHeight + 3 };
491 for(e = listBox.firstChild; e; e = e.next)
493 if(e._class == class(DataBox))
502 void NotifyChecked(CheckListBox listBox, DataRow row)
504 Component * component = ((CheckItem *)row.GetData(componentField))->data;
506 component->selected = listBox.IsChecked(row);
508 if(!component->parent) totalSize -= component->requiredSize;
509 component->requiredSize = 0;
510 if(component->selected)
512 component->requiredSize += component->size;
513 if(component->subComponents)
514 for(c = 0; component->subComponents[c].name; c++)
515 component->requiredSize += component->subComponents[c].requiredSize;
517 if(component->requiredSize)
519 uint requiredSize = component->requiredSize;
520 row.SetData(reqField, requiredSize);
523 row.UnsetData(reqField);
524 if(!component->parent)
526 totalSize += component->requiredSize;
528 char sizeString[100];
529 PrintSize(sizeString, totalSize, 2);
530 totalSpaceValue.text = sizeString;
535 Label agreementLbl { parent = this, text = $"By installing the Ecere SDK, you agree to the .", font = { "Tahoma", 8.25f }, anchor = Anchor { left = 24, top = 424 } };
538 this, inactive = true, offset = false, bevel = false, foreground = blue, font = { "Tahoma", 8.25f, underline = true, bold = true },
539 // text = $"terms and conditions", anchor = Anchor { left = 241, top = 421 };
540 text = $"terms and conditions", anchor = Anchor { left = 237, top = 421 };
541 cursor = ((GuiApplication)__thisModule).GetCursor(hand);
543 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
545 // LicenseBox { master = this, sourceFile = ":ecere-sdk/doc/LICENSE" }.Modal();
546 LicensesForm { master = this }.Modal();
550 CheckListBox optionsBox
552 this, size = { 460, 94 }, position = { 160, 284 };
553 fullRowSelect = false, collapseControl = true, treeBranches = true, rootCollapseButton = true,
558 void NotifyChecked(CheckListBox listBox, DataRow row)
560 CheckItem * item = row.GetData(optionField);
561 InstallOption * option = item->data;
562 option->selected = listBox.IsChecked(row);
567 parent = this, text = $"Install", isDefault = true, size = { 75, 23 }, position = { 432, 416 };
569 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
571 installProgress.Create();
573 // installProgress.thread.Main();
574 installProgress.thread.Create();
578 Button button3 { parent = this, text = $"Cancel", hotKey = altX, size = Size { 75, 23 }, anchor = Anchor { left = 544, top = 416 }, NotifyClicked = ButtonCloseDialog };
579 Label label1 { labeledWindow = destBox, tabCycle = true, isGroupBox = true, parent = this, inactive = false, size = Size { 458, 50 }, anchor = Anchor { left = 160, top = 96 } };
582 parent = label1, master = this, text = $" Destination Folder", size = Size { 336, 22 }, anchor = Anchor { left = 12, top = 20, right = 12 };
583 typeExpected = directory;
584 browseDialog = fileDialog;
587 bool NotifyModified(PathBox pathBox)
590 strcpy(installDir, destBox.path);
591 install.disabled = false;
592 for(c = 0; components[c].name; c++)
594 SetAvailableSpace(components[c], installDir);
601 label1, this, $"Browse", altB, size = { 83, 24 }, position = { 360, 16 };
603 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
605 strcpy(fileDialog.filePath, installDir);
606 StripLastDirectory(installDir, fileDialog.currentDirectory);
607 if(fileDialog.Modal())
609 strcpy(installDir, fileDialog.filePath);
610 destBox.contents = installDir;
611 // TOCHECK: Should setting contents call NotifyModified?
612 destBox.NotifyModified(destBox.master, destBox);
619 this, multiLine = true,
620 opacity = 0, borderStyle = none, inactive = true, size = { 136, 53 }, position = { 14, 96 }, noSelect = true,
621 contents = $"Select the default root\n"
622 "folder where to install\n"
627 this, opacity = 0, borderStyle = none, inactive = true, size = { 136, 132 }, position = { 14, 152 }, noSelect = true,
629 contents = $"Select the optional\n"
630 "components you wish\n"
632 "You may customize the\n"
633 "install location for each\n"
634 "of them, or use the default\n"
635 "based on the main\n"
636 "destination folder."
640 this, opacity = 0, borderStyle = none, inactive = true, size = { 136, 53 }, position = { 14, 280 }, noSelect = true,
642 contents = $"Select icons to install, file\n"
643 "associations, and system\n"
644 "environment modifications:"
646 Label totalSpaceLabel
648 this, position = { 18, 352 }, text = $"Space Required: "
650 Label totalSpaceValue
652 this, position = { 100, 352 }, text = "0 mb"
656 inactive = true, noSelect = true,
657 multiLine = true, parent = label3, text = "editBox1", opacity = 0, borderStyle = none, size = Size { 350, 35 }, anchor = Anchor { horz = 111, vert = 13 },
658 contents = $"Choose in which folder to install the ECERE SDK, which features\n"
659 "of the SDK to install, as well as where to install program icons."
661 Label label2 { parent = this, text = buildString, position = { 16, 392 }, font = { "Tahoma", 10, true }, disabled = true, opacity = 0, background = activeBorder };
664 image = BitmapResource { ":ecere.png", alphaBlend = true }, filter = true, parent = label3, text = "picture1", anchor = Anchor { left = 16, top = 4 };
665 cursor = ((GuiApplication)__thisModule).GetCursor(hand);
667 bool OnLeftButtonDown(int x, int y, Modifiers mods)
669 ShellOpen("http://www.ecere.com/");
673 Label label4 { parent = label3, text = $"Choose Components, Locations and Install Options", font = FontResource { "Tahoma", 8.25f, bold = true }, size = Size { 326, 16 }, anchor = Anchor { horz = 91, vert = -12 } };
674 DataField componentField { "CheckItem", width = 140, header = $"Component" };
675 DataField locationField { "char *", width = 108, header = $"Destination Folder", editable = true };
676 DataField reqField { "FileSize", width = 80, header = $"Req. Space", alignment = right };
677 DataField avField { "FileSize64", width = 80, header = $"Avail. Space", alignment = right };
678 DataField optionField { "CheckItem" };
680 void SetAvailableSpace(Component component, char * parentPath)
682 char path[MAX_LOCATION];
686 strcpy(path, parentPath);
687 PathCat(path, component.installPath);
689 if(component.subComponents)
690 for(c = 0; component.subComponents[c].name; c++)
691 SetAvailableSpace(component.subComponents[c], path);
693 while(!FileExists(path) && path[0])
694 StripLastDirectory(path, path);
697 GetFreeSpace(path, &size);
698 component.row.SetData(avField, size);
699 if(!size) install.disabled = true;
702 FileSize ComputeSize(char * path)
705 FileAttribs attribs = FileExists(path);
706 if(attribs.isDirectory)
708 FileListing listing { path };
709 while(listing.Find())
711 if(listing.stats.attribs.isDirectory)
712 size += ComputeSize(listing.path);
714 size += listing.stats.size;
718 FileGetSize(path, &size);
722 void AddComponent(Component component, Component parent, char * parentPath)
724 DataRow row = (parent != null) ? parent.row.AddRow() : componentsBox.AddRow();
726 FileSize64 avSize = 0;
727 char path[MAX_LOCATION];
730 strcpy(path, parentPath);
731 if(component.defInstallPath)
732 PathCat(path, component.defInstallPath);
733 component.parent = parent;
735 row.SetData(null, CheckItem { component.name, component } );
737 if(component.defInstallPath)
739 strcpy(component.installPath, component.defInstallPath);
740 ChangeCh(component.installPath, '/', DIR_SEP);
741 row.SetData(locationField, component.installPath);
744 if(component.mandatory)
745 componentsBox.SetDisabled(row, true);
746 componentsBox.SetCheck(row, component.selected);
748 if(component.dataPath)
750 char path[MAX_LOCATION];
752 PathCat(path, component.dataPath);
753 component.size = ComputeSize(path);
755 if(component.subComponents)
758 for(c = 0; component.subComponents[c].name; c++)
760 AddComponent(component.subComponents[c], component, path);
761 size += component.subComponents[c].requiredSize;
765 component.requiredSize = component.selected ? (size + component.size) : 0;
766 if(component.requiredSize)
767 row.SetData(reqField, component.requiredSize);
769 while(!FileExists(path) && path[0])
770 StripLastDirectory(path, path);
773 GetFreeSpace(path, &avSize);
776 row.SetData(avField, avSize);
777 row.collapsed = true;
780 void AddOption(InstallOption option, InstallOption parent)
782 DataRow row = option.row = (parent != null) ? parent.row.AddRow() : optionsBox.AddRow();
783 row.SetData(null, CheckItem { option.name, option } );
784 optionsBox.SetCheck(row, option.selected);
785 if(option.subOptions)
788 for(c = 0; option.subOptions[c].name; c++)
790 AddOption(option.subOptions[c], option);
793 row.collapsed = true;
799 char programFilesDir[MAX_LOCATION];
800 char appData[MAX_LOCATION];
801 char homeDrive[MAX_LOCATION];
802 char winDir[MAX_LOCATION];
804 GetEnvironment("APPDATA", appData, sizeof(appData));
805 GetEnvironment("HOMEDRIVE", homeDrive, sizeof(homeDrive));
806 GetEnvironment("windir", winDir, sizeof(winDir));
808 componentsBox.AddField(componentField);
809 componentsBox.AddField(locationField);
810 componentsBox.AddField(reqField);
811 componentsBox.AddField(avField);
813 optionsBox.AddField(optionField);
815 if(GetEnvironment("ProgramFiles", programFilesDir, MAX_LOCATION))
817 strcpy(installDir, programFilesDir);
818 PathCat(installDir, "ECERE SDK");
820 else if(homeDrive && homeDrive[0])
822 strcpy(installDir, homeDrive);
823 PathCat(installDir, "ECERE SDK");
825 else if(winDir && winDir[0])
827 strcpy(installDir, winDir);
828 PathCat(installDir, "..\\ECERE SDK");
831 strcpy(installDir, "C:\\ECERE SDK");
833 if(appData && appData[0])
835 static char defSamplesPath[MAX_LOCATION];
836 static char defExtrasPath[MAX_LOCATION];
837 strcpy(defSamplesPath, appData);
838 PathCat(defSamplesPath, "ECERE SDK\\Samples");
839 components[samples].defInstallPath = defSamplesPath;
841 strcpy(defExtrasPath, appData);
842 PathCat(defExtrasPath, "ECERE SDK\\extras");
843 coreSDK[extras].defInstallPath = defExtrasPath;
846 destBox.path = installDir;
850 for(c = 0; components[c].name; c++)
851 AddComponent(components[c], null, installDir);
854 // Compute size apart because ToggleCheck will change it
858 for(c = 0; components[c].name; c++)
859 totalSize += components[c].requiredSize;
862 char sizeString[100];
863 PrintSize(sizeString, totalSize, 2);
864 totalSpaceValue.text = sizeString;
866 for(c = 0; options[c].name; c++)
867 AddOption(options[c], null);
876 void OnDrawOverChildren(Surface surface)
878 int tw = label2.size.w;
879 surface.SetForeground(Color { 128, 128, 128 });
880 surface.HLine(label2.position.x + tw + 6, 620, 400);
881 surface.SetForeground(white);
882 surface.HLine(label2.position.x + tw + 6, 621, 401);
883 surface.PutPixel(621, 400);
888 parent = this, opacity = 0, borderStyle = deep, size = Size { 644, 93 }, anchor = Anchor { left = -8, top = -8 };
892 class InstallProgress : Window
894 text = $"Ecere Software Development Kit Setup - v0.44 \"Ryōan-ji\"";
895 background = activeBorder;
900 // size = Size { 640, 480 };
901 clientSize = { 636, 456 };
902 //clientSize = { 796, 576 };
903 icon = { ":icon.png" };
905 Picture back { image = BitmapResource { ":ryoanji-progress.png" }, parent = this, position = { 0, 0 } };
906 Label installing { this, position = { 32, 160 } };
907 ProgressBar progressBar { parent = this, size = Size { 588, 24 }, anchor = Anchor { left = 24, top = 184 } };
910 parent = this, text = $"Install", disabled = true, isDefault = true, size = Size { 75, 23 }, anchor = Anchor { left = 432, top = 416 };
912 NotifyClicked = ButtonCloseDialog
916 this, text = $"Cancel", hotKey = altX, size = Size { 75, 23 }, anchor = Anchor { left = 544, top = 416 };
918 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
926 inactive = true, noSelect = true,
927 multiLine = true, parent = label3, opacity = 0, borderStyle = none, size = Size { 350, 35 }, anchor = Anchor { horz = 111, vert = 13 },
928 contents = $"Please wait while the Ecere Software Development Kit is being installed."
930 Label label2 { parent = this, text = buildString, position = { 16, 392 }, font = { "Tahoma", 10, true }, disabled = true, opacity = 0, background = activeBorder };
933 image = BitmapResource { ":ecere.png", alphaBlend = true }, filter = true, parent = label3, anchor = Anchor { left = 16, top = 4 };
934 cursor = ((GuiApplication)__thisModule).GetCursor(hand);
936 bool OnLeftButtonDown(int x, int y, Modifiers mods)
938 ShellOpen("http://www.ecere.com/");
942 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 } };
944 void OnDrawOverChildren(Surface surface)
946 int tw = label2.size.w;
947 surface.SetForeground(Color { 128, 128, 128 });
948 surface.HLine(label2.position.x + tw + 6, 620, 400);
949 surface.SetForeground(white);
950 surface.HLine(label2.position.x + tw + 6, 621, 401);
951 surface.PutPixel(621, 400);
956 parent = this, opacity = 0, borderStyle = deep, size = Size { 644, 93 }, anchor = Anchor { left = -8, top = -8 };
963 Installer installer {};
964 InstallProgress installProgress { autoCreate = false };
966 void ModifyPath(char * newPath)
973 strcpy(oldPath, newPath);
974 count = TokenizeWith(oldPath, sizeof(paths) / sizeof(char *), paths, ";", false);
976 for(c = 0; coreSDK[c].name; c++)
978 char path[MAX_LOCATION];
979 if(c == extras || c == vanilla) continue;
981 coreSDK[c].GetFullPath(path);
982 if(c != ide && c != runtime && c != eda && c != ec)
985 if(!pathOptions[PathOptions::AddMinGWPaths].selected)
988 PathCat(path, "bin");
990 else if(!pathOptions[PathOptions::AddECEREPaths].selected) continue;
992 for(p = 0; p<count; p++)
993 if(!fstrcmp(paths[p], path))
1000 strcat(newPath, ";");
1001 start = paths[count-1] + strlen(paths[count-1])+1;
1006 strcpy(start, path);
1007 *(start + strlen(path)) = '\0';
1008 paths[count++] = start;
1010 strcat(newPath, path);
1014 if(pathOptions[PathOptions::AddMinGWPaths].selected)
1017 // Up to before Win32 APIs
1018 for(c = 0; c < 4 /*additional[c].name*/; c++)
1020 char path[MAX_LOCATION];
1021 additional[c].GetFullPath(path);
1022 if(c != 0) // UPX already is in bin
1023 PathCat(path, "bin");
1024 for(p = 0; p<count; p++)
1025 if(!fstrcmp(paths[p], path))
1033 strcat(newPath, ";");
1034 start = paths[count-1] + strlen(paths[count-1])+1;
1039 strcpy(start, path);
1040 *(start + strlen(path)) = '\0';
1041 paths[count++] = start;
1043 strcat(newPath, path);
1050 void AssociateExtension(char * extension, char * description, char *name, char * action, char * path)
1056 RegCreateKeyEx(HKEY_CLASSES_ROOT, extension, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1057 RegSetValueEx(key, null, 0, REG_SZ, name, (uint)strlen(name)+1);
1060 RegCreateKeyEx(HKEY_CLASSES_ROOT, name, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1061 RegSetValueEx(key, null, 0, REG_SZ, description, (uint)strlen(description)+1);
1064 sprintf(keyName, "%s\\shell", extension);
1065 RegCreateKeyEx(HKEY_CLASSES_ROOT, keyName, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1066 RegSetValueEx(key, null, 0, REG_SZ, action, (uint)strlen(action)+1);
1069 sprintf(keyName, "%s\\shell\\%s", name, action);
1070 RegCreateKeyEx(HKEY_CLASSES_ROOT, keyName, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1073 sprintf(keyName, "%s\\shell\\%s\\command", name, action);
1074 RegCreateKeyEx(HKEY_CLASSES_ROOT, keyName, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1076 sprintf(keyName, path);
1077 strcat(keyName, " \"%L\"");
1079 uint16 wKeyName[2048];
1080 UTF8toUTF16Buffer(keyName, wKeyName, sizeof(wKeyName) / sizeof(uint16));
1081 RegSetValueExW(key, null, 0, REG_SZ, (byte *)wKeyName, (uint)(wcslen(wKeyName) + 1)*sizeof(uint16));
1086 class InstallThread : Thread
1091 ((GuiApplication)__thisModule).Lock();
1092 installProgress.progressBar.range = totalSize;
1093 for(c = 0; components[c].name && !abortInstall; c++)
1094 components[c].Install(installDir);
1097 installProgress.progressBar.range = 0;
1098 installProgress.finish.Destroy(0);
1099 installProgress.cancel.text = $"Close";
1100 installProgress.cancel.isDefault = true;
1101 installProgress.cancel.disabled = false;
1102 installProgress.cancel.NotifyClicked = Window::ButtonCloseDialog;
1103 installProgress.installing.text = $"Installation Cancelled.";
1104 installProgress.title.text = $"Installation Cancelled";
1105 installProgress.titleInfo.contents = $"The installation was not completed.";
1110 char idePath[MAX_LOCATION];
1111 char userProfile[MAX_LOCATION];
1114 IDESettings settings = null; // Don't instantiate yet so we can pick up old settings
1116 IDESettingsContainer settingsContainer
1119 dataOwner = &settings;
1120 dataClass = class(IDESettings);
1122 CompilerConfig compiler;
1123 installProgress.installing.text = $"Configuring ECERE IDE...";
1124 ((GuiApplication)__thisModule).Unlock();
1125 ((GuiApplication)__thisModule).SignalEvent();
1127 settingsContainer.Load();
1128 compiler = settings.GetCompilerConfig(defaultCompilerName);
1131 for(c = 0; coreSDK[c].name; c++)
1133 char path[MAX_LOCATION];
1135 if(c == extras) continue;
1136 coreSDK[c].GetFullPath(path);
1137 if(c != ide && c != runtime && c != eda && c != ec && c != vanilla)
1138 PathCat(path, "bin");
1139 MakeSlashPath(path);
1142 coreSDK[c].GetFullPath(idePath);
1143 PathCat(idePath, "IDE.exe");
1148 if(!compiler.executableDirs.Find(path))
1149 compiler.executableDirs.Add(CopyString(path));
1152 if(c == runtime || c == vanilla)
1154 if(!compiler.libraryDirs.Find(path))
1155 compiler.libraryDirs.Add(CopyString(path));
1159 // Up to before Win32 APIs
1160 for(c = 0; c < 4 /*additional[c].name*/; c++)
1162 char path[MAX_LOCATION];
1163 additional[c].GetFullPath(path);
1165 PathCat(path, "bin");
1166 MakeSlashPath(path);
1167 if(!compiler.executableDirs.Find(path))
1168 compiler.executableDirs.Add(CopyString(path));
1174 char path[MAX_LOCATION] = "";
1176 if(components[samples].selected)
1177 components[samples].GetFullPath(path);
1179 components[coreSDK].GetFullPath(path);
1181 if(!settings.ideProjectFileDialogLocation[0])
1182 settings.ideProjectFileDialogLocation = path;
1183 if(!settings.ideFileDialogLocation[0])
1184 settings.ideFileDialogLocation = path;
1186 if(documentation[apiRef].selected)
1188 documentation[apiRef].GetFullPath(path);
1189 if(!settings.docDir[0])
1190 settings.docDir = path;
1194 settingsContainer.Save();
1195 delete settingsContainer;
1198 // Set up Uninstaller
1199 ((GuiApplication)__thisModule).Lock();
1200 installProgress.installing.text = $"Registering uninstaller...";
1201 ((GuiApplication)__thisModule).Unlock();
1202 ((GuiApplication)__thisModule).SignalEvent();
1207 char * displayName = "ECERE SDK 0.44";
1208 char uninstaller[MAX_LOCATION];
1209 bool nomodify = true;
1211 strcpy(uninstaller, installDir);
1212 PathCat(uninstaller, "uninstall_ecere.exe");
1214 RegCreateKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\ECERE SDK", 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1216 RegSetValueEx(key, "DisplayName", 0, REG_SZ, displayName, (uint)strlen(displayName)+1);
1217 RegSetValueEx(key, "UninstallString", 0, REG_SZ, uninstaller, (uint)strlen(uninstaller)+1);
1218 RegSetValueEx(key, "DisplayIcon", 0, REG_SZ, idePath, (uint)strlen(idePath)+1);
1219 //RegSetValueEx(key, "NoModify", 0, REG_DWORD, (byte *)&nomodify, sizeof(nomodify));
1220 //RegSetValueEx(key, "NoRepair", 0, REG_DWORD, (byte *)&nomodify, sizeof(nomodify));
1225 if(pathOptions[PathOptions::AddECEREPaths].selected
1227 || pathOptions[PathOptions::AddMinGWPaths].selected
1233 char path[4096] = "";
1236 ((GuiApplication)__thisModule).Lock();
1237 installProgress.installing.text = "Registering paths...";
1238 ((GuiApplication)__thisModule).Unlock();
1239 ((GuiApplication)__thisModule).SignalEvent();
1241 // if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Environment", 0, KEY_ALL_ACCESS, &key) == ERROR_SUCCESS)
1243 RegCreateKeyEx(HKEY_CURRENT_USER, "Environment", 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1244 // RegCreateKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1245 if(status == REG_OPENED_EXISTING_KEY)
1247 size = sizeof(wPath);
1248 RegQueryValueExW(key, L"path", null, null, (byte *)wPath, &size);
1249 UTF16toUTF8Buffer(wPath, path, sizeof(path));
1252 UTF8toUTF16Buffer(path, wPath, sizeof(wPath) / sizeof(uint16));
1253 RegSetValueExW(key, L"path", 0, REG_EXPAND_SZ, (byte *)wPath, (uint)(wcslen(wPath)+1) * 2);
1256 SendMessageTimeout (HWND_BROADCAST, WM_SETTINGCHANGE, 0, (int)"Environment", SMTO_NORMAL, 1000, NULL);
1259 // Install Program Group Icons
1260 GetEnvironment("USERPROFILE", userProfile, sizeof(userProfile));
1262 if(options[IconOptions::StartMenuIcon].selected)
1264 char destPath[MAX_LOCATION];
1265 char startMenuPath[MAX_LOCATION] = "";
1268 ((GuiApplication)__thisModule).Lock();
1269 installProgress.installing.text = $"Installing Start Menu Icons...";
1270 ((GuiApplication)__thisModule).Unlock();
1271 ((GuiApplication)__thisModule).SignalEvent();
1273 strcpy(destPath, userProfile);
1275 if(RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", 0, KEY_ALL_ACCESS, &key) == ERROR_SUCCESS)
1277 uint16 wStartMenuPath[2048];
1278 uint size = sizeof(wStartMenuPath);
1279 // RegQueryValueEx(key, "Start Menu", null, null, startMenuPath, &size);
1280 RegQueryValueExW(key, L"Programs", null, null, (byte *)wStartMenuPath, &size);
1281 UTF16toUTF8Buffer(wStartMenuPath, startMenuPath, sizeof(startMenuPath));
1284 if(!startMenuPath[0] && userProfile[0])
1286 strcpy(startMenuPath, userProfile);
1287 PathCat(startMenuPath, "Start Menu\\Programs");
1290 if(startMenuPath[0])
1292 strcpy(destPath, startMenuPath);
1293 PathCat(destPath, "ECERE SDK");
1296 strcpy(destPath, startMenuPath);
1297 PathCat(destPath, "ECERE SDK\\ECERE IDE.lnk");
1298 CreateLink(idePath, destPath, null); //"ECERE IDE");
1299 if(components[samples].selected)
1301 char samplesPath[MAX_LOCATION] = "";
1302 components[samples].GetFullPath(samplesPath);
1304 strcpy(destPath, startMenuPath);
1305 PathCat(destPath, "ECERE SDK\\Sample Projects.lnk");
1306 CreateLink(samplesPath, destPath, null);//"Sample Projects");
1308 if(components[documentation].selected && documentation[ecereBook].selected)
1310 char docPath[MAX_LOCATION] = "";
1311 documentation[ecereBook].GetFullPath(docPath);
1312 PathCat(docPath, "Ecere Tao of Programming [work in progress].pdf");
1315 char tao[MAX_LOCATION] ;
1316 documentation[ecereBook].GetFullPath(tao);
1317 PathCat(tao, "tao.pdf");
1318 RenameFile(tao, docPath);
1321 strcpy(destPath, startMenuPath);
1322 PathCat(destPath, "ECERE SDK\\The Ecere Tao of Programming.lnk");
1323 CreateLink(docPath, destPath, null);
1328 // Install Desktop Icon
1329 if(options[IconOptions::DesktopIcon].selected)
1332 char desktopPath[MAX_LOCATION];
1334 if(RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", 0, KEY_ALL_ACCESS, &key) == ERROR_SUCCESS)
1336 uint16 wDesktopPath[MAX_LOCATION];
1337 uint size = sizeof(wDesktopPath);
1338 RegQueryValueExW(key, L"Desktop", null, null, (byte *)wDesktopPath, &size);
1339 UTF16toUTF8Buffer(wDesktopPath, desktopPath, sizeof(desktopPath));
1342 if(!desktopPath[0] && userProfile[0])
1344 strcpy(desktopPath, userProfile);
1345 PathCat(desktopPath, "Desktop");
1350 PathCat(desktopPath, "ECERE IDE.lnk");
1352 ((GuiApplication)__thisModule).Lock();
1353 installProgress.installing.text = $"Installing Desktop Icon...";
1354 ((GuiApplication)__thisModule).Unlock();
1355 ((GuiApplication)__thisModule).SignalEvent();
1357 CreateLink(idePath, desktopPath, null);//"ECERE IDE");
1361 // Install QuickLaunch Icon
1362 if(options[IconOptions::QuickLaunchIcon].selected)
1364 char appData[MAX_LOCATION];
1365 GetEnvironment("APPDATA", appData, sizeof(appData));
1369 char destPath[MAX_LOCATION];
1371 ((GuiApplication)__thisModule).Lock();
1372 installProgress.installing.text = $"Installing Quicklaunch Icon...";
1373 ((GuiApplication)__thisModule).Unlock();
1374 ((GuiApplication)__thisModule).SignalEvent();
1376 strcpy(destPath, appData);
1377 PathCat(destPath, "Microsoft\\Internet Explorer\\Quick Launch\\ECERE IDE.lnk");
1379 CreateLink(idePath, destPath, null);//"ECERE IDE");
1383 // Register File Types
1384 if(associateOptions[AssociateOptions::AssociateEPJ].selected ||
1385 associateOptions[AssociateOptions::AssociateEC].selected ||
1386 associateOptions[AssociateOptions::AssociateC].selected ||
1387 associateOptions[AssociateOptions::AssociateCPP].selected ||
1388 associateOptions[AssociateOptions::AssociateTXT].selected ||
1389 associateOptions[AssociateOptions::Associate3DS].selected ||
1390 associateOptions[AssociateOptions::AssociateIMG].selected)
1392 ((GuiApplication)__thisModule).Lock();
1393 installProgress.installing.text = $"Resgistering File Types...";
1394 ((GuiApplication)__thisModule).Unlock();
1395 ((GuiApplication)__thisModule).SignalEvent();
1397 if(associateOptions[AssociateOptions::AssociateEPJ].selected)
1399 AssociateExtension(".epj", "ECERE IDE Project", "epj_file", "Open", idePath);
1401 if(associateOptions[AssociateOptions::AssociateEC].selected)
1403 AssociateExtension(".ec", "eC Source File", "ec_file", "Open", idePath);
1404 AssociateExtension(".eh", "eC Header File", "eh_file", "Open", idePath);
1406 if(associateOptions[AssociateOptions::AssociateC].selected)
1408 AssociateExtension(".c", "C Source File", "c_file", "Open", idePath);
1409 AssociateExtension(".h", "C Header File", "h_file", "Open", idePath);
1411 if(associateOptions[AssociateOptions::AssociateCPP].selected)
1413 AssociateExtension(".cpp", "C++ Source File", "cpp_file", "Open", idePath);
1414 AssociateExtension(".cc", "C++ Source File", "cpp_file", "Open", idePath);
1415 AssociateExtension(".cxx", "C++ Source File", "cpp_file", "Open", idePath);
1416 AssociateExtension(".chh", "C++ Header File", "chh_file", "Open", idePath);
1417 AssociateExtension(".hh", "C++ Header File", "chh_file", "Open", idePath);
1418 AssociateExtension(".hxx", "C++ Header File", "chh_file", "Open", idePath);
1420 if(associateOptions[AssociateOptions::AssociateTXT].selected)
1422 AssociateExtension(".txt", "Text File", "txt_file", "Open", idePath);
1424 if(associateOptions[AssociateOptions::Associate3DS].selected)
1426 AssociateExtension(".3ds", "3D Studio Model", "3ds_file", "View", idePath);
1428 if(associateOptions[AssociateOptions::AssociateIMG].selected)
1430 AssociateExtension(".bmp", "BMP Image", "bmp_file", "View", idePath);
1431 AssociateExtension(".pcx", "PCX Image", "pcx_file", "View", idePath);
1432 AssociateExtension(".png", "PNG Image", "png_file", "View", idePath);
1433 AssociateExtension(".jpg", "JPEG Image", "jpg_file", "View", idePath);
1434 AssociateExtension(".jpeg", "JPEG Image", "jpg_file", "View", idePath);
1435 AssociateExtension(".gif", "GIF Image", "gif_file", "View", idePath);
1438 ((GuiApplication)__thisModule).Lock();
1440 installProgress.cancel.Destroy(0);
1441 installProgress.finish.text = $"Finish";
1442 installProgress.finish.disabled = false;
1443 installProgress.finish.Activate();
1444 installProgress.installing.text = $"Installation Complete.";
1445 installProgress.title.text = $"Installation Complete";
1446 installProgress.titleInfo.contents = $"Thank you for using the Ecere SDK.";
1448 ((GuiApplication)__thisModule).Unlock();