/******************************************************************************* * pvmisc.cpp * * This module implements miscellaneous routines for the Windows build of POV. * * Author: Christopher J. Cason. * * --------------------------------------------------------------------------- * Persistence of Vision Ray Tracer ('POV-Ray') version 3.7. * Copyright 1991-2013 Persistence of Vision Raytracer Pty. Ltd. * * POV-Ray is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * POV-Ray is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . * --------------------------------------------------------------------------- * POV-Ray is based on the popular DKB raytracer version 2.12. * DKBTrace was originally written by David K. Buck. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins. * --------------------------------------------------------------------------- * $File: //depot/public/povray/3.x/windows/pvmisc.cpp $ * $Revision: #1 $ * $Change: 6069 $ * $DateTime: 2013/11/06 11:59:40 $ * $Author: chrisc $ *******************************************************************************/ #define POVWIN_FILE #define _WIN32_IE COMMONCTRL_VERSION #include #include #include #include #include #include #include #include #include #include #include #include #include // #include #include #include "pvengine.h" #include "pvedit.h" #include "resource.h" #include "pvguiext.h" #include "povray.h" #ifdef RTR_SUPPORT #include "rtrsupport.h" #endif // this must be the last file included #include "syspovdebug.h" namespace povwin { extern int alert_sound ; extern int message_xchar ; extern int message_ychar ; extern int renderwin_left ; extern int renderwin_top ; extern int io_restrictions ; extern int bandWidths [8] ; extern int screen_origin_x ; extern int screen_origin_y ; extern int virtual_screen_width ; extern int virtual_screen_height ; extern int renderwin_transparency ; extern char message_font_name [256] ; extern char ourPath [_MAX_PATH] ; extern char helpPath [_MAX_PATH] ; extern char lastRenderName [_MAX_PATH] ; extern char lastBitmapName [_MAX_PATH] ; extern char lastRenderPath [_MAX_PATH] ; extern char lastBitmapPath [_MAX_PATH] ; extern char lastQueuePath [_MAX_PATH] ; extern char lastSecondaryIniFilePath [_MAX_PATH] ; extern char SecondaryRenderIniFileName [_MAX_PATH] ; extern char SecondaryRenderIniFileSection [64] ; extern char background_file [_MAX_PATH ] ; extern char tool_commands [MAX_TOOLCMD] [MAX_TOOLCMDTEXT] ; extern char tool_help [MAX_TOOLCMD] [MAX_TOOLHELPTEXT] ; extern char source_file_name [_MAX_PATH] ; extern char ToolIniFileName [_MAX_PATH] ; extern char command_line [_MAX_PATH * 3] ; extern char queued_files [MAX_QUEUE] [_MAX_PATH] ; extern char RegionStr [] ; extern char engineHelpPath [_MAX_PATH] ; extern char render_complete_sound [_MAX_PATH] ; extern char parse_error_sound [_MAX_PATH] ; extern char render_error_sound [_MAX_PATH] ; extern char FontPath [_MAX_PATH] ; extern void *CurrentEditor ; extern bool render_complete_sound_enabled ; extern bool parse_error_sound_enabled ; extern bool render_error_sound_enabled ; extern bool keep_messages ; extern bool alert_on_completion ; extern bool save_settings ; extern bool running_demo ; extern bool fast_scroll ; extern bool MakeRenderwinActive ; extern bool renderwin_destroyed ; extern bool no_shellout_wait ; extern bool tile_background ; extern bool debugging ; extern bool no_palette_warn ; extern bool HideRenderWithMain ; extern bool RenderwinIsChild ; extern bool IsW95UserInterface ; extern bool use_16bit_editor ; extern bool system_noactive ; extern bool IsWin32 ; extern bool one_instance ; extern bool use_toolbar ; extern bool use_tooltips ; extern bool editors_enabled ; extern bool expert_menus ; extern bool drop_to_editor ; extern bool render_auto_close ; extern bool ExtensionsEnabled ; extern bool use_taskbar ; extern bool allow_rw_source ; extern bool no_shell_outs ; extern bool hide_newuser_help ; extern bool IsW98 ; extern bool IsW2k ; extern bool preserve_bitmap ; extern bool check_new_version ; extern bool check_news ; extern bool send_system_info ; extern bool homeInferred ; extern bool AutoAppendPaths ; extern bool PreventSleep; extern unsigned message_font_size ; extern unsigned message_font_weight ; extern unsigned screen_width ; extern unsigned screen_height ; extern unsigned screen_depth ; extern unsigned renderwin_8bits ; extern unsigned auto_render ; extern unsigned queued_file_count ; extern unsigned renderwin_flags ; extern unsigned render_priority ; extern unsigned Duty_Cycle ; extern unsigned on_completion ; extern unsigned window_count ; extern HWND main_window ; extern HWND toolbar_window ; extern HWND toolbar_cmdline ; extern HWND toolbar_combobox ; extern HWND rebar_window ; extern HMENU hMainMenu ; extern HMENU hToolsMenu ; extern COLORREF background_colour ; extern COLORREF text_colours[3] ; extern HH_AKLINK hh_aklink ; extern WINDOWPLACEMENT mainwin_placement ; extern CRITICAL_SECTION critical_section ; #define MAX_DIRSPEC 70 char *WriteDirSpecs [MAX_DIRSPEC] ; char *ReadDirSpecs [MAX_DIRSPEC] ; typedef struct { unsigned id ; bool *varptr ; bool rval ; bool autowrite ; char *section ; char *entry ; bool defval ; } toggle_struct ; toggle_struct toggles [] = { // rval should be true if no special processing is required within handle_main_command // ID VarPtr RVal AutoWrite Section Name DefVal { CM_SAVE_SETTINGS, (bool *) &save_settings, false, true, "General", "SaveSettingsOnExit" , true }, { CM_PRESERVEMESSAGES, (bool *) &keep_messages, true , true, "Messages", "KeepMessages" , false }, { CM_FORCE8BITS, (bool *) &renderwin_8bits, false, true, "RenderWindow", "Use8BitMode" , false }, { CM_RENDERACTIVE, (bool *) &MakeRenderwinActive, true , true, "RenderWindow", "MakeActive" , true }, { CM_RENDERABOVEMAIN, (bool *) &RenderwinIsChild, false, true, "RenderWindow", "KeepAboveMain" , true }, { CM_RENDERHIDE, (bool *) &HideRenderWithMain, true , true, "RenderWindow", "HideWhenMainMinimized" , true }, { CM_ALERT, (bool *) &alert_on_completion, true , true, "Renderer", "AlertOnCompletion" , true }, { CM_AUTORENDER, (bool *) &auto_render, true , true, "Renderer", "AutoRender" , true }, { CM_PREVENTSLEEP, (bool *) &PreventSleep, true , true, "Renderer", "PreventSleep" , true }, { CM_SHELLOUTWAIT, (bool *) &no_shellout_wait, true , true, "Renderer", "NoShelloutWait" , false }, { CM_TILEDBACKGROUND, (bool *) &tile_background, false, true, "General", "TileBackground" , false }, { CM_SYSTEMNOACTIVE, (bool *) &system_noactive, true, true, "Renderer", "SystemNoActive" , false }, { CM_SINGLEINSTANCE, (bool *) &one_instance, false, false, "General", "OneInstance" , true }, { CM_USETOOLBAR, (bool *) &use_toolbar, false, true, "MainWindow", "UseToolbar" , true }, { CM_USETOOLTIPS, (bool *) &use_tooltips, true, true, "MainWindow", "UseTooltips" , true }, { CM_RENDERAUTOCLOSE, (bool *) &render_auto_close, true, true, "RenderWindow", "AutoClose" , false }, { CM_USEEXTENSIONS, (bool *) &ExtensionsEnabled, true, true, "GUIExtensions", "UseExtensions" , true }, { CM_RW_SOURCE, (bool *) &allow_rw_source, true, true, "Scripting", "ReadWriteSourceDir" , true }, { CM_NO_SHELLOUTS, (bool *) &no_shell_outs, true, true, "Scripting", "NoShellOuts" , true }, { CM_HIDENEWUSERHELP, (bool *) &hide_newuser_help, false, true, "General", "HideNewUserHelp" , false }, { CM_PRESERVERENDERBITMAP,(bool *) &preserve_bitmap, true, true, "RenderWindow", "PreserveBitmap" , true }, { CM_CHECKNEWVERSION, (bool *) &check_new_version, true, true, "General", "CheckNewVersion" , true }, { CM_SENDSYSTEMINFO, (bool *) &send_system_info, true, true, "General", "SendSystemInfo" , true }, { -1, (bool *) NULL, false, true, "", "" , false } } ; #ifdef MAP_INI_TO_REGISTRY bool PutHKCU(const char *Section, const char *Name, const char *Value) { char path[1024] = "Software\\" REGKEY "\\" REGVERKEY "\\Windows\\Engine\\"; HKEY hKey ; strcat(path, Section); if (RegCreateKeyEx(HKEY_CURRENT_USER, path, 0, "", REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL) != ERROR_SUCCESS) return (false) ; if (Value != NULL) RegSetValueEx(hKey, Name, 0, REG_SZ, (BYTE *) Value, (DWORD) strlen(Value) + 1) ; else RegDeleteValue(hKey, Name); RegCloseKey(hKey) ; return true; } bool PutHKCU(const char *Section, const char *Name, const string& Value) { return PutHKCU(Section, Name, Value.c_str()); } bool PutHKCU(const char *Section, const char *Name, unsigned Value) { char path[1024] = "Software\\" REGKEY "\\" REGVERKEY "\\Windows\\Engine\\"; HKEY hKey ; strcat(path, Section); if (RegCreateKeyEx (HKEY_CURRENT_USER, path, 0, "", REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL) != ERROR_SUCCESS) return (false) ; RegSetValueEx(hKey, Name, 0, REG_DWORD, (BYTE *) &Value, sizeof(DWORD)) ; RegCloseKey(hKey); return true; } unsigned GetHKCU(const char *Section, const char *Name, unsigned DefaultValue) { char path[1024] = "Software\\" REGKEY "\\" REGVERKEY "\\Windows\\Engine\\"; HKEY key; DWORD type; DWORD len = sizeof(DWORD); DWORD result = DefaultValue; strcat(path, Section); if (RegOpenKeyEx(HKEY_CURRENT_USER, path, 0, KEY_READ, &key) == ERROR_SUCCESS) { if (RegQueryValueEx(key, Name, 0, &type, (BYTE *) &result, &len) != ERROR_SUCCESS || type != REG_DWORD) result = DefaultValue; RegCloseKey(key) ; } return result; } size_t GetHKCU(const char *Section, const char *Name, const char *DefaultValue, char *Buffer, unsigned MaxLength) { char path[1024] = "Software\\" REGKEY "\\" REGVERKEY "\\Windows\\Engine\\"; HKEY key; DWORD type; DWORD len = MaxLength; strcat(path, Section); if (RegOpenKeyEx(HKEY_CURRENT_USER, path, 0, KEY_READ, &key) == ERROR_SUCCESS) { if (RegQueryValueEx(key, Name, 0, &type, (BYTE *) Buffer, &len) != ERROR_SUCCESS || type != REG_SZ) strcpy(Buffer, DefaultValue); RegCloseKey(key) ; } else strcpy(Buffer, DefaultValue); return strlen(Buffer); } #else // MAP_INI_TO_REGISTRY bool PutHKCU(const char *section, const char *entry, const char *value) { WritePrivateProfileString(section, entry, value, EngineIniFileName); return true; } bool PutHKCU(const char *section, const char *entry, const string& value) { WritePrivateProfileString(section, entry, value.c_str(), EngineIniFileName); return true; } bool PutHKCU(const char *section, const char *entry, unsigned int value) { char str [32] ; sprintf (str, "%u", value) ; WritePrivateProfileString(section, entry, str, EngineIniFileName); return true; } unsigned GetHKCU(const char *section, const char *name, unsigned defval) { return GetPrivateProfileInt(section, name, defval, EngineIniFileName); } size_t GetHKCU(const char *section, const char *name, const char *defval, char *buffer, unsigned maxlen) { return GetPrivateProfileString(section, name, defval, buffer, maxlen, EngineIniFileName); } #endif bool GetDontShowAgain (const char *Name) { return (GetHKCU("DontShowAgain", Name, 0) != 0) ; } void PutDontShowAgain (const char *Name, bool dontShow) { PutHKCU("DontShowAgain", Name, dontShow ? 1 : 0) ; } bool process_toggles (WPARAM wParam) { toggle_struct *t ; for (t = toggles ; t->id != -1 ; t++) { if (t->id == LOWORD (wParam)) { *t->varptr = !*t->varptr ; PVCheckMenuItem (t->id, *t->varptr ? MF_CHECKED : MF_UNCHECKED) ; return (t->rval) ; } } return (false) ; } void set_toggles (void) { toggle_struct *t ; for (t = toggles ; (int) t->id != -1 ; t++) PVCheckMenuItem (t->id, *t->varptr ? MF_CHECKED : MF_UNCHECKED) ; } void read_toggles (void) { toggle_struct *t ; for (t = toggles ; (int) t->id != -1 ; t++) *t->varptr = (GetHKCU(t->section, t->entry, t->defval) != 0); } void write_toggles (void) { toggle_struct *t ; for (t = toggles ; (int) t->id != -1 ; t++) if (t->autowrite) PutHKCU(t->section, t->entry, *t->varptr) ; } bool fileExists (const char *filename) { struct stat statBuf ; if ((stat (filename, &statBuf) != 0) || ((statBuf.st_mode & _S_IFREG) == 0)) return (false) ; return (true) ; } bool dirExists (const char *filename) { char str[_MAX_PATH]; struct stat statBuf ; if (filename[0] == '\0') return false; if (hasTrailingPathSeparator(filename)) { strcpy(str, filename); str[strlen(filename) - 1] = '\0'; return stat(str, &statBuf) == 0 && (statBuf.st_mode & _S_IFDIR) != 0; } return stat(filename, &statBuf) == 0 && (statBuf.st_mode & _S_IFDIR) != 0; } void read_dir_restriction (char *iniSection, char **store) { int i ; char EntryName [16] ; char str1 [_MAX_PATH] ; char str2 [_MAX_PATH] ; char *s ; // we can afford to be generous with respect to errors here - if an entry // doesn't make it into the list, it won't reduce security, since the system // defaults to denying access. for (i = 0 ; i < MAX_DIRSPEC - 1 ; i++) { sprintf (EntryName, "%d", i) ; GetHKCU(iniSection, EntryName, "", str1, sizeof (str1)) ; if (str1 [0] == '\0') continue ; if (_strnicmp (str1, "%INSTALLDIR%", 12) == 0) { strcpy (str2, str1) ; strcpy (str1, BinariesPath) ; trimTrailingPathSeparator (str1) ; strcat (str1, str2 + 12) ; } else if (_strnicmp (str1, "%PROFILEDIR%", 12) == 0) { strcpy (str2, str1) ; strcpy (str1, DocumentsPath) ; trimTrailingPathSeparator (str1) ; strcat (str1, str2 + 12) ; } else if (_strnicmp (str1, "%FONTDIR%", 9) == 0) { strcpy (str2, str1 + 9) ; strcpy (str1, FontPath) ; trimTrailingPathSeparator (str1) ; strcat (str1, str2) ; } appendPathSeparator (str1) ; if (GetFullPathName (str1, sizeof (str2), str2, &s) == 0) continue ; _strupr (str2) ; if ((s = (char *) malloc (strlen (str2) + 1)) == NULL) continue ; strcpy (s, str2) ; *store++ = s ; } } void read_dir_restrictions (void) { io_restrictions = GetHKCU("Scripting", "IO Restrictions", 1) ; PVCheckMenuRadioItem (CM_IO_NO_RESTRICTIONS, CM_IO_RESTRICT_READWRITE, io_restrictions + CM_IO_NO_RESTRICTIONS) ; read_dir_restriction ("Permitted Input Paths", ReadDirSpecs) ; read_dir_restriction ("Permitted Output Paths", WriteDirSpecs) ; } void clear_dir_restrictions (void) { for (char **dirspec = ReadDirSpecs ; *dirspec != NULL ; dirspec++) free (*dirspec) ; for (char **dirspec = WriteDirSpecs ; *dirspec != NULL ; dirspec++) free (*dirspec) ; memset (ReadDirSpecs, 0, sizeof (ReadDirSpecs)) ; memset (WriteDirSpecs, 0, sizeof (WriteDirSpecs)) ; } void read_INI_settings (void) { char str [_MAX_PATH] ; mainwin_placement.showCmd = GetHKCU("MainWindow", "ShowCmd", SW_SHOWNORMAL) ; mainwin_placement.ptMinPosition.x = GetHKCU("MainWindow", "MinPositionX", -1) ; mainwin_placement.ptMinPosition.y = GetHKCU("MainWindow", "MinPositionY", -1) ; mainwin_placement.ptMaxPosition.x = GetHKCU("MainWindow", "MaxPositionX", -1) ; mainwin_placement.ptMaxPosition.y = GetHKCU("MainWindow", "MaxPositionY", -1) ; mainwin_placement.rcNormalPosition.left = GetHKCU("MainWindow", "NormalPositionLeft", 128) ; mainwin_placement.rcNormalPosition.top = GetHKCU("MainWindow", "NormalPositionTop", 128) ; mainwin_placement.rcNormalPosition.right = GetHKCU("MainWindow", "NormalPositionRight", -1) ; mainwin_placement.rcNormalPosition.bottom = GetHKCU("MainWindow", "NormalPositionBottom", -1) ; renderwin_left = GetHKCU("RenderWindow", "NormalPositionX", 256) ; renderwin_top = GetHKCU("RenderWindow", "NormalPositionY", 256) ; renderwin_flags = GetHKCU("RenderWindow", "Flags", 0) ; renderwin_transparency = GetHKCU("RenderWindow", "Transparency", 128) ; GetHKCU("Messages", "Font", "Lucida Console", message_font_name, sizeof (message_font_name)) ; message_font_size = GetHKCU("Messages", "FontSize", 8) ; message_font_weight = GetHKCU("Messages", "FontWeight", FW_NORMAL) ; fast_scroll = (GetHKCU("Messages", "FastScroll", false) != 0); alert_sound = GetHKCU("Renderer", "AlertSound", MB_ICONASTERISK) ; render_priority = GetHKCU("Renderer", "Priority", CM_RENDERPRIORITY_NORMAL) ; Duty_Cycle = GetHKCU("Renderer", "DutyCycle", 9) ; on_completion = GetHKCU("Renderer", "Completion", CM_COMPLETION_NOTHING) ; no_palette_warn = (GetHKCU("General", "NoPaletteWarn", false) != 0); GetHKCU("General", "SecondaryINISection", "[512x384, No AA]", SecondaryRenderIniFileSection, sizeof (SecondaryRenderIniFileSection)) ; // some paths change between betas; since the INI file is not created or removed // by the installer, it may refer to old paths. fix this here and further on by // checking to make sure the path exists. GetHKCU("General", "LastRenderName", "", lastRenderName, sizeof (lastRenderName)) ; GetHKCU("General", "LastRenderPath", "", lastRenderPath, sizeof (lastRenderPath)) ; if (!dirExists(lastRenderPath)) lastRenderPath[0] = '\0'; GetHKCU("General", "LastQueuePath", "", lastQueuePath, sizeof (lastQueuePath)) ; if (!dirExists(lastQueuePath)) lastQueuePath[0] = '\0'; GetHKCU("General", "LastBitmapName", "*.bmp", lastBitmapName, sizeof (lastBitmapName)) ; if (strchr(lastBitmapName, '*') == NULL && !fileExists(lastBitmapName)) strcpy(lastBitmapName, "*.bmp"); GetHKCU("General", "LastBitmapPath", "", lastBitmapPath, sizeof (lastBitmapPath)) ; if (!dirExists(lastBitmapPath)) lastBitmapPath[0] = '\0'; sprintf (str, "%sini", DocumentsPath) ; GetHKCU("General", "LastINIPath", str, lastSecondaryIniFilePath, sizeof (lastSecondaryIniFilePath)) ; if (!dirExists (lastSecondaryIniFilePath)) strcpy (lastSecondaryIniFilePath, str) ; sprintf (str, "%sini\\quickres.ini", DocumentsPath) ; GetHKCU("General", "SecondaryINIFile", str, SecondaryRenderIniFileName, sizeof (SecondaryRenderIniFileName)) ; if (!fileExists (SecondaryRenderIniFileName)) strcpy (SecondaryRenderIniFileName, str) ; GetHKCU("General", "BackgroundFile", screen_depth > 8 ? "0" : "1", background_file, sizeof (background_file)) ; text_colours[0] = GetHKCU("General", "TextColour", RGB (255, 255, 255)) ; text_colours[1] = GetHKCU("General", "WarningColour", RGB (255, 255, 0)) ; text_colours[2] = GetHKCU("General", "ErrorColour", RGB (0, 255, 255)) ; background_colour = GetHKCU("General", "BackgroundColour", RGB (31, 0, 63)) ; if (!debugging) debugging = (GetHKCU("General", "Debug", 0) != 0); drop_to_editor = (GetHKCU("General", "DropToEditor", 1) != 0); editors_enabled = (GetHKCU("General", "UseEditors", 1) != 0); for (int i = 0 ; i < 6 ; i++) { sprintf (str, "Band%dWidth", i) ; bandWidths [i] = GetHKCU("ToolBar", str, 0) ; } read_toggles() ; read_dir_restrictions() ; sprintf (str, "%ssounds\\Render Finished.wav", BinariesPath) ; GetHKCU("Sounds", "RenderCompleteSound", str, render_complete_sound, _MAX_PATH) ; if (!fileExists(render_complete_sound)) strcpy(render_complete_sound, str); sprintf (str, "%ssounds\\Parse Error.wav", BinariesPath) ; GetHKCU("Sounds", "ParseErrorSound", str, parse_error_sound, _MAX_PATH) ; if (!fileExists(parse_error_sound)) strcpy(parse_error_sound, str); sprintf (str, "%ssounds\\Render Cancelled.wav", BinariesPath) ; GetHKCU("Sounds", "RenderErrorSound", str, render_error_sound, _MAX_PATH) ; if (!fileExists(render_error_sound)) strcpy(render_error_sound, str); render_complete_sound_enabled = GetHKCU("Sounds", "RenderCompleteSoundEnabled", TRUE) != 0 ; parse_error_sound_enabled = GetHKCU("Sounds", "ParseErrorSoundEnabled", TRUE) != 0 ; render_error_sound_enabled = GetHKCU("Sounds", "RenderErrorSoundEnabled", TRUE) != 0 ; AutoAppendPaths = GetHKCU("General", "AutoAppendPaths", TRUE) != 0 ; #ifdef RTR_SUPPORT GetHKCU("RTR", "VideoSource", "", str, sizeof (str)) ; SetVideoSourceName(str); #endif } void write_INI_settings (bool noreset) { char *s ; char str [sizeof (command_line)] ; REBARBANDINFO rebarInfo ; if (noreset) strcpy (str, command_line) ; if (RegionStr [0] != '\0') { if ((s = strstr (command_line, RegionStr)) != NULL) strcpy (s, s + strlen (RegionStr)) ; else if ((s = strstr (command_line, RegionStr + 1)) != NULL) strcpy (s, s + strlen (RegionStr) - 1) ; if (!noreset) SendMessage (toolbar_cmdline, WM_SETTEXT, 0, (LPARAM) command_line) ; } PutHKCU("General", "CommandLine", command_line) ; if (noreset) strcpy (command_line, str) ; rebarInfo.cbSize = sizeof (REBARBANDINFO) ; rebarInfo.fMask = RBBIM_SIZE ; for (int i = 0 ; i < 6 ; i++) { sprintf (str, "Band%dWidth", i) ; // under XP64 the SendMessage() call returns TRUE but the cx value is not altered. // so we detect that and avoid writing the data unless the problem is fixed. rebarInfo.cx = 0x12345678 ; if (SendMessage (rebar_window, RB_GETBANDINFO, i, (LPARAM) (LPREBARBANDINFO) &rebarInfo)) if (rebarInfo.cx != 0x12345678) PutHKCU("ToolBar", str, rebarInfo.cx) ; } PutHKCU("MainWindow", "ShowCmd", mainwin_placement.showCmd) ; PutHKCU("MainWindow", "NormalPositionLeft", mainwin_placement.rcNormalPosition.left) ; PutHKCU("MainWindow", "NormalPositionTop", mainwin_placement.rcNormalPosition.top) ; PutHKCU("MainWindow", "NormalPositionRight", mainwin_placement.rcNormalPosition.right) ; PutHKCU("MainWindow", "NormalPositionBottom", mainwin_placement.rcNormalPosition.bottom) ; PutHKCU("RenderWindow", "NormalPositionX", renderwin_left) ; PutHKCU("RenderWindow", "NormalPositionY", renderwin_top) ; PutHKCU("RenderWindow", "Flags", renderwin_flags) ; PutHKCU("RenderWindow", "Transparency", renderwin_transparency) ; PutHKCU("Messages", "FontSize", message_font_size) ; PutHKCU("Messages", "FontWeight", message_font_weight) ; PutHKCU("Renderer", "AlertSound", alert_sound) ; PutHKCU("Renderer", "Completion", on_completion) ; PutHKCU("Renderer", "Priority", render_priority) ; PutHKCU("Renderer", "DutyCycle", Duty_Cycle) ; PutHKCU("General", "TextColour", text_colours[0]) ; PutHKCU("General", "WarningColour", text_colours[1]) ; PutHKCU("General", "ErrorColour", text_colours[2]) ; PutHKCU("General", "BackgroundColour", background_colour) ; PutHKCU("General", "DropToEditor", drop_to_editor) ; PutHKCU("Messages", "Font", message_font_name) ; PutHKCU("General", "LastRenderName", lastRenderName) ; PutHKCU("General", "LastRenderPath", lastRenderPath) ; PutHKCU("General", "LastQueuePath", lastQueuePath) ; PutHKCU("General", "SecondaryINISection", SecondaryRenderIniFileSection) ; PutHKCU("General", VERSIONVAL, POV_RAY_VERSION COMPILER_VER "." PVENGINE_VER) ; PutHKCU("Sounds", "RenderCompleteSoundEnabled", render_complete_sound_enabled) ; PutHKCU("Sounds", "ParseErrorSoundEnabled", parse_error_sound_enabled) ; PutHKCU("Sounds", "RenderErrorSoundEnabled", render_error_sound_enabled) ; PutHKCU("General", "LastBitmapName", lastBitmapName) ; PutHKCU("General", "LastBitmapPath", lastBitmapPath) ; PutHKCU("General", "LastINIPath", lastSecondaryIniFilePath) ; PutHKCU("General", "SecondaryINIFile", SecondaryRenderIniFileName) ; PutHKCU("General", "BackgroundFile", background_file) ; PutHKCU("Sounds", "RenderCompleteSound", render_complete_sound) ; PutHKCU("Sounds", "ParseErrorSound", parse_error_sound) ; PutHKCU("Sounds", "RenderErrorSound", render_error_sound) ; write_toggles () ; #ifdef RTR_SUPPORT PutHKCU("RTR", "VideoSource", GetVideoSourceName().c_str()) ; #endif } #ifdef BOOST_REGEX_NO_LONGER_BROKEN // can't use regex right now: on exit from povwin, the atexit handler registered by // boost calls something in the regex library that causes an exception. this happens // even if all we ever did was declare a single regex (e.g. 'boost::regex foo("bar");') // and never use it. // // TODO: add replace regex to alter paths from old to new where appropriate void cloneOldIni(string oldPath, string newPath) { bool keep = false; smatch what; string sectionName; string line; const regex section("^\\[\\s*([^\\]]*)\\s*\\].*"); const regex entry("^([^=\\s]+)\\s*=.*"); const regex skipEntries("runcount|itsabouttime|commandline|lastinipath|secondaryinifile|version|backgroundfile|.*sound"); const regex copiedSections("general|editor|tipoftheday|toolbar|mainwindow|renderwindow|messages|renderer|lastrender|dontshowagain|sounds"); map hadSection; line = oldPath + "ini\\pvengine.ini"; std::ifstream inF(line.c_str()); if (inF.bad()) return; line = newPath + "ini\\pvengine.ini"; ofstream outF(line.c_str()); if (outF.bad()) return; outF << "[Permitted Input Paths]" << endl; outF << "1=%INSTALLDIR%" << endl; outF << "2=%PROFILEDIR%" << endl; outF << "3=%FONTDIR%" << endl; outF << endl << "[Permitted Output Paths]" << endl; outF << "1=%PROFILEDIR%\\Insert Menu" << endl; // some INI files I've seen have duplicate sections. during the copy we filter out any such. while (getline(inF, line)) { trim(line); string str(to_lower_copy(line)); if (str.empty()) continue; if (regex_match(str, what, section)) { keep = !hadSection[sectionName = what[1]] && regex_match(sectionName, copiedSections); hadSection[sectionName] = true; if (keep) outF << endl << line << endl; continue; } if (keep && regex_match(str, what, entry) && regex_match(static_cast(what[1]), skipEntries)) continue; if (keep) outF << line << endl; } inF.close(); outF << "[GUIExtensions]" << endl << endl; outF << "[Scripting]" << endl << endl; outF << "[RTR]" << endl << endl; outF << "[Info]" << endl << endl; outF.close(); } #else void cloneOldIni(string oldPath, string newPath) { bool keep = false; size_t pos; string sectionName; string line; string oldPathLC = boost::to_lower_copy(oldPath); const string keepSections("general^toolbar^mainwindow^renderwindow^renderer^lastrender^dontshowagain^editor^"); const string skipEntries("runcount^itsabouttime^commandline^version^backgroundcolour^textcolour^" "tilebackground^bigsplash^savesettingsonexit^"); std::ifstream inF; map hadSection; if (oldPath != "") { line = oldPath + "ini\\pvengine.ini"; inF.open(line.c_str()); if (inF.bad()) return; } line = newPath + "ini\\pvengine.ini"; ofstream outF(line.c_str()); if (outF.bad()) { if (oldPath != "") inF.close(); return; } outF << "[Permitted Input Paths]" << endl; outF << "1=%INSTALLDIR%" << endl; outF << "2=%PROFILEDIR%" << endl; outF << "3=%FONTDIR%" << endl; outF << endl << "[Permitted Output Paths]" << endl; outF << "1=%PROFILEDIR%\\Insert Menu" << endl; outF << endl << "[GUIExtensions]" << endl << endl; outF << "[Scripting]" << endl << endl; outF << "[RTR]" << endl << endl; outF << "[Info]" << endl << endl; if (oldPath == "") { outF.close(); return; } // some INI files I've seen have duplicate sections. during the copy we filter out any such. while (getline(inF, line)) { boost::trim(line); string str(boost::to_lower_copy(line)); if (str.empty()) continue; if (str[0] == '[' && (pos = str.find(']')) != string::npos) { sectionName = boost::trim_copy(str.substr(1, pos - 1)); keep = !hadSection[sectionName] && keepSections.find(sectionName + "^") != string::npos; hadSection[sectionName] = true; if (keep) outF << endl << line << endl; continue; } if (keep) { // any INI entry that refers to the previous install dir is ignored if (str.find(oldPathLC) != string::npos) continue; if ((pos = str.find('=')) != string::npos) { str.erase(pos); boost::trim(str); // skip other entries we don't want to copy into the new install's INI if (skipEntries.find(str + "^") != string::npos) continue; } outF << line << endl; } } inF.close(); outF << endl; outF.close(); } #endif void GetRelativeClientRect (HWND hParent, HWND hChild, RECT *rect) { POINT *points = (POINT *) rect ; GetWindowRect (hChild, rect) ; ScreenToClient (hParent, points++) ; ScreenToClient (hParent, points) ; } void CenterWindowRelative (HWND hRelativeTo, HWND hTarget, bool bRepaint, bool checkBorders) { int difference ; int width ; int height ; int x ; int y ; int twidth ; int theight ; RECT relativeToRect ; RECT targetRect ; if (hRelativeTo != NULL && IsWindowVisible (hRelativeTo)) { WINDOWPLACEMENT wp ; wp.length = sizeof (WINDOWPLACEMENT) ; GetWindowPlacement (hRelativeTo, &wp) ; if (wp.showCmd == SW_SHOWMINIMIZED) hRelativeTo = GetDesktopWindow () ; } else hRelativeTo = GetDesktopWindow () ; GetWindowRect (hRelativeTo, &relativeToRect) ; GetWindowRect (hTarget, &targetRect) ; width = targetRect.right - targetRect.left ; height = targetRect.bottom - targetRect.top ; difference = relativeToRect.right - relativeToRect.left - width ; x = relativeToRect.left + difference / 2 ; difference = relativeToRect.bottom - relativeToRect.top - height ; y = relativeToRect.top + difference / 2 ; MoveWindow (hTarget, x, y, width, height, bRepaint && !checkBorders) ; if (checkBorders) { GetWindowRect (hTarget, &targetRect) ; if (targetRect.left < screen_origin_x) OffsetRect (&targetRect, screen_origin_x - targetRect.left, 0) ; if (targetRect.top < screen_origin_y) OffsetRect (&targetRect, 0, screen_origin_y - targetRect.top) ; if (targetRect.right > virtual_screen_width + screen_origin_x) OffsetRect (&targetRect, -(targetRect.right - (virtual_screen_width + screen_origin_x)), 0) ; if (targetRect.bottom > virtual_screen_height + screen_origin_y) OffsetRect (&targetRect, 0, -(targetRect.bottom - (virtual_screen_height + screen_origin_y))) ; twidth = targetRect.right - targetRect.left ; theight = targetRect.bottom - targetRect.top ; MoveWindow (hTarget, targetRect.left, targetRect.top, twidth, theight, bRepaint) ; } } void FitWindowInWindow (HWND hRelativeTo, HWND hTarget) { int rwidth ; int rheight ; int twidth ; int theight ; int x ; int y ; RECT relativeToRect ; RECT targetRect ; GetWindowRect (hTarget, &targetRect) ; if (hRelativeTo == NULL) { if (targetRect.right > virtual_screen_width + screen_origin_x) OffsetRect (&targetRect, -(targetRect.right - (virtual_screen_width + screen_origin_x)), 0) ; if (targetRect.bottom > virtual_screen_height + screen_origin_y) OffsetRect (&targetRect, 0, -(targetRect.bottom - (virtual_screen_height + screen_origin_y))) ; if (targetRect.left < screen_origin_x) OffsetRect (&targetRect, screen_origin_x - targetRect.left, 0) ; if (targetRect.top < screen_origin_y) OffsetRect (&targetRect, 0, screen_origin_y - targetRect.top) ; twidth = targetRect.right - targetRect.left ; theight = targetRect.bottom - targetRect.top ; MoveWindow (hTarget, targetRect.left, targetRect.top, twidth, theight, true) ; return ; } // if window is not visible GetWindowRect() is not reliable. if (!IsWindowVisible (hRelativeTo)) hRelativeTo = GetDesktopWindow () ; GetWindowRect (hRelativeTo, &relativeToRect) ; twidth = targetRect.right - targetRect.left ; theight = targetRect.bottom - targetRect.top ; rwidth = relativeToRect.right - relativeToRect.left ; rheight = relativeToRect.bottom - relativeToRect.top ; x = targetRect.left ; y = targetRect.top ; if (twidth > rwidth) twidth = rwidth ; if (theight > rheight) theight = rheight ; if (x < relativeToRect.left) x = relativeToRect.left ; if (y < relativeToRect.top) y = relativeToRect.top ; if (x + twidth > relativeToRect.right) x = relativeToRect.right - twidth ; if (y + theight > relativeToRect.bottom) y = relativeToRect.bottom - theight ; MoveWindow (hTarget, x, y, twidth, theight, true) ; } void CenterOffset (HWND win, int id, int offx, int offy, int offw, int offh) { int x ; int y ; int w ; int h ; RECT R ; HWND dlg = GetDlgItem (win, id) ; POINT P ; if (dlg) { GetWindowRect (dlg, &R) ; P.x = R.left ; P.y = R.top ; ScreenToClient (win, &P) ; x = P.x ; y = P.y ; w = R.right - R.left ; h = R.bottom - R.top ; SetWindowPos (dlg, NULL, x + offx, y + offy, w + offw, h + offh, SWP_NOZORDER) ; } } void SetupExplorerDialog (HWND win) { int dx ; int dy ; RECT winPos ; win = GetParent (win) ; GetWindowRect (win, &winPos) ; dx = screen_width * 2 / 3 - (winPos.right - winPos.left) ; dy = screen_height * 2 / 3 - (winPos.bottom - winPos.top) ; SetWindowPos (win, NULL, 0, 0, screen_width * 2 / 3, screen_height * 2 / 3, SWP_NOZORDER | SWP_NOACTIVATE) ; CenterWindowRelative (main_window, win, true, true) ; FitWindowInWindow (NULL, win) ; CenterOffset (win, 1091, 0, 0, 0, 0) ; CenterOffset (win, 1137, 0, 0, 0, 0) ; CenterOffset (win, 1088, 0, 0, 0, 0) ; CenterOffset (win, 1120, 0, 0, dx, dy) ; CenterOffset (win, 1090, 0, dy, 0, 0) ; CenterOffset (win, 1152, 0, dy, dx, 0) ; CenterOffset (win, 1089, 0, dy, 0, 0) ; CenterOffset (win, 1136, 0, dy, dx, 0) ; CenterOffset (win, 1040, 0, dy, 0, 0) ; CenterOffset (win, 1, dx , dy, 0, 0) ; CenterOffset (win, 2, dx , dy, 0, 0) ; CenterOffset (win, 1038, dx , dy, 0, 0) ; } FileType get_file_type (const char *filename) { char ext [_MAX_EXT] ; splitfn (filename, NULL, NULL, ext) ; _strupr (ext) ; if (strcmp (ext, ".POV") == 0) return (filePOV) ; else if (strcmp (ext, ".INC") == 0) return (filePOV) ; else if (strcmp (ext, ".MCR") == 0) return (filePOV) ; else if (strcmp (ext, ".MAC") == 0) return (filePOV) ; else if (strcmp (ext, ".INI") == 0) return (fileINI) ; else if (strcmp (ext, ".PPM") == 0) return (filePPM) ; else if (strcmp (ext, ".PGM") == 0) return (filePGM) ; else if (strcmp (ext, ".PBM") == 0) return (filePBM) ; else if (strcmp (ext, ".PNG") == 0) return (filePNG) ; else if (strcmp (ext, ".GIF") == 0) return (fileGIF) ; else if (strcmp (ext, ".BMP") == 0) return (fileBMP) ; else if (strcmp (ext, ".EXR") == 0) return (fileEXR) ; else return (fileUnknown) ; } bool is_non_primary_file(const char *filename) { char ext [_MAX_EXT] ; splitfn (filename, NULL, NULL, ext) ; _strupr (ext) ; if (strcmp (ext, ".POV") == 0) return (false) ; if (strcmp (ext, ".INI") == 0) return (false) ; return true; } char *get_full_name (char *s) { char dir [_MAX_PATH + 1] ; static char str [_MAX_PATH] ; if (*s == 0) return (s) ; splitpath (s, str, NULL) ; if (str [0] == '\0') { #ifdef TIME_WARP // workaround for suspected Win32s bug SetCurrentDirectory (".") ; #endif GetCurrentDirectory (sizeof (dir), dir) ; joinPath (str, dir, s) ; return (str) ; } return (s) ; } void update_menu_for_render (bool rendering) { PVEnableMenuItem (CM_FILERENDER, MF_ENABLED) ; PVEnableMenuItem (CM_STOPRENDER, MF_ENABLED) ; if (rendering) { PVModifyMenu (CM_FILERENDER, MF_STRING, CM_FILERENDER, "&Stop Rendering\tAlt+G") ; PVEnableMenuItem (CM_COMMANDLINE, MF_GRAYED) ; PVEnableMenuItem (CM_RENDERINSERT, MF_GRAYED) ; PVEnableMenuItem (CM_SOURCEFILE, MF_GRAYED) ; PVEnableMenuItem (CM_DEMO, MF_GRAYED) ; PVEnableMenuItem (CM_BENCHMARK, MF_GRAYED) ; PVEnableMenuItem (CM_FORCE8BITS, MF_GRAYED) ; PVEnableMenuItem (CM_RENDERTHREADCOUNT, MF_GRAYED) ; SendMessage (toolbar_window, TB_CHECKBUTTON, (WPARAM) CM_RENDERSLEEP, 0L) ; SendMessage (toolbar_window, TB_HIDEBUTTON, (WPARAM) CM_FILERENDER, MAKELONG (1, 0)) ; SendMessage (toolbar_window, TB_HIDEBUTTON, (WPARAM) CM_STOPRENDER, MAKELONG (0, 0)) ; EnableWindow (toolbar_cmdline, false) ; } else { PVEnableMenuItem (CM_SOURCEFILE, MF_ENABLED) ; PVEnableMenuItem (CM_COMMANDLINE, MF_ENABLED) ; PVEnableMenuItem (CM_RENDERINSERT, MF_ENABLED) ; PVEnableMenuItem (CM_DEMO, MF_ENABLED) ; PVEnableMenuItem (CM_BENCHMARK, MF_ENABLED) ; PVModifyMenu (CM_FILERENDER, MF_STRING, CM_FILERENDER, "&Start Rendering\tAlt+G") ; PVEnableMenuItem (CM_FORCE8BITS, MF_ENABLED) ; PVEnableMenuItem (CM_RENDERSLEEP, MF_GRAYED) ; PVEnableMenuItem (CM_RENDERTHREADCOUNT, MF_ENABLED) ; SendMessage (toolbar_window, TB_CHECKBUTTON, (WPARAM) CM_RENDERSLEEP, 0L) ; SendMessage (toolbar_window, TB_HIDEBUTTON, (WPARAM) CM_FILERENDER, MAKELONG (0, 0)) ; SendMessage (toolbar_window, TB_HIDEBUTTON, (WPARAM) CM_STOPRENDER, MAKELONG (1, 0)) ; EnableWindow (toolbar_cmdline, true) ; } DrawMenuBar (main_window) ; } void update_queue_status (bool write_files) { int i ; char str [64] ; if (queued_file_count == 0) { PVModifyMenu (CM_CLEARQUEUE, MF_STRING, CM_CLEARQUEUE, "C&lear Queue (no entries)") ; PVEnableMenuItem (CM_CLEARQUEUE, MF_GRAYED) ; } else { sprintf (str, "C&lear Queue (%d %s)", queued_file_count, queued_file_count == 1 ? "entry" : "entries") ; PVModifyMenu (CM_CLEARQUEUE, MF_STRING, CM_CLEARQUEUE, str) ; PVEnableMenuItem (CM_CLEARQUEUE, queued_file_count ? MF_ENABLED : MF_GRAYED) ; } if (write_files) { PutHKCU("FileQueue", "QueueCount", queued_file_count) ; for (i = 0 ; i < MAX_QUEUE ; i++) { sprintf (str, "QueuedFile%d", i) ; PutHKCU("FileQueue", str, i < queued_file_count ? queued_files [i] : NULL) ; } } } void resize_listbox_dialog (HWND hDlg, int idLb, int chars) { int difference ; HWND hLb ; HWND hBtn ; RECT lbRect ; RECT btnRect ; RECT dlgRect ; hLb = GetDlgItem (hDlg, idLb) ; hBtn = GetDlgItem (hDlg, IDOK) ; GetRelativeClientRect (hDlg, hLb, &lbRect) ; GetRelativeClientRect (hDlg, hBtn, &btnRect) ; GetWindowRect (hDlg, &dlgRect) ; difference = message_xchar * (chars + 2) - (lbRect.right - lbRect.left) ; lbRect.right += difference ; MoveWindow (hLb, lbRect.left, lbRect.top, lbRect.right - lbRect.left, lbRect.bottom - lbRect.top, true) ; btnRect.left += difference / 2 ; btnRect.right += difference / 2 ; MoveWindow (hBtn, btnRect.left, btnRect.top, btnRect.right - btnRect.left, btnRect.bottom - btnRect.top, true) ; dlgRect.right += difference ; MoveWindow (hDlg, dlgRect.left, dlgRect.top, dlgRect.right - dlgRect.left, dlgRect.bottom - dlgRect.top, true) ; } #if 0 char *save_demo_file (void) { GetTempPath (sizeof (filename), filename) ; strcat (filename, "POVDEMO.$$$") ; if ((hrsc = FindResource (hInst, MAKEINTRESOURCE (ID_DEMOFILE), RT_RCDATA)) == NULL) { PovMessageBox ("Cannot locate file resource\r\n(internal error)", "Cannot run demo") ; return (NULL) ; } if ((hglobal = LoadResource (hInst, hrsc)) == NULL) { PovMessageBox ("Cannot load file resource", "Cannot run demo") ; return (NULL) ; } if ((s = LockResource (hglobal)) == NULL) { PovMessageBox ("Cannot lock file resource", "Cannot run demo") ; return (NULL) ; } size = SizeofResource (hInst, hrsc) ; if ((outH = _lcreat (filename, 0)) == HFILE_ERROR) { PovMessageBox ("Cannot create temporary file", "Cannot run demo") ; return (NULL) ; } if (_lwrite (outH, s, size) != size) { PovMessageBox ("Cannot write temporary file", "Cannot run demo") ; return (NULL) ; } _lclose (outH) ; } #endif int splitfn (const char *filename, char *path, char *name, char *ext) { char *s ; char str [_MAX_PATH] ; char *fn = strncpy (str, filename, _MAX_PATH) ; str[_MAX_PATH - 1] = '\0'; if (path != NULL) *path = '\0' ; if (name != NULL) *name = '\0' ; if (ext != NULL) *ext = '\0' ; if ((s = findLastPathSeparator(fn)) != NULL) { *s++ = '\0' ; if (path) { strcpy (path, fn) ; strcat (path, "\\"); } fn = s; } if ((s = strrchr (fn, '.')) != NULL) { if (ext) strcpy (ext, s) ; *s = '\0' ; } if (name) strcpy (name, fn) ; return (0) ; } void splitpath (const char *filename, char *path, char *name) { char str [_MAX_PATH] ; splitfn (filename, path, name, str) ; if (name != NULL) strcat (name, str) ; } void load_tool_menu (char *iniFilename) { int i ; int count ; char str [32] ; char entry [256] ; char *s ; memset (tool_commands, 0, sizeof (tool_commands)) ; memset (tool_help, 0, sizeof (tool_help)) ; DeleteMenu (hToolsMenu, 1, MF_BYCOMMAND) ; for (i = 0 ; i < MAX_TOOLCMD ; i++) DeleteMenu (hToolsMenu, CM_FIRSTTOOL + i, MF_BYCOMMAND) ; for (i = count = 0 ; i < MAX_TOOLCMD ; i++) { sprintf (str, "Item%d", i) ; GetPrivateProfileString ("Command", str, "", entry, sizeof (entry) - 1, iniFilename) ; if (strlen (entry) == 0) continue ; s = entry ; while (*s == ' ') s++ ; if (strlen (s) >= MAX_TOOLCMDTEXT) { message_printf ("Tool command %s is too long\n", str) ; s [MAX_TOOLCMDTEXT - 1] = '\0' ; } strcpy (tool_commands [count], s) ; GetPrivateProfileString ("Menu", str, "", entry, sizeof (entry) - 1, iniFilename) ; if (strlen (entry) == 0) { message_printf ("Tool menu entry %s is missing\n", str) ; continue ; } s = entry ; while (*s == ' ') s++ ; if (strlen (s) > 31) { message_printf ("Tool menu entry %s is too long\n", str) ; continue ; } if (count == 0) AppendMenu (hToolsMenu, MF_SEPARATOR, 1, "-") ; AppendMenu (hToolsMenu, MF_STRING, CM_FIRSTTOOL + count, s) ; GetPrivateProfileString ("Help", str, "", entry, sizeof (entry) - 1, iniFilename) ; if (strlen (entry) == 0) { count++ ; continue ; } s = entry ; while (*s == ' ') s++ ; if (strlen (s) >= MAX_TOOLHELPTEXT) { message_printf ("Tool help %s is too long\n", str) ; s [MAX_TOOLHELPTEXT - 1] = '\0' ; } strcpy (tool_help [count++], s) ; } message_printf ("Loaded %d %s into Tool Menu.\n", count, count != 1 ? "tools" : "tool") ; } char *parse_tool_command (char *command) { char *s ; char ExternalStr [512] ; static char str [512] ; str [0] = '\0' ; while (*command == ' ') command++ ; strcpy (ExternalStr, command) ; ExternalParseToolCommand (ExternalStr) ; if (strlen (ExternalStr)) command = ExternalStr ; for (s = str ; *command ; command++) { if (strlen (str) >= sizeof (str) - _MAX_PATH) break ; if (*command == '%') { if (*++command == '%') { *s++ = *command ; continue ; } switch (toupper (*command)) { case 'I' : s += sprintf (s, "%sini\\", DocumentsPath) ; break ; case 'T' : s += sprintf (s, "%s", ToolIniFileName) ; break ; case 'H' : s += sprintf (s, "%s", BinariesPath) ; break ; case 'P' : s += sprintf (s, "%s", DocumentsPath) ; break ; case 'R' : s += joinPath (s, lastRenderPath, lastRenderName) ; break ; case 'S' : s += sprintf (s, "%s", source_file_name) ; break ; case 'N' : s += sprintf (s, "%s", SecondaryRenderIniFileName) ; break ; case 'D' : s += GetHKCU("LastRender", "CurrentDirectory", "", s, _MAX_PATH) ; break ; case '0' : s += GetHKCU("LastRender", "SourceFile", "", s, _MAX_PATH) ; break ; case '1' : s += GetHKCU("LastRender", "OutputFile", "", s, _MAX_PATH) ; break ; case '2' : s += GetHKCU("LastRender", "SceneFile", "", s, _MAX_PATH) ; break ; case '4' : s += GetHKCU("LastRender", "IniOutputFile", "", s, _MAX_PATH) ; break ; } continue ; } if (s == str && isspace (*command)) continue ; *s++ = *command ; } *s = '\0' ; return (str) ; } char *get_elapsed_time (int seconds) { static char str [19] ; str [0] = '\0' ; sprintf (str, "%ud %02uh %02um %02us", seconds / 86400, seconds % 86400 / 3600, seconds % 3600 / 60, seconds % 60) ; return (str) ; } char *clean (char *s) { static char str [_MAX_PATH] ; while (*s == ' ' || *s == '\t' || *s == '\r' || *s == '\n' ) s++ ; s = strncpy (str, s, sizeof (str) - 1) ; if (*s == '\0') return (str) ; for (s += strlen (s) - 1 ; *s == ' ' || *s == '\t' || *s == '\r' || *s == '\n' ; s--) *s = '\0' ; return (str) ; } void extract_ini_sections (char *filename, HWND hwnd) { char str [256] ; char *s1 ; char *s2 ; FILE *inF ; static char inbuf [16384] ; /* ** flush the INI file cache */ SendMessage (hwnd, CB_RESETCONTENT, 0, 0L) ; if ((inF = fopen (filename, "rt")) == NULL) return ; setvbuf (inF, inbuf, _IOFBF, sizeof (inbuf)) ; while (fgets (str, sizeof (str), inF) != NULL) { s1 = clean (str) ; if (*s1 == '[') { if ((s2 = strchr (s1, ']')) != NULL) { *++s2 = '\0' ; SendMessage (hwnd, CB_ADDSTRING, 0, (LPARAM) s1) ; } } } fclose (inF) ; SendMessage (hwnd, CB_SETCURSEL, 0, 0L) ; } int select_combo_item_ex (HWND hwnd, char *s) { int i ; char str [256] ; if ((i = SendMessage (hwnd, CB_GETCOUNT, 0, 0)) < 0) return (i) ; while (i--) { SendMessage (hwnd, CB_GETLBTEXT, i, (LPARAM) str) ; if (strcmp (s, str) == 0) { SendMessage (hwnd, CB_SETCURSEL, i, 0) ; return (i) ; } } return (-1) ; } void extract_ini_sections_ex (char *filename, HWND hwnd) { extract_ini_sections (filename, hwnd) ; } bool PovInvalidateRect (HWND hWnd, CONST RECT *lpRect, bool bErase) { if (hWnd != NULL) return (InvalidateRect (hWnd, lpRect, bErase) != 0) ; return (0) ; } bool TaskBarAddIcon (HWND hwnd, UINT uID, HICON hicon, LPSTR lpszTip) { NOTIFYICONDATA tnid ; memset (&tnid, 0, sizeof (tnid)) ; tnid.cbSize = sizeof(NOTIFYICONDATA) ; tnid.hWnd = hwnd ; tnid.uID = uID ; tnid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP ; tnid.uCallbackMessage = TASKBAR_NOTIFY_MESSAGE ; tnid.hIcon = hicon ; lstrcpyn (tnid.szTip, lpszTip, sizeof(tnid.szTip)) ; return (Shell_NotifyIcon (NIM_ADD, &tnid) != 0) ; } bool TaskBarModifyIcon (HWND hwnd, UINT uID, LPSTR lpszTip) { NOTIFYICONDATA tnid ; memset (&tnid, 0, sizeof (tnid)) ; tnid.cbSize = sizeof(NOTIFYICONDATA) ; tnid.hWnd = hwnd ; tnid.uID = uID ; tnid.uFlags = NIF_TIP ; lstrcpyn (tnid.szTip, lpszTip, sizeof(tnid.szTip)) ; return (Shell_NotifyIcon (NIM_MODIFY, &tnid) != 0) ; } bool TaskBarDeleteIcon (HWND hwnd, UINT uID) { NOTIFYICONDATA tnid ; memset (&tnid, 0, sizeof (tnid)) ; tnid.cbSize = sizeof(NOTIFYICONDATA) ; tnid.hWnd = hwnd ; tnid.uID = uID ; return (Shell_NotifyIcon (NIM_DELETE, &tnid) != 0) ; } bool ShowRestrictionMessage (char *Message, char *Dir) { int i ; char str [8192] ; // the main window code will expect this to be already set up if it gets a WM_HELP hh_aklink.pszKeywords = "I/O Restrictions" ; if (Dir == NULL) { sprintf (str, "%s\nPress the HELP button to learn about I/O Restrictions.", Message) ; MessageBox (main_window, str, "I/O Restriction Activated", MB_ICONERROR | MB_OK | MB_HELP) ; return (false) ; } sprintf (str, "%s\n" "Press OK to grant temporary read/write permission in that directory (and its subdirectories).\n" "Press CANCEL to halt the render.\n\n" "Press the HELP button to learn about I/O Restrictions.", Message) ; if (MessageBox (main_window, str, "I/O Restriction Activated", MB_ICONSTOP | MB_OKCANCEL | MB_HELP | MB_DEFBUTTON2) != IDOK) return (false) ; for (i = 0 ; i < MAX_DIRSPEC - 1 ; i++) if (WriteDirSpecs [i] == NULL) break ; if (i == MAX_DIRSPEC - 1) { MessageBox (main_window, "Ran out of room to store directory grant permission", "I/O Restriction Error", MB_ICONERROR | MB_OK) ; // return true anyhow return (true) ; } WriteDirSpecs [i] = _strdup (Dir) ; return (true) ; } }