2 static define buildString = $"ECERE SDK v0.44 (Without MinGW) -- built on March 7, 2012 ";
4 static define buildString = $"ECERE SDK v0.44 -- built on March 7, 2012 ";
7 #define WIN32_LEAN_AND_MEAN
8 #define GetFreeSpace _GetFreeSpace
21 class CheckListBox : ListBox
23 fullRowSelect = false, collapseControl = true, treeBranches = true, rootCollapseButton = true,
27 void ToggleCheck(DataRow row)
29 Button checkBox = (Button)row.tag;
31 bool checked = !(checkBox.checked) || checkBox.buttonState == down;
32 if(!checkBox.disabled)
34 SetCheck(row, checked);
35 checkBox.buttonState = up;
37 for(parent = row; parent; parent = parent.parent)
39 for(row = parent.firstRow; row; row = row.next)
41 checkBox = (Button)row.tag;
42 if(checkBox.checked != checked)
45 checkBox = (Button)parent.tag;
48 checkBox.checked = true;
49 NotifyChecked(master, this, parent);
50 checkBox.buttonState = down;
55 checkBox.checked = checked;
56 NotifyChecked(master, this, parent);
57 checkBox.buttonState = up;
63 void SetCheck(DataRow row, bool checked)
65 Button checkBox = (Button)row.tag;
67 if(!checkBox.disabled && (checkBox.checked != checked || checkBox.buttonState == down))
69 checkBox.checked = checked;
70 for(subRow = row.firstRow; subRow; subRow = subRow.next)
71 SetCheck(subRow, checked);
72 NotifyChecked(master, this, row);
76 DataRow AddRow(DataRow parentRow)
78 DataRow row = parentRow ? parentRow.AddRow() : ListBox::AddRow();
82 for(parent = row.parent; parent; parent = parent.parent)
86 this, isCheckbox = true, inactive = true, checked = true,
87 position = { 2 + indent, 1+(row.index + hasHeader) * rowHeight }, size = { 12, 12 };
90 bool NotifyPushed(Button button, int x, int y, Modifiers mods)
92 currentRow = (DataRow)button.id;
93 ToggleCheck(currentRow);
97 bool NotifyReleased(Button button, int x, int y, Modifiers mods)
102 bool OnMouseOver(int x, int y, Modifiers mods)
108 bool OnMouseLeave(Modifiers mods)
117 bool NotifyKeyDown(CheckListBox listBox, DataRow row, Key key, unichar ch)
121 listBox.ToggleCheck(row);
127 bool OnKeyHit(Key key, unichar ch)
131 return ListBox::OnKeyHit(key, ch);
134 bool NotifyDoubleClick(CheckListBox listBox, int x, int y, Modifiers mods)
136 listBox.OnLeftButtonDown(x, y, mods);
140 bool NotifyReclick(CheckListBox listBox, DataRow row, Modifiers mods)
142 listBox.ToggleCheck(row);
146 bool NotifyCollapse(ListBox listBox, DataRow row, bool collapsed)
149 for(r = row.firstRow; r && r != row; )
151 Button checkBox = (Button)r.tag;
152 checkBox.visible = !collapsed;
153 if(r.firstRow && !r.collapsed)
156 for(; r != row; r = r.parent)
157 if(r.next) { r = r.next; break; }
159 for(r = row.GetNextRow(); r; r = r.GetNextRow())
161 Button checkBox = (Button)r.tag;
162 checkBox.position.y = 1 + (r.index + listBox.hasHeader) * listBox.rowHeight;
167 virtual void Window::NotifyChecked(CheckListBox listBox, DataRow row);
174 char * OnGetString(char * tempString, void * fieldData, bool * needClass)
179 void OnDisplay(Surface surface, int x, int y, int width, void * fieldData, Alignment alignment, DataDisplayFlags displayFlags)
181 if(!displayFlags.active) displayFlags.current = false;
182 class::OnDisplay(surface, x + 22, y, width - 22, fieldData, alignment, displayFlags);
186 //#define BUFFERSIZE 0x10000
187 #define BUFFERSIZE 0x1000
188 bool abortInstall = false;
190 void ExtractFileFromArchive(ProgressBar progressBar, char * path, char * outputFile)
192 char fileName[MAX_LOCATION];
193 FileAttribs exists = FileExists(path);
194 bool setTime = false;
197 if(exists.isDirectory)
199 FileListing listing { path };
203 if(MakeDir(outputFile))
206 FileGetStats(path, &stats);
210 while(listing.Find() && !abortInstall)
212 strcpy(fileName, outputFile);
214 // Tweak file name if out
217 if(!strcmp(fileName, ".")) fileName[0] = '\0';
218 if(listing.name[0] == '/' || listing.name[0] == '\\')
220 char * afterSlash, rest[MAX_LOCATION];
221 for(afterSlash = fileName; *afterSlash == '/' || *afterSlash == '\\'; afterSlash++);
222 strcpy(rest, afterSlash);
223 PathCat(fileName, "_root");
224 PathCat(fileName, rest);
226 else if(listing.name[1] == ':')
229 sprintf(letter, "_%cdrive", toupper(listing.name[0]));
230 PathCat(fileName, letter);
231 PathCat(fileName, listing.name[2] ? (listing.name + 3) : (listing.name + 2));
234 PathCat(fileName, listing.name);
237 PathCat(fileName, listing.name);
238 if(!strcmp(fileName, "/") || !strcmp(fileName, "\\"))
239 strcpy(fileName, DIR_SEPS);
240 ExtractFileFromArchive(progressBar, listing.path, fileName);
246 File input = FileOpen(path, read);
249 File output = FileOpen(outputFile, write);
252 char fileName[MAX_FILENAME];
253 uint position = progressBar.progress;
256 byte buffer[BUFFERSIZE];
258 FileGetSize(path, &dataSize);
259 GetLastDirectory(outputFile, fileName);
261 ((GuiApplication)__thisModule).SignalEvent();
262 //((GuiApplication)__thisModule).ProcessInput();
263 //((GuiApplication)__thisModule).UpdateDisplay();
265 for(c = 0; c<dataSize && !abortInstall; c += BUFFERSIZE)
267 uint size = (dataSize > c + BUFFERSIZE) ? BUFFERSIZE : (dataSize - c);
269 ((GuiApplication)__thisModule).Unlock();
271 input.Read(buffer, 1, size);
272 output.Write(buffer, 1, size);
274 ((GuiApplication)__thisModule).Lock();
276 progressBar.progress = position + c + size;
277 ((GuiApplication)__thisModule).SignalEvent();
279 //((GuiApplication)__thisModule).ProcessInput();
280 //((GuiApplication)__thisModule).UpdateDisplay();
285 FileGetStats(path, &stats);
291 FileSetTime(outputFile, stats.created, 0, stats.modified);
298 char * defInstallPath;
299 Component * subComponents;
306 char installPath[MAX_LOCATION];
309 void GetFullPath(char * path)
311 if(this != null && parent)
312 parent->GetFullPath(path);
314 strcpy(path, installDir);
317 PathCat(path, installPath);
320 void Install(char * parentPath)
325 char path[MAX_LOCATION];
326 strcpy(path, parentPath);
327 PathCat(path, installPath);
329 installProgress.installing.SetText($"Installing %s...", name);
330 ((GuiApplication)__thisModule).UpdateDisplay();
334 char source[MAX_LOCATION];
336 strcat(source, dataPath);
340 if(FileExists(source).isFile)
342 char name[MAX_FILENAME];
343 GetLastDirectory(source, name);
348 uint p = installProgress.progressBar.progress;
349 ExtractFileFromArchive(installProgress.progressBar, source, path);
354 for(c = 0; subComponents[c].name; c++)
355 subComponents[c].Install(path);
360 Component samples[] =
362 { "Ecere Chess", "samples/chess", "chess", null, false, true },
363 { "Ecere Fractals", "samples/fractals", "fractals", null, false, true },
364 { "3D", "samples/3D", "3D", null, false, true },
365 { "Audio", "samples/audio", "audio", null, false, true },
366 { "Database", "samples/db", "db", null, false, true },
367 { "eC", "samples/eC", "eC", null, false, true },
368 { "Games", "samples/games", "games", null, false, true },
369 { "GUI & Graphics", "samples/guiAndGfx", "guiAndGfx", null, false, true },
370 { "Miscellaneous", "samples/misc", "misc", null, false, true },
371 { "Networking", "samples/net", "net", null, false, true },
372 { "WIA Scanning", "samples/scanning", "scanning", null, false, true },
373 { "Threading", "samples/threads", "threads", null, false, true }
377 public enum CoreSDKID
379 ide, runtime, ec, eda, vanilla, extras,
381 gcc, gdb, mingw, binutils, make,
386 Component coreSDK[CoreSDKID] =
388 { "Ecere IDE", "ecere-sdk/ide", "bin", null, true, true },
389 { "Runtime Library", "ecere-sdk/ecere.dll", "bin", null, true, true },
390 { "eC Compiler", "ecere-sdk/compiler", "bin", null, true, true },
391 { "Data Access", "ecere-sdk/eda", "bin", null, false, true },
392 { "Ecere Vanilla", "ecere-sdk/libecereVanilla.a", "lib", null, false, true },
393 { "Ecere Extras", "extras", "extras", null, false, true },
395 { "GNU C Compiler", "mingw/gcc/core", "mingw", null, true, true },
396 { "GNU Debugger", "mingw/gdb", "mingw", null, true, true },
397 { "MinGW Runtime", "mingw/mingwrt", "mingw", null, true, true },
398 { "Binary Utils", "mingw/binutils", "mingw", null, true, true },
399 { "GNU Make", "mingw/make", "mingw", null, true, true },
405 Component additional[] =
407 { "UPX", "upx/bin", "mingw", null, false, true },
408 { "GNU Regexp", "mingw/gnurx", "mingw", null, false, true },
409 { "Win32 APIs", "mingw/w32api", "mingw", null, false, true },
410 { "pthreads", "mingw/pthreads", "mingw", null, false, true },
411 { "C++ Compiler", "mingw/gcc/c++", "mingw", null, false, true },
412 { "GCC I18n", "mingw/locale/gcc", "mingw", null, false, false },
413 { "GDB I18n", "mingw/locale/gdb", "mingw", null, false, false },
414 { "Make I18n", "mingw/locale/make", "mingw", null, false, false },
415 { "Binutils I18n", "mingw/locale/binutils", "mingw", null, false, false },
420 public enum DocumentationID
422 ecereBook, apiRef, tutorials, coursework,
424 gccDoc, gppDocs, gdbDocs, makeDocs, binDocs, mingwDocs, gnurxDocs, upxDocs,
429 Component documentation[DocumentationID] =
431 { "Ecere Book", "ecere-sdk/book", "doc", null, false, true },
432 { "API Reference", "ecere-sdk/doc", "doc", null, false, true },
433 { "Ecere Tutorials", "ecere-sdk/tutorials", "doc", null, false, true },
434 { "Ecere Coursework", "ecere-sdk/coursework", "doc", null, false, true },
436 { "GCC Docs", "mingw/doc/gcc", "mingw", null, false, false },
437 { "G++ Docs", "mingw/doc/g++", "mingw", null, false, false },
438 { "GDB Docs", "mingw/doc/gdb", "mingw", null, false, false },
439 { "Make Docs", "mingw/doc/make", "mingw", null, false, false },
440 { "Binutils Docs", "mingw/doc/binutils", "mingw", null, false, false },
441 { "MinGW Docs", "mingw/doc/mingw", "mingw", null, false, false },
442 { "gnurx Docs", "mingw/doc/gnurx", "mingw", null, false, false },
443 { "UPX Docs", "upx/doc", "mingw/doc/upx", null, false, false },
448 public enum ComponentID
459 Component components[ComponentID] =
461 { "Core SDK Files", null, null, coreSDK, true, true },
463 { "Additional Support", null, null, additional, false, true },
465 { "Documentation", null /*"doc"*/, null /*"doc"*/, documentation, false, true },
466 { "Samples", null, "samples", samples, false, true },
470 FileSize totalInstalled;
475 InstallOption * subOptions;
480 enum AssociateOptions
491 InstallOption associateOptions[] =
493 { "Associate with Ecere Project Files (*.epj)", null, true },
494 { "Associate with eC Files (*.ec, *.eh)", null, true },
495 { "Associate with C files (*.c, *.h)", null, false },
496 { "Associate with C++ Files (*.cpp, *.hpp, *.cc, *.hh, *.cxx, *.hxx)", null, false },
497 { "Associate with text files (*.txt)", null, false },
498 { "Associate with 3D Studio Model Files (*.3ds)", null, true },
499 { "Associate with Image Files (*.png, *.jpg, *.pcx, *.bmp, *.gif)", null, false },
511 InstallOption pathOptions[] =
513 { "Add Ecere binaries location to the system path", null, true },
514 { "Add MinGW to the system path", null, true }
525 InstallOption options[] =
527 { "Start Menu Group", null, true },
528 { "Desktop Icon", null, true },
529 { "Quicklaunch Icon", null, true },
530 { "Associate the ECERE IDE with Supported File Types", associateOptions, true },
532 { "Add binaries location to the system paths", pathOptions, true },
537 char sourceDir[MAX_LOCATION] = ":";
538 char installDir[MAX_LOCATION];
540 class Installer : Window
542 text = $"Ecere Software Development Kit Setup";
543 background = activeBorder;
548 clientSize = { 636, 456 };
549 icon = { ":icon.png" };
551 FileDialog fileDialog
553 master = this, type = selectDir,
554 text = $"Select a new location"
558 master = this, autoCreate = false, inactive = true, /*hotKey = F2,*/ text = "...";
560 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
562 DataRow row = componentsBox.currentRow;
563 Component * component = ((CheckItem *)row.GetData(componentField))->data;
564 component->GetFullPath(fileDialog.filePath);
565 StripLastDirectory(fileDialog.filePath, fileDialog.currentDirectory);
567 if(fileDialog.Modal() == ok)
569 componentsBox.StopEditing(false);
570 row.SetData(locationField, fileDialog.filePath);
571 componentsBox.NotifyChanged(this, componentsBox, row);
572 componentsBox.currentField = componentsBox.currentField;
577 CheckListBox componentsBox
579 this, size = { 460, 112 }, position = { 160, 160 }, hasHeader = true;
582 bool NotifyChanged(ListBox listBox, DataRow row)
584 Component * component = ((CheckItem *)listBox.GetData(componentField))->data;
585 char path[MAX_LOCATION], relative[MAX_LOCATION] = "", ** newPath;
586 char fullPath[MAX_LOCATION];
588 component->parent->GetFullPath(path);
589 strcpy(fullPath, path);
591 newPath = (char **)row.GetData(locationField);
592 if(newPath && *newPath)
594 PathCat(fullPath, *newPath);
595 MakePathRelative(fullPath, path, relative);
597 listBox.SetData(locationField, relative);
598 strcpy(component->installPath, relative);
600 //SetAvailableSpace(component, path);
603 install.disabled = false;
604 for(c = 0; components[c].name; c++)
606 SetAvailableSpace(components[c], installDir);
612 bool NotifyEditDone(ListBox listBox, DataRow row)
618 bool NotifyEdited(ListBox listBox, DataRow row)
620 browse.parent = listBox;
621 browse.position = { componentField.width + locationField.width + 18, (listBox.currentIndex+1) * listBox.rowHeight - 2 };
622 browse.size = { 30, listBox.rowHeight + 3 };
628 void NotifyChecked(CheckListBox listBox, DataRow row)
630 Component * component = ((CheckItem *)row.GetData(componentField))->data;
632 Button checkBox = (Button)row.tag;
633 component->selected = checkBox.checked;
635 if(!component->parent) totalSize -= component->requiredSize;
636 component->requiredSize = 0;
637 if(component->selected)
639 component->requiredSize += component->size;
640 if(component->subComponents)
641 for(c = 0; component->subComponents[c].name; c++)
642 component->requiredSize += component->subComponents[c].requiredSize;
644 if(component->requiredSize)
646 uint requiredSize = component->requiredSize;
647 row.SetData(reqField, requiredSize);
650 row.UnsetData(reqField);
651 if(!component->parent)
653 totalSize += component->requiredSize;
655 char sizeString[100];
656 PrintSize(sizeString, totalSize, 2);
657 totalSpaceValue.text = sizeString;
662 Label agreementLbl { parent = this, text = $"By installing the ECERE SDK, you agree to the terms and conditions.", anchor = Anchor { left = 24, top = 424 } };
665 this, inactive = true, offset = false, bevel = false, foreground = blue, font = { "Tahoma", 8.25f, underline = true },
666 text = $"terms and conditions", anchor = Anchor { left = 241, top = 421 };
667 cursor = ((GuiApplication)__thisModule).GetCursor(hand);
669 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
671 LicenseBox { master = this, sourceFile = ":ecere-sdk/LICENSE" }.Modal();
675 CheckListBox optionsBox
677 this, size = { 460, 94 }, position = { 160, 284 };
679 void NotifyChecked(CheckListBox listBox, DataRow row)
681 CheckItem * item = row.GetData(optionField);
682 InstallOption * option = item->data;
684 Button checkBox = (Button)row.tag;
685 option->selected = checkBox.checked;
690 parent = this, text = $"Install", isDefault = true, size = { 75, 23 }, position = { 432, 416 };
692 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
694 installProgress.Create();
696 // installProgress.thread.Main();
697 installProgress.thread.Create();
701 Button button3 { parent = this, text = $"Cancel", hotKey = altX, size = Size { 75, 23 }, anchor = Anchor { left = 544, top = 416 }, NotifyClicked = ButtonCloseDialog };
702 Label label1 { labeledWindow = destBox, tabCycle = true, isGroupBox = true, parent = this, inactive = false, size = Size { 458, 50 }, anchor = Anchor { left = 160, top = 96 } };
705 parent = label1, master = this, text = $" Destination Folder", size = Size { 336, 19 }, anchor = Anchor { left = 12, top = 20 };
707 bool NotifyModified(EditBox editBox)
710 strcpy(installDir, destBox.contents);
711 install.disabled = false;
712 for(c = 0; components[c].name; c++)
714 SetAvailableSpace(components[c], installDir);
721 label1, this, $"Browse", altB, size = { 83, 24 }, position = { 360, 16 };
723 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
725 strcpy(fileDialog.filePath, installDir);
726 StripLastDirectory(installDir, fileDialog.currentDirectory);
727 if(fileDialog.Modal())
729 strcpy(installDir, fileDialog.filePath);
730 destBox.contents = installDir;
731 // TOCHECK: Should setting contents call NotifyModified?
732 destBox.NotifyModified(destBox.master, destBox);
739 this, multiLine = true,
740 opacity = 0, borderStyle = none, inactive = true, size = { 136, 53 }, position = { 14, 96 }, noSelect = true,
741 contents = $"Select the default root\n"
742 "folder where to install\n"
747 this, opacity = 0, borderStyle = none, inactive = true, size = { 136, 132 }, position = { 14, 152 }, noSelect = true,
749 contents = $"Select the optional\n"
750 "components you wish\n"
752 "You may customize the\n"
753 "install location for each\n"
754 "of them, or use the default\n"
755 "based on the main\n"
756 "destination folder."
760 this, opacity = 0, borderStyle = none, inactive = true, size = { 136, 53 }, position = { 14, 280 }, noSelect = true,
762 contents = $"Select icons to install, file\n"
763 "associations, and system\n"
764 "environment modifications:"
766 Label totalSpaceLabel
768 this, position = { 18, 352 }, text = $"Space Required: "
770 Label totalSpaceValue
772 this, position = { 100, 352 }, text = "0 mb"
776 inactive = true, noSelect = true,
777 multiLine = true, parent = label3, text = "editBox1", opacity = 0, borderStyle = none, size = Size { 350, 35 }, anchor = Anchor { horz = 111, vert = 13 },
778 contents = $"Choose in which folder to install the ECERE SDK, which features\n"
779 "of the SDK to install, as well as where to install program icons."
781 Label label2 { parent = this, text = buildString, position = { 16, 392 }, disabled = true, opacity = 1, background = activeBorder };
782 Picture picture1 { image = BitmapResource { ":ecere.bmp", transparent = true }, filter = true, parent = label3, text = "picture1", anchor = Anchor { left = 16, top = 4 } };
783 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 } };
784 DataField componentField { "CheckItem", width = 140, header = $"Component" };
785 DataField locationField { "char *", width = 108, header = $"Destination Folder", editable = true };
786 DataField reqField { "FileSize", width = 80, header = $"Req. Space", alignment = right };
787 DataField avField { "FileSize64", width = 80, header = $"Avail. Space", alignment = right };
788 DataField optionField { "CheckItem" };
790 void SetAvailableSpace(Component component, char * parentPath)
792 char path[MAX_LOCATION];
796 strcpy(path, parentPath);
797 PathCat(path, component.installPath);
799 if(component.subComponents)
800 for(c = 0; component.subComponents[c].name; c++)
801 SetAvailableSpace(component.subComponents[c], path);
803 while(!FileExists(path) && path[0])
804 StripLastDirectory(path, path);
807 GetFreeSpace(path, &size);
808 component.row.SetData(avField, size);
809 if(!size) install.disabled = true;
812 FileSize ComputeSize(char * path)
815 FileAttribs attribs = FileExists(path);
816 if(attribs.isDirectory)
818 FileListing listing { path };
819 while(listing.Find())
821 if(listing.stats.attribs.isDirectory)
822 size += ComputeSize(listing.path);
824 size += listing.stats.size;
828 FileGetSize(path, &size);
832 void AddComponent(Component component, Component parent, char * parentPath)
834 DataRow row = component.row = componentsBox.AddRow((parent != null) ? parent.row : null);
835 Button checkBox = (Button) row.tag;
837 FileSize64 avSize = 0;
838 char path[MAX_LOCATION];
839 strcpy(path, parentPath);
840 if(component.defInstallPath)
841 PathCat(path, component.defInstallPath);
842 component.parent = parent;
844 row.SetData(null, CheckItem { component.name, component } );
846 if(component.defInstallPath)
848 strcpy(component.installPath, component.defInstallPath);
849 ChangeCh(component.installPath, '/', DIR_SEP);
850 row.SetData(locationField, component.installPath);
853 if(component.mandatory) checkBox.disabled = true;
854 if(!component.selected) componentsBox.ToggleCheck(row);
855 if(component.dataPath)
857 char path[MAX_LOCATION];
859 PathCat(path, component.dataPath);
860 component.size = ComputeSize(path);
862 if(component.subComponents)
865 for(c = 0; component.subComponents[c].name; c++)
867 AddComponent(component.subComponents[c], component, path);
868 size += component.subComponents[c].requiredSize;
872 component.requiredSize = component.selected ? (size + component.size) : 0;
873 if(component.requiredSize)
874 row.SetData(reqField, component.requiredSize);
876 while(!FileExists(path) && path[0])
877 StripLastDirectory(path, path);
880 GetFreeSpace(path, &avSize);
883 row.SetData(avField, avSize);
884 row.collapsed = true;
887 void AddOption(InstallOption option, InstallOption parent)
889 DataRow row = option.row = optionsBox.AddRow((parent != null) ? parent.row : null);
890 row.SetData(null, CheckItem { option.name, option } );
892 optionsBox.ToggleCheck(row);
893 if(option.subOptions)
896 for(c = 0; option.subOptions[c].name; c++)
898 AddOption(option.subOptions[c], option);
901 row.collapsed = true;
907 char programFilesDir[MAX_LOCATION];
908 char appData[MAX_LOCATION]; // = getenv("APPDATA");
909 char homeDrive[MAX_LOCATION]; //= getenv("HOMEDRIVE");
910 char winDir[MAX_LOCATION]; //= getenv("windir");
912 GetEnvironment("APPDATA", appData, sizeof(appData));
913 GetEnvironment("HOMEDRIVE", homeDrive, sizeof(homeDrive));
914 GetEnvironment("windir", winDir, sizeof(winDir));
916 componentsBox.AddField(componentField);
917 componentsBox.AddField(locationField);
918 componentsBox.AddField(reqField);
919 componentsBox.AddField(avField);
921 optionsBox.AddField(optionField);
923 if(GetEnvironment("ProgramFiles", programFilesDir, MAX_LOCATION))
925 strcpy(installDir, programFilesDir);
926 PathCat(installDir, "ECERE SDK");
928 else if(homeDrive && homeDrive[0])
930 strcpy(installDir, homeDrive);
931 PathCat(installDir, "ECERE SDK");
933 else if(winDir && winDir[0])
935 strcpy(installDir, winDir);
936 PathCat(installDir, "..\\ECERE SDK");
939 strcpy(installDir, "C:\\ECERE SDK");
941 if(appData && appData[0])
943 static char defSamplesPath[MAX_LOCATION];
944 static char defExtrasPath[MAX_LOCATION];
945 strcpy(defSamplesPath, appData);
946 PathCat(defSamplesPath, "ECERE SDK\\Samples");
947 components[samples].defInstallPath = defSamplesPath;
949 strcpy(defExtrasPath, appData);
950 PathCat(defExtrasPath, "ECERE SDK\\extras");
951 coreSDK[extras].defInstallPath = defExtrasPath;
954 destBox.contents = installDir;
958 for(c = 0; components[c].name; c++)
959 AddComponent(components[c], null, installDir);
962 // Compute size apart because ToggleCheck will change it
966 for(c = 0; components[c].name; c++)
967 totalSize += components[c].requiredSize;
970 char sizeString[100];
971 PrintSize(sizeString, totalSize, 2);
972 totalSpaceValue.text = sizeString;
974 for(c = 0; options[c].name; c++)
975 AddOption(options[c], null);
984 void OnRedraw(Surface surface)
991 //surface.Gradient(keys, sizeof(keys)/sizeof(ColorKey), 1.0f, Vertical, 0,0, clientSize.w, clientSize.h);
992 surface.SetForeground(Color { 128, 128, 128 });
993 surface.HLine(160, 620, 400);
994 surface.SetForeground(white);
995 surface.HLine(160, 621, 401);
996 surface.PutPixel(621, 400);
1000 parent = this, opacity = 1, borderStyle = deep, size = Size { 644, 93 }, anchor = Anchor { left = -8, top = -8 };
1002 void OnRedraw(Surface surface)
1009 surface.Gradient(keys, sizeof(keys)/sizeof(ColorKey), 0, horizontal, 220,0, clientSize.w, clientSize.h);
1011 Label::OnRedraw(surface);
1016 class InstallProgress : Window
1018 text = $"Ecere Software Development Kit Setup";
1019 background = activeBorder;
1020 borderStyle = fixed;
1024 size = Size { 640, 480 };
1026 Label installing { this, position = { 32, 160 } };
1027 ProgressBar progressBar { parent = this, size = Size { 588, 24 }, anchor = Anchor { left = 24, top = 184 } };
1030 parent = this, text = $"Install", disabled = true, isDefault = true, size = Size { 75, 23 }, anchor = Anchor { left = 432, top = 416 };
1032 NotifyClicked = ButtonCloseDialog
1036 this, text = $"Cancel", hotKey = altX, size = Size { 75, 23 }, anchor = Anchor { left = 544, top = 416 };
1038 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
1040 abortInstall = true;
1046 inactive = true, noSelect = true,
1047 multiLine = true, parent = label3, opacity = 0, borderStyle = none, size = Size { 350, 35 }, anchor = Anchor { horz = 111, vert = 13 },
1048 contents = $"Please wait while the Ecere Software Development Kit is being installed."
1050 Label label2 { parent = this, text = buildString, position = { 16, 392 }, disabled = true, opacity = 1, background = activeBorder };
1051 Picture picture1 { image = BitmapResource { ":ecere.bmp", transparent = true }, filter = true, parent = label3, anchor = Anchor { left = 16, top = 4 } };
1052 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 } };
1054 void OnRedraw(Surface surface)
1061 //surface.Gradient(keys, sizeof(keys)/sizeof(ColorKey), 1.0f, Vertical, 0,0, clientSize.w, clientSize.h);
1062 surface.SetForeground(Color { 128, 128, 128 });
1063 surface.HLine(160, 620, 400);
1064 surface.SetForeground(white);
1065 surface.HLine(160, 621, 401);
1066 surface.PutPixel(621, 400);
1070 parent = this, opacity = 1, borderStyle = deep, size = Size { 644, 93 }, anchor = Anchor { left = -8, top = -8 };
1072 void OnRedraw(Surface surface)
1079 surface.Gradient(keys, sizeof(keys)/sizeof(ColorKey), 0, horizontal, 220,0, clientSize.w, clientSize.h);
1081 Label::OnRedraw(surface);
1084 InstallThread thread
1089 Installer installer {};
1090 InstallProgress installProgress { autoCreate = false };
1092 void ModifyPath(char * newPath)
1099 strcpy(oldPath, newPath);
1100 count = TokenizeWith(oldPath, sizeof(paths) / sizeof(char *), paths, ";", false);
1102 for(c = 0; coreSDK[c].name; c++)
1104 char path[MAX_LOCATION];
1105 coreSDK[c].GetFullPath(path);
1106 if(c != ide && c != runtime && c != eda && c != ec)
1109 if(!pathOptions[PathOptions::AddMinGWPaths].selected)
1112 PathCat(path, "bin");
1114 else if(!pathOptions[PathOptions::AddECEREPaths].selected) continue;
1116 for(p = 0; p<count; p++)
1117 if(!fstrcmp(paths[p], path))
1124 strcat(newPath, ";");
1125 start = oldPath + strlen(paths[count-1])+1;
1130 strcpy(start, path);
1131 *(start + strlen(path)) = '\0';
1132 paths[count++] = start;
1134 strcat(newPath, path);
1138 if(pathOptions[PathOptions::AddMinGWPaths].selected)
1141 for(c = 0; additional[c].name; c++)
1143 char path[MAX_LOCATION];
1145 additional[c].GetFullPath(path);
1146 PathCat(path, "bin");
1147 for(p = 0; p<count; p++)
1148 if(!fstrcmp(paths[p], path))
1156 strcat(newPath, ";");
1157 start = oldPath + strlen(paths[count-1])+1;
1162 strcpy(start, path);
1163 *(start + strlen(path)) = '\0';
1164 paths[count++] = start;
1166 strcat(newPath, path);
1173 void AssociateExtension(char * extension, char * description, char *name, char * action, char * path)
1179 RegCreateKeyEx(HKEY_CLASSES_ROOT, extension, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1180 RegSetValueEx(key, null, 0, REG_SZ, name, strlen(name)+1);
1183 RegCreateKeyEx(HKEY_CLASSES_ROOT, name, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1184 RegSetValueEx(key, null, 0, REG_SZ, description, strlen(description)+1);
1187 sprintf(keyName, "%s\\shell", extension);
1188 RegCreateKeyEx(HKEY_CLASSES_ROOT, keyName, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1189 RegSetValueEx(key, null, 0, REG_SZ, action, strlen(action)+1);
1192 sprintf(keyName, "%s\\shell\\%s", name, action);
1193 RegCreateKeyEx(HKEY_CLASSES_ROOT, keyName, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1196 sprintf(keyName, "%s\\shell\\%s\\command", name, action);
1197 RegCreateKeyEx(HKEY_CLASSES_ROOT, keyName, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1199 sprintf(keyName, path);
1200 strcat(keyName, " \"%L\"");
1202 uint16 wKeyName[2048];
1203 UTF8toUTF16Buffer(keyName, wKeyName, sizeof(wKeyName) / sizeof(uint16));
1204 RegSetValueExW(key, null, 0, REG_SZ, (byte *)wKeyName, (wcslen(wKeyName) + 1)*sizeof(uint16));
1209 class InstallThread : Thread
1214 ((GuiApplication)__thisModule).Lock();
1215 installProgress.progressBar.range = totalSize;
1216 for(c = 0; components[c].name && !abortInstall; c++)
1217 components[c].Install(installDir);
1220 installProgress.progressBar.range = 0;
1221 installProgress.finish.Destroy(0);
1222 installProgress.cancel.text = $"Close";
1223 installProgress.cancel.isDefault = true;
1224 installProgress.cancel.disabled = false;
1225 installProgress.cancel.NotifyClicked = Window::ButtonCloseDialog;
1226 installProgress.installing.text = $"Installation Cancelled.";
1227 installProgress.title.text = $"Installation Cancelled";
1228 installProgress.titleInfo.contents = $"The installation was not completed.";
1233 char idePath[MAX_LOCATION];
1234 char userProfile[MAX_LOCATION];
1237 GlobalSettings settings
1241 installProgress.installing.text = $"Configuring ECERE IDE...";
1242 ((GuiApplication)__thisModule).Unlock();
1243 ((GuiApplication)__thisModule).SignalEvent();
1246 for(c = 0; coreSDK[c].name; c++)
1248 char path[MAX_LOCATION];
1250 coreSDK[c].GetFullPath(path);
1251 if(c != ide && c != runtime && c != eda && c != ec)
1252 PathCat(path, "bin");
1255 coreSDK[c].GetFullPath(idePath);
1256 PathCat(idePath, "IDE.exe");
1259 // TODO: Update This!
1261 for(item = settings.systemDirs[executables].first; item; item = item.next)
1262 if(!fstrcmp(item.name, path))
1266 settings.systemDirs[executables].Add(NamedItem { name = CopyString(path); });
1271 for(item = settings.systemDirs[libraries].first; item; item = item.next)
1272 if(!fstrcmp(item.name, path))
1276 settings.systemDirs[libraries].Add(NamedItem { name = CopyString(path); });
1283 for(c = 0; additional[c].name; c++)
1285 char path[MAX_LOCATION];
1287 additional[c].GetFullPath(path);
1288 PathCat(path, "bin");
1289 for(item = settings.systemDirs[executables].first; item; item = item.next)
1290 if(!fstrcmp(item.name, path))
1294 settings.systemDirs[executables].Add(NamedItem { name = CopyString(path); });
1301 char path[MAX_LOCATION] = "";
1302 if(components[samples].selected)
1303 components[samples].GetFullPath(path);
1305 components[coreSDK].GetFullPath(path);
1306 /* TODO: Update This!
1307 if(!settings.ideProjectFileDialogLocation)
1308 settings.ideProjectFileDialogLocation = path;
1309 if(!settings.ideFileDialogLocation)
1310 settings.ideFileDialogLocation = path;
1317 // Set up Uninstaller
1318 ((GuiApplication)__thisModule).Lock();
1319 installProgress.installing.text = $"Registering uninstaller...";
1320 ((GuiApplication)__thisModule).Unlock();
1321 ((GuiApplication)__thisModule).SignalEvent();
1326 char * displayName = "ECERE SDK 0.44";
1327 char uninstaller[MAX_LOCATION];
1328 bool nomodify = true;
1330 strcpy(uninstaller, installDir);
1331 PathCat(uninstaller, "uninstall_ecere.exe");
1333 RegCreateKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\ECERE SDK", 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1335 RegSetValueEx(key, "DisplayName", 0, REG_SZ, displayName, strlen(displayName)+1);
1336 RegSetValueEx(key, "UninstallString", 0, REG_SZ, uninstaller, strlen(uninstaller)+1);
1337 RegSetValueEx(key, "DisplayIcon", 0, REG_SZ, idePath, strlen(idePath)+1);
1338 //RegSetValueEx(key, "NoModify", 0, REG_DWORD, (byte *)&nomodify, sizeof(nomodify));
1339 //RegSetValueEx(key, "NoRepair", 0, REG_DWORD, (byte *)&nomodify, sizeof(nomodify));
1344 if(pathOptions[PathOptions::AddECEREPaths].selected
1346 || pathOptions[PathOptions::AddMinGWPaths].selected
1352 char path[2048] = "";
1355 ((GuiApplication)__thisModule).Lock();
1356 installProgress.installing.text = "Registering paths...";
1357 ((GuiApplication)__thisModule).Unlock();
1358 ((GuiApplication)__thisModule).SignalEvent();
1360 // if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Environment", 0, KEY_ALL_ACCESS, &key) == ERROR_SUCCESS)
1362 RegCreateKeyEx(HKEY_CURRENT_USER, "Environment", 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1363 // RegCreateKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1364 if(status == REG_OPENED_EXISTING_KEY)
1366 size = sizeof(wPath);
1367 RegQueryValueExW(key, L"path", null, null, (byte *)wPath, &size);
1368 UTF16toUTF8Buffer(wPath, path, sizeof(path));
1371 UTF8toUTF16Buffer(path, wPath, sizeof(wPath) / sizeof(uint16));
1372 RegSetValueExW(key, L"path", 0, REG_EXPAND_SZ, (byte *)wPath, (wcslen(wPath)+1) * 2);
1375 SendMessageTimeout (HWND_BROADCAST, WM_SETTINGCHANGE, 0, (int)"Environment", SMTO_NORMAL, 1000, NULL);
1378 // Install Program Group Icons
1379 // userProfile = getenv("USERPROFILE");
1380 GetEnvironment("USERPROFILE", userProfile, sizeof(userProfile));
1382 if(options[IconOptions::StartMenuIcon].selected)
1384 char destPath[MAX_LOCATION];
1385 char startMenuPath[MAX_LOCATION] = "";
1388 ((GuiApplication)__thisModule).Lock();
1389 installProgress.installing.text = $"Installing Start Menu Icons...";
1390 ((GuiApplication)__thisModule).Unlock();
1391 ((GuiApplication)__thisModule).SignalEvent();
1393 strcpy(destPath, userProfile);
1395 if(RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", 0, KEY_ALL_ACCESS, &key) == ERROR_SUCCESS)
1397 uint16 wStartMenuPath[2048];
1398 uint size = sizeof(wStartMenuPath);
1399 // RegQueryValueEx(key, "Start Menu", null, null, startMenuPath, &size);
1400 RegQueryValueExW(key, L"Programs", null, null, (byte *)wStartMenuPath, &size);
1401 UTF16toUTF8Buffer(wStartMenuPath, startMenuPath, sizeof(startMenuPath));
1404 if(!startMenuPath[0] && userProfile && userProfile[0])
1406 strcpy(startMenuPath, userProfile);
1407 PathCat(startMenuPath, "Start Menu\\Programs");
1410 if(startMenuPath[0])
1412 strcpy(destPath, startMenuPath);
1413 PathCat(destPath, "ECERE SDK");
1416 strcpy(destPath, startMenuPath);
1417 PathCat(destPath, "ECERE SDK\\ECERE IDE.lnk");
1418 CreateLink(idePath, destPath, null); //"ECERE IDE");
1419 if(components[samples].selected)
1421 char samplesPath[MAX_LOCATION] = "";
1422 components[samples].GetFullPath(samplesPath);
1424 strcpy(destPath, startMenuPath);
1425 PathCat(destPath, "ECERE SDK\\Sample Projects.lnk");
1426 CreateLink(samplesPath, destPath, null);//"Sample Projects");
1428 if(components[documentation].selected && documentation[ecereBook].selected)
1430 char docPath[MAX_LOCATION] = "";
1431 documentation[ecereBook].GetFullPath(docPath);
1432 PathCat(docPath, "Ecere Tao of Programming [work in progress].pdf");
1434 strcpy(destPath, startMenuPath);
1435 PathCat(destPath, "ECERE SDK\\The Ecere Tao of Programming.lnk");
1436 CreateLink(docPath, destPath, null);
1441 // Install Desktop Icon
1442 if(options[IconOptions::DesktopIcon].selected)
1445 char desktopPath[MAX_LOCATION];
1447 if(RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", 0, KEY_ALL_ACCESS, &key) == ERROR_SUCCESS)
1449 uint16 wDesktopPath[MAX_LOCATION];
1450 uint size = sizeof(wDesktopPath);
1451 RegQueryValueExW(key, L"Desktop", null, null, (byte *)wDesktopPath, &size);
1452 UTF16toUTF8Buffer(wDesktopPath, desktopPath, sizeof(desktopPath));
1455 if(!desktopPath[0] && userProfile && userProfile[0])
1457 strcpy(desktopPath, userProfile);
1458 PathCat(desktopPath, "Desktop");
1463 PathCat(desktopPath, "ECERE IDE.lnk");
1465 ((GuiApplication)__thisModule).Lock();
1466 installProgress.installing.text = $"Installing Desktop Icon...";
1467 ((GuiApplication)__thisModule).Unlock();
1468 ((GuiApplication)__thisModule).SignalEvent();
1470 CreateLink(idePath, desktopPath, null);//"ECERE IDE");
1474 // Install QuickLaunch Icon
1475 if(options[IconOptions::QuickLaunchIcon].selected)
1477 char appData[MAX_LOCATION]; // = getenv("APPDATA");
1478 GetEnvironment("APPDATA", appData, sizeof(appData));
1480 if(appData && appData[0])
1482 char destPath[MAX_LOCATION];
1484 ((GuiApplication)__thisModule).Lock();
1485 installProgress.installing.text = $"Installing Quicklaunch Icon...";
1486 ((GuiApplication)__thisModule).Unlock();
1487 ((GuiApplication)__thisModule).SignalEvent();
1489 strcpy(destPath, appData);
1490 PathCat(destPath, "Microsoft\\Internet Explorer\\Quick Launch\\ECERE IDE.lnk");
1492 CreateLink(idePath, destPath, null);//"ECERE IDE");
1496 // Register File Types
1497 if(associateOptions[AssociateOptions::AssociateEPJ].selected ||
1498 associateOptions[AssociateOptions::AssociateEC].selected ||
1499 associateOptions[AssociateOptions::AssociateC].selected ||
1500 associateOptions[AssociateOptions::AssociateCPP].selected ||
1501 associateOptions[AssociateOptions::AssociateTXT].selected ||
1502 associateOptions[AssociateOptions::Associate3DS].selected ||
1503 associateOptions[AssociateOptions::AssociateIMG].selected)
1505 ((GuiApplication)__thisModule).Lock();
1506 installProgress.installing.text = $"Resgistering File Types...";
1507 ((GuiApplication)__thisModule).Unlock();
1508 ((GuiApplication)__thisModule).SignalEvent();
1510 if(associateOptions[AssociateOptions::AssociateEPJ].selected)
1512 AssociateExtension(".epj", "ECERE IDE Project", "epj_file", "Open", idePath);
1514 if(associateOptions[AssociateOptions::AssociateEC].selected)
1516 AssociateExtension(".ec", "eC Source File", "ec_file", "Open", idePath);
1517 AssociateExtension(".eh", "eC Header File", "eh_file", "Open", idePath);
1519 if(associateOptions[AssociateOptions::AssociateC].selected)
1521 AssociateExtension(".c", "C Source File", "c_file", "Open", idePath);
1522 AssociateExtension(".h", "C Header File", "h_file", "Open", idePath);
1524 if(associateOptions[AssociateOptions::AssociateCPP].selected)
1526 AssociateExtension(".cpp", "C++ Source File", "cpp_file", "Open", idePath);
1527 AssociateExtension(".cc", "C++ Source File", "cpp_file", "Open", idePath);
1528 AssociateExtension(".cxx", "C++ Source File", "cpp_file", "Open", idePath);
1529 AssociateExtension(".chh", "C++ Header File", "chh_file", "Open", idePath);
1530 AssociateExtension(".hh", "C++ Header File", "chh_file", "Open", idePath);
1531 AssociateExtension(".hxx", "C++ Header File", "chh_file", "Open", idePath);
1533 if(associateOptions[AssociateOptions::AssociateTXT].selected)
1535 AssociateExtension(".txt", "Text File", "txt_file", "Open", idePath);
1537 if(associateOptions[AssociateOptions::Associate3DS].selected)
1539 AssociateExtension(".3ds", "3D Studio Model", "3ds_file", "View", idePath);
1541 if(associateOptions[AssociateOptions::AssociateIMG].selected)
1543 AssociateExtension(".bmp", "BMP Image", "bmp_file", "View", idePath);
1544 AssociateExtension(".pcx", "PCX Image", "pcx_file", "View", idePath);
1545 AssociateExtension(".png", "PNG Image", "png_file", "View", idePath);
1546 AssociateExtension(".jpg", "JPEG Image", "jpg_file", "View", idePath);
1547 AssociateExtension(".jpeg", "JPEG Image", "jpg_file", "View", idePath);
1548 AssociateExtension(".gif", "GIF Image", "gif_file", "View", idePath);
1551 ((GuiApplication)__thisModule).Lock();
1553 installProgress.cancel.Destroy(0);
1554 installProgress.finish.text = $"Finish";
1555 installProgress.finish.disabled = false;
1556 installProgress.finish.Activate();
1557 installProgress.installing.text = $"Installation Complete.";
1558 installProgress.title.text = $"Installation Complete";
1559 installProgress.titleInfo.contents = $"Thank you for using the Ecere SDK.";
1561 ((GuiApplication)__thisModule).Unlock();