2 static define buildString = $"Ecere SDK v0.44.08 (Without MinGW) -- built on August 9, 2013 ";
4 static define buildString = $"Ecere SDK v0.44.08 -- built on August 9, 2013 ";
7 #define WIN32_LEAN_AND_MEAN
8 #define GetFreeSpace _GetFreeSpace
27 char * OnGetString(char * tempString, void * fieldData, bool * needClass)
31 strcpy(tempString, name);
32 strcat(tempString, " (32)");
38 void OnDisplay(Surface surface, int x, int y, int width, void * fieldData, Alignment alignment, DataDisplayFlags displayFlags)
40 if(!displayFlags.active) { displayFlags.current = false; displayFlags.selected = false; }
41 class::OnDisplay(surface, x + 22, y, width - 22, fieldData, alignment, displayFlags);
45 //#define BUFFERSIZE 0x10000
46 #define BUFFERSIZE 0x1000
47 bool abortInstall = false;
49 void ExtractFileFromArchive(ProgressBar progressBar, char * path, char * outputFile)
51 char fileName[MAX_LOCATION];
52 FileAttribs exists = FileExists(path);
56 if(exists.isDirectory)
58 FileListing listing { path };
62 if(MakeDir(outputFile))
65 FileGetStats(path, &stats);
69 while(listing.Find() && !abortInstall)
71 strcpy(fileName, outputFile);
73 // Tweak file name if out
76 if(!strcmp(fileName, ".")) fileName[0] = '\0';
77 if(listing.name[0] == '/' || listing.name[0] == '\\')
79 char * afterSlash, rest[MAX_LOCATION];
80 for(afterSlash = fileName; *afterSlash == '/' || *afterSlash == '\\'; afterSlash++);
81 strcpy(rest, afterSlash);
82 PathCat(fileName, "_root");
83 PathCat(fileName, rest);
85 else if(listing.name[1] == ':')
88 sprintf(letter, "_%cdrive", toupper(listing.name[0]));
89 PathCat(fileName, letter);
90 PathCat(fileName, listing.name[2] ? (listing.name + 3) : (listing.name + 2));
93 PathCat(fileName, listing.name);
96 PathCat(fileName, listing.name);
97 if(!strcmp(fileName, "/") || !strcmp(fileName, "\\"))
98 strcpy(fileName, DIR_SEPS);
99 ExtractFileFromArchive(progressBar, listing.path, fileName);
105 File input = FileOpen(path, read);
108 File output = FileOpen(outputFile, write);
111 char fileName[MAX_FILENAME];
112 uint position = progressBar.progress;
115 byte buffer[BUFFERSIZE];
117 FileGetSize(path, &dataSize);
118 GetLastDirectory(outputFile, fileName);
120 ((GuiApplication)__thisModule).SignalEvent();
121 //((GuiApplication)__thisModule).ProcessInput();
122 //((GuiApplication)__thisModule).UpdateDisplay();
124 for(c = 0; c<dataSize && !abortInstall; c += BUFFERSIZE)
126 uint size = (dataSize > c + BUFFERSIZE) ? BUFFERSIZE : (dataSize - c);
128 ((GuiApplication)__thisModule).Unlock();
130 input.Read(buffer, 1, size);
131 output.Write(buffer, 1, size);
133 ((GuiApplication)__thisModule).Lock();
135 progressBar.progress = position + c + size;
136 ((GuiApplication)__thisModule).SignalEvent();
138 //((GuiApplication)__thisModule).ProcessInput();
139 //((GuiApplication)__thisModule).UpdateDisplay();
144 FileGetStats(path, &stats);
150 FileSetTime(outputFile, stats.created, 0, stats.modified);
153 public enum BitArch { none, bits32, bits64 };
159 char * defInstallPath;
160 Component * subComponents;
170 char installPath[MAX_LOCATION];
173 void GetFullPath(char * path)
175 if(this != null && parent)
176 parent->GetFullPath(path);
178 strcpy(path, installDir);
181 PathCat(path, installPath);
184 void Install(char * parentPath, char * parentPath32)
187 if(selected && (arch == none || arch == bits32 || osIS64bit))
189 char path64[MAX_LOCATION];
190 char path32[MAX_LOCATION];
191 strcpy(path64, parentPath);
192 PathCat(path64, installPath);
194 strcpy(path32, parentPath32);
195 PathCat(path32, installPath);
197 installProgress.installing.SetText($"Installing %s...", name);
198 ((GuiApplication)__thisModule).UpdateDisplay();
202 char * path = path64;
203 char source[MAX_LOCATION];
205 strcat(source, dataPath);
212 if(FileExists(source).isFile)
214 char name[MAX_FILENAME];
215 GetLastDirectory(source, name);
220 uint p = installProgress.progressBar.progress;
221 ExtractFileFromArchive(installProgress.progressBar, source, path);
226 for(c = 0; subComponents[c].name; c++)
227 subComponents[c].Install(path64, path32);
234 define minGWIncluded = true;
236 define minGWIncluded = false;
239 Component samples[] =
241 { "Ecere Chess", "samples/chess", "chess", null, false, true, true, none },
242 { "Ecere Fractals", "samples/fractals", "fractals", null, false, true, true, none },
243 { "3D", "samples/3D", "3D", null, false, true, true, none },
244 { "Android", "samples/android", "android", null, false, true, true, none },
245 { "Audio", "samples/audio", "audio", null, false, true, true, none },
246 { "Database", "samples/db", "db", null, false, true, true, none },
247 { "eC", "samples/eC", "eC", null, false, true, true, none },
248 { "Games", "samples/games", "games", null, false, true, true, none },
249 { "GUI & Graphics", "samples/guiAndGfx", "guiAndGfx", null, false, true, true, none },
250 { "Miscellaneous", "samples/misc", "misc", null, false, true, true, none },
251 { "Networking", "samples/net", "net", null, false, true, true, none },
252 { "WIA Scanning", "samples/scanning", "scanning", null, false, true, true, none },
253 { "Threading", "samples/threads", "threads", null, false, true, true, none }
257 public enum CoreSDKID
259 ide, ide32, runtime, runtime32, ec, ec32,
260 gcc, gdb, gdb32, mingw, binutils, make,
264 Component coreSDK[CoreSDKID] =
266 { "Ecere IDE", "ecere-sdk/ide", "bin", null, true, true, true, bits64 },
267 { "Ecere IDE", "ecere-sdk32/ide", "bin", null, true, true, true, bits32 },
268 { "Runtime Library", "ecere-sdk/ecere.dll", "bin", null, true, true, true, bits64 },
269 { "Runtime Library", "ecere-sdk32/ecere.dll", "bin", null, true, true, true, bits32 },
270 { "eC Compiler", "ecere-sdk/compiler", "bin", null, true, true, true, bits64 },
271 { "eC Compiler", "ecere-sdk32/compiler", "bin", null, true, true, true, bits32 },
272 { "GNU C Compiler", "tdm/gcc/core", "tdm", null, true, true, minGWIncluded, none },
273 { "GNU Debugger", "tdm/gdb", "tdm", null, true, true, minGWIncluded, bits64 },
274 { "GNU Debugger", "tdm/gdb32", "tdm", null, true, true, minGWIncluded, bits32 },
275 { "MinGW Runtime", "tdm/mingwrt", "tdm", null, true, true, minGWIncluded, none },
276 { "Binary Utils", "tdm/binutils", "tdm", null, true, true, minGWIncluded, none },
277 { "GNU Make", "tdm/make", "tdm", null, true, true, minGWIncluded, none },
281 public enum AdditionalID
283 eda, eda32, vanilla, vanilla32, extras, upx, gnurx, gnurx32, /*pthreads, */cpp, /*w32api, */gcci18n, gdbi18n, makei18n, binutilsi18n, none
286 Component additional[AdditionalID] =
288 { "Data Access", "ecere-sdk/eda", "bin", null, false, true, true, bits64 },
289 { "Data Access", "ecere-sdk32/eda", "bin", null, false, true, true, bits32 },
290 { "Ecere Vanilla", "ecere-sdk/libecereVanilla.a", "lib", null, false, true, true, bits64 },
291 { "Ecere Vanilla", "ecere-sdk32/libecereVanilla.a", "lib", null, false, true, true, bits32 },
292 { "Ecere Extras", "extras", "extras", null, false, true, true, none },
293 { "UPX", "upx/bin", "upx/bin", null, false, true, true, none },
294 { "GNU Regexp", "tdm/gnurx", "tdm", null, false, true, true, bits64 },
295 { "GNU Regexp", "tdm/gnurx32", "tdm", null, false, true, true, bits32 },
296 // { "pthreads", "tdm/pthreads", "mingw", null, false, true, minGWIncluded, none },
297 { "C++ Compiler", "tdm/gcc/c++", "tdm", null, false, true, minGWIncluded, none },
298 // { "Win32 APIs", "mingw/w32api", "mingw", null, false, true, minGWIncluded, none },
299 { "GCC I18n", "mingw/locale/gcc", "tdm", null, false, false, minGWIncluded, none },
300 { "GDB I18n", "mingw/locale/gdb", "tdm", null, false, false, minGWIncluded, none },
301 { "Make I18n", "mingw/locale/make", "tdm", null, false, false, minGWIncluded, none },
302 { "Binutils I18n", "mingw/locale/binutils", "tdm", null, false, false, minGWIncluded, none },
306 public enum DocumentationID
308 ecereBook, apiRef, tutorials, coursework,
309 gccDoc, gppDocs, gdbDocs, makeDocs, binDocs, mingwDocs, gnurxDocs, upxDocs,
313 Component documentation[DocumentationID] =
315 { "Ecere Book", "ecere-sdk/book", "doc", null, false, true, true, none },
316 { "API Reference", "ecere-sdk/doc", "doc", null, false, true, true, none },
317 { "Ecere Tutorials", "ecere-sdk/tutorials", "doc", null, false, true, true, none },
318 { "Ecere Coursework", "ecere-sdk/coursework", "doc", null, false, true, true, none },
319 { "GCC Docs", "tdm/doc/gcc", "tdm", null, false, false, minGWIncluded, none },
320 { "G++ Docs", "tdm/doc/g++", "tdm", null, false, false, minGWIncluded, none },
321 { "GDB Docs", "tdm/doc/gdb", "tdm", null, false, false, minGWIncluded, none },
322 { "Make Docs", "tdm/doc/make", "tdm", null, false, false, minGWIncluded, none },
323 { "Binutils Docs", "tdm/doc/binutils", "tdm", null, false, false, minGWIncluded, none },
324 { "MinGW Docs", "tdm/doc/mingwrt", "tdm", null, false, false, minGWIncluded, none },
325 { "gnurx Docs", "tdm/doc/gnurx", "tdm", null, false, false, minGWIncluded, none },
326 { "UPX Docs", "upx/doc", "upx/doc", null, false, false, minGWIncluded, none },
330 public enum ComponentID
339 Component components[ComponentID] =
341 { "Core SDK Files", null, null, coreSDK, true, true, true, none },
342 { "Additional Support", null, null, additional, false, true, true, none },
343 { "Documentation", null /*"doc"*/, null /*"doc"*/, documentation, false, true, true, none },
344 { "Samples", null, "samples", samples, false, true, true, none },
348 FileSize totalInstalled;
353 InstallOption * subOptions;
359 enum AssociateOptions
370 InstallOption associateOptions[] =
372 { "Associate with Ecere Project Files (*.epj)", null, true },
373 { "Associate with eC Files (*.ec, *.eh)", null, true },
374 { "Associate with C files (*.c, *.h)", null, false },
375 { "Associate with C++ Files (*.cpp, *.hpp, *.cc, *.hh, *.cxx, *.hxx)", null, false },
376 { "Associate with text files (*.txt)", null, false },
377 { "Associate with 3D Studio Model Files (*.3ds)", null, true },
378 { "Associate with Image Files (*.png, *.jpg, *.pcx, *.bmp, *.gif)", null, false },
384 AddECEREPaths, AddMinGWPaths
387 InstallOption pathOptions[] =
389 { "Add Ecere binaries location to the user environment path", null, true, true },
390 { "Add MinGW to the user environment path", null, true, minGWIncluded }
401 InstallOption options[] =
403 { "Start Menu Group", null, true, true },
404 { "Desktop Icon", null, true, true },
405 { "Quicklaunch Icon", null, true, true },
406 { "Associate the Ecere IDE with Supported File Types", associateOptions, true, true },
407 { "Add binaries location to the user environment paths", pathOptions, true, minGWIncluded },
411 char sourceDir[MAX_LOCATION] = ":";
412 char installDir[MAX_LOCATION];
413 char installDir32[MAX_LOCATION];
416 class Installer : Window
418 text = $"Ecere Software Development Kit Setup - v0.44.08 \"Ryōan-ji\" 64 Bit Edition";
419 background = activeBorder;
424 clientSize = { 636, 456 };
425 // clientSize = { 796, 576 };
426 icon = { ":icon.png" };
428 Picture back { image = BitmapResource { ":ryoanji.png" }, parent = this, position = { 0, 0 } };
429 FileDialog fileDialog
431 master = this, type = selectDir,
432 text = $"Select a new location"
436 master = this, autoCreate = false, inactive = true, text = "...";
438 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
440 DataRow row = componentsBox.currentRow;
441 Component * component = ((CheckItem *)row.GetData(componentField))->data;
442 component->GetFullPath(fileDialog.filePath);
443 StripLastDirectory(fileDialog.filePath, fileDialog.currentDirectory);
445 if(fileDialog.Modal() == ok)
447 componentsBox.StopEditing(false);
448 row.SetData(locationField, fileDialog.filePath);
449 componentsBox.NotifyChanged(this, componentsBox, row);
450 componentsBox.currentField = componentsBox.currentField;
455 CheckListBox componentsBox
457 this, size = { 460, 112 }, position = { 160, 160 }, hasHeader = true;
458 fullRowSelect = false, collapseControl = true, treeBranches = true, rootCollapseButton = true,
461 selectionColor = { 145, 150, 140 };
466 bool NotifyKeyDown(ListBox listBox, DataRow row, Key key, unichar ch)
468 if(key == f2 && browse.visible)
469 browse.NotifyClicked(this, browse, 0, 0, 0);
473 bool NotifyChanged(ListBox listBox, DataRow row)
475 Component * component = ((CheckItem *)listBox.GetData(componentField))->data;
476 char path[MAX_LOCATION], relative[MAX_LOCATION] = "", * newPath;
477 char fullPath[MAX_LOCATION];
479 component->parent->GetFullPath(path);
480 strcpy(fullPath, path);
482 newPath = row.GetData(locationField);
485 PathCat(fullPath, newPath);
486 MakePathRelative(fullPath, path, relative);
488 listBox.SetData(locationField, relative);
489 strcpy(component->installPath, relative);
491 //SetAvailableSpace(component, path);
494 install.disabled = false;
495 for(c = 0; components[c].name; c++)
497 SetAvailableSpace(components[c], installDir);
503 bool NotifyEditDone(ListBox listBox, DataRow row)
509 bool NotifyEdited(ListBox listBox, DataRow row)
512 browse.parent = listBox;
513 browse.position = { componentField.width + locationField.width + 18, (listBox.currentIndex+1) * listBox.rowHeight - 2 };
514 browse.size = { 30, listBox.rowHeight + 3 };
515 for(e = listBox.firstChild; e; e = e.next)
517 if(e._class == class(DataBox))
526 void NotifyChecked(CheckListBox listBox, DataRow row)
528 Component * component = ((CheckItem *)row.GetData(componentField))->data;
530 component->selected = listBox.IsChecked(row);
532 if(!component->parent) totalSize -= component->requiredSize;
533 component->requiredSize = 0;
534 if(component->selected)
536 component->requiredSize += component->size;
537 if(component->subComponents)
538 for(c = 0; component->subComponents[c].name; c++)
539 component->requiredSize += component->subComponents[c].requiredSize;
541 if(component->requiredSize)
543 uint requiredSize = component->requiredSize;
544 row.SetData(reqField, requiredSize);
547 row.UnsetData(reqField);
548 if(!component->parent)
550 totalSize += component->requiredSize;
552 char sizeString[100];
553 PrintSize(sizeString, totalSize, 2);
554 totalSpaceValue.text = sizeString;
559 Label agreementLbl { parent = this, text = $"By installing the Ecere SDK, you agree to the .", font = { "Tahoma", 8.25f }, anchor = Anchor { left = 24, top = 424 } };
562 this, inactive = true, offset = false, bevel = false, foreground = blue, font = { "Tahoma", 8.25f, underline = true, bold = true },
563 // text = $"terms and conditions", anchor = Anchor { left = 241, top = 421 };
564 text = $"terms and conditions", anchor = Anchor { left = 237, top = 421 };
565 cursor = ((GuiApplication)__thisModule).GetCursor(hand);
567 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
569 // LicenseBox { master = this, sourceFile = ":ecere-sdk/doc/LICENSE" }.Modal();
570 LicensesForm { master = this }.Modal();
574 CheckListBox optionsBox
576 this, size = { 460, 94 }, position = { 160, 284 };
577 fullRowSelect = false, collapseControl = true, treeBranches = true, rootCollapseButton = true,
582 void NotifyChecked(CheckListBox listBox, DataRow row)
584 CheckItem * item = row.GetData(optionField);
585 InstallOption * option = item->data;
586 option->selected = listBox.IsChecked(row);
591 parent = this, text = $"Install", isDefault = true, size = { 75, 23 }, position = { 432, 416 };
593 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
595 installProgress.Create();
597 // installProgress.thread.Main();
598 installProgress.thread.Create();
602 Button button3 { parent = this, text = $"Cancel", hotKey = altX, size = Size { 75, 23 }, anchor = Anchor { left = 544, top = 416 }, NotifyClicked = ButtonCloseDialog };
603 Label label1 { labeledWindow = destBox, tabCycle = true, isGroupBox = true, parent = this, inactive = false, size = Size { 458, 50 }, anchor = Anchor { left = 160, top = 96 } };
606 parent = label1, master = this, text = $" Destination Folder", size = Size { 336, 22 }, anchor = Anchor { left = 12, top = 20, right = 12 };
607 typeExpected = directory;
608 browseDialog = fileDialog;
611 bool NotifyModified(PathBox pathBox)
614 strcpy(installDir, destBox.path);
615 install.disabled = false;
616 for(c = 0; components[c].name; c++)
618 SetAvailableSpace(components[c], installDir);
625 label1, this, $"Browse", altB, size = { 83, 24 }, position = { 360, 16 };
627 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
629 strcpy(fileDialog.filePath, installDir);
630 StripLastDirectory(installDir, fileDialog.currentDirectory);
631 if(fileDialog.Modal())
633 strcpy(installDir, fileDialog.filePath);
634 destBox.contents = installDir;
635 // TOCHECK: Should setting contents call NotifyModified?
636 destBox.NotifyModified(destBox.master, destBox);
643 this, multiLine = true,
644 opacity = 0, borderStyle = none, inactive = true, size = { 136, 53 }, position = { 14, 96 }, noSelect = true,
645 contents = $"Select the default root\n"
646 "folder where to install\n"
651 this, opacity = 0, borderStyle = none, inactive = true, size = { 136, 132 }, position = { 14, 152 }, noSelect = true,
653 contents = $"Select the optional\n"
654 "components you wish\n"
656 "You may customize the\n"
657 "install location for each\n"
658 "of them, or use the default\n"
659 "based on the main\n"
660 "destination folder."
664 this, opacity = 0, borderStyle = none, inactive = true, size = { 136, 53 }, position = { 14, 280 }, noSelect = true,
666 contents = $"Select icons to install, file\n"
667 "associations, and system\n"
668 "environment modifications:"
670 Label totalSpaceLabel
672 this, position = { 18, 352 }, text = $"Space Required: "
674 Label totalSpaceValue
676 this, position = { 100, 352 }, text = "0 mb"
680 inactive = true, noSelect = true,
681 multiLine = true, parent = label3, text = "editBox1", opacity = 0, borderStyle = none, size = Size { 350, 35 }, anchor = Anchor { horz = 111, vert = 13 },
682 contents = $"Choose in which folder to install the Ecere SDK, which features\n"
683 "of the SDK to install, as well as where to install program icons."
685 Label label2 { parent = this, text = buildString, position = { 16, 392 }, font = { "Tahoma", 10, true }, disabled = true, opacity = 0, background = activeBorder };
688 image = BitmapResource { ":ecere.png", alphaBlend = true }, filter = true, parent = label3, text = "picture1", anchor = Anchor { left = 16, top = 4 };
689 cursor = ((GuiApplication)__thisModule).GetCursor(hand);
691 bool OnLeftButtonDown(int x, int y, Modifiers mods)
693 ShellOpen("http://www.ecere.com/");
697 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 } };
698 DataField componentField { "CheckItem", width = 160, header = $"Component" };
699 DataField locationField { "char *", width = 108, header = $"Destination Folder", editable = true };
700 DataField reqField { "FileSize", width = 70, header = $"Req. Space", alignment = right };
701 DataField avField { "FileSize64", width = 70, header = $"Avail. Space", alignment = right };
702 DataField optionField { "CheckItem" };
704 void SetAvailableSpace(Component component, char * parentPath)
706 char path[MAX_LOCATION];
710 strcpy(path, parentPath);
711 PathCat(path, component.installPath);
713 if(component.subComponents)
714 for(c = 0; component.subComponents[c].name; c++)
715 SetAvailableSpace(component.subComponents[c], path);
717 while(!FileExists(path) && path[0])
718 StripLastDirectory(path, path);
721 GetFreeSpace(path, &size);
722 component.row.SetData(avField, size);
723 if(!size) install.disabled = true;
726 FileSize ComputeSize(char * path)
729 FileAttribs attribs = FileExists(path);
730 if(attribs.isDirectory)
732 FileListing listing { path };
733 while(listing.Find())
735 if(listing.stats.attribs.isDirectory)
736 size += ComputeSize(listing.path);
738 size += listing.stats.size;
742 FileGetSize(path, &size);
746 void AddComponent(Component component, Component parent, char * parentPath)
748 DataRow row = (parent != null) ? parent.row.AddRow() : componentsBox.AddRow();
750 FileSize64 avSize = 0;
751 char path[MAX_LOCATION];
754 strcpy(path, parentPath);
755 if(component.defInstallPath)
756 PathCat(path, component.defInstallPath);
757 component.parent = parent;
759 row.SetData(null, CheckItem { component.name, component, (component.arch == bits32 && osIS64bit) } );
761 if(component.defInstallPath)
763 strcpy(component.installPath, component.defInstallPath);
764 ChangeCh(component.installPath, '/', DIR_SEP);
765 row.SetData(locationField, component.installPath);
768 if(component.mandatory)
770 if(component.arch != bits32 || !osIS64bit || component == &coreSDK[gdb32])
771 componentsBox.SetDisabled(row, true);
773 component.selected = false;
775 else if(component.arch == bits32 && osIS64bit)
776 component.selected = false;
778 componentsBox.SetCheck(row, component.selected);
780 if(component.dataPath)
782 char path[MAX_LOCATION];
784 PathCat(path, component.dataPath);
785 component.size = ComputeSize(path);
787 if(component.subComponents)
790 for(c = 0; component.subComponents[c].name; c++)
792 Component * sub = &component.subComponents[c];
793 if(sub->available && (osIS64bit || sub->arch == bits32 || sub->arch == none))
795 AddComponent(sub, component, path);
796 size += sub->requiredSize;
799 sub->selected = false;
803 component.requiredSize = component.selected ? (size + component.size) : 0;
804 if(component.requiredSize)
805 row.SetData(reqField, component.requiredSize);
807 while(!FileExists(path) && path[0])
808 StripLastDirectory(path, path);
811 GetFreeSpace(path, &avSize);
814 row.SetData(avField, avSize);
815 row.collapsed = true;
818 void AddOption(InstallOption option, InstallOption parent)
820 DataRow row = option.row = (parent != null) ? parent.row.AddRow() : optionsBox.AddRow();
821 row.SetData(null, CheckItem { option.name, option } );
822 optionsBox.SetCheck(row, option.selected);
823 if(option.subOptions)
826 for(c = 0; option.subOptions[c].name; c++)
828 AddOption(option.subOptions[c], option);
831 row.collapsed = true;
837 char programFilesDir[MAX_LOCATION];
838 char appData[MAX_LOCATION];
839 char homeDrive[MAX_LOCATION];
840 char winDir[MAX_LOCATION];
842 GetEnvironment("APPDATA", appData, sizeof(appData));
843 GetEnvironment("HOMEDRIVE", homeDrive, sizeof(homeDrive));
844 GetEnvironment("windir", winDir, sizeof(winDir));
846 componentsBox.AddField(componentField);
847 componentsBox.AddField(locationField);
848 componentsBox.AddField(reqField);
849 componentsBox.AddField(avField);
851 optionsBox.AddField(optionField);
853 if(GetEnvironment("ProgramFiles", programFilesDir, MAX_LOCATION))
855 char * x86 = strstr(programFilesDir, " (x86)");
858 strcpy(installDir32, programFilesDir);
862 PathCat(installDir, "Ecere SDK");
863 strcpy(installDir, programFilesDir);
867 PathCat(installDir, "Ecere SDK");
868 strcpy(installDir, programFilesDir);
871 else if(homeDrive && homeDrive[0])
873 strcpy(installDir, homeDrive);
874 PathCat(installDir, "Ecere SDK");
876 else if(winDir && winDir[0])
878 strcpy(installDir, winDir);
879 PathCat(installDir, "..\\Ecere SDK");
882 strcpy(installDir, "C:\\Ecere SDK");
884 if(appData && appData[0])
886 static char defSamplesPath[MAX_LOCATION];
887 static char defExtrasPath[MAX_LOCATION];
888 strcpy(defSamplesPath, appData);
889 PathCat(defSamplesPath, "Ecere SDK\\Samples");
890 components[samples].defInstallPath = defSamplesPath;
892 strcpy(defExtrasPath, appData);
893 PathCat(defExtrasPath, "Ecere SDK\\extras");
894 additional[extras].defInstallPath = defExtrasPath;
897 destBox.path = installDir;
901 for(c = 0; components[c].name; c++)
902 AddComponent(components[c], null, installDir);
905 // Compute size apart because ToggleCheck will change it
909 for(c = 0; components[c].name; c++)
910 totalSize += components[c].requiredSize;
913 char sizeString[100];
914 PrintSize(sizeString, totalSize, 2);
915 totalSpaceValue.text = sizeString;
917 for(c = 0; options[c].name; c++)
918 AddOption(options[c], null);
927 void OnDrawOverChildren(Surface surface)
929 int tw = label2.size.w;
930 surface.SetForeground(Color { 128, 128, 128 });
931 surface.HLine(label2.position.x + tw + 6, 620, 400);
932 surface.SetForeground(white);
933 surface.HLine(label2.position.x + tw + 6, 621, 401);
934 surface.PutPixel(621, 400);
939 parent = this, opacity = 0, borderStyle = deep, size = Size { 644, 93 }, anchor = Anchor { left = -8, top = -8 };
943 class InstallProgress : Window
945 text = $"Ecere Software Development Kit Setup - v0.44.08 \"Ryōan-ji\" 64 Bit Edition";
946 background = activeBorder;
951 // size = Size { 640, 480 };
952 clientSize = { 636, 456 };
953 //clientSize = { 796, 576 };
954 icon = { ":icon.png" };
956 Picture back { image = BitmapResource { ":ryoanji-progress.png" }, parent = this, position = { 0, 0 } };
957 Label installing { this, position = { 32, 160 } };
958 ProgressBar progressBar { parent = this, size = Size { 588, 24 }, anchor = Anchor { left = 24, top = 184 } };
961 parent = this, text = $"Install", disabled = true, isDefault = true, size = Size { 75, 23 }, anchor = Anchor { left = 432, top = 416 };
963 NotifyClicked = ButtonCloseDialog
967 this, text = $"Cancel", hotKey = altX, size = Size { 75, 23 }, anchor = Anchor { left = 544, top = 416 };
969 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
977 inactive = true, noSelect = true,
978 multiLine = true, parent = label3, opacity = 0, borderStyle = none, size = Size { 350, 35 }, anchor = Anchor { horz = 111, vert = 13 },
979 contents = $"Please wait while the Ecere Software Development Kit is being installed."
981 Label label2 { parent = this, text = buildString, position = { 16, 392 }, font = { "Tahoma", 10, true }, disabled = true, opacity = 0, background = activeBorder };
984 image = BitmapResource { ":ecere.png", alphaBlend = true }, filter = true, parent = label3, anchor = Anchor { left = 16, top = 4 };
985 cursor = ((GuiApplication)__thisModule).GetCursor(hand);
987 bool OnLeftButtonDown(int x, int y, Modifiers mods)
989 ShellOpen("http://www.ecere.com/");
993 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 } };
995 void OnDrawOverChildren(Surface surface)
997 int tw = label2.size.w;
998 surface.SetForeground(Color { 128, 128, 128 });
999 surface.HLine(label2.position.x + tw + 6, 620, 400);
1000 surface.SetForeground(white);
1001 surface.HLine(label2.position.x + tw + 6, 621, 401);
1002 surface.PutPixel(621, 400);
1007 parent = this, opacity = 0, borderStyle = deep, size = Size { 644, 93 }, anchor = Anchor { left = -8, top = -8 };
1009 InstallThread thread
1014 Installer installer {};
1015 InstallProgress installProgress { autoCreate = false };
1017 static void AddPath(char * sysPaths[200], int sysCount, char * paths[200], int * count, char * oldPath, char * userPath, char * path)
1021 for(p = 0; p<sysCount; p++)
1022 if(!fstrcmp(sysPaths[p], path))
1027 for(p = 0; !found && p<*count; p++)
1028 if(!fstrcmp(paths[p], path))
1038 strcat(userPath, ";");
1039 start = paths[(*count)-1] + strlen(paths[(*count)-1])+1;
1044 strcpy(start, path);
1045 *(start + strlen(path)) = '\0';
1046 paths[(*count)++] = start;
1048 strcat(userPath, path);
1053 void ModifyPath(char * systemPath, char * userPath)
1055 char oldPath[8192], * paths[200], * sysPaths[200];
1056 int count, sysCount;
1058 strcpy(oldPath, userPath);
1059 count = TokenizeWith(oldPath, sizeof(paths) / sizeof(char *), paths, ";", false);
1060 sysCount = TokenizeWith(systemPath, sizeof(sysPaths) / sizeof(char *), sysPaths, ";", false);
1064 for(c = 0; coreSDK[c].name; c++)
1067 char path[MAX_LOCATION];
1068 if(!coreSDK[c].selected) continue;
1069 coreSDK[c].GetFullPath(path);
1070 if(c != ide && c != runtime && c != ec &&
1071 c != ide32 && c != runtime32 && c != ec32)
1073 if(!pathOptions[PathOptions::AddMinGWPaths].available || !pathOptions[PathOptions::AddMinGWPaths].selected)
1075 PathCat(path, "bin");
1077 else if(!pathOptions[PathOptions::AddECEREPaths].selected) continue;
1079 AddPath(sysPaths, sysCount, paths, &count, oldPath, userPath, path);
1085 for(c = 0; c <= cpp; c++)
1088 char path[MAX_LOCATION];
1089 if(!additional[c].selected || c == vanilla || c == vanilla32 || c == extras) continue;
1090 if((c != eda && c != eda32 && c != upx) && (!pathOptions[PathOptions::AddMinGWPaths].available || !pathOptions[PathOptions::AddMinGWPaths].selected))
1092 additional[c].GetFullPath(path);
1093 if(c != eda && c != eda32 && c != upx)
1094 PathCat(path, "bin");
1095 AddPath(sysPaths, sysCount, paths, &count, oldPath, userPath, path);
1100 void AssociateExtension(char * extension, char * description, char *name, char * action, char * path)
1106 RegCreateKeyEx(HKEY_CLASSES_ROOT, extension, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1107 RegSetValueEx(key, null, 0, REG_SZ, name, (uint)strlen(name)+1);
1110 RegCreateKeyEx(HKEY_CLASSES_ROOT, name, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1111 RegSetValueEx(key, null, 0, REG_SZ, description, (uint)strlen(description)+1);
1114 sprintf(keyName, "%s\\shell", extension);
1115 RegCreateKeyEx(HKEY_CLASSES_ROOT, keyName, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1116 RegSetValueEx(key, null, 0, REG_SZ, action, (uint)strlen(action)+1);
1119 sprintf(keyName, "%s\\shell\\%s", name, action);
1120 RegCreateKeyEx(HKEY_CLASSES_ROOT, keyName, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1123 sprintf(keyName, "%s\\shell\\%s\\command", name, action);
1124 RegCreateKeyEx(HKEY_CLASSES_ROOT, keyName, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1126 sprintf(keyName, path);
1127 strcat(keyName, " \"%L\"");
1129 uint16 wKeyName[2048];
1130 UTF8toUTF16Buffer(keyName, wKeyName, sizeof(wKeyName) / sizeof(uint16));
1131 RegSetValueExW(key, null, 0, REG_SZ, (byte *)wKeyName, (uint)(wcslen(wKeyName) + 1)*sizeof(uint16));
1136 class InstallThread : Thread
1141 ((GuiApplication)__thisModule).Lock();
1142 installProgress.progressBar.range = totalSize;
1143 for(c = 0; components[c].name && !abortInstall; c++)
1144 components[c].Install(installDir, installDir32);
1147 installProgress.progressBar.range = 0;
1148 installProgress.finish.Destroy(0);
1149 installProgress.cancel.text = $"Close";
1150 installProgress.cancel.isDefault = true;
1151 installProgress.cancel.disabled = false;
1152 installProgress.cancel.NotifyClicked = Window::ButtonCloseDialog;
1153 installProgress.installing.text = $"Installation Cancelled.";
1154 installProgress.title.text = $"Installation Cancelled";
1155 installProgress.titleInfo.contents = $"The installation was not completed.";
1159 char idePath[MAX_LOCATION];
1160 char userProfile[MAX_LOCATION];
1163 IDESettings settings = null; // Don't instantiate yet so we can pick up old settings
1165 IDESettingsContainer settingsContainer
1168 dataOwner = &settings;
1169 dataClass = class(IDESettings);
1171 CompilerConfig compiler;
1172 installProgress.installing.text = $"Configuring Ecere IDE...";
1173 ((GuiApplication)__thisModule).Unlock();
1174 ((GuiApplication)__thisModule).SignalEvent();
1176 settingsContainer.Load();
1177 compiler = settings.GetCompilerConfig(defaultCompilerName);
1182 for(c = 0; coreSDK[c].name; c++)
1184 char path[MAX_LOCATION];
1185 if(!coreSDK[c].selected || !coreSDK[c].available) continue;
1187 coreSDK[c].GetFullPath(path);
1188 if(c != ide && c != runtime && c != ec &&
1189 c != ide32 && c != runtime32 && c != ec32)
1190 PathCat(path, "bin");
1191 MakeSlashPath(path);
1192 if((c == ide && osIS64bit) || (c == ide32 && !osIS64bit))
1194 coreSDK[c].GetFullPath(idePath);
1195 PathCat(idePath, "ide.exe");
1198 if(c == runtime || c == runtime32)
1200 if(!compiler.libraryDirs.Find(path))
1201 compiler.libraryDirs.Add(CopyString(path));
1208 for(c = 0; c <= cpp; c++)
1210 char path[MAX_LOCATION];
1211 if(c == extras || !additional[c].selected || !additional[c].available) continue;
1212 additional[c].GetFullPath(path);
1213 if(c != upx && c != eda && c != vanilla && c != eda32 && c != vanilla32)
1214 PathCat(path, "bin");
1215 MakeSlashPath(path);
1216 if(c == vanilla || c == vanilla32)
1218 if(!compiler.libraryDirs.Find(path))
1219 compiler.libraryDirs.Add(CopyString(path));
1223 if(!compiler.executableDirs.Find(path))
1224 compiler.executableDirs.Add(CopyString(path));
1231 char path[MAX_LOCATION] = "";
1233 if(components[samples].selected)
1234 components[samples].GetFullPath(path);
1236 components[coreSDK].GetFullPath(path);
1238 if(!settings.ideProjectFileDialogLocation[0])
1239 settings.ideProjectFileDialogLocation = path;
1240 if(!settings.ideFileDialogLocation[0])
1241 settings.ideFileDialogLocation = path;
1243 if(documentation[apiRef].selected)
1245 documentation[apiRef].GetFullPath(path);
1246 if(!settings.docDir[0])
1247 settings.docDir = path;
1251 settingsContainer.Save();
1252 delete settingsContainer;
1255 // Set up Uninstaller
1256 ((GuiApplication)__thisModule).Lock();
1257 installProgress.installing.text = $"Registering uninstaller...";
1258 ((GuiApplication)__thisModule).Unlock();
1259 ((GuiApplication)__thisModule).SignalEvent();
1264 char * displayName = "Ecere SDK 0.44";
1265 char uninstaller[MAX_LOCATION];
1266 bool nomodify = true;
1268 strcpy(uninstaller, installDir);
1269 PathCat(uninstaller, "uninstall_ecere.exe");
1271 RegCreateKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Ecere SDK", 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1273 RegSetValueEx(key, "DisplayName", 0, REG_SZ, displayName, (uint)strlen(displayName)+1);
1274 RegSetValueEx(key, "UninstallString", 0, REG_SZ, uninstaller, (uint)strlen(uninstaller)+1);
1275 RegSetValueEx(key, "DisplayIcon", 0, REG_SZ, idePath, (uint)strlen(idePath)+1);
1276 //RegSetValueEx(key, "NoModify", 0, REG_DWORD, (byte *)&nomodify, sizeof(nomodify));
1277 //RegSetValueEx(key, "NoRepair", 0, REG_DWORD, (byte *)&nomodify, sizeof(nomodify));
1282 if(pathOptions[PathOptions::AddECEREPaths].selected
1284 || pathOptions[PathOptions::AddMinGWPaths].selected
1288 HKEY userKey = null, systemKey = null;
1290 char userPath[8192] = "";
1291 char systemPath[8192] = "";
1292 uint16 wUserPath[8192];
1293 uint16 wSystemPath[8192];
1298 ((GuiApplication)__thisModule).Lock();
1299 installProgress.installing.text = "Registering paths...";
1300 ((GuiApplication)__thisModule).Unlock();
1301 ((GuiApplication)__thisModule).SignalEvent();
1303 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", 0, KEY_QUERY_VALUE, &systemKey) == ERROR_SUCCESS)
1305 size = sizeof(wSystemPath);
1306 RegQueryValueExW(systemKey, L"path", null, null, (byte *)wSystemPath, &size);
1307 UTF16toUTF8Buffer(wSystemPath, systemPath, sizeof(systemPath));
1310 RegCreateKeyEx(HKEY_CURRENT_USER, "Environment", 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &userKey, &status);
1311 if(status == REG_OPENED_EXISTING_KEY)
1313 size = sizeof(wUserPath);
1314 RegQueryValueExW(userKey, L"path", null, null, (byte *)wUserPath, &size);
1315 UTF16toUTF8Buffer(wUserPath, userPath, sizeof(userPath));
1317 ModifyPath(systemPath, userPath);
1318 UTF8toUTF16Buffer(userPath, wUserPath, sizeof(wUserPath) / sizeof(uint16));
1319 RegSetValueExW(userKey, L"path", 0, REG_EXPAND_SZ, (byte *)wUserPath, (uint)(wcslen(wUserPath)+1) * 2);
1320 RegCloseKey(userKey);
1321 RegCloseKey(systemKey);
1323 SendMessageTimeout (HWND_BROADCAST, WM_SETTINGCHANGE, 0, (int)"Environment", SMTO_NORMAL, 1000, NULL);
1326 // Install Program Group Icons
1327 GetEnvironment("USERPROFILE", userProfile, sizeof(userProfile));
1329 if(options[IconOptions::StartMenuIcon].selected)
1331 char destPath[MAX_LOCATION];
1332 char startMenuPath[MAX_LOCATION] = "";
1335 ((GuiApplication)__thisModule).Lock();
1336 installProgress.installing.text = $"Installing Start Menu Icons...";
1337 ((GuiApplication)__thisModule).Unlock();
1338 ((GuiApplication)__thisModule).SignalEvent();
1340 strcpy(destPath, userProfile);
1342 if(RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", 0, KEY_ALL_ACCESS, &key) == ERROR_SUCCESS)
1344 uint16 wStartMenuPath[2048];
1345 uint size = sizeof(wStartMenuPath);
1346 // RegQueryValueEx(key, "Start Menu", null, null, startMenuPath, &size);
1347 RegQueryValueExW(key, L"Programs", null, null, (byte *)wStartMenuPath, &size);
1348 UTF16toUTF8Buffer(wStartMenuPath, startMenuPath, sizeof(startMenuPath));
1351 if(!startMenuPath[0] && userProfile[0])
1353 strcpy(startMenuPath, userProfile);
1354 PathCat(startMenuPath, "Start Menu\\Programs");
1357 if(startMenuPath[0])
1359 strcpy(destPath, startMenuPath);
1360 PathCat(destPath, "Ecere SDK");
1363 strcpy(destPath, startMenuPath);
1364 PathCat(destPath, "Ecere SDK\\Ecere IDE.lnk");
1365 CreateLink(idePath, destPath, null); //"Ecere IDE");
1366 if(components[samples].selected)
1368 char samplesPath[MAX_LOCATION] = "";
1369 components[samples].GetFullPath(samplesPath);
1371 strcpy(destPath, startMenuPath);
1372 PathCat(destPath, "Ecere SDK\\Sample Projects.lnk");
1373 CreateLink(samplesPath, destPath, null);//"Sample Projects");
1375 if(components[documentation].selected && documentation[ecereBook].selected)
1377 char docPath[MAX_LOCATION] = "";
1378 documentation[ecereBook].GetFullPath(docPath);
1379 PathCat(docPath, "Ecere Tao of Programming [work in progress].pdf");
1382 char tao[MAX_LOCATION] ;
1383 documentation[ecereBook].GetFullPath(tao);
1384 PathCat(tao, "tao.pdf");
1385 RenameFile(tao, docPath);
1388 strcpy(destPath, startMenuPath);
1389 PathCat(destPath, "Ecere SDK\\The Ecere Tao of Programming.lnk");
1390 CreateLink(docPath, destPath, null);
1395 // Install Desktop Icon
1396 if(options[IconOptions::DesktopIcon].selected)
1399 char desktopPath[MAX_LOCATION];
1401 if(RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", 0, KEY_ALL_ACCESS, &key) == ERROR_SUCCESS)
1403 uint16 wDesktopPath[MAX_LOCATION];
1404 uint size = sizeof(wDesktopPath);
1405 RegQueryValueExW(key, L"Desktop", null, null, (byte *)wDesktopPath, &size);
1406 UTF16toUTF8Buffer(wDesktopPath, desktopPath, sizeof(desktopPath));
1409 if(!desktopPath[0] && userProfile[0])
1411 strcpy(desktopPath, userProfile);
1412 PathCat(desktopPath, "Desktop");
1417 PathCat(desktopPath, "Ecere IDE.lnk");
1419 ((GuiApplication)__thisModule).Lock();
1420 installProgress.installing.text = $"Installing Desktop Icon...";
1421 ((GuiApplication)__thisModule).Unlock();
1422 ((GuiApplication)__thisModule).SignalEvent();
1424 CreateLink(idePath, desktopPath, null);//"Ecere IDE");
1428 // Install QuickLaunch Icon
1429 if(options[IconOptions::QuickLaunchIcon].selected)
1431 char appData[MAX_LOCATION];
1432 GetEnvironment("APPDATA", appData, sizeof(appData));
1436 char destPath[MAX_LOCATION];
1438 ((GuiApplication)__thisModule).Lock();
1439 installProgress.installing.text = $"Installing Quicklaunch Icon...";
1440 ((GuiApplication)__thisModule).Unlock();
1441 ((GuiApplication)__thisModule).SignalEvent();
1443 strcpy(destPath, appData);
1444 PathCat(destPath, "Microsoft\\Internet Explorer\\Quick Launch\\Ecere IDE.lnk");
1446 CreateLink(idePath, destPath, null);//"Ecere IDE");
1450 // Register File Types
1451 if(associateOptions[AssociateOptions::AssociateEPJ].selected ||
1452 associateOptions[AssociateOptions::AssociateEC].selected ||
1453 associateOptions[AssociateOptions::AssociateC].selected ||
1454 associateOptions[AssociateOptions::AssociateCPP].selected ||
1455 associateOptions[AssociateOptions::AssociateTXT].selected ||
1456 associateOptions[AssociateOptions::Associate3DS].selected ||
1457 associateOptions[AssociateOptions::AssociateIMG].selected)
1459 ((GuiApplication)__thisModule).Lock();
1460 installProgress.installing.text = $"Resgistering File Types...";
1461 ((GuiApplication)__thisModule).Unlock();
1462 ((GuiApplication)__thisModule).SignalEvent();
1464 if(associateOptions[AssociateOptions::AssociateEPJ].selected)
1466 AssociateExtension(".epj", "Ecere IDE Project", "epj_file", "Open", idePath);
1468 if(associateOptions[AssociateOptions::AssociateEC].selected)
1470 AssociateExtension(".ec", "eC Source File", "ec_file", "Open", idePath);
1471 AssociateExtension(".eh", "eC Header File", "eh_file", "Open", idePath);
1473 if(associateOptions[AssociateOptions::AssociateC].selected)
1475 AssociateExtension(".c", "C Source File", "c_file", "Open", idePath);
1476 AssociateExtension(".h", "C Header File", "h_file", "Open", idePath);
1478 if(associateOptions[AssociateOptions::AssociateCPP].selected)
1480 AssociateExtension(".cpp", "C++ Source File", "cpp_file", "Open", idePath);
1481 AssociateExtension(".cc", "C++ Source File", "cpp_file", "Open", idePath);
1482 AssociateExtension(".cxx", "C++ Source File", "cpp_file", "Open", idePath);
1483 AssociateExtension(".chh", "C++ Header File", "chh_file", "Open", idePath);
1484 AssociateExtension(".hh", "C++ Header File", "chh_file", "Open", idePath);
1485 AssociateExtension(".hxx", "C++ Header File", "chh_file", "Open", idePath);
1487 if(associateOptions[AssociateOptions::AssociateTXT].selected)
1489 AssociateExtension(".txt", "Text File", "txt_file", "Open", idePath);
1491 if(associateOptions[AssociateOptions::Associate3DS].selected)
1493 AssociateExtension(".3ds", "3D Studio Model", "3ds_file", "View", idePath);
1495 if(associateOptions[AssociateOptions::AssociateIMG].selected)
1497 AssociateExtension(".bmp", "BMP Image", "bmp_file", "View", idePath);
1498 AssociateExtension(".pcx", "PCX Image", "pcx_file", "View", idePath);
1499 AssociateExtension(".png", "PNG Image", "png_file", "View", idePath);
1500 AssociateExtension(".jpg", "JPEG Image", "jpg_file", "View", idePath);
1501 AssociateExtension(".jpeg", "JPEG Image", "jpg_file", "View", idePath);
1502 AssociateExtension(".gif", "GIF Image", "gif_file", "View", idePath);
1505 ((GuiApplication)__thisModule).Lock();
1507 installProgress.cancel.Destroy(0);
1508 installProgress.finish.text = $"Finish";
1509 installProgress.finish.disabled = false;
1510 installProgress.finish.Activate();
1511 installProgress.installing.text = $"Installation Complete.";
1512 installProgress.title.text = $"Installation Complete";
1513 installProgress.titleInfo.contents = $"Thank you for using the Ecere SDK.";
1515 ((GuiApplication)__thisModule).Unlock();