1 /* 2 * PROJECT: ReactOS System Control Panel Applet 3 * LICENSE: GPL - See COPYING in the top level directory 4 * FILE: dll/cpl/sysdm/environment.c 5 * PURPOSE: Environment variable settings 6 * COPYRIGHT: Copyright Eric Kohl 7 * 8 */ 9 10 #include "precomp.h" 11 12 typedef struct _VARIABLE_DATA 13 { 14 DWORD dwType; 15 LPTSTR lpName; 16 LPTSTR lpRawValue; 17 LPTSTR lpCookedValue; 18 } VARIABLE_DATA, *PVARIABLE_DATA; 19 20 21 static INT 22 GetSelectedListViewItem(HWND hwndListView) 23 { 24 INT iCount; 25 INT iItem; 26 27 iCount = SendMessage(hwndListView, 28 LVM_GETITEMCOUNT, 29 0, 30 0); 31 if (iCount != LB_ERR) 32 { 33 for (iItem = 0; iItem < iCount; iItem++) 34 { 35 if (SendMessage(hwndListView, 36 LVM_GETITEMSTATE, 37 iItem, 38 (LPARAM) LVIS_SELECTED) == LVIS_SELECTED) 39 { 40 return iItem; 41 } 42 } 43 } 44 45 return -1; 46 } 47 48 49 static INT_PTR CALLBACK 50 EditVariableDlgProc(HWND hwndDlg, 51 UINT uMsg, 52 WPARAM wParam, 53 LPARAM lParam) 54 { 55 PVARIABLE_DATA VarData; 56 DWORD dwNameLength; 57 DWORD dwValueLength; 58 59 VarData = (PVARIABLE_DATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); 60 61 switch (uMsg) 62 { 63 case WM_INITDIALOG: 64 SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)lParam); 65 VarData = (PVARIABLE_DATA)lParam; 66 67 if (VarData->lpName != NULL) 68 { 69 SendDlgItemMessage(hwndDlg, IDC_VARIABLE_NAME, WM_SETTEXT, 0, (LPARAM)VarData->lpName); 70 } 71 72 if (VarData->lpRawValue != NULL) 73 { 74 SendDlgItemMessage(hwndDlg, IDC_VARIABLE_VALUE, WM_SETTEXT, 0, (LPARAM)VarData->lpRawValue); 75 } 76 break; 77 78 case WM_COMMAND: 79 switch (LOWORD(wParam)) 80 { 81 case IDOK: 82 dwNameLength = (DWORD)SendDlgItemMessage(hwndDlg, IDC_VARIABLE_NAME, WM_GETTEXTLENGTH, 0, 0); 83 dwValueLength = (DWORD)SendDlgItemMessage(hwndDlg, IDC_VARIABLE_VALUE, WM_GETTEXTLENGTH, 0, 0); 84 if (dwNameLength > 0 && dwValueLength > 0) 85 { 86 LPTSTR p; 87 88 if (VarData->lpName == NULL) 89 { 90 VarData->lpName = GlobalAlloc(GPTR, (dwNameLength + 1) * sizeof(TCHAR)); 91 } 92 else if (_tcslen(VarData->lpName) < dwNameLength) 93 { 94 GlobalFree(VarData->lpName); 95 VarData->lpName = GlobalAlloc(GPTR, (dwNameLength + 1) * sizeof(TCHAR)); 96 } 97 SendDlgItemMessage(hwndDlg, IDC_VARIABLE_NAME, WM_GETTEXT, dwNameLength + 1, (LPARAM)VarData->lpName); 98 99 if (VarData->lpRawValue == NULL) 100 { 101 VarData->lpRawValue = GlobalAlloc(GPTR, (dwValueLength + 1) * sizeof(TCHAR)); 102 } 103 else if (_tcslen(VarData->lpRawValue) < dwValueLength) 104 { 105 GlobalFree(VarData->lpRawValue); 106 VarData->lpRawValue = GlobalAlloc(GPTR, (dwValueLength + 1) * sizeof(TCHAR)); 107 } 108 SendDlgItemMessage(hwndDlg, IDC_VARIABLE_VALUE, WM_GETTEXT, dwValueLength + 1, (LPARAM)VarData->lpRawValue); 109 110 if (VarData->lpCookedValue != NULL) 111 { 112 GlobalFree(VarData->lpCookedValue); 113 VarData->lpCookedValue = NULL; 114 } 115 116 p = _tcschr(VarData->lpRawValue, _T('%')); 117 if (p && _tcschr(++p, _T('%'))) 118 { 119 VarData->dwType = REG_EXPAND_SZ; 120 VarData->lpCookedValue = GlobalAlloc(GPTR, 2 * MAX_PATH * sizeof(TCHAR)); 121 122 ExpandEnvironmentStrings(VarData->lpRawValue, 123 VarData->lpCookedValue, 124 2 * MAX_PATH); 125 } 126 else 127 { 128 VarData->dwType = REG_SZ; 129 VarData->lpCookedValue = GlobalAlloc(GPTR, (dwValueLength + 1) * sizeof(TCHAR)); 130 _tcscpy(VarData->lpCookedValue, VarData->lpRawValue); 131 } 132 } 133 EndDialog(hwndDlg, 1); 134 return TRUE; 135 136 case IDCANCEL: 137 EndDialog(hwndDlg, 0); 138 return TRUE; 139 } 140 break; 141 } 142 143 return FALSE; 144 } 145 146 147 static VOID 148 GetEnvironmentVariables(HWND hwndListView, 149 HKEY hRootKey, 150 LPTSTR lpSubKeyName) 151 { 152 HKEY hKey; 153 DWORD dwValues; 154 DWORD dwMaxValueNameLength; 155 DWORD dwMaxValueDataLength; 156 DWORD i; 157 LPTSTR lpName; 158 LPTSTR lpData; 159 LPTSTR lpExpandData; 160 DWORD dwNameLength; 161 DWORD dwDataLength; 162 DWORD dwType; 163 PVARIABLE_DATA VarData; 164 165 LV_ITEM lvi; 166 int iItem; 167 168 if (RegOpenKeyEx(hRootKey, 169 lpSubKeyName, 170 0, 171 KEY_READ, 172 &hKey)) 173 return; 174 175 if (RegQueryInfoKey(hKey, 176 NULL, 177 NULL, 178 NULL, 179 NULL, 180 NULL, 181 NULL, 182 &dwValues, 183 &dwMaxValueNameLength, 184 &dwMaxValueDataLength, 185 NULL, 186 NULL)) 187 { 188 RegCloseKey(hKey); 189 return; 190 } 191 192 lpName = GlobalAlloc(GPTR, (dwMaxValueNameLength + 1) * sizeof(TCHAR)); 193 if (lpName == NULL) 194 { 195 RegCloseKey(hKey); 196 return; 197 } 198 199 lpData = GlobalAlloc(GPTR, (dwMaxValueDataLength + 1) * sizeof(TCHAR)); 200 if (lpData == NULL) 201 { 202 GlobalFree(lpName); 203 RegCloseKey(hKey); 204 return; 205 } 206 207 lpExpandData = GlobalAlloc(GPTR, 2048 * sizeof(TCHAR)); 208 if (lpExpandData == NULL) 209 { 210 GlobalFree(lpName); 211 GlobalFree(lpData); 212 RegCloseKey(hKey); 213 return; 214 } 215 216 for (i = 0; i < dwValues; i++) 217 { 218 dwNameLength = dwMaxValueNameLength + 1; 219 dwDataLength = dwMaxValueDataLength + 1; 220 221 if (RegEnumValue(hKey, 222 i, 223 lpName, 224 &dwNameLength, 225 NULL, 226 &dwType, 227 (LPBYTE)lpData, 228 &dwDataLength)) 229 { 230 GlobalFree(lpExpandData); 231 GlobalFree(lpName); 232 GlobalFree(lpData); 233 RegCloseKey(hKey); 234 return; 235 } 236 237 if (dwType != REG_SZ && dwType != REG_EXPAND_SZ) 238 continue; 239 240 VarData = GlobalAlloc(GPTR, sizeof(VARIABLE_DATA)); 241 242 VarData->dwType = dwType; 243 244 VarData->lpName = GlobalAlloc(GPTR, (dwNameLength + 1) * sizeof(TCHAR)); 245 _tcscpy(VarData->lpName, lpName); 246 247 VarData->lpRawValue = GlobalAlloc(GPTR, (dwDataLength + 1) * sizeof(TCHAR)); 248 _tcscpy(VarData->lpRawValue, lpData); 249 250 ExpandEnvironmentStrings(lpData, lpExpandData, 2048); 251 252 VarData->lpCookedValue = GlobalAlloc(GPTR, (_tcslen(lpExpandData) + 1) * sizeof(TCHAR)); 253 _tcscpy(VarData->lpCookedValue, lpExpandData); 254 255 memset(&lvi, 0x00, sizeof(lvi)); 256 lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_PARAM; 257 lvi.lParam = (LPARAM)VarData; 258 lvi.pszText = VarData->lpName; 259 lvi.state = (i == 0) ? LVIS_SELECTED : 0; 260 iItem = ListView_InsertItem(hwndListView, &lvi); 261 262 ListView_SetItemText(hwndListView, iItem, 1, VarData->lpCookedValue); 263 } 264 265 GlobalFree(lpExpandData); 266 GlobalFree(lpName); 267 GlobalFree(lpData); 268 RegCloseKey(hKey); 269 } 270 271 272 static VOID 273 SetEnvironmentDialogListViewColumns(HWND hwndListView) 274 { 275 RECT rect; 276 LV_COLUMN column; 277 TCHAR szStr[32]; 278 279 GetClientRect(hwndListView, &rect); 280 281 memset(&column, 0x00, sizeof(column)); 282 column.mask=LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM | LVCF_TEXT; 283 column.fmt=LVCFMT_LEFT; 284 column.cx = (INT)((rect.right - rect.left) * 0.32); 285 column.iSubItem = 0; 286 LoadString(hApplet, IDS_VARIABLE, szStr, sizeof(szStr) / sizeof(szStr[0])); 287 column.pszText = szStr; 288 (void)ListView_InsertColumn(hwndListView, 0, &column); 289 290 column.cx = (INT)((rect.right - rect.left) * 0.63); 291 column.iSubItem = 1; 292 LoadString(hApplet, IDS_VALUE, szStr, sizeof(szStr) / sizeof(szStr[0])); 293 column.pszText = szStr; 294 (void)ListView_InsertColumn(hwndListView, 1, &column); 295 } 296 297 298 static VOID 299 OnInitEnvironmentDialog(HWND hwndDlg) 300 { 301 HWND hwndListView; 302 303 /* Set user environment variables */ 304 hwndListView = GetDlgItem(hwndDlg, IDC_USER_VARIABLE_LIST); 305 306 (void)ListView_SetExtendedListViewStyle(hwndListView, LVS_EX_FULLROWSELECT); 307 308 SetEnvironmentDialogListViewColumns(hwndListView); 309 310 GetEnvironmentVariables(hwndListView, 311 HKEY_CURRENT_USER, 312 _T("Environment")); 313 314 (void)ListView_SetColumnWidth(hwndListView, 2, LVSCW_AUTOSIZE_USEHEADER); 315 316 ListView_SetItemState(hwndListView, 0, 317 LVIS_FOCUSED | LVIS_SELECTED, 318 LVIS_FOCUSED | LVIS_SELECTED); 319 320 (void)ListView_Update(hwndListView,0); 321 322 /* Set system environment variables */ 323 hwndListView = GetDlgItem(hwndDlg, IDC_SYSTEM_VARIABLE_LIST); 324 325 (void)ListView_SetExtendedListViewStyle(hwndListView, LVS_EX_FULLROWSELECT); 326 327 SetEnvironmentDialogListViewColumns(hwndListView); 328 329 GetEnvironmentVariables(hwndListView, 330 HKEY_LOCAL_MACHINE, 331 _T("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment")); 332 333 (void)ListView_SetColumnWidth(hwndListView, 2, LVSCW_AUTOSIZE_USEHEADER); 334 335 ListView_SetItemState(hwndListView, 0, 336 LVIS_FOCUSED | LVIS_SELECTED, 337 LVIS_FOCUSED | LVIS_SELECTED); 338 339 (void)ListView_Update(hwndListView, 0); 340 } 341 342 343 static VOID 344 OnNewVariable(HWND hwndDlg, 345 INT iDlgItem) 346 { 347 HWND hwndListView; 348 PVARIABLE_DATA VarData; 349 LV_ITEM lvi; 350 INT iItem; 351 352 hwndListView = GetDlgItem(hwndDlg, iDlgItem); 353 354 VarData = GlobalAlloc(GPTR, sizeof(VARIABLE_DATA)); 355 356 if (DialogBoxParam(hApplet, 357 MAKEINTRESOURCE(IDD_EDIT_VARIABLE), 358 hwndDlg, 359 EditVariableDlgProc, 360 (LPARAM)VarData) <= 0) 361 { 362 if (VarData->lpName != NULL) 363 GlobalFree(VarData->lpName); 364 365 if (VarData->lpRawValue != NULL) 366 GlobalFree(VarData->lpRawValue); 367 368 if (VarData->lpCookedValue != NULL) 369 GlobalFree(VarData->lpCookedValue); 370 371 GlobalFree(VarData); 372 } 373 else 374 { 375 if (VarData->lpName != NULL && (VarData->lpCookedValue || VarData->lpRawValue)) 376 { 377 memset(&lvi, 0x00, sizeof(lvi)); 378 lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_PARAM; 379 lvi.lParam = (LPARAM)VarData; 380 lvi.pszText = VarData->lpName; 381 lvi.state = 0; 382 iItem = ListView_InsertItem(hwndListView, &lvi); 383 384 ListView_SetItemText(hwndListView, iItem, 1, VarData->lpCookedValue); 385 } 386 } 387 } 388 389 390 static VOID 391 OnEditVariable(HWND hwndDlg, 392 INT iDlgItem) 393 { 394 HWND hwndListView; 395 PVARIABLE_DATA VarData; 396 LV_ITEM lvi; 397 INT iItem; 398 399 hwndListView = GetDlgItem(hwndDlg, iDlgItem); 400 401 iItem = GetSelectedListViewItem(hwndListView); 402 if (iItem != -1) 403 { 404 memset(&lvi, 0x00, sizeof(lvi)); 405 lvi.mask = LVIF_PARAM; 406 lvi.iItem = iItem; 407 408 if (ListView_GetItem(hwndListView, &lvi)) 409 { 410 VarData = (PVARIABLE_DATA)lvi.lParam; 411 412 if (DialogBoxParam(hApplet, 413 MAKEINTRESOURCE(IDD_EDIT_VARIABLE), 414 hwndDlg, 415 EditVariableDlgProc, 416 (LPARAM)VarData) > 0) 417 { 418 ListView_SetItemText(hwndListView, iItem, 0, VarData->lpName); 419 ListView_SetItemText(hwndListView, iItem, 1, VarData->lpCookedValue); 420 } 421 } 422 } 423 } 424 425 426 static VOID 427 OnDeleteVariable(HWND hwndDlg, 428 INT iDlgItem) 429 { 430 HWND hwndListView; 431 PVARIABLE_DATA VarData; 432 LV_ITEM lvi; 433 INT iItem; 434 435 hwndListView = GetDlgItem(hwndDlg, iDlgItem); 436 437 iItem = GetSelectedListViewItem(hwndListView); 438 if (iItem != -1) 439 { 440 memset(&lvi, 0x00, sizeof(lvi)); 441 lvi.mask = LVIF_PARAM; 442 lvi.iItem = iItem; 443 444 if (ListView_GetItem(hwndListView, &lvi)) 445 { 446 VarData = (PVARIABLE_DATA)lvi.lParam; 447 if (VarData != NULL) 448 { 449 if (VarData->lpName != NULL) 450 GlobalFree(VarData->lpName); 451 452 if (VarData->lpRawValue != NULL) 453 GlobalFree(VarData->lpRawValue); 454 455 if (VarData->lpCookedValue != NULL) 456 GlobalFree(VarData->lpCookedValue); 457 458 GlobalFree(VarData); 459 lvi.lParam = 0; 460 } 461 } 462 463 (void)ListView_DeleteItem(hwndListView, iItem); 464 465 /* Select the previous item */ 466 if (iItem > 0) 467 iItem--; 468 469 ListView_SetItemState(hwndListView, iItem, 470 LVIS_FOCUSED | LVIS_SELECTED, 471 LVIS_FOCUSED | LVIS_SELECTED); 472 } 473 } 474 475 476 static VOID 477 ReleaseListViewItems(HWND hwndDlg, 478 INT iDlgItem) 479 { 480 HWND hwndListView; 481 PVARIABLE_DATA VarData; 482 LV_ITEM lvi; 483 INT nItemCount; 484 INT i; 485 486 hwndListView = GetDlgItem(hwndDlg, iDlgItem); 487 488 memset(&lvi, 0x00, sizeof(lvi)); 489 490 nItemCount = ListView_GetItemCount(hwndListView); 491 for (i = 0; i < nItemCount; i++) 492 { 493 lvi.mask = LVIF_PARAM; 494 lvi.iItem = i; 495 496 if (ListView_GetItem(hwndListView, &lvi)) 497 { 498 VarData = (PVARIABLE_DATA)lvi.lParam; 499 if (VarData != NULL) 500 { 501 if (VarData->lpName != NULL) 502 GlobalFree(VarData->lpName); 503 504 if (VarData->lpRawValue != NULL) 505 GlobalFree(VarData->lpRawValue); 506 507 if (VarData->lpCookedValue != NULL) 508 GlobalFree(VarData->lpCookedValue); 509 510 GlobalFree(VarData); 511 lvi.lParam = 0; 512 } 513 } 514 } 515 } 516 517 518 static VOID 519 SetAllVars(HWND hwndDlg, 520 INT iDlgItem) 521 { 522 HWND hwndListView; 523 PVARIABLE_DATA VarData; 524 LV_ITEM lvi; 525 INT iItem; 526 HKEY hKey; 527 DWORD dwValueCount; 528 DWORD dwMaxValueNameLength; 529 LPTSTR *aValueArray; 530 DWORD dwNameLength; 531 DWORD i; 532 TCHAR szBuffer[256]; 533 LPTSTR lpBuffer; 534 535 memset(&lvi, 0x00, sizeof(lvi)); 536 537 /* Get the handle to the list box with all system vars in it */ 538 hwndListView = GetDlgItem(hwndDlg, iDlgItem); 539 /* First item is 0 */ 540 iItem = 0; 541 /* Set up struct to retrieve item */ 542 lvi.mask = LVIF_PARAM; 543 lvi.iItem = iItem; 544 545 /* Open or create the key */ 546 if (RegCreateKeyEx((iDlgItem == IDC_SYSTEM_VARIABLE_LIST ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER), 547 (iDlgItem == IDC_SYSTEM_VARIABLE_LIST ? _T("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment") : _T("Environment")), 548 0, 549 NULL, 550 REG_OPTION_NON_VOLATILE, 551 KEY_WRITE | KEY_READ, 552 NULL, 553 &hKey, 554 NULL)) 555 { 556 return; 557 } 558 559 /* Get the number of values and the maximum value name length */ 560 if (RegQueryInfoKey(hKey, 561 NULL, 562 NULL, 563 NULL, 564 NULL, 565 NULL, 566 NULL, 567 &dwValueCount, 568 &dwMaxValueNameLength, 569 NULL, 570 NULL, 571 NULL)) 572 { 573 RegCloseKey(hKey); 574 return; 575 } 576 577 if (dwValueCount > 0) 578 { 579 /* Allocate the value array */ 580 aValueArray = GlobalAlloc(GPTR, dwValueCount * sizeof(LPTSTR)); 581 if (aValueArray != NULL) 582 { 583 /* Get all value names */ 584 for (i = 0; i < dwValueCount; i++) 585 { 586 dwNameLength = 256; 587 if (!RegEnumValue(hKey, 588 i, 589 szBuffer, 590 &dwNameLength, 591 NULL, 592 NULL, 593 NULL, 594 NULL)) 595 { 596 /* Allocate a value name buffer, fill it and attach it to the array */ 597 lpBuffer = (LPTSTR)GlobalAlloc(GPTR, (dwNameLength + 1) * sizeof(TCHAR)); 598 if (lpBuffer != NULL) 599 { 600 _tcscpy(lpBuffer, szBuffer); 601 aValueArray[i] = lpBuffer; 602 } 603 } 604 } 605 606 /* Delete all values */ 607 for (i = 0; i < dwValueCount; i++) 608 { 609 if (aValueArray[i] != NULL) 610 { 611 /* Delete the value */ 612 RegDeleteValue(hKey, 613 aValueArray[i]); 614 615 /* Free the value name */ 616 GlobalFree(aValueArray[i]); 617 } 618 } 619 620 /* Free the value array */ 621 GlobalFree(aValueArray); 622 } 623 } 624 625 /* Loop through all variables */ 626 while (ListView_GetItem(hwndListView, &lvi)) 627 { 628 /* Get the data in each item */ 629 VarData = (PVARIABLE_DATA)lvi.lParam; 630 if (VarData != NULL) 631 { 632 /* Set the new value */ 633 if (RegSetValueEx(hKey, 634 VarData->lpName, 635 0, 636 VarData->dwType, 637 (LPBYTE)VarData->lpRawValue, 638 (DWORD)(_tcslen(VarData->lpRawValue) + 1) * sizeof(TCHAR))) 639 { 640 RegCloseKey(hKey); 641 return; 642 } 643 } 644 645 /* Fill struct for next item */ 646 lvi.mask = LVIF_PARAM; 647 lvi.iItem = ++iItem; 648 } 649 650 RegCloseKey(hKey); 651 } 652 653 654 static BOOL 655 OnNotify(HWND hwndDlg, NMHDR *phdr) 656 { 657 switch(phdr->code) 658 { 659 case NM_DBLCLK: 660 if (phdr->idFrom == IDC_USER_VARIABLE_LIST || 661 phdr->idFrom == IDC_SYSTEM_VARIABLE_LIST) 662 { 663 OnEditVariable(hwndDlg, (INT)phdr->idFrom); 664 return TRUE; 665 } 666 break; 667 668 case LVN_KEYDOWN: 669 if (((LPNMLVKEYDOWN)phdr)->wVKey == VK_DELETE && 670 (phdr->idFrom == IDC_USER_VARIABLE_LIST || 671 phdr->idFrom == IDC_SYSTEM_VARIABLE_LIST)) 672 { 673 OnDeleteVariable(hwndDlg, (INT)phdr->idFrom); 674 return TRUE; 675 } 676 break; 677 } 678 679 return FALSE; 680 } 681 682 683 /* Environment dialog procedure */ 684 INT_PTR CALLBACK 685 EnvironmentDlgProc(HWND hwndDlg, 686 UINT uMsg, 687 WPARAM wParam, 688 LPARAM lParam) 689 { 690 switch (uMsg) 691 { 692 case WM_INITDIALOG: 693 OnInitEnvironmentDialog(hwndDlg); 694 break; 695 696 case WM_COMMAND: 697 switch (LOWORD(wParam)) 698 { 699 case IDC_USER_VARIABLE_NEW: 700 OnNewVariable(hwndDlg, IDC_USER_VARIABLE_LIST); 701 return TRUE; 702 703 case IDC_USER_VARIABLE_EDIT: 704 OnEditVariable(hwndDlg, IDC_USER_VARIABLE_LIST); 705 return TRUE; 706 707 case IDC_USER_VARIABLE_DELETE: 708 OnDeleteVariable(hwndDlg, IDC_USER_VARIABLE_LIST); 709 return TRUE; 710 711 case IDC_SYSTEM_VARIABLE_NEW: 712 OnNewVariable(hwndDlg, IDC_SYSTEM_VARIABLE_LIST); 713 return TRUE; 714 715 case IDC_SYSTEM_VARIABLE_EDIT: 716 OnEditVariable(hwndDlg, IDC_SYSTEM_VARIABLE_LIST); 717 return TRUE; 718 719 case IDC_SYSTEM_VARIABLE_DELETE: 720 OnDeleteVariable(hwndDlg, IDC_SYSTEM_VARIABLE_LIST); 721 return TRUE; 722 723 case IDOK: 724 SetAllVars(hwndDlg, IDC_USER_VARIABLE_LIST); 725 SetAllVars(hwndDlg, IDC_SYSTEM_VARIABLE_LIST); 726 SendMessage(HWND_BROADCAST, WM_WININICHANGE, 727 0, (LPARAM)_T("Environment")); 728 EndDialog(hwndDlg, 0); 729 return TRUE; 730 731 case IDCANCEL: 732 EndDialog(hwndDlg, 0); 733 return TRUE; 734 } 735 break; 736 737 case WM_DESTROY: 738 ReleaseListViewItems(hwndDlg, IDC_USER_VARIABLE_LIST); 739 ReleaseListViewItems(hwndDlg, IDC_SYSTEM_VARIABLE_LIST); 740 break; 741 742 case WM_NOTIFY: 743 return OnNotify(hwndDlg, (NMHDR*)lParam); 744 } 745 746 return FALSE; 747 } 748 749 /* EOF */ 750