Win_ent.cpp (32502B)
1 /* 2 =========================================================================== 3 Copyright (C) 1999-2005 Id Software, Inc. 4 5 This file is part of Quake III Arena source code. 6 7 Quake III Arena source code is free software; you can redistribute it 8 and/or modify it under the terms of the GNU General Public License as 9 published by the Free Software Foundation; either version 2 of the License, 10 or (at your option) any later version. 11 12 Quake III Arena source code is distributed in the hope that it will be 13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with Foobar; if not, write to the Free Software 19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 =========================================================================== 21 */ 22 #include "stdafx.h" 23 #include "qe3.h" 24 #include "entityw.h" 25 #include "TexWnd.h" 26 #include "WaveOpen.h" 27 28 int rgIds[EntLast] = { 29 IDC_E_LIST, 30 IDC_E_COMMENT, 31 IDC_CHECK1, 32 IDC_CHECK2, 33 IDC_CHECK3, 34 IDC_CHECK4, 35 IDC_CHECK5, 36 IDC_CHECK6, 37 IDC_CHECK7, 38 IDC_CHECK8, 39 IDC_CHECK9, 40 IDC_CHECK10, 41 IDC_CHECK11, 42 IDC_CHECK12, 43 IDC_E_PROPS, 44 IDC_E_0, 45 IDC_E_45, 46 IDC_E_90, 47 IDC_E_135, 48 IDC_E_180, 49 IDC_E_225, 50 IDC_E_270, 51 IDC_E_315, 52 IDC_E_UP, 53 IDC_E_DOWN, 54 IDC_E_DELPROP, 55 56 IDC_STATIC_KEY, 57 IDC_E_KEY_FIELD, 58 IDC_STATIC_VALUE, 59 IDC_E_VALUE_FIELD, 60 61 IDC_E_COLOR, 62 63 IDC_BTN_ASSIGNSOUND, 64 IDC_BTN_ASSIGNMODEL 65 66 }; 67 68 HWND hwndEnt[EntLast]; 69 CTabCtrl g_wndTabs; 70 71 int inspector_mode; // W_TEXTURE, W_ENTITY, or W_CONSOLE 72 73 qboolean multiple_entities; 74 75 entity_t *edit_entity; 76 77 78 BOOL CALLBACK EntityWndProc( 79 HWND hwndDlg, // handle to dialog box 80 UINT uMsg, // message 81 WPARAM wParam, // first message parameter 82 LPARAM lParam); // second message parameter 83 84 void SizeEntityDlg(int iWidth, int iHeight); 85 void AddProp(); 86 void GetTexMods(void); 87 88 89 LRESULT (CALLBACK* OldFieldWindowProc) (HWND, UINT, WPARAM, LPARAM); 90 LRESULT (CALLBACK* OldEntityListWindowProc) (HWND, UINT, WPARAM, LPARAM); 91 92 /* 93 ========================= 94 FieldWndProc 95 96 Just to handle tab and enter... 97 ========================= 98 */ 99 BOOL CALLBACK FieldWndProc( 100 HWND hwnd, 101 UINT uMsg, 102 WPARAM wParam, 103 LPARAM lParam) 104 { 105 switch (uMsg) 106 { 107 case WM_CHAR: 108 if (LOWORD(wParam) == VK_TAB) 109 return FALSE; 110 if (LOWORD(wParam) == VK_RETURN) 111 return FALSE; 112 if (LOWORD(wParam) == VK_ESCAPE) 113 { 114 SetFocus (g_qeglobals.d_hwndCamera); 115 return FALSE; 116 } 117 break; 118 119 case WM_KEYDOWN: 120 if (LOWORD(wParam) == VK_TAB) 121 { 122 if (hwnd == hwndEnt[EntKeyField]) 123 { 124 SendMessage (hwndEnt[EntValueField], WM_SETTEXT, 0, (long)""); 125 SetFocus (hwndEnt[EntValueField]); 126 } 127 else 128 SetFocus (hwndEnt[EntKeyField]); 129 } 130 if (LOWORD(wParam) == VK_RETURN) 131 { 132 if (hwnd == hwndEnt[EntKeyField]) 133 { 134 SendMessage (hwndEnt[EntValueField], WM_SETTEXT, 0, (long)""); 135 SetFocus (hwndEnt[EntValueField]); 136 } 137 else 138 { 139 AddProp (); 140 SetFocus (g_qeglobals.d_hwndCamera); 141 } 142 } 143 break; 144 // case WM_NCHITTEST: 145 case WM_LBUTTONDOWN: 146 SetFocus (hwnd); 147 break; 148 } 149 return CallWindowProc (OldFieldWindowProc, hwnd, uMsg, wParam, lParam); 150 } 151 152 153 /* 154 ========================= 155 EntityListWndProc 156 157 Just to handle enter... 158 ========================= 159 */ 160 BOOL CALLBACK EntityListWndProc( 161 HWND hwnd, 162 UINT uMsg, 163 WPARAM wParam, 164 LPARAM lParam) 165 { 166 switch (uMsg) 167 { 168 case WM_KEYDOWN: 169 if (LOWORD(wParam) == VK_RETURN) 170 { 171 SendMessage ( g_qeglobals.d_hwndEntity, 172 WM_COMMAND, 173 (LBN_DBLCLK<<16) + IDC_E_LIST, 174 0 ); 175 return 0; 176 } 177 break; 178 } 179 return CallWindowProc (OldEntityListWindowProc, hwnd, uMsg, wParam, lParam); 180 } 181 182 183 /* 184 ================ 185 GetEntityControls 186 187 Finds the controls from the dialog and 188 moves them to the window 189 ================ 190 */ 191 void GetEntityControls(HWND ghwndEntity) 192 { 193 int i; 194 195 for (i = 0; i < EntLast; i++) 196 { 197 if (i == EntList || i == EntProps || i == EntComment) 198 continue; 199 if (i == EntKeyField || i == EntValueField) 200 continue; 201 hwndEnt[i] = GetDlgItem(ghwndEntity, rgIds[i]); 202 if (hwndEnt[i]) 203 { 204 SetParent (hwndEnt[i], g_qeglobals.d_hwndEntity ); 205 SendMessage(hwndEnt[i], WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), (LPARAM)TRUE); 206 } 207 } 208 209 210 // SetParent apears to not modify some internal state 211 // on listboxes, so create it from scratch... 212 213 hwndEnt[EntList] = CreateWindow ("listbox", NULL, 214 LBS_STANDARD | LBS_NOINTEGRALHEIGHT | LBS_WANTKEYBOARDINPUT 215 | WS_VSCROLL | WS_CHILD | WS_VISIBLE, 216 5, 5, 180, 99, 217 g_qeglobals.d_hwndEntity, 218 (HMENU)IDC_E_LIST, 219 g_qeglobals.d_hInstance, 220 NULL); 221 if (!hwndEnt[EntList]) 222 Error ("CreateWindow failed"); 223 224 hwndEnt[EntProps] = CreateWindow ("listbox", NULL, 225 LBS_STANDARD | LBS_NOINTEGRALHEIGHT | LBS_USETABSTOPS 226 | WS_VSCROLL | WS_CHILD | WS_VISIBLE, 227 5, 100, 180, 99, 228 g_qeglobals.d_hwndEntity, 229 (HMENU)IDC_E_PROPS, 230 g_qeglobals.d_hInstance, 231 NULL); 232 if (!hwndEnt[EntProps]) 233 Error ("CreateWindow failed"); 234 235 hwndEnt[EntComment] = CreateWindow ("edit", NULL, 236 ES_MULTILINE | ES_READONLY | WS_VSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER, 237 5, 100, 180, 99, 238 g_qeglobals.d_hwndEntity, 239 (HMENU)IDC_E_COMMENT, 240 g_qeglobals.d_hInstance, 241 NULL); 242 if (!hwndEnt[EntComment]) 243 Error ("CreateWindow failed"); 244 245 hwndEnt[EntKeyField] = CreateWindow ("edit", NULL, 246 WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL, 247 5, 100, 180, 99, 248 g_qeglobals.d_hwndEntity, 249 (HMENU)IDC_E_KEY_FIELD, 250 g_qeglobals.d_hInstance, 251 NULL); 252 if (!hwndEnt[EntKeyField]) 253 Error ("CreateWindow failed"); 254 255 hwndEnt[EntValueField] = CreateWindow ("edit", NULL, 256 WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL, 257 5, 100, 180, 99, 258 g_qeglobals.d_hwndEntity, 259 (HMENU)IDC_E_VALUE_FIELD, 260 g_qeglobals.d_hInstance, 261 NULL); 262 if (!hwndEnt[EntValueField]) 263 Error ("CreateWindow failed"); 264 265 g_wndTabs.SubclassDlgItem(IDC_TAB_MODE, CWnd::FromHandle(ghwndEntity)); 266 hwndEnt[EntTab] = g_wndTabs.GetSafeHwnd(); 267 g_wndTabs.InsertItem(0, "Groups"); 268 ::SetParent(g_wndTabs.GetSafeHwnd(), g_qeglobals.d_hwndEntity); 269 270 if (g_pParentWnd->CurrentStyle() > 0 && g_pParentWnd->CurrentStyle() < 3) 271 { 272 g_qeglobals.d_hwndEdit = CreateWindow ("edit", NULL, ES_MULTILINE | ES_READONLY | WS_VSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER, 273 5, 100, 180, 99, g_qeglobals.d_hwndEntity, (HMENU)IDC_E_STATUS, 274 g_qeglobals.d_hInstance, NULL); 275 if (!g_qeglobals.d_hwndEdit) 276 Error ("CreateWindow failed"); 277 g_wndTabs.InsertItem(0, "Console"); 278 g_wndTabs.InsertItem(0, "Textures"); 279 } 280 g_wndTabs.InsertItem(0, "Entities"); 281 g_wndTabs.ShowWindow(SW_SHOW); 282 283 #if 0 284 for (i=0 ; i<12 ; i++) 285 { 286 hwndEnt[EntCheck1 + i] = CreateWindow ("button", NULL, 287 BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE, 288 5, 100, 180, 99, 289 entwindow, 290 (HMENU)IDC_E_STATUS, 291 main_instance, 292 NULL); 293 if (!hwndEnt[EntCheck1 + i]) 294 Error ("CreateWindow failed"); 295 } 296 #endif 297 SendMessage(hwndEnt[EntList], WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), (LPARAM)TRUE); 298 SendMessage(hwndEnt[EntProps], WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), (LPARAM)TRUE); 299 SendMessage(hwndEnt[EntComment], WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), (LPARAM)TRUE); 300 SendMessage(hwndEnt[EntKeyField], WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), (LPARAM)TRUE); 301 SendMessage(hwndEnt[EntValueField], WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), (LPARAM)TRUE); 302 SendMessage(hwndEnt[EntTab], WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), (LPARAM)TRUE); 303 304 if (g_pParentWnd->CurrentStyle() > 0 && g_pParentWnd->CurrentStyle() < 3) 305 SendMessage(g_qeglobals.d_hwndEdit, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), (LPARAM)TRUE); 306 } 307 308 309 310 /* 311 =============================================================== 312 313 ENTITY WINDOW 314 315 =============================================================== 316 */ 317 318 319 void FillClassList (void) 320 { 321 eclass_t *pec; 322 int iIndex; 323 324 SendMessage(hwndEnt[EntList], LB_RESETCONTENT, 0 , 0); 325 326 for (pec = eclass ; pec ; pec = pec->next) 327 { 328 iIndex = SendMessage(hwndEnt[EntList], LB_ADDSTRING, 0 , (LPARAM)pec->name); 329 SendMessage(hwndEnt[EntList], LB_SETITEMDATA, iIndex, (LPARAM)pec); 330 } 331 332 } 333 334 335 /* 336 ============== 337 WEnt_Create 338 ============== 339 */ 340 void WEnt_Create (HINSTANCE hInstance) 341 { 342 WNDCLASS wc; 343 344 /* Register the camera class */ 345 memset (&wc, 0, sizeof(wc)); 346 347 wc.style = CS_NOCLOSE | CS_OWNDC; 348 wc.lpfnWndProc = (WNDPROC)EntityWndProc; 349 wc.cbClsExtra = 0; 350 wc.cbWndExtra = 0; 351 wc.hInstance = hInstance; 352 wc.hIcon = 0; 353 wc.hCursor = LoadCursor (NULL,IDC_ARROW); 354 wc.hbrBackground = (HBRUSH)GetStockObject (LTGRAY_BRUSH); 355 wc.lpszMenuName = NULL; 356 wc.lpszClassName = ENT_WINDOW_CLASS; 357 358 RegisterClass (&wc); 359 360 int nStyle = (g_pParentWnd->CurrentStyle() == QR_QE4) ? QE3_STYLE : QE3_STYLE2; 361 g_qeglobals.d_hwndEntity = CreateWindow (ENT_WINDOW_CLASS , 362 "Entity", 363 nStyle, 364 20, 365 20, 366 100, 367 480, // size 368 369 g_qeglobals.d_hwndMain, // parent 370 0, // no menu 371 hInstance, 372 NULL); 373 374 if (!g_qeglobals.d_hwndEntity ) 375 Error ("Couldn't create Entity window"); 376 } 377 378 /* 379 ============== 380 CreateEntityWindow 381 ============== 382 */ 383 BOOL CreateEntityWindow(HINSTANCE hInstance) 384 { 385 HWND hwndEntityPalette; 386 387 inspector_mode = W_ENTITY; 388 389 WEnt_Create (hInstance); 390 391 hwndEntityPalette = CreateDialog(hInstance, (char *)IDD_ENTITY, g_qeglobals.d_hwndMain, (DLGPROC)NULL); 392 if (!hwndEntityPalette) 393 Error ("CreateDialog failed"); 394 395 GetEntityControls (hwndEntityPalette); 396 DestroyWindow (hwndEntityPalette); 397 398 OldFieldWindowProc = (WNDPROC)GetWindowLong (hwndEnt[EntKeyField], GWL_WNDPROC); 399 SetWindowLong (hwndEnt[EntKeyField], GWL_WNDPROC, (long)FieldWndProc); 400 SetWindowLong (hwndEnt[EntValueField], GWL_WNDPROC, (long)FieldWndProc); 401 402 OldEntityListWindowProc = (WNDPROC)GetWindowLong (hwndEnt[EntList], GWL_WNDPROC); 403 SetWindowLong (hwndEnt[EntList], GWL_WNDPROC, (long)EntityListWndProc); 404 405 FillClassList (); 406 407 408 LoadWindowPlacement(g_qeglobals.d_hwndEntity, "EntityWindowPlace"); 409 ShowWindow (g_qeglobals.d_hwndEntity, SW_HIDE); 410 SetInspectorMode (W_CONSOLE); 411 412 return TRUE; 413 } 414 415 /* 416 ============== 417 SetInspectorMode 418 ============== 419 */ 420 void SetInspectorMode(int iType) 421 { 422 RECT rc; 423 HMENU hMenu = GetMenu( g_qeglobals.d_hwndMain ); 424 425 if ((g_pParentWnd->CurrentStyle() == QR_SPLIT || g_pParentWnd->CurrentStyle() == QR_SPLITZ) && (iType == W_TEXTURE || iType == W_CONSOLE)) 426 return; 427 428 429 // Is the caller asking us to cycle to the next window? 430 431 if (iType == -1) 432 { 433 if (inspector_mode == W_ENTITY) 434 iType = W_TEXTURE; 435 else if (inspector_mode == W_TEXTURE) 436 iType = W_CONSOLE; 437 else if (inspector_mode == W_CONSOLE) 438 iType = W_GROUP; 439 else 440 iType = W_ENTITY; 441 } 442 443 inspector_mode = iType; 444 switch(iType) 445 { 446 447 case W_ENTITY: 448 SetWindowText(g_qeglobals.d_hwndEntity, "Entity"); 449 EnableMenuItem( hMenu, ID_MISC_SELECTENTITYCOLOR, MF_ENABLED | MF_BYCOMMAND ); 450 // entity is always first in the inspector 451 g_wndTabs.SetCurSel(0); 452 break; 453 454 case W_TEXTURE: 455 SetWindowText(g_qeglobals.d_hwndEntity, "Textures"); 456 g_pParentWnd->GetTexWnd()->FocusEdit(); 457 EnableMenuItem( hMenu, ID_MISC_SELECTENTITYCOLOR, MF_GRAYED | MF_DISABLED | MF_BYCOMMAND ); 458 if (g_pParentWnd->CurrentStyle() > 0 && g_pParentWnd->CurrentStyle() < 3) 459 g_wndTabs.SetCurSel(1); 460 break; 461 462 case W_CONSOLE: 463 SetWindowText(g_qeglobals.d_hwndEntity, "Console"); 464 EnableMenuItem( hMenu, ID_MISC_SELECTENTITYCOLOR, MF_GRAYED | MF_DISABLED | MF_BYCOMMAND ); 465 if (g_pParentWnd->CurrentStyle() > 0 && g_pParentWnd->CurrentStyle() < 3) 466 g_wndTabs.SetCurSel(2); 467 break; 468 469 case W_GROUP: 470 SetWindowText(g_qeglobals.d_hwndEntity, "Groups"); 471 EnableMenuItem( hMenu, ID_MISC_SELECTENTITYCOLOR, MF_GRAYED | MF_DISABLED | MF_BYCOMMAND ); 472 if (g_pParentWnd->CurrentStyle() > 0 && g_pParentWnd->CurrentStyle() < 3) 473 g_wndTabs.SetCurSel(3); 474 else 475 g_wndTabs.SetCurSel(1); 476 break; 477 478 479 default: 480 break; 481 } 482 483 GetWindowRect (g_qeglobals.d_hwndEntity, &rc); 484 SizeEntityDlg( rc.right - rc.left - 8, rc.bottom - rc.top - 20); 485 486 487 // InvalidateRect(entwindow, NULL, true); 488 // ShowWindow (entwindow, SW_SHOW); 489 // UpdateWindow (entwindow); 490 491 HWND hFlag = (g_pParentWnd->CurrentStyle() == QR_QE4) ? HWND_TOP : HWND_TOPMOST; 492 SetWindowPos( g_qeglobals.d_hwndEntity, hFlag, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, SWP_NOSIZE | SWP_NOMOVE ); 493 RedrawWindow (g_qeglobals.d_hwndEntity, NULL, NULL, RDW_ERASE | RDW_INVALIDATE| RDW_ERASENOW | RDW_UPDATENOW | RDW_ALLCHILDREN); 494 } 495 496 497 498 499 500 // SetKeyValuePairs 501 // 502 // Reset the key/value (aka property) listbox and fill it with the 503 // k/v pairs from the entity being edited. 504 // 505 506 void SetKeyValuePairs (bool bClearMD3) 507 { 508 epair_t *pep; 509 RECT rc; 510 char sz[4096]; 511 512 if (edit_entity == NULL) 513 return; 514 515 // set key/value pair list 516 517 GetWindowRect(hwndEnt[EntProps], &rc); 518 SendMessage(hwndEnt[EntProps], LB_SETCOLUMNWIDTH, (rc.right - rc.left)/2, 0); 519 SendMessage(hwndEnt[EntProps], LB_RESETCONTENT, 0, 0); 520 521 // Walk through list and add pairs 522 523 for (pep = edit_entity->epairs ; pep ; pep = pep->next) 524 { 525 // if the key is less than 8 chars, add a tab for alignment 526 if (strlen(pep->key) > 8) 527 sprintf (sz, "%s\t%s", pep->key, pep->value); 528 else 529 sprintf (sz, "%s\t\t%s", pep->key, pep->value); 530 SendMessage(hwndEnt[EntProps], LB_ADDSTRING, 0, (LPARAM)sz); 531 } 532 533 if (edit_entity->eclass->nShowFlags & ECLASS_MISCMODEL) 534 { 535 // if this is a misc_model 536 // cache the md3 for display later 537 if (bClearMD3) 538 { 539 edit_entity->md3Class = NULL; 540 } 541 //char *pModel = ValueForKey(edit_entity, "model"); 542 543 /* 544 if (pModel != NULL) 545 { 546 GetCachedModel(pModel, vMin, vMax); 547 } 548 */ 549 } 550 551 Sys_UpdateWindows(W_CAMERA | W_XY); 552 553 } 554 555 // SetSpawnFlags 556 // 557 // Update the checkboxes to reflect the flag state of the entity 558 // 559 void SetSpawnFlags(void) 560 { 561 int f; 562 int i; 563 int v; 564 565 f = atoi(ValueForKey (edit_entity, "spawnflags")); 566 for (i=0 ; i<12 ; i++) 567 { 568 v = !!(f&(1<<i)); 569 SendMessage(hwndEnt[EntCheck1+i], BM_SETCHECK, v, 0); 570 } 571 } 572 573 574 // GetSpawnFlags 575 // 576 // Update the entity flags to reflect the state of the checkboxes 577 // 578 void GetSpawnFlags(void) 579 { 580 int f; 581 int i, v; 582 char sz[32]; 583 584 f = 0; 585 for (i=0 ; i<12 ; i++) 586 { 587 v = SendMessage(hwndEnt[EntCheck1+i], BM_GETCHECK, 0, 0); 588 f |= v<<i; 589 } 590 591 sprintf (sz, "%i", f); 592 593 if (multiple_entities) 594 { 595 brush_t *b; 596 597 for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next) 598 SetKeyValue(b->owner, "spawnflags", sz); 599 } 600 else 601 SetKeyValue (edit_entity, "spawnflags", sz); 602 SetKeyValuePairs (); 603 } 604 605 // UpdateSel 606 // 607 // Update the listbox, checkboxes and k/v pairs to reflect the new selection 608 // 609 BOOL UpdateSel(int iIndex, eclass_t *pec) 610 { 611 int i; 612 brush_t *b; 613 614 if (selected_brushes.next == &selected_brushes) 615 { 616 edit_entity = world_entity; 617 multiple_entities = false; 618 } 619 else 620 { 621 edit_entity = selected_brushes.next->owner; 622 for (b=selected_brushes.next->next ; b != &selected_brushes ; b=b->next) 623 { 624 if (b->owner != edit_entity) 625 { 626 multiple_entities = true; 627 break; 628 } 629 } 630 } 631 632 if (iIndex != LB_ERR) 633 SendMessage(hwndEnt[EntList], LB_SETCURSEL, iIndex, 0); 634 635 if (pec == NULL) 636 return TRUE; 637 638 // Set up the description 639 640 SendMessage(hwndEnt[EntComment], WM_SETTEXT, 0, 641 (LPARAM)TranslateString(pec->comments)); 642 643 for (i=0 ; i<8 ; i++) 644 { 645 HWND hwnd = hwndEnt[EntCheck1+i]; 646 if (pec->flagnames[i] && pec->flagnames[i][0] != 0) 647 { 648 EnableWindow(hwnd, TRUE); 649 SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)pec->flagnames[i]); 650 } else { 651 652 // disable check box 653 SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)" "); 654 EnableWindow(hwnd, FALSE); 655 } 656 } 657 658 SetSpawnFlags(); 659 SetKeyValuePairs(); 660 return TRUE; 661 } 662 663 BOOL UpdateEntitySel(eclass_t *pec) 664 { 665 int iIndex; 666 667 iIndex = (int)SendMessage(hwndEnt[EntList], LB_FINDSTRINGEXACT, 668 (WPARAM)-1, (LPARAM)pec->name); 669 670 return UpdateSel(iIndex, pec); 671 } 672 673 // CreateEntity 674 // 675 // Creates a new entity based on the currently selected brush and entity type. 676 // 677 678 void CreateEntity(void) 679 { 680 eclass_t *pecNew; 681 entity_t *petNew; 682 int i; 683 HWND hwnd; 684 char sz[1024]; 685 686 // check to make sure we have a brush 687 688 if (selected_brushes.next == &selected_brushes) 689 { 690 MessageBox(g_qeglobals.d_hwndMain, "You must have a selected brush to create an entity" 691 , "info", 0); 692 return; 693 } 694 695 696 // find out what type of entity we are trying to create 697 698 hwnd = hwndEnt[EntList]; 699 700 i = SendMessage(hwndEnt[EntList], LB_GETCURSEL, 0, 0); 701 702 if (i < 0) 703 { 704 MessageBox(g_qeglobals.d_hwndMain, "You must have a selected class to create an entity" 705 , "info", 0); 706 return; 707 } 708 709 SendMessage(hwnd, LB_GETTEXT, i, (LPARAM)sz); 710 711 if (!stricmp(sz, "worldspawn")) 712 { 713 MessageBox(g_qeglobals.d_hwndMain, "Can't create an entity with worldspawn.", "info", 0); 714 return; 715 } 716 717 pecNew = Eclass_ForName(sz, false); 718 719 // create it 720 721 petNew = Entity_Create(pecNew); 722 723 if (petNew == NULL) 724 { 725 MessageBox(g_qeglobals.d_hwndMain, "Failed to create entity.", "info", 0); 726 return; 727 } 728 729 if (selected_brushes.next == &selected_brushes) 730 edit_entity = world_entity; 731 else 732 edit_entity = selected_brushes.next->owner; 733 734 SetKeyValuePairs(); 735 Select_Deselect (); 736 Select_Brush (edit_entity->brushes.onext); 737 Sys_UpdateWindows(W_ALL); 738 739 } 740 741 742 743 /* 744 =============== 745 AddProp 746 747 =============== 748 */ 749 void AddProp() 750 { 751 char key[4096]; 752 char value[4096]; 753 754 if (edit_entity == NULL) 755 return; 756 757 // Get current selection text 758 759 SendMessage(hwndEnt[EntKeyField], WM_GETTEXT, sizeof(key)-1, (LPARAM)key); 760 SendMessage(hwndEnt[EntValueField], WM_GETTEXT, sizeof(value)-1, (LPARAM)value); 761 762 if (multiple_entities) 763 { 764 brush_t *b; 765 766 for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next) 767 SetKeyValue(b->owner, key, value); 768 } 769 else 770 SetKeyValue(edit_entity, key, value); 771 772 // refresh the prop listbox 773 SetKeyValuePairs(); 774 775 // if it's a plugin entity, perhaps we need to update some drawing parameters 776 // NOTE: perhaps moving this code to a seperate func would help if we need it in other places 777 // TODO: we need to call some update func in the IPluginEntity in case model name changes etc. 778 // ( for the moment only bounding brush is updated ), see UpdateModelBrush in Ritual's Q3Radiant 779 if (edit_entity->eclass->nShowFlags & ECLASS_PLUGINENTITY) 780 { 781 vec3_t mins, maxs; 782 edit_entity->pPlugEnt->GetBounds( mins, maxs ); 783 // replace old bounding brush by newly computed one 784 // NOTE: this part is similar to Entity_BuildModelBrush in Ritual's Q3Radiant, it can be 785 // usefull moved into a seperate func 786 brush_t *b,*oldbrush; 787 if (edit_entity->brushes.onext != &edit_entity->brushes) 788 oldbrush = edit_entity->brushes.onext; 789 b = Brush_Create (mins, maxs, &edit_entity->eclass->texdef); 790 Entity_LinkBrush (edit_entity, b); 791 Brush_Build( b, true ); 792 Select_Deselect(); 793 Brush_AddToList (edit_entity->brushes.onext, &selected_brushes); 794 if (oldbrush) 795 Brush_Free( oldbrush ); 796 } 797 798 } 799 800 /* 801 =============== 802 DelProp 803 804 =============== 805 */ 806 void DelProp(void) 807 { 808 char sz[4096]; 809 810 if (edit_entity == NULL) 811 return; 812 813 // Get current selection text 814 815 SendMessage(hwndEnt[EntKeyField], WM_GETTEXT, sizeof(sz)-1, (LPARAM)sz); 816 817 if (multiple_entities) 818 { 819 brush_t *b; 820 821 for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next) 822 DeleteKey(b->owner, sz); 823 } 824 else 825 DeleteKey(edit_entity, sz); 826 827 // refresh the prop listbox 828 829 SetKeyValuePairs(); 830 } 831 832 BOOL GetSelectAllCriteria(CString &strKey, CString &strVal) { 833 char sz[4096]; 834 HWND hwnd = hwndEnt[EntProps]; 835 int i = SendMessage(hwnd, LB_GETCURSEL, 0, 0); 836 if (i >= 0 && inspector_mode == W_ENTITY) { 837 SendMessage(hwndEnt[EntKeyField], WM_GETTEXT, sizeof(sz), (LPARAM)sz); 838 strKey = sz; 839 SendMessage(hwndEnt[EntValueField], WM_GETTEXT, sizeof(sz), (LPARAM)sz); 840 strVal = sz; 841 return TRUE; 842 } 843 return FALSE; 844 } 845 846 /* 847 =============== 848 EditProp 849 850 =============== 851 */ 852 void EditProp(void) 853 { 854 int i; 855 HWND hwnd; 856 char sz[4096]; 857 char *val; 858 859 if (edit_entity == NULL) 860 return; 861 862 hwnd = hwndEnt[EntProps]; 863 864 // Get current selection text 865 866 i = SendMessage(hwnd, LB_GETCURSEL, 0, 0); 867 868 if (i < 0) 869 return; 870 871 SendMessage(hwnd, LB_GETTEXT, i, (LPARAM)sz); 872 873 // strip it down to the key name 874 875 for(i=0;sz[i] != '\t';i++) 876 ; 877 878 sz[i] = '\0'; 879 880 val = sz + i + 1; 881 if (*val == '\t') 882 val++; 883 884 SendMessage(hwndEnt[EntKeyField], WM_SETTEXT, 0, (LPARAM)sz); 885 SendMessage(hwndEnt[EntValueField], WM_SETTEXT, 0, (LPARAM)val); 886 } 887 888 889 HDWP defer; 890 int col; 891 void MOVE(HWND e, int x, int y, int w, int h, HWND hwndPlacement = HWND_TOP, int swp = SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_NOZORDER) 892 { 893 // defer=DeferWindowPos(defer,e,HWND_TOP,col+(x),y,w,h,SWP_SHOWWINDOW); 894 // MoveWindow (e, col+x, y, w, h, FALSE); 895 SetWindowPos (e, hwndPlacement, col+x, y, w, h, swp); 896 } 897 898 899 /* 900 =============== 901 SizeEnitityDlg 902 903 Positions all controls so that the active inspector 904 is displayed correctly and the inactive ones are 905 off the side 906 =============== 907 */ 908 void SizeEntityDlg(int iWidth, int iHeight) 909 { 910 int y, x, xCheck, yCheck; 911 int i, iRow; 912 int w, h; 913 914 if (iWidth < 32 || iHeight < 32) 915 return; 916 917 SendMessage( g_qeglobals.d_hwndEntity, WM_SETREDRAW, 0, 0); 918 iHeight -= 24; 919 920 921 //========================================== 922 923 924 // 925 // console 926 // 927 if (inspector_mode == W_CONSOLE) 928 { 929 col = 0; 930 } 931 else 932 { 933 col = iWidth; 934 } 935 936 if (g_pParentWnd->CurrentStyle() > 0 && g_pParentWnd->CurrentStyle() < 3) 937 MOVE(g_qeglobals.d_hwndEdit, DlgXBorder, DlgYBorder, iWidth - (2 * DlgXBorder), iHeight - (2 * DlgYBorder) ); 938 939 //========================================== 940 941 // 942 // texture controls 943 // 944 if (inspector_mode == W_TEXTURE) 945 { 946 col = 0; 947 } 948 else 949 { 950 col = iWidth; 951 } 952 953 if (g_pParentWnd->CurrentStyle() > 0 && g_pParentWnd->CurrentStyle() < 3) 954 MOVE(g_qeglobals.d_hwndTexture, DlgXBorder, DlgYBorder, iWidth - (2 * DlgXBorder), iHeight - (2 * DlgYBorder) ); 955 956 if (inspector_mode == W_GROUP) 957 { 958 col = 0; 959 } 960 else 961 { 962 col = iWidth; 963 } 964 965 MOVE(g_qeglobals.d_hwndGroup, DlgXBorder, DlgYBorder, iWidth - (2 * DlgXBorder), iHeight - (2 * DlgYBorder) ); 966 967 //========================================== 968 969 // 970 // entity controls 971 // 972 if (inspector_mode == W_ENTITY) 973 { 974 col = 0; 975 } 976 else 977 { 978 col = iWidth; 979 } 980 981 982 983 // top half includes the entity list (2/3) and the 984 // comments (1/3) - 2 gaps, above and below. 985 986 y = iHeight/2; 987 y -= 2 * DlgYBorder; 988 y = y / 3; 989 w = iWidth - (2 * DlgXBorder); 990 MOVE(hwndEnt[EntList], DlgXBorder, DlgYBorder, w, 2 * y); 991 992 MOVE(hwndEnt[EntComment], DlgXBorder, 2 * DlgYBorder + 2 * y, w, y - (2 * DlgYBorder)); 993 994 // bottom half includes flags (fixed), k/v pairs, 995 // and buttons (fixed). 996 997 // xCheck = width of a single check box 998 // yCheck = distance from top of one check to the next 999 1000 xCheck = (iWidth - (2 * DlgXBorder)) / 3; 1001 yCheck = 18; 1002 1003 x = DlgXBorder; 1004 1005 for (iRow = 0; iRow <= 12; iRow += 4) 1006 { 1007 y = iHeight/2; 1008 1009 for (i = 0; i < 4; i++) 1010 { 1011 MOVE(hwndEnt[EntCheck1 + i + iRow], 1012 x, y, xCheck, yCheck); 1013 y += yCheck; 1014 } 1015 1016 x += xCheck; 1017 } 1018 1019 // 1020 // properties scroll box 1021 // 1022 y = iHeight/2 + 4 * yCheck; 1023 1024 w = iWidth - (2 * DlgXBorder); 1025 h = (iHeight - (yCheck * 5 + 2 * DlgYBorder) ) - y; 1026 1027 MOVE(hwndEnt[EntProps], DlgXBorder, y, w, h); 1028 1029 y += h + DlgYBorder; 1030 1031 // 1032 // key / value fields 1033 // 1034 w = iWidth-(DlgXBorder+45); 1035 MOVE(hwndEnt[EntKeyLabel], DlgXBorder, y, 40, yCheck); 1036 MOVE(hwndEnt[EntKeyField], DlgXBorder+40, y, w, yCheck); 1037 y += yCheck; 1038 1039 MOVE(hwndEnt[EntValueLabel], DlgXBorder, y, 40, yCheck); 1040 MOVE(hwndEnt[EntValueField], DlgXBorder+40, y, w, yCheck); 1041 y += yCheck; 1042 1043 // 1044 // angle check boxes 1045 // 1046 y += 2; 1047 i = y; 1048 x = DlgXBorder; 1049 1050 xCheck = yCheck*2; 1051 1052 MOVE(hwndEnt[EntDir135], x, y, xCheck, yCheck); 1053 y += yCheck; 1054 1055 MOVE(hwndEnt[EntDir180], x, y, xCheck, yCheck); 1056 y += yCheck; 1057 1058 MOVE(hwndEnt[EntDir225], x, y, xCheck, yCheck); 1059 1060 y = i; 1061 x += xCheck; 1062 1063 1064 MOVE(hwndEnt[EntDir90], x, y, xCheck, yCheck); 1065 y += yCheck; 1066 y += yCheck; 1067 1068 MOVE(hwndEnt[EntDir270], x, y, xCheck, yCheck); 1069 1070 y = i; 1071 x += xCheck; 1072 1073 1074 MOVE(hwndEnt[EntDir45], x, y, xCheck, yCheck); 1075 y += yCheck; 1076 1077 MOVE(hwndEnt[EntDir0], x, y, xCheck, yCheck); 1078 y += yCheck; 1079 1080 MOVE(hwndEnt[EntDir315], x, y, xCheck, yCheck); 1081 1082 y = i + yCheck/2; 1083 x += xCheck + xCheck/2; 1084 1085 1086 MOVE(hwndEnt[EntDirUp], x, y, xCheck, yCheck); 1087 y += yCheck; 1088 1089 MOVE(hwndEnt[EntDirDown], x, y, xCheck, yCheck); 1090 1091 y = i; 1092 x += 1.5 * xCheck; 1093 1094 MOVE(hwndEnt[EntDelProp], x, y, xCheck*2, yCheck); 1095 y += yCheck + 4; 1096 1097 MOVE(hwndEnt[EntAssignSounds], x, y, xCheck*2, yCheck); 1098 y += yCheck; 1099 MOVE(hwndEnt[EntAssignModels], x, y, xCheck*2, yCheck); 1100 1101 // tab selector is always visible 1102 col = 0; 1103 iHeight += 24; 1104 MOVE(hwndEnt[EntTab], 0,0,iWidth,iHeight, HWND_BOTTOM, SWP_NOACTIVATE | SWP_NOCOPYBITS); 1105 1106 SendMessage( g_qeglobals.d_hwndEntity, WM_SETREDRAW, 1, 0); 1107 // InvalidateRect(entwindow, NULL, TRUE); 1108 } 1109 1110 void AssignSound() 1111 { 1112 CString strBasePath = ValueForKey(g_qeglobals.d_project_entity, "basepath"); 1113 AddSlash(strBasePath); 1114 CString strPath = strBasePath; 1115 strPath += "sound\\"; 1116 1117 CWaveOpen dlgFile(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "Sound files (*.wav)|*.wav||", g_pParentWnd); 1118 dlgFile.m_ofn.lpstrInitialDir = strPath; 1119 if (dlgFile.DoModal() == IDOK) 1120 { 1121 SendMessage(hwndEnt[EntKeyField], WM_SETTEXT, 0, (LPARAM)"noise"); 1122 CString str = dlgFile.GetPathName().GetBuffer(0); 1123 str.MakeLower(); 1124 strBasePath.MakeLower(); 1125 QE_ConvertDOSToUnixName(str.GetBuffer(0), str.GetBuffer(0)); 1126 QE_ConvertDOSToUnixName(strBasePath.GetBuffer(0), strBasePath.GetBuffer(0)); 1127 int n = str.Find(strBasePath); 1128 if (n == 0) 1129 { 1130 str = str.Right(str.GetLength() - strBasePath.GetLength()); 1131 } 1132 1133 SendMessage(hwndEnt[EntValueField], WM_SETTEXT, 0, (LPARAM)str.GetBuffer(0)); 1134 AddProp(); 1135 g_pParentWnd->GetXYWnd()->SetFocus(); 1136 } 1137 } 1138 1139 void AssignModel() 1140 { 1141 CString strBasePath = ValueForKey(g_qeglobals.d_project_entity, "basepath"); 1142 AddSlash(strBasePath); 1143 CString strPath = strBasePath; 1144 strPath += "models\\mapobjects\\"; 1145 1146 CFileDialog dlgFile(TRUE, NULL, NULL, OFN_OVERWRITEPROMPT, "Model files (*.md3)|*.md3||", g_pParentWnd); 1147 dlgFile.m_ofn.lpstrInitialDir = strPath; 1148 if (dlgFile.DoModal() == IDOK) 1149 { 1150 SendMessage(hwndEnt[EntKeyField], WM_SETTEXT, 0, (LPARAM)"model"); 1151 CString str = dlgFile.GetPathName().GetBuffer(0); 1152 str.MakeLower(); 1153 strBasePath.MakeLower(); 1154 QE_ConvertDOSToUnixName(str.GetBuffer(0), str.GetBuffer(0)); 1155 QE_ConvertDOSToUnixName(strBasePath.GetBuffer(0), strBasePath.GetBuffer(0)); 1156 int n = str.Find(strBasePath); 1157 if (n == 0) 1158 { 1159 str = str.Right(str.GetLength() - strBasePath.GetLength()); 1160 } 1161 1162 SendMessage(hwndEnt[EntValueField], WM_SETTEXT, 0, (LPARAM)str.GetBuffer(0)); 1163 AddProp(); 1164 edit_entity->md3Class = NULL; 1165 edit_entity->brushes.onext->bModelFailed = false; 1166 g_pParentWnd->GetXYWnd()->SetFocus(); 1167 } 1168 } 1169 1170 1171 /* 1172 ========================= 1173 EntityWndProc 1174 ========================= 1175 */ 1176 BOOL CALLBACK EntityWndProc( 1177 HWND hwndDlg, // handle to dialog box 1178 UINT uMsg, // message 1179 WPARAM wParam, // first message parameter 1180 LPARAM lParam) // second message parameter 1181 { 1182 LPNMHDR lpnmh = NULL; 1183 RECT rc; 1184 1185 GetClientRect(hwndDlg, &rc); 1186 1187 switch (uMsg) 1188 { 1189 1190 case WM_CHAR : 1191 { 1192 char c = toupper(LOWORD(wParam)); 1193 // escape: hide the window 1194 if (c == 27) 1195 ShowWindow(hwndDlg, SW_HIDE); 1196 if (c == 'N') 1197 g_pParentWnd->PostMessage(WM_COMMAND, ID_VIEW_ENTITY, 0); 1198 else 1199 if (c == 'O') 1200 g_pParentWnd->PostMessage(WM_COMMAND, ID_VIEW_CONSOLE, 0); 1201 else 1202 if (c == 'T') 1203 g_pParentWnd->PostMessage(WM_COMMAND, ID_VIEW_TEXTURE, 0); 1204 else 1205 if (c == 'G') 1206 g_pParentWnd->PostMessage(WM_COMMAND, ID_VIEW_GROUPS, 0); 1207 else 1208 DefWindowProc (hwndDlg, uMsg, wParam, lParam); 1209 break; 1210 } 1211 1212 case WM_NOTIFY: 1213 lpnmh = reinterpret_cast<LPNMHDR>(lParam); 1214 if (lpnmh->hwndFrom == g_wndTabs.GetSafeHwnd()) { 1215 if ( lpnmh->code == TCN_SELCHANGE) 1216 { 1217 int n = g_wndTabs.GetCurSel(); 1218 if (g_pParentWnd->CurrentStyle() == 2 || g_pParentWnd->CurrentStyle() == 1) 1219 { 1220 if (n == 0) { 1221 SetInspectorMode(W_ENTITY); 1222 } else if (n == 1) { 1223 SetInspectorMode(W_TEXTURE); 1224 } else if (n == 2) { 1225 SetInspectorMode(W_CONSOLE); 1226 } else { 1227 SetInspectorMode(W_GROUP); 1228 } 1229 } 1230 else 1231 { 1232 if (n == 0) { 1233 SetInspectorMode(W_ENTITY); 1234 } else if (n == 1) { 1235 SetInspectorMode(W_GROUP); 1236 } 1237 } 1238 } 1239 } 1240 break; 1241 1242 case WM_SIZE: 1243 1244 DefWindowProc (hwndDlg, uMsg, wParam, lParam); 1245 break; 1246 1247 case WM_DESTROY: 1248 SaveWindowPlacement(g_qeglobals.d_hwndEntity, "EntityWindowPlace"); 1249 DefWindowProc(hwndDlg, uMsg, wParam, lParam); 1250 break; 1251 1252 case WM_GETMINMAXINFO: 1253 { 1254 LPMINMAXINFO lpmmi; 1255 1256 lpmmi = (LPMINMAXINFO) lParam; 1257 lpmmi->ptMinTrackSize.x = 320; 1258 lpmmi->ptMinTrackSize.y = 500; 1259 } 1260 return 0; 1261 1262 case WM_WINDOWPOSCHANGING: 1263 { 1264 LPWINDOWPOS lpwp; 1265 lpwp = (LPWINDOWPOS) lParam; 1266 1267 DefWindowProc (hwndDlg, uMsg, wParam, lParam); 1268 1269 lpwp->flags |= SWP_NOCOPYBITS; 1270 SizeEntityDlg(lpwp->cx-8, lpwp->cy-32); 1271 return 0; 1272 1273 } 1274 return 0; 1275 1276 1277 case WM_COMMAND: 1278 switch (LOWORD(wParam)) { 1279 1280 case IDC_BTN_ASSIGNSOUND: 1281 AssignSound(); 1282 break; 1283 1284 case IDC_BTN_ASSIGNMODEL: 1285 AssignModel(); 1286 break; 1287 1288 case IDC_E_DELPROP: 1289 DelProp(); 1290 SetFocus (g_qeglobals.d_hwndCamera); 1291 break; 1292 1293 case IDC_E_0: 1294 SetKeyValue (edit_entity, "angle", "360"); 1295 SetFocus (g_qeglobals.d_hwndCamera); 1296 SetKeyValuePairs (); 1297 break; 1298 case IDC_E_45: 1299 SetKeyValue (edit_entity, "angle", "45"); 1300 SetFocus (g_qeglobals.d_hwndCamera); 1301 SetKeyValuePairs (); 1302 break; 1303 case IDC_E_90: 1304 SetKeyValue (edit_entity, "angle", "90"); 1305 SetFocus (g_qeglobals.d_hwndCamera); 1306 SetKeyValuePairs (); 1307 break; 1308 case IDC_E_135: 1309 SetKeyValue (edit_entity, "angle", "135"); 1310 SetFocus (g_qeglobals.d_hwndCamera); 1311 SetKeyValuePairs (); 1312 break; 1313 case IDC_E_180: 1314 SetKeyValue (edit_entity, "angle", "180"); 1315 SetFocus (g_qeglobals.d_hwndCamera); 1316 SetKeyValuePairs (); 1317 break; 1318 case IDC_E_225: 1319 SetKeyValue (edit_entity, "angle", "225"); 1320 SetFocus (g_qeglobals.d_hwndCamera); 1321 SetKeyValuePairs (); 1322 break; 1323 case IDC_E_270: 1324 SetKeyValue (edit_entity, "angle", "270"); 1325 SetFocus (g_qeglobals.d_hwndCamera); 1326 SetKeyValuePairs (); 1327 break; 1328 case IDC_E_315: 1329 SetKeyValue (edit_entity, "angle", "315"); 1330 SetFocus (g_qeglobals.d_hwndCamera); 1331 SetKeyValuePairs (); 1332 break; 1333 case IDC_E_UP: 1334 SetKeyValue (edit_entity, "angle", "-1"); 1335 SetFocus (g_qeglobals.d_hwndCamera); 1336 SetKeyValuePairs (); 1337 break; 1338 case IDC_E_DOWN: 1339 SetKeyValue (edit_entity, "angle", "-2"); 1340 SetFocus (g_qeglobals.d_hwndCamera); 1341 SetKeyValuePairs (); 1342 break; 1343 1344 case IDC_BTN_HIDE: 1345 ::PostMessage(g_qeglobals.d_hwndMain, WM_COMMAND, ID_VIEW_CAMERATOGGLE, 0); 1346 break; 1347 1348 case IDC_CHECK1: 1349 case IDC_CHECK2: 1350 case IDC_CHECK3: 1351 case IDC_CHECK4: 1352 case IDC_CHECK5: 1353 case IDC_CHECK6: 1354 case IDC_CHECK7: 1355 case IDC_CHECK8: 1356 case IDC_CHECK9: 1357 case IDC_CHECK10: 1358 case IDC_CHECK11: 1359 case IDC_CHECK12: 1360 GetSpawnFlags(); 1361 SetFocus (g_qeglobals.d_hwndCamera); 1362 break; 1363 1364 1365 case IDC_E_PROPS: 1366 switch (HIWORD(wParam)) 1367 { 1368 case LBN_SELCHANGE: 1369 1370 EditProp(); 1371 return TRUE; 1372 } 1373 break; 1374 1375 case IDC_E_LIST: 1376 1377 switch (HIWORD(wParam)) { 1378 1379 case LBN_SELCHANGE: 1380 { 1381 int iIndex; 1382 eclass_t *pec; 1383 1384 iIndex = SendMessage(hwndEnt[EntList], LB_GETCURSEL, 0, 0); 1385 pec = (eclass_t *)SendMessage(hwndEnt[EntList], LB_GETITEMDATA, 1386 iIndex, 0); 1387 1388 UpdateSel(iIndex, pec); 1389 1390 return TRUE; 1391 break; 1392 } 1393 1394 case LBN_DBLCLK: 1395 CreateEntity (); 1396 SetFocus (g_qeglobals.d_hwndCamera); 1397 break; 1398 } 1399 break; 1400 1401 1402 default: 1403 return DefWindowProc( hwndDlg, uMsg, wParam, lParam ); 1404 } 1405 1406 return 0; 1407 } 1408 1409 return DefWindowProc (hwndDlg, uMsg, wParam, lParam); 1410 } 1411