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 strcpy(defSamplesPath, appData);
945 PathCat(defSamplesPath, "ECERE SDK\\Samples");
946 components[samples].defInstallPath = defSamplesPath;
949 destBox.contents = installDir;
953 for(c = 0; components[c].name; c++)
954 AddComponent(components[c], null, installDir);
957 // Compute size apart because ToggleCheck will change it
961 for(c = 0; components[c].name; c++)
962 totalSize += components[c].requiredSize;
965 char sizeString[100];
966 PrintSize(sizeString, totalSize, 2);
967 totalSpaceValue.text = sizeString;
969 for(c = 0; options[c].name; c++)
970 AddOption(options[c], null);
979 void OnRedraw(Surface surface)
986 //surface.Gradient(keys, sizeof(keys)/sizeof(ColorKey), 1.0f, Vertical, 0,0, clientSize.w, clientSize.h);
987 surface.SetForeground(Color { 128, 128, 128 });
988 surface.HLine(160, 620, 400);
989 surface.SetForeground(white);
990 surface.HLine(160, 621, 401);
991 surface.PutPixel(621, 400);
995 parent = this, opacity = 1, borderStyle = deep, size = Size { 644, 93 }, anchor = Anchor { left = -8, top = -8 };
997 void OnRedraw(Surface surface)
1004 surface.Gradient(keys, sizeof(keys)/sizeof(ColorKey), 0, horizontal, 220,0, clientSize.w, clientSize.h);
1006 Label::OnRedraw(surface);
1011 class InstallProgress : Window
1013 text = $"Ecere Software Development Kit Setup";
1014 background = activeBorder;
1015 borderStyle = fixed;
1019 size = Size { 640, 480 };
1021 Label installing { this, position = { 32, 160 } };
1022 ProgressBar progressBar { parent = this, size = Size { 588, 24 }, anchor = Anchor { left = 24, top = 184 } };
1025 parent = this, text = $"Install", disabled = true, isDefault = true, size = Size { 75, 23 }, anchor = Anchor { left = 432, top = 416 };
1027 NotifyClicked = ButtonCloseDialog
1031 this, text = $"Cancel", hotKey = altX, size = Size { 75, 23 }, anchor = Anchor { left = 544, top = 416 };
1033 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
1035 abortInstall = true;
1041 inactive = true, noSelect = true,
1042 multiLine = true, parent = label3, opacity = 0, borderStyle = none, size = Size { 350, 35 }, anchor = Anchor { horz = 111, vert = 13 },
1043 contents = $"Please wait while the Ecere Software Development Kit is being installed."
1045 Label label2 { parent = this, text = buildString, position = { 16, 392 }, disabled = true, opacity = 1, background = activeBorder };
1046 Picture picture1 { image = BitmapResource { ":ecere.bmp", transparent = true }, filter = true, parent = label3, anchor = Anchor { left = 16, top = 4 } };
1047 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 } };
1049 void OnRedraw(Surface surface)
1056 //surface.Gradient(keys, sizeof(keys)/sizeof(ColorKey), 1.0f, Vertical, 0,0, clientSize.w, clientSize.h);
1057 surface.SetForeground(Color { 128, 128, 128 });
1058 surface.HLine(160, 620, 400);
1059 surface.SetForeground(white);
1060 surface.HLine(160, 621, 401);
1061 surface.PutPixel(621, 400);
1065 parent = this, opacity = 1, borderStyle = deep, size = Size { 644, 93 }, anchor = Anchor { left = -8, top = -8 };
1067 void OnRedraw(Surface surface)
1074 surface.Gradient(keys, sizeof(keys)/sizeof(ColorKey), 0, horizontal, 220,0, clientSize.w, clientSize.h);
1076 Label::OnRedraw(surface);
1079 InstallThread thread
1084 Installer installer {};
1085 InstallProgress installProgress { autoCreate = false };
1087 void ModifyPath(char * newPath)
1094 strcpy(oldPath, newPath);
1095 count = TokenizeWith(oldPath, sizeof(paths) / sizeof(char *), paths, ";", false);
1097 for(c = 0; coreSDK[c].name; c++)
1099 char path[MAX_LOCATION];
1100 coreSDK[c].GetFullPath(path);
1101 if(c != ide && c != runtime && c != eda && c != ec)
1104 if(!pathOptions[PathOptions::AddMinGWPaths].selected)
1107 PathCat(path, "bin");
1109 else if(!pathOptions[PathOptions::AddECEREPaths].selected) continue;
1111 for(p = 0; p<count; p++)
1112 if(!fstrcmp(paths[p], path))
1119 strcat(newPath, ";");
1120 start = oldPath + strlen(paths[count-1])+1;
1125 strcpy(start, path);
1126 *(start + strlen(path)) = '\0';
1127 paths[count++] = start;
1129 strcat(newPath, path);
1133 if(pathOptions[PathOptions::AddMinGWPaths].selected)
1136 for(c = 0; additional[c].name; c++)
1138 char path[MAX_LOCATION];
1140 additional[c].GetFullPath(path);
1141 PathCat(path, "bin");
1142 for(p = 0; p<count; p++)
1143 if(!fstrcmp(paths[p], path))
1151 strcat(newPath, ";");
1152 start = oldPath + strlen(paths[count-1])+1;
1157 strcpy(start, path);
1158 *(start + strlen(path)) = '\0';
1159 paths[count++] = start;
1161 strcat(newPath, path);
1168 void AssociateExtension(char * extension, char * description, char *name, char * action, char * path)
1174 RegCreateKeyEx(HKEY_CLASSES_ROOT, extension, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1175 RegSetValueEx(key, null, 0, REG_SZ, name, strlen(name)+1);
1178 RegCreateKeyEx(HKEY_CLASSES_ROOT, name, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1179 RegSetValueEx(key, null, 0, REG_SZ, description, strlen(description)+1);
1182 sprintf(keyName, "%s\\shell", extension);
1183 RegCreateKeyEx(HKEY_CLASSES_ROOT, keyName, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1184 RegSetValueEx(key, null, 0, REG_SZ, action, strlen(action)+1);
1187 sprintf(keyName, "%s\\shell\\%s", name, action);
1188 RegCreateKeyEx(HKEY_CLASSES_ROOT, keyName, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1191 sprintf(keyName, "%s\\shell\\%s\\command", name, action);
1192 RegCreateKeyEx(HKEY_CLASSES_ROOT, keyName, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1194 sprintf(keyName, path);
1195 strcat(keyName, " \"%L\"");
1197 uint16 wKeyName[2048];
1198 UTF8toUTF16Buffer(keyName, wKeyName, sizeof(wKeyName) / sizeof(uint16));
1199 RegSetValueExW(key, null, 0, REG_SZ, (byte *)wKeyName, (wcslen(wKeyName) + 1)*sizeof(uint16));
1204 class InstallThread : Thread
1209 ((GuiApplication)__thisModule).Lock();
1210 installProgress.progressBar.range = totalSize;
1211 for(c = 0; components[c].name && !abortInstall; c++)
1212 components[c].Install(installDir);
1215 installProgress.progressBar.range = 0;
1216 installProgress.finish.Destroy(0);
1217 installProgress.cancel.text = $"Close";
1218 installProgress.cancel.isDefault = true;
1219 installProgress.cancel.disabled = false;
1220 installProgress.cancel.NotifyClicked = Window::ButtonCloseDialog;
1221 installProgress.installing.text = $"Installation Cancelled.";
1222 installProgress.title.text = $"Installation Cancelled";
1223 installProgress.titleInfo.contents = $"The installation was not completed.";
1228 char idePath[MAX_LOCATION];
1229 char userProfile[MAX_LOCATION];
1232 GlobalSettings settings
1236 installProgress.installing.text = $"Configuring ECERE IDE...";
1237 ((GuiApplication)__thisModule).Unlock();
1238 ((GuiApplication)__thisModule).SignalEvent();
1241 for(c = 0; coreSDK[c].name; c++)
1243 char path[MAX_LOCATION];
1245 coreSDK[c].GetFullPath(path);
1246 if(c != ide && c != runtime && c != eda && c != ec)
1247 PathCat(path, "bin");
1250 coreSDK[c].GetFullPath(idePath);
1251 PathCat(idePath, "IDE.exe");
1254 // TODO: Update This!
1256 for(item = settings.systemDirs[executables].first; item; item = item.next)
1257 if(!fstrcmp(item.name, path))
1261 settings.systemDirs[executables].Add(NamedItem { name = CopyString(path); });
1266 for(item = settings.systemDirs[libraries].first; item; item = item.next)
1267 if(!fstrcmp(item.name, path))
1271 settings.systemDirs[libraries].Add(NamedItem { name = CopyString(path); });
1278 for(c = 0; additional[c].name; c++)
1280 char path[MAX_LOCATION];
1282 additional[c].GetFullPath(path);
1283 PathCat(path, "bin");
1284 for(item = settings.systemDirs[executables].first; item; item = item.next)
1285 if(!fstrcmp(item.name, path))
1289 settings.systemDirs[executables].Add(NamedItem { name = CopyString(path); });
1296 char path[MAX_LOCATION] = "";
1297 if(components[samples].selected)
1298 components[samples].GetFullPath(path);
1300 components[coreSDK].GetFullPath(path);
1301 /* TODO: Update This!
1302 if(!settings.ideProjectFileDialogLocation)
1303 settings.ideProjectFileDialogLocation = path;
1304 if(!settings.ideFileDialogLocation)
1305 settings.ideFileDialogLocation = path;
1312 // Set up Uninstaller
1313 ((GuiApplication)__thisModule).Lock();
1314 installProgress.installing.text = $"Registering uninstaller...";
1315 ((GuiApplication)__thisModule).Unlock();
1316 ((GuiApplication)__thisModule).SignalEvent();
1321 char * displayName = "ECERE SDK 0.44";
1322 char uninstaller[MAX_LOCATION];
1323 bool nomodify = true;
1325 strcpy(uninstaller, installDir);
1326 PathCat(uninstaller, "uninstall_ecere.exe");
1328 RegCreateKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\ECERE SDK", 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1330 RegSetValueEx(key, "DisplayName", 0, REG_SZ, displayName, strlen(displayName)+1);
1331 RegSetValueEx(key, "UninstallString", 0, REG_SZ, uninstaller, strlen(uninstaller)+1);
1332 RegSetValueEx(key, "DisplayIcon", 0, REG_SZ, idePath, strlen(idePath)+1);
1333 //RegSetValueEx(key, "NoModify", 0, REG_DWORD, (byte *)&nomodify, sizeof(nomodify));
1334 //RegSetValueEx(key, "NoRepair", 0, REG_DWORD, (byte *)&nomodify, sizeof(nomodify));
1339 if(pathOptions[PathOptions::AddECEREPaths].selected
1341 || pathOptions[PathOptions::AddMinGWPaths].selected
1347 char path[2048] = "";
1350 ((GuiApplication)__thisModule).Lock();
1351 installProgress.installing.text = "Registering paths...";
1352 ((GuiApplication)__thisModule).Unlock();
1353 ((GuiApplication)__thisModule).SignalEvent();
1355 // if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Environment", 0, KEY_ALL_ACCESS, &key) == ERROR_SUCCESS)
1357 RegCreateKeyEx(HKEY_CURRENT_USER, "Environment", 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1358 // RegCreateKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1359 if(status == REG_OPENED_EXISTING_KEY)
1361 size = sizeof(wPath);
1362 RegQueryValueExW(key, L"path", null, null, (byte *)wPath, &size);
1363 UTF16toUTF8Buffer(wPath, path, sizeof(path));
1366 UTF8toUTF16Buffer(path, wPath, sizeof(wPath) / sizeof(uint16));
1367 RegSetValueExW(key, L"path", 0, REG_EXPAND_SZ, (byte *)wPath, (wcslen(wPath)+1) * 2);
1370 SendMessageTimeout (HWND_BROADCAST, WM_SETTINGCHANGE, 0, (int)"Environment", SMTO_NORMAL, 1000, NULL);
1373 // Install Program Group Icons
1374 // userProfile = getenv("USERPROFILE");
1375 GetEnvironment("USERPROFILE", userProfile, sizeof(userProfile));
1377 if(options[IconOptions::StartMenuIcon].selected)
1379 char destPath[MAX_LOCATION];
1380 char startMenuPath[MAX_LOCATION] = "";
1383 ((GuiApplication)__thisModule).Lock();
1384 installProgress.installing.text = $"Installing Start Menu Icons...";
1385 ((GuiApplication)__thisModule).Unlock();
1386 ((GuiApplication)__thisModule).SignalEvent();
1388 strcpy(destPath, userProfile);
1390 if(RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", 0, KEY_ALL_ACCESS, &key) == ERROR_SUCCESS)
1392 uint16 wStartMenuPath[2048];
1393 uint size = sizeof(wStartMenuPath);
1394 // RegQueryValueEx(key, "Start Menu", null, null, startMenuPath, &size);
1395 RegQueryValueExW(key, L"Programs", null, null, (byte *)wStartMenuPath, &size);
1396 UTF16toUTF8Buffer(wStartMenuPath, startMenuPath, sizeof(startMenuPath));
1399 if(!startMenuPath[0] && userProfile && userProfile[0])
1401 strcpy(startMenuPath, userProfile);
1402 PathCat(startMenuPath, "Start Menu\\Programs");
1405 if(startMenuPath[0])
1407 strcpy(destPath, startMenuPath);
1408 PathCat(destPath, "ECERE SDK");
1411 strcpy(destPath, startMenuPath);
1412 PathCat(destPath, "ECERE SDK\\ECERE IDE.lnk");
1413 CreateLink(idePath, destPath, null); //"ECERE IDE");
1414 if(components[samples].selected)
1416 char samplesPath[MAX_LOCATION] = "";
1417 components[samples].GetFullPath(samplesPath);
1419 strcpy(destPath, startMenuPath);
1420 PathCat(destPath, "ECERE SDK\\Sample Projects.lnk");
1421 CreateLink(samplesPath, destPath, null);//"Sample Projects");
1423 if(components[documentation].selected && documentation[ecereBook].selected)
1425 char docPath[MAX_LOCATION] = "";
1426 documentation[ecereBook].GetFullPath(docPath);
1427 PathCat(docPath, "Ecere Tao of Programming [work in progress].pdf");
1429 strcpy(destPath, startMenuPath);
1430 PathCat(destPath, "ECERE SDK\\The Ecere Tao of Programming.lnk");
1431 CreateLink(docPath, destPath, null);
1436 // Install Desktop Icon
1437 if(options[IconOptions::DesktopIcon].selected)
1440 char desktopPath[MAX_LOCATION];
1442 if(RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", 0, KEY_ALL_ACCESS, &key) == ERROR_SUCCESS)
1444 uint16 wDesktopPath[MAX_LOCATION];
1445 uint size = sizeof(wDesktopPath);
1446 RegQueryValueExW(key, L"Desktop", null, null, (byte *)wDesktopPath, &size);
1447 UTF16toUTF8Buffer(wDesktopPath, desktopPath, sizeof(desktopPath));
1450 if(!desktopPath[0] && userProfile && userProfile[0])
1452 strcpy(desktopPath, userProfile);
1453 PathCat(desktopPath, "Desktop");
1458 PathCat(desktopPath, "ECERE IDE.lnk");
1460 ((GuiApplication)__thisModule).Lock();
1461 installProgress.installing.text = $"Installing Desktop Icon...";
1462 ((GuiApplication)__thisModule).Unlock();
1463 ((GuiApplication)__thisModule).SignalEvent();
1465 CreateLink(idePath, desktopPath, null);//"ECERE IDE");
1469 // Install QuickLaunch Icon
1470 if(options[IconOptions::QuickLaunchIcon].selected)
1472 char appData[MAX_LOCATION]; // = getenv("APPDATA");
1473 GetEnvironment("APPDATA", appData, sizeof(appData));
1475 if(appData && appData[0])
1477 char destPath[MAX_LOCATION];
1479 ((GuiApplication)__thisModule).Lock();
1480 installProgress.installing.text = $"Installing Quicklaunch Icon...";
1481 ((GuiApplication)__thisModule).Unlock();
1482 ((GuiApplication)__thisModule).SignalEvent();
1484 strcpy(destPath, appData);
1485 PathCat(destPath, "Microsoft\\Internet Explorer\\Quick Launch\\ECERE IDE.lnk");
1487 CreateLink(idePath, destPath, null);//"ECERE IDE");
1491 // Register File Types
1492 if(associateOptions[AssociateOptions::AssociateEPJ].selected ||
1493 associateOptions[AssociateOptions::AssociateEC].selected ||
1494 associateOptions[AssociateOptions::AssociateC].selected ||
1495 associateOptions[AssociateOptions::AssociateCPP].selected ||
1496 associateOptions[AssociateOptions::AssociateTXT].selected ||
1497 associateOptions[AssociateOptions::Associate3DS].selected ||
1498 associateOptions[AssociateOptions::AssociateIMG].selected)
1500 ((GuiApplication)__thisModule).Lock();
1501 installProgress.installing.text = $"Resgistering File Types...";
1502 ((GuiApplication)__thisModule).Unlock();
1503 ((GuiApplication)__thisModule).SignalEvent();
1505 if(associateOptions[AssociateOptions::AssociateEPJ].selected)
1507 AssociateExtension(".epj", "ECERE IDE Project", "epj_file", "Open", idePath);
1509 if(associateOptions[AssociateOptions::AssociateEC].selected)
1511 AssociateExtension(".ec", "eC Source File", "ec_file", "Open", idePath);
1512 AssociateExtension(".eh", "eC Header File", "eh_file", "Open", idePath);
1514 if(associateOptions[AssociateOptions::AssociateC].selected)
1516 AssociateExtension(".c", "C Source File", "c_file", "Open", idePath);
1517 AssociateExtension(".h", "C Header File", "h_file", "Open", idePath);
1519 if(associateOptions[AssociateOptions::AssociateCPP].selected)
1521 AssociateExtension(".cpp", "C++ Source File", "cpp_file", "Open", idePath);
1522 AssociateExtension(".cc", "C++ Source File", "cpp_file", "Open", idePath);
1523 AssociateExtension(".cxx", "C++ Source File", "cpp_file", "Open", idePath);
1524 AssociateExtension(".chh", "C++ Header File", "chh_file", "Open", idePath);
1525 AssociateExtension(".hh", "C++ Header File", "chh_file", "Open", idePath);
1526 AssociateExtension(".hxx", "C++ Header File", "chh_file", "Open", idePath);
1528 if(associateOptions[AssociateOptions::AssociateTXT].selected)
1530 AssociateExtension(".txt", "Text File", "txt_file", "Open", idePath);
1532 if(associateOptions[AssociateOptions::Associate3DS].selected)
1534 AssociateExtension(".3ds", "3D Studio Model", "3ds_file", "View", idePath);
1536 if(associateOptions[AssociateOptions::AssociateIMG].selected)
1538 AssociateExtension(".bmp", "BMP Image", "bmp_file", "View", idePath);
1539 AssociateExtension(".pcx", "PCX Image", "pcx_file", "View", idePath);
1540 AssociateExtension(".png", "PNG Image", "png_file", "View", idePath);
1541 AssociateExtension(".jpg", "JPEG Image", "jpg_file", "View", idePath);
1542 AssociateExtension(".jpeg", "JPEG Image", "jpg_file", "View", idePath);
1543 AssociateExtension(".gif", "GIF Image", "gif_file", "View", idePath);
1546 ((GuiApplication)__thisModule).Lock();
1548 installProgress.cancel.Destroy(0);
1549 installProgress.finish.text = $"Finish";
1550 installProgress.finish.disabled = false;
1551 installProgress.finish.Activate();
1552 installProgress.installing.text = $"Installation Complete.";
1553 installProgress.title.text = $"Installation Complete";
1554 installProgress.titleInfo.contents = $"Thank you for using the Ecere SDK.";
1556 ((GuiApplication)__thisModule).Unlock();