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 bool NotifyChanged(CheckListBox listBox, DataRow row)
560 CheckItem * item = row.GetData(optionField);
561 InstallOption * option = item->data;
563 option->selected = listBox.IsChecked(row);
569 parent = this, text = $"Install", isDefault = true, size = { 75, 23 }, position = { 432, 416 };
571 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
573 installProgress.Create();
575 // installProgress.thread.Main();
576 installProgress.thread.Create();
580 Button button3 { parent = this, text = $"Cancel", hotKey = altX, size = Size { 75, 23 }, anchor = Anchor { left = 544, top = 416 }, NotifyClicked = ButtonCloseDialog };
581 Label label1 { labeledWindow = destBox, tabCycle = true, isGroupBox = true, parent = this, inactive = false, size = Size { 458, 50 }, anchor = Anchor { left = 160, top = 96 } };
584 parent = label1, master = this, text = $" Destination Folder", size = Size { 336, 22 }, anchor = Anchor { left = 12, top = 20, right = 12 };
585 typeExpected = directory;
586 browseDialog = fileDialog;
589 bool NotifyModified(PathBox pathBox)
592 strcpy(installDir, destBox.path);
593 install.disabled = false;
594 for(c = 0; components[c].name; c++)
596 SetAvailableSpace(components[c], installDir);
603 label1, this, $"Browse", altB, size = { 83, 24 }, position = { 360, 16 };
605 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
607 strcpy(fileDialog.filePath, installDir);
608 StripLastDirectory(installDir, fileDialog.currentDirectory);
609 if(fileDialog.Modal())
611 strcpy(installDir, fileDialog.filePath);
612 destBox.contents = installDir;
613 // TOCHECK: Should setting contents call NotifyModified?
614 destBox.NotifyModified(destBox.master, destBox);
621 this, multiLine = true,
622 opacity = 0, borderStyle = none, inactive = true, size = { 136, 53 }, position = { 14, 96 }, noSelect = true,
623 contents = $"Select the default root\n"
624 "folder where to install\n"
629 this, opacity = 0, borderStyle = none, inactive = true, size = { 136, 132 }, position = { 14, 152 }, noSelect = true,
631 contents = $"Select the optional\n"
632 "components you wish\n"
634 "You may customize the\n"
635 "install location for each\n"
636 "of them, or use the default\n"
637 "based on the main\n"
638 "destination folder."
642 this, opacity = 0, borderStyle = none, inactive = true, size = { 136, 53 }, position = { 14, 280 }, noSelect = true,
644 contents = $"Select icons to install, file\n"
645 "associations, and system\n"
646 "environment modifications:"
648 Label totalSpaceLabel
650 this, position = { 18, 352 }, text = $"Space Required: "
652 Label totalSpaceValue
654 this, position = { 100, 352 }, text = "0 mb"
658 inactive = true, noSelect = true,
659 multiLine = true, parent = label3, text = "editBox1", opacity = 0, borderStyle = none, size = Size { 350, 35 }, anchor = Anchor { horz = 111, vert = 13 },
660 contents = $"Choose in which folder to install the ECERE SDK, which features\n"
661 "of the SDK to install, as well as where to install program icons."
663 Label label2 { parent = this, text = buildString, position = { 16, 392 }, font = { "Tahoma", 10, true }, disabled = true, opacity = 0, background = activeBorder };
666 image = BitmapResource { ":ecere.png", alphaBlend = true }, filter = true, parent = label3, text = "picture1", anchor = Anchor { left = 16, top = 4 };
667 cursor = ((GuiApplication)__thisModule).GetCursor(hand);
669 bool OnLeftButtonDown(int x, int y, Modifiers mods)
671 ShellOpen("http://www.ecere.com/");
675 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 } };
676 DataField componentField { "CheckItem", width = 140, header = $"Component" };
677 DataField locationField { "char *", width = 108, header = $"Destination Folder", editable = true };
678 DataField reqField { "FileSize", width = 80, header = $"Req. Space", alignment = right };
679 DataField avField { "FileSize64", width = 80, header = $"Avail. Space", alignment = right };
680 DataField optionField { "CheckItem" };
682 void SetAvailableSpace(Component component, char * parentPath)
684 char path[MAX_LOCATION];
688 strcpy(path, parentPath);
689 PathCat(path, component.installPath);
691 if(component.subComponents)
692 for(c = 0; component.subComponents[c].name; c++)
693 SetAvailableSpace(component.subComponents[c], path);
695 while(!FileExists(path) && path[0])
696 StripLastDirectory(path, path);
699 GetFreeSpace(path, &size);
700 component.row.SetData(avField, size);
701 if(!size) install.disabled = true;
704 FileSize ComputeSize(char * path)
707 FileAttribs attribs = FileExists(path);
708 if(attribs.isDirectory)
710 FileListing listing { path };
711 while(listing.Find())
713 if(listing.stats.attribs.isDirectory)
714 size += ComputeSize(listing.path);
716 size += listing.stats.size;
720 FileGetSize(path, &size);
724 void AddComponent(Component component, Component parent, char * parentPath)
726 DataRow row = (parent != null) ? parent.row.AddRow() : componentsBox.AddRow();
728 FileSize64 avSize = 0;
729 char path[MAX_LOCATION];
732 strcpy(path, parentPath);
733 if(component.defInstallPath)
734 PathCat(path, component.defInstallPath);
735 component.parent = parent;
737 row.SetData(null, CheckItem { component.name, component } );
739 if(component.defInstallPath)
741 strcpy(component.installPath, component.defInstallPath);
742 ChangeCh(component.installPath, '/', DIR_SEP);
743 row.SetData(locationField, component.installPath);
746 if(component.mandatory)
747 componentsBox.SetDisabled(row, true);
748 componentsBox.SetCheck(row, component.selected);
750 if(component.dataPath)
752 char path[MAX_LOCATION];
754 PathCat(path, component.dataPath);
755 component.size = ComputeSize(path);
757 if(component.subComponents)
760 for(c = 0; component.subComponents[c].name; c++)
762 AddComponent(component.subComponents[c], component, path);
763 size += component.subComponents[c].requiredSize;
767 component.requiredSize = component.selected ? (size + component.size) : 0;
768 if(component.requiredSize)
769 row.SetData(reqField, component.requiredSize);
771 while(!FileExists(path) && path[0])
772 StripLastDirectory(path, path);
775 GetFreeSpace(path, &avSize);
778 row.SetData(avField, avSize);
779 row.collapsed = true;
782 void AddOption(InstallOption option, InstallOption parent)
784 DataRow row = option.row = (parent != null) ? parent.row.AddRow() : optionsBox.AddRow();
785 row.SetData(null, CheckItem { option.name, option } );
786 optionsBox.SetCheck(row, option.selected);
787 if(option.subOptions)
790 for(c = 0; option.subOptions[c].name; c++)
792 AddOption(option.subOptions[c], option);
795 row.collapsed = true;
801 char programFilesDir[MAX_LOCATION];
802 char appData[MAX_LOCATION];
803 char homeDrive[MAX_LOCATION];
804 char winDir[MAX_LOCATION];
806 GetEnvironment("APPDATA", appData, sizeof(appData));
807 GetEnvironment("HOMEDRIVE", homeDrive, sizeof(homeDrive));
808 GetEnvironment("windir", winDir, sizeof(winDir));
810 componentsBox.AddField(componentField);
811 componentsBox.AddField(locationField);
812 componentsBox.AddField(reqField);
813 componentsBox.AddField(avField);
815 optionsBox.AddField(optionField);
817 if(GetEnvironment("ProgramFiles", programFilesDir, MAX_LOCATION))
819 strcpy(installDir, programFilesDir);
820 PathCat(installDir, "ECERE SDK");
822 else if(homeDrive && homeDrive[0])
824 strcpy(installDir, homeDrive);
825 PathCat(installDir, "ECERE SDK");
827 else if(winDir && winDir[0])
829 strcpy(installDir, winDir);
830 PathCat(installDir, "..\\ECERE SDK");
833 strcpy(installDir, "C:\\ECERE SDK");
835 if(appData && appData[0])
837 static char defSamplesPath[MAX_LOCATION];
838 static char defExtrasPath[MAX_LOCATION];
839 strcpy(defSamplesPath, appData);
840 PathCat(defSamplesPath, "ECERE SDK\\Samples");
841 components[samples].defInstallPath = defSamplesPath;
843 strcpy(defExtrasPath, appData);
844 PathCat(defExtrasPath, "ECERE SDK\\extras");
845 coreSDK[extras].defInstallPath = defExtrasPath;
848 destBox.path = installDir;
852 for(c = 0; components[c].name; c++)
853 AddComponent(components[c], null, installDir);
856 // Compute size apart because ToggleCheck will change it
860 for(c = 0; components[c].name; c++)
861 totalSize += components[c].requiredSize;
864 char sizeString[100];
865 PrintSize(sizeString, totalSize, 2);
866 totalSpaceValue.text = sizeString;
868 for(c = 0; options[c].name; c++)
869 AddOption(options[c], null);
878 void OnDrawOverChildren(Surface surface)
880 int tw = label2.size.w;
881 surface.SetForeground(Color { 128, 128, 128 });
882 surface.HLine(label2.position.x + tw + 6, 620, 400);
883 surface.SetForeground(white);
884 surface.HLine(label2.position.x + tw + 6, 621, 401);
885 surface.PutPixel(621, 400);
890 parent = this, opacity = 0, borderStyle = deep, size = Size { 644, 93 }, anchor = Anchor { left = -8, top = -8 };
894 class InstallProgress : Window
896 text = $"Ecere Software Development Kit Setup - v0.44 \"Ryōan-ji\"";
897 background = activeBorder;
902 // size = Size { 640, 480 };
903 clientSize = { 636, 456 };
904 //clientSize = { 796, 576 };
905 icon = { ":icon.png" };
907 Picture back { image = BitmapResource { ":ryoanji-progress.png" }, parent = this, position = { 0, 0 } };
908 Label installing { this, position = { 32, 160 } };
909 ProgressBar progressBar { parent = this, size = Size { 588, 24 }, anchor = Anchor { left = 24, top = 184 } };
912 parent = this, text = $"Install", disabled = true, isDefault = true, size = Size { 75, 23 }, anchor = Anchor { left = 432, top = 416 };
914 NotifyClicked = ButtonCloseDialog
918 this, text = $"Cancel", hotKey = altX, size = Size { 75, 23 }, anchor = Anchor { left = 544, top = 416 };
920 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
928 inactive = true, noSelect = true,
929 multiLine = true, parent = label3, opacity = 0, borderStyle = none, size = Size { 350, 35 }, anchor = Anchor { horz = 111, vert = 13 },
930 contents = $"Please wait while the Ecere Software Development Kit is being installed."
932 Label label2 { parent = this, text = buildString, position = { 16, 392 }, font = { "Tahoma", 10, true }, disabled = true, opacity = 0, background = activeBorder };
935 image = BitmapResource { ":ecere.png", alphaBlend = true }, filter = true, parent = label3, anchor = Anchor { left = 16, top = 4 };
936 cursor = ((GuiApplication)__thisModule).GetCursor(hand);
938 bool OnLeftButtonDown(int x, int y, Modifiers mods)
940 ShellOpen("http://www.ecere.com/");
944 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 } };
946 void OnDrawOverChildren(Surface surface)
948 int tw = label2.size.w;
949 surface.SetForeground(Color { 128, 128, 128 });
950 surface.HLine(label2.position.x + tw + 6, 620, 400);
951 surface.SetForeground(white);
952 surface.HLine(label2.position.x + tw + 6, 621, 401);
953 surface.PutPixel(621, 400);
958 parent = this, opacity = 0, borderStyle = deep, size = Size { 644, 93 }, anchor = Anchor { left = -8, top = -8 };
965 Installer installer {};
966 InstallProgress installProgress { autoCreate = false };
968 void ModifyPath(char * newPath)
975 strcpy(oldPath, newPath);
976 count = TokenizeWith(oldPath, sizeof(paths) / sizeof(char *), paths, ";", false);
978 for(c = 0; coreSDK[c].name; c++)
980 char path[MAX_LOCATION];
981 if(c == extras || c == vanilla) continue;
983 coreSDK[c].GetFullPath(path);
984 if(c != ide && c != runtime && c != eda && c != ec)
987 if(!pathOptions[PathOptions::AddMinGWPaths].selected)
990 PathCat(path, "bin");
992 else if(!pathOptions[PathOptions::AddECEREPaths].selected) continue;
994 for(p = 0; p<count; p++)
995 if(!fstrcmp(paths[p], path))
1002 strcat(newPath, ";");
1003 start = paths[count-1] + strlen(paths[count-1])+1;
1008 strcpy(start, path);
1009 *(start + strlen(path)) = '\0';
1010 paths[count++] = start;
1012 strcat(newPath, path);
1016 if(pathOptions[PathOptions::AddMinGWPaths].selected)
1019 // Up to before Win32 APIs
1020 for(c = 0; c < 4 /*additional[c].name*/; c++)
1022 char path[MAX_LOCATION];
1023 additional[c].GetFullPath(path);
1024 if(c != 0) // UPX already is in bin
1025 PathCat(path, "bin");
1026 for(p = 0; p<count; p++)
1027 if(!fstrcmp(paths[p], path))
1035 strcat(newPath, ";");
1036 start = paths[count-1] + strlen(paths[count-1])+1;
1041 strcpy(start, path);
1042 *(start + strlen(path)) = '\0';
1043 paths[count++] = start;
1045 strcat(newPath, path);
1052 void AssociateExtension(char * extension, char * description, char *name, char * action, char * path)
1058 RegCreateKeyEx(HKEY_CLASSES_ROOT, extension, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1059 RegSetValueEx(key, null, 0, REG_SZ, name, (uint)strlen(name)+1);
1062 RegCreateKeyEx(HKEY_CLASSES_ROOT, name, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1063 RegSetValueEx(key, null, 0, REG_SZ, description, (uint)strlen(description)+1);
1066 sprintf(keyName, "%s\\shell", extension);
1067 RegCreateKeyEx(HKEY_CLASSES_ROOT, keyName, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1068 RegSetValueEx(key, null, 0, REG_SZ, action, (uint)strlen(action)+1);
1071 sprintf(keyName, "%s\\shell\\%s", name, action);
1072 RegCreateKeyEx(HKEY_CLASSES_ROOT, keyName, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1075 sprintf(keyName, "%s\\shell\\%s\\command", name, action);
1076 RegCreateKeyEx(HKEY_CLASSES_ROOT, keyName, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1078 sprintf(keyName, path);
1079 strcat(keyName, " \"%L\"");
1081 uint16 wKeyName[2048];
1082 UTF8toUTF16Buffer(keyName, wKeyName, sizeof(wKeyName) / sizeof(uint16));
1083 RegSetValueExW(key, null, 0, REG_SZ, (byte *)wKeyName, (uint)(wcslen(wKeyName) + 1)*sizeof(uint16));
1088 class InstallThread : Thread
1093 ((GuiApplication)__thisModule).Lock();
1094 installProgress.progressBar.range = totalSize;
1095 for(c = 0; components[c].name && !abortInstall; c++)
1096 components[c].Install(installDir);
1099 installProgress.progressBar.range = 0;
1100 installProgress.finish.Destroy(0);
1101 installProgress.cancel.text = $"Close";
1102 installProgress.cancel.isDefault = true;
1103 installProgress.cancel.disabled = false;
1104 installProgress.cancel.NotifyClicked = Window::ButtonCloseDialog;
1105 installProgress.installing.text = $"Installation Cancelled.";
1106 installProgress.title.text = $"Installation Cancelled";
1107 installProgress.titleInfo.contents = $"The installation was not completed.";
1112 char idePath[MAX_LOCATION];
1113 char userProfile[MAX_LOCATION];
1116 IDESettings settings = null; // Don't instantiate yet so we can pick up old settings
1118 IDESettingsContainer settingsContainer
1121 dataOwner = &settings;
1122 dataClass = class(IDESettings);
1124 CompilerConfig compiler;
1125 installProgress.installing.text = $"Configuring ECERE IDE...";
1126 ((GuiApplication)__thisModule).Unlock();
1127 ((GuiApplication)__thisModule).SignalEvent();
1129 settingsContainer.Load();
1130 compiler = settings.GetCompilerConfig(defaultCompilerName);
1133 for(c = 0; coreSDK[c].name; c++)
1135 char path[MAX_LOCATION];
1137 if(c == extras) continue;
1138 coreSDK[c].GetFullPath(path);
1139 if(c != ide && c != runtime && c != eda && c != ec && c != vanilla)
1140 PathCat(path, "bin");
1141 MakeSlashPath(path);
1144 coreSDK[c].GetFullPath(idePath);
1145 PathCat(idePath, "IDE.exe");
1150 if(!compiler.executableDirs.Find(path))
1151 compiler.executableDirs.Add(CopyString(path));
1154 if(c == runtime || c == vanilla)
1156 if(!compiler.libraryDirs.Find(path))
1157 compiler.libraryDirs.Add(CopyString(path));
1161 // Up to before Win32 APIs
1162 for(c = 0; c < 4 /*additional[c].name*/; c++)
1164 char path[MAX_LOCATION];
1165 additional[c].GetFullPath(path);
1167 PathCat(path, "bin");
1168 MakeSlashPath(path);
1169 if(!compiler.executableDirs.Find(path))
1170 compiler.executableDirs.Add(CopyString(path));
1175 char path[MAX_LOCATION] = "";
1176 if(components[samples].selected)
1177 components[samples].GetFullPath(path);
1179 components[coreSDK].GetFullPath(path);
1181 if(!settings.ideProjectFileDialogLocation)
1182 settings.ideProjectFileDialogLocation = path;
1183 if(!settings.ideFileDialogLocation)
1184 settings.ideFileDialogLocation = path;
1188 settingsContainer.Save();
1189 delete settingsContainer;
1192 // Set up Uninstaller
1193 ((GuiApplication)__thisModule).Lock();
1194 installProgress.installing.text = $"Registering uninstaller...";
1195 ((GuiApplication)__thisModule).Unlock();
1196 ((GuiApplication)__thisModule).SignalEvent();
1201 char * displayName = "ECERE SDK 0.44";
1202 char uninstaller[MAX_LOCATION];
1203 bool nomodify = true;
1205 strcpy(uninstaller, installDir);
1206 PathCat(uninstaller, "uninstall_ecere.exe");
1208 RegCreateKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\ECERE SDK", 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1210 RegSetValueEx(key, "DisplayName", 0, REG_SZ, displayName, (uint)strlen(displayName)+1);
1211 RegSetValueEx(key, "UninstallString", 0, REG_SZ, uninstaller, (uint)strlen(uninstaller)+1);
1212 RegSetValueEx(key, "DisplayIcon", 0, REG_SZ, idePath, (uint)strlen(idePath)+1);
1213 //RegSetValueEx(key, "NoModify", 0, REG_DWORD, (byte *)&nomodify, sizeof(nomodify));
1214 //RegSetValueEx(key, "NoRepair", 0, REG_DWORD, (byte *)&nomodify, sizeof(nomodify));
1219 if(pathOptions[PathOptions::AddECEREPaths].selected
1221 || pathOptions[PathOptions::AddMinGWPaths].selected
1227 char path[4096] = "";
1230 ((GuiApplication)__thisModule).Lock();
1231 installProgress.installing.text = "Registering paths...";
1232 ((GuiApplication)__thisModule).Unlock();
1233 ((GuiApplication)__thisModule).SignalEvent();
1235 // if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Environment", 0, KEY_ALL_ACCESS, &key) == ERROR_SUCCESS)
1237 RegCreateKeyEx(HKEY_CURRENT_USER, "Environment", 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1238 // RegCreateKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1239 if(status == REG_OPENED_EXISTING_KEY)
1241 size = sizeof(wPath);
1242 RegQueryValueExW(key, L"path", null, null, (byte *)wPath, &size);
1243 UTF16toUTF8Buffer(wPath, path, sizeof(path));
1246 UTF8toUTF16Buffer(path, wPath, sizeof(wPath) / sizeof(uint16));
1247 RegSetValueExW(key, L"path", 0, REG_EXPAND_SZ, (byte *)wPath, (uint)(wcslen(wPath)+1) * 2);
1250 SendMessageTimeout (HWND_BROADCAST, WM_SETTINGCHANGE, 0, (int)"Environment", SMTO_NORMAL, 1000, NULL);
1253 // Install Program Group Icons
1254 GetEnvironment("USERPROFILE", userProfile, sizeof(userProfile));
1256 if(options[IconOptions::StartMenuIcon].selected)
1258 char destPath[MAX_LOCATION];
1259 char startMenuPath[MAX_LOCATION] = "";
1262 ((GuiApplication)__thisModule).Lock();
1263 installProgress.installing.text = $"Installing Start Menu Icons...";
1264 ((GuiApplication)__thisModule).Unlock();
1265 ((GuiApplication)__thisModule).SignalEvent();
1267 strcpy(destPath, userProfile);
1269 if(RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", 0, KEY_ALL_ACCESS, &key) == ERROR_SUCCESS)
1271 uint16 wStartMenuPath[2048];
1272 uint size = sizeof(wStartMenuPath);
1273 // RegQueryValueEx(key, "Start Menu", null, null, startMenuPath, &size);
1274 RegQueryValueExW(key, L"Programs", null, null, (byte *)wStartMenuPath, &size);
1275 UTF16toUTF8Buffer(wStartMenuPath, startMenuPath, sizeof(startMenuPath));
1278 if(!startMenuPath[0] && userProfile[0])
1280 strcpy(startMenuPath, userProfile);
1281 PathCat(startMenuPath, "Start Menu\\Programs");
1284 if(startMenuPath[0])
1286 strcpy(destPath, startMenuPath);
1287 PathCat(destPath, "ECERE SDK");
1290 strcpy(destPath, startMenuPath);
1291 PathCat(destPath, "ECERE SDK\\ECERE IDE.lnk");
1292 CreateLink(idePath, destPath, null); //"ECERE IDE");
1293 if(components[samples].selected)
1295 char samplesPath[MAX_LOCATION] = "";
1296 components[samples].GetFullPath(samplesPath);
1298 strcpy(destPath, startMenuPath);
1299 PathCat(destPath, "ECERE SDK\\Sample Projects.lnk");
1300 CreateLink(samplesPath, destPath, null);//"Sample Projects");
1302 if(components[documentation].selected && documentation[ecereBook].selected)
1304 char docPath[MAX_LOCATION] = "";
1305 documentation[ecereBook].GetFullPath(docPath);
1306 PathCat(docPath, "Ecere Tao of Programming [work in progress].pdf");
1309 char tao[MAX_LOCATION] ;
1310 documentation[ecereBook].GetFullPath(tao);
1311 PathCat(tao, "tao.pdf");
1312 RenameFile(tao, docPath);
1315 strcpy(destPath, startMenuPath);
1316 PathCat(destPath, "ECERE SDK\\The Ecere Tao of Programming.lnk");
1317 CreateLink(docPath, destPath, null);
1322 // Install Desktop Icon
1323 if(options[IconOptions::DesktopIcon].selected)
1326 char desktopPath[MAX_LOCATION];
1328 if(RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", 0, KEY_ALL_ACCESS, &key) == ERROR_SUCCESS)
1330 uint16 wDesktopPath[MAX_LOCATION];
1331 uint size = sizeof(wDesktopPath);
1332 RegQueryValueExW(key, L"Desktop", null, null, (byte *)wDesktopPath, &size);
1333 UTF16toUTF8Buffer(wDesktopPath, desktopPath, sizeof(desktopPath));
1336 if(!desktopPath[0] && userProfile[0])
1338 strcpy(desktopPath, userProfile);
1339 PathCat(desktopPath, "Desktop");
1344 PathCat(desktopPath, "ECERE IDE.lnk");
1346 ((GuiApplication)__thisModule).Lock();
1347 installProgress.installing.text = $"Installing Desktop Icon...";
1348 ((GuiApplication)__thisModule).Unlock();
1349 ((GuiApplication)__thisModule).SignalEvent();
1351 CreateLink(idePath, desktopPath, null);//"ECERE IDE");
1355 // Install QuickLaunch Icon
1356 if(options[IconOptions::QuickLaunchIcon].selected)
1358 char appData[MAX_LOCATION];
1359 GetEnvironment("APPDATA", appData, sizeof(appData));
1363 char destPath[MAX_LOCATION];
1365 ((GuiApplication)__thisModule).Lock();
1366 installProgress.installing.text = $"Installing Quicklaunch Icon...";
1367 ((GuiApplication)__thisModule).Unlock();
1368 ((GuiApplication)__thisModule).SignalEvent();
1370 strcpy(destPath, appData);
1371 PathCat(destPath, "Microsoft\\Internet Explorer\\Quick Launch\\ECERE IDE.lnk");
1373 CreateLink(idePath, destPath, null);//"ECERE IDE");
1377 // Register File Types
1378 if(associateOptions[AssociateOptions::AssociateEPJ].selected ||
1379 associateOptions[AssociateOptions::AssociateEC].selected ||
1380 associateOptions[AssociateOptions::AssociateC].selected ||
1381 associateOptions[AssociateOptions::AssociateCPP].selected ||
1382 associateOptions[AssociateOptions::AssociateTXT].selected ||
1383 associateOptions[AssociateOptions::Associate3DS].selected ||
1384 associateOptions[AssociateOptions::AssociateIMG].selected)
1386 ((GuiApplication)__thisModule).Lock();
1387 installProgress.installing.text = $"Resgistering File Types...";
1388 ((GuiApplication)__thisModule).Unlock();
1389 ((GuiApplication)__thisModule).SignalEvent();
1391 if(associateOptions[AssociateOptions::AssociateEPJ].selected)
1393 AssociateExtension(".epj", "ECERE IDE Project", "epj_file", "Open", idePath);
1395 if(associateOptions[AssociateOptions::AssociateEC].selected)
1397 AssociateExtension(".ec", "eC Source File", "ec_file", "Open", idePath);
1398 AssociateExtension(".eh", "eC Header File", "eh_file", "Open", idePath);
1400 if(associateOptions[AssociateOptions::AssociateC].selected)
1402 AssociateExtension(".c", "C Source File", "c_file", "Open", idePath);
1403 AssociateExtension(".h", "C Header File", "h_file", "Open", idePath);
1405 if(associateOptions[AssociateOptions::AssociateCPP].selected)
1407 AssociateExtension(".cpp", "C++ Source File", "cpp_file", "Open", idePath);
1408 AssociateExtension(".cc", "C++ Source File", "cpp_file", "Open", idePath);
1409 AssociateExtension(".cxx", "C++ Source File", "cpp_file", "Open", idePath);
1410 AssociateExtension(".chh", "C++ Header File", "chh_file", "Open", idePath);
1411 AssociateExtension(".hh", "C++ Header File", "chh_file", "Open", idePath);
1412 AssociateExtension(".hxx", "C++ Header File", "chh_file", "Open", idePath);
1414 if(associateOptions[AssociateOptions::AssociateTXT].selected)
1416 AssociateExtension(".txt", "Text File", "txt_file", "Open", idePath);
1418 if(associateOptions[AssociateOptions::Associate3DS].selected)
1420 AssociateExtension(".3ds", "3D Studio Model", "3ds_file", "View", idePath);
1422 if(associateOptions[AssociateOptions::AssociateIMG].selected)
1424 AssociateExtension(".bmp", "BMP Image", "bmp_file", "View", idePath);
1425 AssociateExtension(".pcx", "PCX Image", "pcx_file", "View", idePath);
1426 AssociateExtension(".png", "PNG Image", "png_file", "View", idePath);
1427 AssociateExtension(".jpg", "JPEG Image", "jpg_file", "View", idePath);
1428 AssociateExtension(".jpeg", "JPEG Image", "jpg_file", "View", idePath);
1429 AssociateExtension(".gif", "GIF Image", "gif_file", "View", idePath);
1432 ((GuiApplication)__thisModule).Lock();
1434 installProgress.cancel.Destroy(0);
1435 installProgress.finish.text = $"Finish";
1436 installProgress.finish.disabled = false;
1437 installProgress.finish.Activate();
1438 installProgress.installing.text = $"Installation Complete.";
1439 installProgress.title.text = $"Installation Complete";
1440 installProgress.titleInfo.contents = $"Thank you for using the Ecere SDK.";
1442 ((GuiApplication)__thisModule).Unlock();