pvdialog.cpp
1 /******************************************************************************* 2 * pvdialog.cpp 3 * 4 * This module implements dialog-box routines for the Windows build of POV. 5 * 6 * Author: Christopher J. Cason. 7 * 8 * --------------------------------------------------------------------------- 9 * Persistence of Vision Ray Tracer ('POV-Ray') version 3.7. 10 * Copyright 1991-2013 Persistence of Vision Raytracer Pty. Ltd. 11 * 12 * POV-Ray is free software: you can redistribute it and/or modify 13 * it under the terms of the GNU Affero General Public License as 14 * published by the Free Software Foundation, either version 3 of the 15 * License, or (at your option) any later version. 16 * 17 * POV-Ray is distributed in the hope that it will be useful, 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 * GNU Affero General Public License for more details. 21 * 22 * You should have received a copy of the GNU Affero General Public License 23 * along with this program. If not, see <http://www.gnu.org/licenses/>. 24 * --------------------------------------------------------------------------- 25 * POV-Ray is based on the popular DKB raytracer version 2.12. 26 * DKBTrace was originally written by David K. Buck. 27 * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins. 28 * --------------------------------------------------------------------------- 29 * $File: //depot/public/povray/3.x/windows/pvdialog.cpp $ 30 * $Revision: #1 $ 31 * $Change: 6069 $ 32 * $DateTime: 2013/11/06 11:59:40 $ 33 * $Author: chrisc $ 34 *******************************************************************************/ 35 36 #define POVWIN_FILE 37 #define _WIN32_IE COMMONCTRL_VERSION 38 39 #include <windows.h> 40 #include <commdlg.h> 41 #include <commctrl.h> 42 #include <htmlhelp.h> 43 #include <setjmp.h> 44 #include <string.h> 45 #include "pvengine.h" 46 #include "resource.h" 47 #include "pvedit.h" 48 #include "pvguiext.h" 49 #include "pvdisplay.h" 50 #include "pvdialog.h" 51 52 // this must be the last file included 53 #include "syspovdebug.h" 54 55 namespace povwin 56 { 57 58 bool otaChecked ; 59 const char *otaTitle ; 60 const char *otaText ; 61 const char *otaHelpString ; 62 63 64 extern int listbox_ychar ; 65 extern int tb_combo_sel ; 66 extern char engineHelpPath [_MAX_PATH] ; 67 extern char lastRenderName [_MAX_PATH] ; 68 extern char lastRenderPath [_MAX_PATH] ; 69 extern char lastBitmapPath [_MAX_PATH] ; 70 extern char lastQueuePath [_MAX_PATH] ; 71 extern char lastSecondaryIniFilePath [_MAX_PATH] ; 72 extern char DefaultRenderIniFileName [_MAX_PATH] ; 73 extern char SecondaryRenderIniFileName [_MAX_PATH] ; 74 extern char RegionStr [128] ; 75 extern char TempRegionStr [128] ; 76 extern char command_line [_MAX_PATH * 3] ; 77 extern char old_command_line [_MAX_PATH * 3] ; 78 extern char SecondaryRenderIniFileSection [64] ; 79 extern char source_file_name [_MAX_PATH] ; 80 extern char render_complete_sound [_MAX_PATH] ; 81 extern char parse_error_sound [_MAX_PATH] ; 82 extern char render_error_sound [_MAX_PATH] ; 83 extern char queued_files [MAX_QUEUE] [_MAX_PATH] ; 84 extern bool IsW95UserInterface ; 85 extern bool use_editors; 86 extern bool running_demo ; 87 extern bool render_complete_sound_enabled ; 88 extern bool parse_error_sound_enabled ; 89 extern bool render_error_sound_enabled ; 90 extern HWND render_window ; 91 extern HWND toolbar_window ; 92 extern HWND aux_toolbar_window ; 93 extern HWND window_list [MAX_WINDOWS] ; 94 extern HWND toolbar_combobox ; 95 extern HWND rebar_window ; 96 extern HWND StatusWindow ; 97 extern HWND toolbar_cmdline ; 98 extern HWND tab_window ; 99 extern HWND main_window ; 100 extern HMENU hMainMenu ; 101 extern unsigned screen_width ; 102 extern unsigned screen_height ; 103 extern unsigned renderwin_8bits ; 104 extern unsigned auto_render ; 105 extern unsigned queued_file_count ; 106 extern unsigned ThreadCount ; 107 extern HH_AKLINK hh_aklink ; 108 109 // include prototype here to avoid the need to include commdlg.h in all files 110 extern void init_ofn (OPENFILENAME *ofn, HWND hWnd, char *title, char *name, int maxlen, char *lastPath, char *defaultExt); 111 112 char *GetINIFile (HWND hWnd, char *path) 113 { 114 int result ; 115 OPENFILENAME ofnTemp ; 116 static char name [_MAX_PATH] ; 117 118 validatePath (path) ; 119 init_ofn (&ofnTemp, hWnd, "Choose INI File", name, sizeof (name), path, "ini") ; 120 ofnTemp.lpstrFilter = "INI files (*.ini)\0*.ini\0Text Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0" ; 121 if ((result = GetOpenFileName (&ofnTemp)) != 0) 122 { 123 strcpy (path, name) ; 124 path [ofnTemp.nFileOffset - 1] = '\0' ; 125 } 126 return (result ? name : NULL) ; 127 } 128 129 void AddQueue (HWND hWnd, HWND hlb) 130 { 131 int queue_count ; 132 char name [8192] ; 133 char *s ; 134 char str [_MAX_PATH] ; 135 OPENFILENAME ofnTemp ; 136 137 queue_count = SendMessage (hlb, LB_GETCOUNT, 0, 0) ; 138 if (queue_count >= MAX_QUEUE) 139 { 140 PovMessageBox ("File queue is full", "Cannot add any more files!") ; 141 return ; 142 } 143 strcpy (name, lastRenderName) ; 144 name [strlen (name) + 1] = '\0' ; 145 validatePath (lastQueuePath) ; 146 init_ofn (&ofnTemp, hWnd, "Add to Queue", name, sizeof (name), lastQueuePath, "pov") ; 147 ofnTemp.lpstrFilter = "POV source and INI (*.pov;*.ini)\0*.pov;*.ini\0POV files (*.pov)\0*.pov\0INI files (*.ini)\0*.ini\0All Files (*.*)\0*.*\0" ; 148 ofnTemp.Flags |= OFN_ALLOWMULTISELECT ; 149 if (GetOpenFileName (&ofnTemp) != false) 150 { 151 // convert spaces into NULL's if we're not using the new interface so it works with the below code 152 if (!IsW95UserInterface) 153 for (s = name ; *s ; s++) 154 if (*s == ' ') 155 *s = '\0' ; 156 if (ofnTemp.nFileOffset < strlen (name)) 157 { 158 strcpy (lastQueuePath, name) ; 159 lastQueuePath [ofnTemp.nFileOffset - 1] = '\0' ; 160 SendMessage (hlb, LB_ADDSTRING, 0, (LPARAM) name) ; 161 } 162 else 163 { 164 s = name ; 165 strcpy (lastQueuePath, name) ; 166 for (s += strlen (s) + 1 ; *s ; s += strlen (s) + 1) 167 { 168 if (queue_count++ >= MAX_QUEUE) 169 { 170 PovMessageBox ("File queue is full", "Cannot add any more files!") ; 171 return ; 172 } 173 joinPath (str, lastQueuePath, s) ; 174 _strlwr (str) ; 175 SendMessage (hlb, LB_ADDSTRING, 0, (LPARAM) str) ; 176 } 177 } 178 } 179 } 180 181 char *SelectSound (HWND hWnd, char *currentSound) 182 { 183 int result ; 184 char path [_MAX_PATH] ; 185 static char name [_MAX_PATH] ; 186 OPENFILENAME ofnTemp ; 187 188 splitpath (currentSound, path, name) ; 189 validatePath (path) ; 190 init_ofn (&ofnTemp, hWnd, "Select Sound File", name, sizeof (name), path, "wav") ; 191 ofnTemp.Flags &= ~OFN_HIDEREADONLY ; 192 ofnTemp.lpstrFilter = "Sound Files (*.wav)\0*.wav\0All Files (*.*)\0*.*\0" ; 193 if ((result = GetOpenFileName (&ofnTemp)) != 0) 194 return (name) ; 195 return (NULL) ; 196 } 197 198 SIZE *GetTextExtent (HWND hWnd, LPCSTR text) 199 { 200 int result ; 201 HDC hDC ; 202 HFONT hFont = (HFONT) SendMessage (hWnd, WM_GETFONT, 0, 0) ; 203 static SIZE extent ; 204 205 if (hFont == NULL) 206 return (0) ; 207 hDC = GetDC (hWnd) ; 208 HFONT hOldFont = (HFONT) SelectObject (hDC, hFont); 209 result = GetTextExtentPoint32 (hDC, text, (int) strlen(text), &extent) ; 210 SelectObject (hDC, hOldFont) ; 211 ReleaseDC (hWnd, hDC) ; 212 if (!result) 213 return (0) ; 214 return (&extent) ; 215 } 216 217 int GetTextWidth (HWND hWnd, LPCSTR text) 218 { 219 int width = 0; 220 int result = 0; 221 SIZE extent; 222 HDC hDC ; 223 HFONT hFont = (HFONT) SendMessage (hWnd, WM_GETFONT, 0, 0) ; 224 const char *s; 225 226 if (hFont == NULL) 227 return (0) ; 228 hDC = GetDC (hWnd) ; 229 HFONT hOldFont = (HFONT) SelectObject (hDC, hFont); 230 while (strlen(text) > 0) 231 { 232 if ((s = strchr(text, '\n')) == NULL) 233 s = text + strlen(text) - 1; 234 if ((result = GetTextExtentPoint32 (hDC, text, (int) (s - text), &extent)) == 0) 235 return -1; 236 text = s + 1; 237 if (extent.cx > width) 238 width = extent.cx; 239 } 240 SelectObject (hDC, hOldFont) ; 241 ReleaseDC (hWnd, hDC) ; 242 return width; 243 } 244 245 void NudgeChildWindow (HWND hDlg, int idItem, int pixels) 246 { 247 RECT rect ; 248 HWND hWnd ; 249 250 hWnd = GetDlgItem (hDlg, idItem) ; 251 GetWindowRect (hWnd, &rect) ; 252 ScreenToClient (hDlg, (LPPOINT) &rect) ; 253 SetWindowPos (hWnd, NULL, rect.left + pixels, rect.top, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER) ; 254 } 255 256 INT_PTR CALLBACK PovCommandLineDialogProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) 257 { 258 char *s ; 259 char str [_MAX_PATH * 2] ; 260 char str1 [_MAX_PATH] ; 261 char str2 [_MAX_PATH] ; 262 static char editINIname [_MAX_PATH] ; 263 static char editFilename [_MAX_PATH] ; 264 static char lastIniFilename [_MAX_PATH] ; 265 static bool had_region = false ; 266 static struct stat statbuf1 ; 267 static struct stat statbuf2 ; 268 269 switch (message) 270 { 271 case WM_INITDIALOG : 272 had_region = false ; 273 hh_aklink.pszKeywords = "command-line options" ; 274 if (use_editors) 275 { 276 if ((EditGetFlags () & EDIT_MSG_SELECTED) == 0) 277 { 278 if ((s = EditGetFilename(false)) != NULL) 279 { 280 EnableWindow (GetDlgItem (hDlg, IDC_PRESETSOURCEPATH), false) ; 281 EnableWindow (GetDlgItem (hDlg, IDC_PRESETSOURCENAME), false) ; 282 EnableWindow (GetDlgItem (hDlg, IDC_SOURCEDEFAULT), false) ; 283 EnableWindow (GetDlgItem (hDlg, IDC_BROWSESOURCEFILE), false) ; 284 EnableWindow (GetDlgItem (hDlg, IDC_EDITRENDER), false) ; 285 splitpath (s, lastRenderPath, lastRenderName) ; 286 EnableWindow (GetDlgItem (hDlg, IDC_EDITRENDER), false) ; 287 } 288 } 289 SetDlgItemText (hDlg, IDC_PRESETSOURCEPATH, lastRenderPath) ; 290 SetDlgItemText (hDlg, IDC_PRESETSOURCENAME, lastRenderName) ; 291 } 292 else 293 { 294 SetDlgItemText (hDlg, IDC_PRESETSOURCEPATH, lastRenderPath) ; 295 SetDlgItemText (hDlg, IDC_PRESETSOURCENAME, lastRenderName) ; 296 EnableWindow (GetDlgItem (hDlg, IDC_EDITRENDER), false) ; 297 EnableWindow (GetDlgItem (hDlg, IDC_EDITINI), false) ; 298 } 299 SendDlgItemMessage (hDlg, IDC_PRESETSOURCENAME, EM_LIMITTEXT, 64, 0L) ; 300 SendDlgItemMessage (hDlg, IDC_INIFILENAME, EM_LIMITTEXT, 64, 0L) ; 301 _strupr (SecondaryRenderIniFileName) ; 302 validatePath (lastRenderPath) ; 303 CenterWindowRelative ((HWND) lParam, hDlg, true, true) ; 304 FitWindowInWindow (NULL, hDlg) ; 305 if (strlen (TempRegionStr)) 306 { 307 if (strlen (command_line)) 308 { 309 strcpy (str, command_line) ; 310 strcat (str, TempRegionStr) ; 311 } 312 else 313 strcpy (str, TempRegionStr + 1) ; 314 strcpy (RegionStr, TempRegionStr) ; 315 TempRegionStr [0] = '\0' ; 316 SetDlgItemText (hDlg, IDC_COMMANDLINE, str) ; 317 } 318 else 319 { 320 SetDlgItemText (hDlg, IDC_COMMANDLINE, command_line) ; 321 if (RegionStr [0]) 322 if (strstr (command_line, RegionStr + 1) != NULL) 323 had_region = true ; 324 } 325 if (SecondaryRenderIniFileName [0] != '\0') 326 { 327 if (!hasTrailingPathSeparator(SecondaryRenderIniFileName)) 328 { 329 splitpath (SecondaryRenderIniFileName, str1, str2) ; 330 validatePath (str1) ; 331 strcpy (editINIname, str2) ; 332 SetDlgItemText (hDlg, IDC_INIFILEPATH, str1) ; 333 SetDlgItemText (hDlg, IDC_INIFILENAME, str2) ; 334 extract_ini_sections (SecondaryRenderIniFileName, GetDlgItem (hDlg, IDC_INIFILESECTION)) ; 335 SendMessage (toolbar_combobox, CB_GETLBTEXT, SendMessage (toolbar_combobox, CB_GETCURSEL, 0, 0), (LPARAM) SecondaryRenderIniFileSection) ; 336 SendDlgItemMessage (hDlg, IDC_INIFILESECTION, CB_SELECTSTRING, -1, (LPARAM) SecondaryRenderIniFileSection) ; 337 strcpy (lastIniFilename, SecondaryRenderIniFileName) ; 338 stat (SecondaryRenderIniFileName, &statbuf1) ; 339 } 340 else 341 SetDlgItemText (hDlg, IDC_INIFILEPATH, SecondaryRenderIniFileName) ; 342 } 343 SetFocus (GetDlgItem (hDlg, IDC_COMMANDLINE)) ; 344 return (false) ; 345 346 case WM_CTLCOLORBTN: 347 case WM_CTLCOLORDLG: 348 case WM_CTLCOLOREDIT: 349 case WM_CTLCOLORLISTBOX: 350 case WM_CTLCOLORSCROLLBAR: 351 case WM_CTLCOLORSTATIC: 352 return (DefWindowProc (hDlg, message, wParam, lParam)) ; 353 354 case WM_COMMAND : 355 switch (LOWORD (wParam)) 356 { 357 case IDC_INIFILESECTION : 358 if (HIWORD (wParam) == CBN_SETFOCUS) 359 { 360 stat (lastIniFilename, &statbuf2) ; 361 if (statbuf1.st_atime != statbuf2.st_atime) 362 { 363 statbuf1 = statbuf2 ; 364 GetDlgItemText (hDlg, IDC_INIFILESECTION, str, sizeof (str)) ; 365 extract_ini_sections (lastIniFilename, GetDlgItem (hDlg, IDC_INIFILESECTION)) ; 366 SendDlgItemMessage (hDlg, IDC_INIFILESECTION, CB_SELECTSTRING, -1, (LPARAM) str) ; 367 } 368 return (true) ; 369 } 370 return (false) ; 371 372 case IDC_EDITRENDER : 373 GetDlgItemText (hDlg, IDC_PRESETSOURCEPATH, str1, sizeof (str1)) ; 374 GetDlgItemText (hDlg, IDC_PRESETSOURCENAME, str2, sizeof (str2)) ; 375 validatePath (str1) ; 376 strcat (str1, "\\") ; 377 strcat (str1, str2) ; 378 if (EditOpenFile (str1)) 379 { 380 EndDialog (hDlg, false) ; 381 return (true) ; 382 } 383 return (true) ; 384 385 case IDC_EDITINI : 386 GetDlgItemText (hDlg, IDC_INIFILEPATH, str1, sizeof (str1)) ; 387 GetDlgItemText (hDlg, IDC_INIFILENAME, str2, sizeof (str2)) ; 388 validatePath (str1) ; 389 strcat (str1, "\\") ; 390 strcat (str1, str2) ; 391 if (EditOpenFile (str1)) 392 { 393 EndDialog (hDlg, false) ; 394 return (true) ; 395 } 396 return (true) ; 397 398 case IDC_BROWSEINIFILE : 399 if ((s = GetINIFile (hDlg, lastSecondaryIniFilePath)) != NULL) 400 { 401 _strupr (s) ; 402 splitpath (s, str1, str2) ; 403 validatePath (str1) ; 404 SetDlgItemText (hDlg, IDC_INIFILEPATH, str1) ; 405 SetDlgItemText (hDlg, IDC_INIFILENAME, str2) ; 406 if (strcmp (s, lastIniFilename)) 407 { 408 extract_ini_sections (s, GetDlgItem (hDlg, IDC_INIFILESECTION)) ; 409 strcpy (lastIniFilename, s) ; 410 stat (lastIniFilename, &statbuf1) ; 411 } 412 } 413 return (true) ; 414 415 case IDC_INIFILENAME : 416 if (HIWORD (wParam) == EN_KILLFOCUS) 417 { 418 GetDlgItemText (hDlg, IDC_INIFILEPATH, str1, sizeof (str1)) ; 419 GetDlgItemText (hDlg, IDC_INIFILENAME, str2, sizeof (str2)) ; 420 validatePath (str1) ; 421 joinPath (str, str1, str2) ; 422 if (_stricmp (str, lastIniFilename)) 423 { 424 extract_ini_sections (str, GetDlgItem (hDlg, IDC_INIFILESECTION)) ; 425 strcpy (lastIniFilename, str) ; 426 } 427 return (true) ; 428 } 429 if (HIWORD (wParam) == EN_UPDATE) 430 { 431 GetDlgItemText (hDlg, IDC_INIFILENAME, str, sizeof (str)) ; 432 if (strchr (str, '\\') != NULL) // TODO FIXME - shouldn't we also reject '/' and strings starting drive letter? 433 SetDlgItemText (hDlg, IDC_INIFILENAME, editINIname) ; 434 else 435 strcpy (editINIname, str) ; 436 } 437 return (true) ; 438 439 case IDC_RESETINI : 440 SetDlgItemText (hDlg, IDC_INIFILENAME, "") ; 441 GetDlgItemText (hDlg, IDC_INIFILEPATH, lastIniFilename, sizeof (lastIniFilename)) ; 442 SendMessage (GetDlgItem (hDlg, IDC_INIFILESECTION), CB_RESETCONTENT, 0, 0L) ; 443 return (true) ; 444 445 case IDC_INIDEFAULT : 446 sprintf (str, "%sini", DocumentsPath) ; 447 SetDlgItemText (hDlg, IDC_INIFILEPATH, str) ; 448 SetDlgItemText (hDlg, IDC_INIFILENAME, "quickres.ini") ; 449 SendMessage (hDlg, WM_COMMAND, (EN_KILLFOCUS << 16) | IDC_INIFILENAME, 0L) ; 450 return (true) ; 451 452 case IDC_PRESETSOURCENAME : 453 if (HIWORD (wParam) == EN_UPDATE) 454 { 455 GetDlgItemText (hDlg, IDC_PRESETSOURCENAME, str, sizeof (str)) ; 456 if (strchr (str, '\\') != NULL) // TODO FIXME - shouldn't we also reject '/' and strings starting drive letter? 457 SetDlgItemText (hDlg, IDC_PRESETSOURCENAME, editFilename) ; 458 else 459 strcpy (editFilename, str) ; 460 } 461 return (true) ; 462 463 case IDC_BROWSESOURCEFILE : 464 if ((s = file_open (hDlg)) != NULL) 465 { 466 splitpath (s, str1, str2) ; 467 validatePath (str1) ; 468 SetDlgItemText (hDlg, IDC_PRESETSOURCEPATH, str1) ; 469 SetDlgItemText (hDlg, IDC_PRESETSOURCENAME, str2) ; 470 } 471 return (true) ; 472 473 case IDC_SOURCEDEFAULT : 474 sprintf (str, "%sScenes\\advanced", DocumentsPath) ; 475 SetDlgItemText (hDlg, IDC_PRESETSOURCEPATH, str) ; 476 SetDlgItemText (hDlg, IDC_PRESETSOURCENAME, "Biscuit.pov") ; 477 return (true) ; 478 479 case IDC_SET : 480 case IDC_RENDER : 481 case IDC_RENDERa: // IDC_RENDERa is defined because the render dialog 482 // has 2 render buttons on it, and VC++ complains 483 if (!running_demo) 484 { 485 GetDlgItemText (hDlg, IDC_PRESETSOURCEPATH, lastRenderPath, sizeof (lastRenderPath)) ; 486 GetDlgItemText (hDlg, IDC_PRESETSOURCENAME, lastRenderName, sizeof (lastRenderName)) ; 487 validatePath (lastRenderPath) ; 488 // _strupr (lastRenderPath) ; 489 // _strupr (lastRenderName) ; 490 joinPath (source_file_name, lastRenderPath, lastRenderName) ; 491 } 492 GetDlgItemText (hDlg, IDC_INIFILEPATH, str1, sizeof (str1)) ; 493 GetDlgItemText (hDlg, IDC_INIFILENAME, str2, sizeof (str2)) ; 494 validatePath (str1) ; 495 strcpy (lastSecondaryIniFilePath, str1) ; 496 joinPath (SecondaryRenderIniFileName, str1, str2) ; 497 _strupr (SecondaryRenderIniFileName) ; 498 GetDlgItemText (hDlg, IDC_INIFILESECTION, SecondaryRenderIniFileSection, sizeof (SecondaryRenderIniFileSection)) ; 499 GetDlgItemText (hDlg, IDC_COMMANDLINE, command_line, sizeof (command_line)) ; 500 SendMessage (toolbar_cmdline, WM_SETTEXT, 0, (LPARAM) command_line) ; 501 extract_ini_sections_ex (SecondaryRenderIniFileName, toolbar_combobox) ; 502 SendMessage (toolbar_combobox, CB_ADDSTRING, 0, (LPARAM) "More Resolutions ...") ; 503 tb_combo_sel = select_combo_item_ex (toolbar_combobox, SecondaryRenderIniFileSection) ; 504 if (tb_combo_sel == -1) 505 tb_combo_sel = 0 ; 506 507 // was there a region string on the command line before it was edited ? 508 if (had_region) 509 { 510 // if so, is it still there now, in an unchanged form ? 511 // (we look at RegionStr + 1 since they always start with a space). 512 if (strstr (command_line, RegionStr + 1) == NULL) 513 { 514 // it's not, so we remove the region string. 515 RegionStr [0] = '\0' ; 516 } 517 } 518 519 if (LOWORD (wParam) == IDC_RENDER || LOWORD(wParam) == IDC_RENDERa) 520 { 521 if (EditSaveModified (NULL) == 0) 522 return (true) ; 523 EndDialog (hDlg, true) ; 524 } 525 else 526 EndDialog (hDlg, false) ; 527 return (true) ; 528 529 case IDC_COMMANDHELP : 530 hh_aklink.pszKeywords = "command-line dialog" ; 531 HtmlHelp (NULL, engineHelpPath, HH_KEYWORD_LOOKUP, (DWORD_PTR) &hh_aklink) ; 532 return (true) ; 533 534 case IDCANCEL : 535 EndDialog (hDlg, false) ; 536 return (true) ; 537 } 538 break ; 539 } 540 return (false) ; 541 } 542 543 INT_PTR CALLBACK PovShortCommandLineDialogProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) 544 { 545 static bool had_region = false ; 546 547 switch (message) 548 { 549 case WM_INITDIALOG : 550 had_region = false ; 551 hh_aklink.pszKeywords = "command-line options" ; 552 CenterWindowRelative ((HWND) lParam, hDlg, true, true) ; 553 FitWindowInWindow (NULL, hDlg) ; 554 SetDlgItemText (hDlg, IDC_COMMANDLINE, command_line) ; 555 if (RegionStr [0]) 556 if (strstr (command_line, RegionStr + 1) != NULL) 557 had_region = true ; 558 return (true) ; 559 560 case WM_CTLCOLORBTN: 561 case WM_CTLCOLORDLG: 562 case WM_CTLCOLOREDIT: 563 case WM_CTLCOLORLISTBOX: 564 case WM_CTLCOLORSCROLLBAR: 565 case WM_CTLCOLORSTATIC: 566 return (DefWindowProc (hDlg, message, wParam, lParam)); 567 568 case WM_COMMAND : 569 switch (LOWORD (wParam)) 570 { 571 case IDC_RENDER : 572 case IDC_RENDERa: 573 GetDlgItemText (hDlg, IDC_COMMANDLINE, command_line, sizeof (command_line) - 1) ; 574 SendMessage (toolbar_cmdline, WM_SETTEXT, 0, (LPARAM) command_line) ; 575 576 // was there a region string on the command line before it was edited ? 577 if (had_region) 578 { 579 // if so, is it still there now, in an unchanged form ? 580 // (we look at RegionStr + 1 since they always start with a space). 581 if (strstr (command_line, RegionStr + 1) == NULL) 582 { 583 // it's not, so we remove the region string. 584 RegionStr [0] = '\0' ; 585 } 586 } 587 588 if (LOWORD (wParam) == IDC_RENDER || LOWORD(wParam) == IDC_RENDERa) 589 { 590 if (EditSaveModified (NULL) == 0) 591 return (true) ; 592 EndDialog (hDlg, true) ; 593 } 594 else 595 EndDialog (hDlg, false) ; 596 597 return (true) ; 598 599 case IDCANCEL : 600 EndDialog (hDlg, false) ; 601 return (true) ; 602 } 603 break ; 604 } 605 return (false) ; 606 } 607 608 INT_PTR CALLBACK PovFileQueueDialogProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) 609 { 610 int i ; 611 char str [64] ; 612 HWND hlb ; 613 DRAWITEMSTRUCT *d ; 614 MEASUREITEMSTRUCT *m ; 615 static HBRUSH hbr ; 616 617 switch (message) 618 { 619 case WM_INITDIALOG : 620 hh_aklink.pszKeywords = "File Queue" ; 621 CenterWindowRelative ((HWND) lParam, hDlg, true, true) ; 622 FitWindowInWindow (NULL, hDlg) ; 623 hlb = GetDlgItem (hDlg, IDC_FILEQUEUE) ; 624 hbr = CreateSolidBrush (GetSysColor (COLOR_BTNFACE)) ; 625 for (i = 0 ; i < queued_file_count ; i++) 626 SendMessage (hlb, LB_ADDSTRING, 0, (LPARAM) queued_files [i]) ; 627 sprintf (str, "Queue has %d entr%s", queued_file_count, queued_file_count != 1 ? "ies" : "y") ; 628 SetDlgItemText (hDlg, IDC_QUEUEENTRIES, str) ; 629 CheckDlgButton (hDlg, IDC_RELOADQUEUE, GetHKCU("FileQueue", "ReloadOnStartup", 0)) ; 630 CheckDlgButton (hDlg, IDC_AUTORENDER, auto_render) ; 631 return (true) ; 632 633 case WM_CTLCOLORBTN: 634 case WM_CTLCOLORDLG: 635 case WM_CTLCOLOREDIT: 636 case WM_CTLCOLORLISTBOX: 637 case WM_CTLCOLORSCROLLBAR: 638 case WM_CTLCOLORSTATIC: 639 return(DefWindowProc(hDlg, message, wParam, lParam)); 640 641 case WM_COMMAND : 642 switch (LOWORD (wParam)) 643 { 644 case IDOK : 645 hlb = GetDlgItem (hDlg, IDC_FILEQUEUE) ; 646 queued_file_count = SendMessage (hlb, LB_GETCOUNT, 0, 0) ; 647 if (queued_file_count > MAX_QUEUE) 648 queued_file_count = MAX_QUEUE ; 649 for (i = 0 ; i < queued_file_count ; i++) 650 SendMessage (hlb, LB_GETTEXT, i, (LPARAM) queued_files [i]) ; 651 auto_render = IsDlgButtonChecked (hDlg, IDC_AUTORENDER) ; 652 PVCheckMenuItem (CM_AUTORENDER, auto_render ? MF_CHECKED : MF_UNCHECKED) ; 653 PutHKCU ("FileQueue", "ReloadOnStartup", IsDlgButtonChecked (hDlg, IDC_RELOADQUEUE)) ; 654 update_queue_status (true) ; 655 DeleteObject (hbr) ; 656 EndDialog (hDlg, true) ; 657 return (true) ; 658 659 case IDCANCEL : 660 DeleteObject (hbr) ; 661 EndDialog (hDlg, false) ; 662 return (true) ; 663 664 case IDC_DELETEFILE : 665 hlb = GetDlgItem (hDlg, IDC_FILEQUEUE) ; 666 if ((i = SendMessage (hlb, LB_GETCURSEL, 0, 0)) != LB_ERR) 667 { 668 SendMessage (hlb, LB_DELETESTRING, i, 0) ; 669 if (i) 670 i-- ; 671 SendMessage (hlb, LB_SETCURSEL, i, 0) ; 672 } 673 i = SendMessage (hlb, LB_GETCOUNT, 0, 0) ; 674 sprintf (str, "Queue will have %d entr%s", i, i != 1 ? "ies" : "y") ; 675 SetDlgItemText (hDlg, IDC_QUEUEENTRIES, str) ; 676 return (true) ; 677 678 case IDC_ADDFILE : 679 hlb = GetDlgItem (hDlg, IDC_FILEQUEUE) ; 680 AddQueue (hDlg, hlb) ; 681 i = SendMessage (hlb, LB_GETCOUNT, 0, 0) ; 682 sprintf (str, "Queue will have %d entr%s", i, i != 1 ? "ies" : "y") ; 683 SetDlgItemText (hDlg, IDC_QUEUEENTRIES, str) ; 684 return (true) ; 685 686 case IDC_CONTEXTHELP : 687 hh_aklink.pszKeywords = "File Queue" ; 688 HtmlHelp (NULL, engineHelpPath, HH_KEYWORD_LOOKUP, (DWORD_PTR) &hh_aklink) ; 689 return (true) ; 690 } 691 break ; 692 693 case WM_MEASUREITEM : 694 if (wParam == IDC_FILEQUEUE) 695 { 696 m = (MEASUREITEMSTRUCT *) lParam ; 697 m->itemHeight = listbox_ychar ; 698 return (true) ; 699 } 700 else 701 return (false) ; 702 703 case WM_DRAWITEM : 704 if (wParam == IDC_FILEQUEUE) 705 { 706 d = (DRAWITEMSTRUCT *) lParam ; 707 draw_ordinary_listbox (d, true) ; 708 return (true) ; 709 } 710 else 711 return (false) ; 712 } 713 return (false) ; 714 } 715 716 INT_PTR CALLBACK PovFeatureAdviceDialogProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) 717 { 718 switch (message) 719 { 720 case WM_INITDIALOG : 721 hh_aklink.pszKeywords = otaHelpString ; 722 SetWindowText (hDlg, otaTitle) ; 723 SetDlgItemText (hDlg, IDC_ADVICETEXT, otaText) ; 724 CheckDlgButton (hDlg, IDC_DONTTELLMEAGAIN, otaChecked ? BST_CHECKED : BST_UNCHECKED) ; 725 if (lParam == 0) 726 lParam = (LPARAM) GetDesktopWindow () ; 727 CenterWindowRelative ((HWND) lParam, hDlg, true, true) ; 728 return (true) ; 729 730 case WM_CTLCOLORBTN: 731 case WM_CTLCOLORDLG: 732 case WM_CTLCOLOREDIT: 733 case WM_CTLCOLORLISTBOX: 734 case WM_CTLCOLORSCROLLBAR: 735 case WM_CTLCOLORSTATIC: 736 return (DefWindowProc (hDlg, message, wParam, lParam)); 737 738 case WM_COMMAND : 739 switch (LOWORD (wParam)) 740 { 741 case IDOK : 742 otaChecked = IsDlgButtonChecked (hDlg, IDC_DONTTELLMEAGAIN) == BST_CHECKED ; 743 EndDialog (hDlg, true) ; 744 return (true) ; 745 746 case IDCANCEL : 747 otaChecked = false ; 748 EndDialog (hDlg, false) ; 749 return (true) ; 750 751 case IDC_CONTEXTHELP : 752 hh_aklink.pszKeywords = otaHelpString ; 753 HtmlHelp (NULL, engineHelpPath, HH_KEYWORD_LOOKUP, (DWORD_PTR) &hh_aklink) ; 754 return (true) ; 755 } 756 break ; 757 758 } 759 return (false) ; 760 } 761 762 INT_PTR CALLBACK PovSoundsDialogProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) 763 { 764 char *s ; 765 766 switch (message) 767 { 768 case WM_INITDIALOG : 769 hh_aklink.pszKeywords = "sounds" ; 770 CenterWindowRelative ((HWND) lParam, hDlg, true, true) ; 771 FitWindowInWindow (NULL, hDlg) ; 772 SetDlgItemText (hDlg, IDC_SOUND_RENDERCOMPLETE, render_complete_sound) ; 773 SetDlgItemText (hDlg, IDC_SOUND_PARSEERROR, parse_error_sound) ; 774 SetDlgItemText (hDlg, IDC_SOUND_RENDERERROR, render_error_sound) ; 775 CheckDlgButton (hDlg, IDC_ENABLE_RENDERCOMPLETESOUND, render_complete_sound_enabled ? BST_CHECKED : BST_UNCHECKED) ; 776 CheckDlgButton (hDlg, IDC_ENABLE_PARSEERRORSOUND, parse_error_sound_enabled ? BST_CHECKED : BST_UNCHECKED) ; 777 CheckDlgButton (hDlg, IDC_ENABLE_RENDERERRORSOUND, render_error_sound_enabled ? BST_CHECKED : BST_UNCHECKED) ; 778 return (true) ; 779 780 case WM_CTLCOLORBTN: 781 case WM_CTLCOLORDLG: 782 case WM_CTLCOLOREDIT: 783 case WM_CTLCOLORLISTBOX: 784 case WM_CTLCOLORSCROLLBAR: 785 case WM_CTLCOLORSTATIC: 786 return(DefWindowProc(hDlg, message, wParam, lParam)); 787 788 case WM_COMMAND : 789 switch (LOWORD (wParam)) 790 { 791 case IDC_BROWSE_RENDERCOMPLETESOUND: 792 if ((s = SelectSound (hDlg, render_complete_sound)) != NULL) 793 SetDlgItemText (hDlg, IDC_SOUND_RENDERCOMPLETE, s) ; 794 return (true) ; 795 796 case IDC_BROWSE_PARSEERRORSOUND: 797 if ((s = SelectSound (hDlg, parse_error_sound)) != NULL) 798 SetDlgItemText (hDlg, IDC_SOUND_PARSEERROR, s) ; 799 return (true) ; 800 801 case IDC_BROWSE_RENDERERRORSOUND: 802 if ((s = SelectSound (hDlg, render_error_sound)) != NULL) 803 SetDlgItemText (hDlg, IDC_SOUND_RENDERERROR, s) ; 804 return (true) ; 805 806 case IDOK : 807 render_complete_sound_enabled = IsDlgButtonChecked (hDlg, IDC_ENABLE_RENDERCOMPLETESOUND) == BST_CHECKED ; 808 parse_error_sound_enabled = IsDlgButtonChecked (hDlg, IDC_ENABLE_PARSEERRORSOUND) == BST_CHECKED ; 809 render_error_sound_enabled = IsDlgButtonChecked (hDlg, IDC_ENABLE_RENDERERRORSOUND) == BST_CHECKED ; 810 GetDlgItemText (hDlg, IDC_SOUND_RENDERCOMPLETE, render_complete_sound, _MAX_PATH) ; 811 GetDlgItemText (hDlg, IDC_SOUND_PARSEERROR, parse_error_sound, _MAX_PATH) ; 812 GetDlgItemText (hDlg, IDC_SOUND_RENDERERROR, render_error_sound, _MAX_PATH) ; 813 EndDialog (hDlg, true) ; 814 return (true) ; 815 816 case IDCANCEL : 817 EndDialog (hDlg, false) ; 818 return (true) ; 819 820 case IDC_CONTEXTHELP : 821 hh_aklink.pszKeywords = "sounds" ; 822 HtmlHelp (NULL, engineHelpPath, HH_KEYWORD_LOOKUP, (DWORD_PTR) &hh_aklink) ; 823 return (true) ; 824 } 825 break ; 826 } 827 return (false) ; 828 } 829 830 INT_PTR CALLBACK PovThreadCountDialogProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) 831 { 832 int val; 833 BOOL result; 834 835 switch (message) 836 { 837 case WM_INITDIALOG : 838 hh_aklink.pszKeywords = "thread count" ; // TODO 839 SetDlgItemInt (hDlg, IDC_THREADCOUNT, ThreadCount, FALSE) ; 840 SendDlgItemMessage (hDlg, IDC_THREADCOUNT, EM_LIMITTEXT, 3, 0L) ; 841 SendDlgItemMessage (hDlg, IDC_THREADSPIN, UDM_SETRANGE, 0, MAKELONG(255, 1)) ; 842 CenterWindowRelative ((HWND) lParam, hDlg, true, true) ; 843 FitWindowInWindow (NULL, hDlg) ; 844 return (true) ; 845 846 case WM_CTLCOLORBTN: 847 case WM_CTLCOLORDLG: 848 case WM_CTLCOLOREDIT: 849 case WM_CTLCOLORLISTBOX: 850 case WM_CTLCOLORSCROLLBAR: 851 case WM_CTLCOLORSTATIC: 852 return (DefWindowProc (hDlg, message, wParam, lParam)); 853 854 case WM_COMMAND : 855 switch (LOWORD (wParam)) 856 { 857 case IDC_THREADCOUNT : 858 if (HIWORD (wParam) == EN_CHANGE) 859 { 860 if (SendDlgItemMessage (hDlg, IDC_THREADCOUNT, EM_LINELENGTH, 0, 0) > 0) 861 { 862 val = GetDlgItemInt (hDlg, IDC_THREADCOUNT, &result, FALSE) ; 863 if (result == FALSE || val < 1 || val > 255) 864 { 865 if (result == FALSE) 866 SetDlgItemInt (hDlg, IDC_THREADCOUNT, ThreadCount, FALSE) ; 867 else if (val < 1) 868 SetDlgItemInt (hDlg, IDC_THREADCOUNT, 1, FALSE) ; 869 else if (val > 255) 870 SetDlgItemInt (hDlg, IDC_THREADCOUNT, 255, FALSE) ; 871 SendDlgItemMessage (hDlg, IDC_THREADCOUNT, EM_SETSEL, 0, -1); 872 } 873 EnableWindow (GetDlgItem (hDlg, IDOK), TRUE); 874 } 875 else 876 EnableWindow (GetDlgItem (hDlg, IDOK), FALSE); 877 return (true); 878 } 879 return (false) ; 880 881 case IDOK : 882 val = GetDlgItemInt (hDlg, IDC_THREADCOUNT, &result, FALSE) ; 883 if (result == TRUE && val > 0 && val < 256) 884 ThreadCount = val ; 885 EndDialog (hDlg, true) ; 886 return (true) ; 887 888 case IDCANCEL : 889 EndDialog (hDlg, false) ; 890 return (true) ; 891 } 892 break ; 893 } 894 return (false) ; 895 } 896 897 INT_PTR CALLBACK RenderAlternativeFileDialogProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) 898 { 899 int width ; 900 int max = 0; 901 int diff ; 902 char str [8192] ; 903 char *s = str; 904 char *s2; 905 char srcname[_MAX_PATH]; 906 char altname[_MAX_PATH]; 907 RECT rect ; 908 HWND hText ; 909 const char *src = source_file_name; 910 const char *alt = (LPCSTR) lParam; 911 912 switch (message) 913 { 914 case WM_INITDIALOG : 915 splitpath(src, NULL, srcname); 916 splitpath(alt, NULL, altname); 917 hText = GetDlgItem (hDlg, IDC_ALTERNATEFILETEXT) ; 918 s += sprintf(s, "You have requested to render '%s'.\n\n", src); 919 max = GetTextExtent(hText, str)->cx; 920 s += sprintf(s, "This is an include file that has been used by another render during this session. "); 921 s += sprintf(s, "The most recent use of %s was when rendering the below file:\n\n", srcname); 922 s += sprintf(s2 = s, "\t%s\n\n", alt); 923 if ((width = GetTextExtent(hText, s2)->cx) > max) 924 max = width; 925 s += sprintf(s, "If you prefer, POV-Ray will render %s instead of %s.\n\n", altname, srcname); 926 s += sprintf(s, "If you select \"Yes, For This Session\", POV will render %s and remember your choice for this session. ", altname); 927 s += sprintf(s, "If you select \"Yes, This Time\", you will be asked next time you render %s. ", srcname); 928 s += sprintf(s, "If you select \"No, Don't Ask Again\", POV will render %s and won't bug you about it for the remainder of this session.\n", srcname); 929 SetDlgItemText (hDlg, IDC_ALTERNATEFILETEXT, str) ; 930 if (max <= 0) 931 return (false) ; 932 GetClientRect (hText, &rect) ; 933 if (rect.right >= max + 10) 934 return (false) ; 935 diff = max - rect.right + 10 ; 936 SetWindowPos (hText, NULL, 0, 0, rect.right + diff, rect.bottom, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER) ; 937 GetWindowRect (hDlg, &rect) ; 938 rect.right -= rect.left ; 939 rect.bottom -= rect.top ; 940 rect.right += diff ; 941 SetWindowPos (hDlg, NULL, 0, 0, rect.right + 10, rect.bottom, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER) ; 942 diff /= 2 ; 943 NudgeChildWindow (hDlg, IDYES, diff) ; 944 NudgeChildWindow (hDlg, IDOK, diff) ; 945 NudgeChildWindow (hDlg, IDNO, diff) ; 946 NudgeChildWindow (hDlg, IDHELP, diff) ; 947 return (false) ; 948 949 case WM_COMMAND : 950 switch (LOWORD (wParam)) 951 { 952 case IDYES : 953 case IDOK : 954 case IDNO : 955 case IDCANCEL : 956 EndDialog (hDlg, LOWORD(wParam)) ; 957 return (true) ; 958 } 959 break ; 960 } 961 return (false) ; 962 } 963 964 void FeatureNotify (const char *labelStr, const char *titleStr, const char *textStr, const char *helpStr, bool checked) 965 { 966 bool result = false ; 967 968 if (GetDontShowAgain (labelStr)) 969 return ; 970 otaTitle = titleStr ; 971 otaText = textStr ; 972 hh_aklink.pszKeywords = otaHelpString = helpStr ; 973 otaChecked = checked ; 974 if (DialogBoxParam (hInstance, MAKEINTRESOURCE (IDD_FEATUREADVICE), main_window, (DLGPROC) PovFeatureAdviceDialogProc, (LPARAM) main_window) > 0) 975 if (otaChecked) 976 PutDontShowAgain (labelStr, true) ; 977 } 978 979 }