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 * Copyright 2021 Arnav Bhatt <arnavbhatt288@gmail.com> 8 */ 9 10 #include "precomp.h" 11 #include <commctrl.h> 12 #include <commdlg.h> 13 #include <string.h> 14 15 typedef struct _VARIABLE_DATA 16 { 17 DWORD dwType; 18 LPTSTR lpName; 19 LPTSTR lpRawValue; 20 LPTSTR lpCookedValue; 21 } VARIABLE_DATA, *PVARIABLE_DATA; 22 23 typedef struct _ENVIRONMENT_DIALOG_DATA 24 { 25 DWORD cxMin; 26 DWORD cyMin; 27 DWORD cxOld; 28 DWORD cyOld; 29 } ENVIRONMENT_DIALOG_DATA, *PENVIRONMENT_DIALOG_DATA; 30 31 typedef struct _ENVIRONMENT_EDIT_DIALOG_DATA 32 { 33 BOOL bIsItemSelected; 34 DWORD dwSelectedValueIndex; 35 DWORD cxMin; 36 DWORD cyMin; 37 DWORD cxOld; 38 DWORD cyOld; 39 DWORD dwDlgID; 40 HWND hEditBox; 41 PVARIABLE_DATA VarData; 42 } EDIT_DIALOG_DATA, *PEDIT_DIALOG_DATA; 43 44 static BOOL 45 DetermineDialogBoxType(LPTSTR lpRawValue) 46 { 47 DWORD dwValueLength; 48 LPTSTR lpTemp; 49 LPTSTR lpToken; 50 51 dwValueLength = _tcslen(lpRawValue) + 1; 52 lpTemp = GlobalAlloc(GPTR, dwValueLength * sizeof(TCHAR)); 53 if (!lpTemp) 54 return FALSE; 55 56 StringCchCopy(lpTemp, dwValueLength, lpRawValue); 57 58 for (lpToken = _tcstok(lpTemp, _T(";")); 59 lpToken != NULL; 60 lpToken = _tcstok(NULL, _T(";"))) 61 { 62 /* If the string has environment variable then expand it */ 63 ExpandEnvironmentStrings(lpToken, lpToken, dwValueLength); 64 65 if (!PathIsDirectoryW(lpToken)) 66 return FALSE; 67 } 68 GlobalFree(lpTemp); 69 70 return TRUE; 71 } 72 73 static DWORD 74 GatherDataFromEditBox(HWND hwndDlg, 75 PVARIABLE_DATA VarData) 76 { 77 DWORD dwNameLength; 78 DWORD dwValueLength; 79 80 dwNameLength = SendDlgItemMessage(hwndDlg, IDC_VARIABLE_NAME, WM_GETTEXTLENGTH, 0, 0); 81 dwValueLength = SendDlgItemMessage(hwndDlg, IDC_VARIABLE_VALUE, WM_GETTEXTLENGTH, 0, 0); 82 83 if (dwNameLength == 0 || dwValueLength == 0) 84 { 85 return 0; 86 } 87 88 /* Reallocate the name buffer, regrowing it if necessary */ 89 if (!VarData->lpName || (_tcslen(VarData->lpName) < dwNameLength)) 90 { 91 if (VarData->lpName) 92 GlobalFree(VarData->lpName); 93 94 VarData->lpName = GlobalAlloc(GPTR, (dwNameLength + 1) * sizeof(TCHAR)); 95 if (!VarData->lpName) 96 return 0; 97 } 98 SendDlgItemMessage(hwndDlg, IDC_VARIABLE_NAME, WM_GETTEXT, dwNameLength + 1, (LPARAM)VarData->lpName); 99 100 /* Reallocate the value buffer, regrowing it if necessary */ 101 if (!VarData->lpRawValue || (_tcslen(VarData->lpRawValue) < dwValueLength)) 102 { 103 if (VarData->lpRawValue) 104 GlobalFree(VarData->lpRawValue); 105 106 VarData->lpRawValue = GlobalAlloc(GPTR, (dwValueLength + 1) * sizeof(TCHAR)); 107 if (!VarData->lpRawValue) 108 return 0; 109 } 110 SendDlgItemMessage(hwndDlg, IDC_VARIABLE_VALUE, WM_GETTEXT, dwValueLength + 1, (LPARAM)VarData->lpRawValue); 111 112 return dwValueLength; 113 } 114 115 static DWORD 116 GatherDataFromListView(HWND hwndListView, 117 PVARIABLE_DATA VarData) 118 { 119 DWORD dwValueLength; 120 DWORD NumberOfItems; 121 DWORD i; 122 TCHAR szData[MAX_PATH]; 123 124 /* Gather the number of items for the semi-colon */ 125 NumberOfItems = ListView_GetItemCount(hwndListView); 126 if (NumberOfItems == 0) 127 { 128 return 0; 129 } 130 131 /* Since the last item doesn't need the semi-colon subtract 1 */ 132 dwValueLength = NumberOfItems - 1; 133 134 for (i = 0; i < NumberOfItems; i++) 135 { 136 ListView_GetItemText(hwndListView, 137 i, 138 0, 139 szData, 140 _countof(szData)); 141 dwValueLength += _tcslen(szData); 142 } 143 144 /* Reallocate the value buffer, regrowing it if necessary */ 145 if (!VarData->lpRawValue || (_tcslen(VarData->lpRawValue) < dwValueLength)) 146 { 147 if (VarData->lpRawValue) 148 GlobalFree(VarData->lpRawValue); 149 150 VarData->lpRawValue = GlobalAlloc(GPTR, (dwValueLength + 1) * sizeof(TCHAR)); 151 if (!VarData->lpRawValue) 152 return 0; 153 } 154 155 /* First reinitialize the value buffer, then copy the variable values while 156 * separating them with a semi-colon, except for the last value. */ 157 VarData->lpRawValue[0] = _T('\0'); 158 for (i = 0; i < NumberOfItems; i++) 159 { 160 if (i > 0) 161 { 162 StringCchCat(VarData->lpRawValue, dwValueLength + 1, _T(";")); 163 } 164 ListView_GetItemText(hwndListView, 165 i, 166 0, 167 szData, 168 _countof(szData)); 169 StringCchCat(VarData->lpRawValue, dwValueLength + 1, szData); 170 } 171 return dwValueLength; 172 } 173 174 static INT 175 GetSelectedListViewItem(HWND hwndListView) 176 { 177 INT iCount; 178 INT iItem; 179 180 iCount = SendMessage(hwndListView, 181 LVM_GETITEMCOUNT, 182 0, 183 0); 184 if (iCount != LB_ERR) 185 { 186 for (iItem = 0; iItem < iCount; iItem++) 187 { 188 if (SendMessage(hwndListView, 189 LVM_GETITEMSTATE, 190 iItem, 191 (LPARAM) LVIS_SELECTED) == LVIS_SELECTED) 192 { 193 return iItem; 194 } 195 } 196 } 197 198 return -1; 199 } 200 201 static LRESULT CALLBACK 202 ListViewSubclassProc(HWND hListBox, 203 UINT uMsg, 204 WPARAM wParam, 205 LPARAM lParam, 206 UINT_PTR uIdSubclass, 207 DWORD_PTR dwRefData) 208 { 209 switch (uMsg) 210 { 211 case WM_DESTROY: 212 { 213 RemoveWindowSubclass(hListBox, ListViewSubclassProc, uIdSubclass); 214 break; 215 } 216 217 /* Whenever the control is resized make sure it doesn't spawn the horizontal scrollbar */ 218 case WM_SIZE: 219 { 220 ShowScrollBar(hListBox, SB_HORZ, FALSE); 221 break; 222 } 223 } 224 225 return DefSubclassProc(hListBox, uMsg, wParam, lParam); 226 } 227 228 static VOID 229 AddEmptyItem(HWND hwndListView, 230 DWORD dwSelectedValueIndex) 231 { 232 LV_ITEM lvi; 233 234 ZeroMemory(&lvi, sizeof(lvi)); 235 lvi.mask = LVIF_TEXT | LVIF_STATE; 236 lvi.cchTextMax = MAX_PATH; 237 lvi.pszText = _T(""); 238 lvi.iItem = dwSelectedValueIndex; 239 lvi.iSubItem = 0; 240 ListView_InsertItem(hwndListView, &lvi); 241 } 242 243 static VOID 244 AddValuesToList(HWND hwndDlg, 245 PEDIT_DIALOG_DATA DlgData) 246 { 247 LV_COLUMN column; 248 LV_ITEM lvi; 249 RECT rItem; 250 251 DWORD dwValueLength; 252 DWORD i; 253 HWND hwndListView; 254 LPTSTR lpTemp; 255 LPTSTR lpToken; 256 257 ZeroMemory(&column, sizeof(column)); 258 ZeroMemory(&lvi, sizeof(lvi)); 259 260 hwndListView = GetDlgItem(hwndDlg, IDC_LIST_VARIABLE_VALUE); 261 262 GetClientRect(hwndListView, &rItem); 263 264 column.mask = LVCF_WIDTH; 265 column.cx = rItem.right; 266 ListView_InsertColumn(hwndListView, 0, &column); 267 ShowScrollBar(hwndListView, SB_HORZ, FALSE); 268 269 lvi.mask = LVIF_TEXT | LVIF_STATE; 270 lvi.cchTextMax = MAX_PATH; 271 lvi.iSubItem = 0; 272 273 dwValueLength = _tcslen(DlgData->VarData->lpRawValue) + 1; 274 lpTemp = GlobalAlloc(GPTR, dwValueLength * sizeof(TCHAR)); 275 if (!lpTemp) 276 return; 277 278 StringCchCopy(lpTemp, dwValueLength, DlgData->VarData->lpRawValue); 279 280 for (lpToken = _tcstok(lpTemp, _T(";")), i = 0; 281 lpToken != NULL; 282 lpToken = _tcstok(NULL, _T(";")), i++) 283 { 284 lvi.iItem = i; 285 lvi.pszText = lpToken; 286 lvi.state = (i == 0) ? LVIS_SELECTED : 0; 287 ListView_InsertItem(hwndListView, &lvi); 288 } 289 290 DlgData->dwSelectedValueIndex = 0; 291 ListView_SetExtendedListViewStyle(hwndListView, LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT); 292 ListView_SetItemState(hwndListView, DlgData->dwSelectedValueIndex, 293 LVIS_FOCUSED | LVIS_SELECTED, 294 LVIS_FOCUSED | LVIS_SELECTED); 295 296 ListView_Update(hwndListView, DlgData->dwSelectedValueIndex); 297 GlobalFree(lpTemp); 298 } 299 300 static VOID 301 BrowseRequiredFile(HWND hwndDlg) 302 { 303 OPENFILENAME ofn; 304 TCHAR szFilter[MAX_STR_LENGTH] = _T(""); 305 TCHAR szFile[MAX_PATH] = _T(""); 306 307 LoadString(hApplet, IDS_FILE_BROWSE_FILTER, szFilter, _countof(szFilter)); 308 309 ZeroMemory(&ofn, sizeof(ofn)); 310 311 ofn.lStructSize = sizeof(ofn); 312 ofn.hwndOwner = hwndDlg; 313 ofn.lpstrFilter = szFilter; 314 ofn.lpstrFile = szFile; 315 ofn.nMaxFile = _countof(szFile); 316 ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; 317 318 if (GetOpenFileName(&ofn)) 319 { 320 SetDlgItemText(hwndDlg, IDC_VARIABLE_VALUE, szFile); 321 } 322 } 323 324 static VOID 325 BrowseRequiredFolder(HWND hwndDlg, 326 PEDIT_DIALOG_DATA DlgData) 327 { 328 HWND hwndListView; 329 TCHAR szDir[MAX_PATH]; 330 331 BROWSEINFO bi; 332 LPITEMIDLIST pidllist; 333 334 ZeroMemory(&bi, sizeof(bi)); 335 bi.hwndOwner = hwndDlg; 336 bi.ulFlags = BIF_NEWDIALOGSTYLE; 337 338 hwndListView = GetDlgItem(hwndDlg, IDC_LIST_VARIABLE_VALUE); 339 340 pidllist = SHBrowseForFolder(&bi); 341 if (!pidllist) 342 { 343 return; 344 } 345 346 if (SHGetPathFromIDList(pidllist, szDir)) 347 { 348 if (DlgData->dwDlgID == IDD_EDIT_VARIABLE_FANCY) 349 { 350 /* If no item is selected then create a new empty item and add the required location to it */ 351 if (!DlgData->bIsItemSelected) 352 { 353 DlgData->dwSelectedValueIndex = ListView_GetItemCount(hwndListView); 354 AddEmptyItem(hwndListView, DlgData->dwSelectedValueIndex); 355 } 356 ListView_SetItemText(hwndListView, 357 DlgData->dwSelectedValueIndex, 358 0, 359 szDir); 360 ListView_SetItemState(hwndListView, DlgData->dwSelectedValueIndex, 361 LVIS_FOCUSED | LVIS_SELECTED, 362 LVIS_FOCUSED | LVIS_SELECTED); 363 } 364 else 365 { 366 SetDlgItemText(hwndDlg, IDC_VARIABLE_VALUE, szDir); 367 } 368 } 369 370 CoTaskMemFree(pidllist); 371 } 372 373 static VOID 374 MoveListItem(HWND hwndDlg, 375 PEDIT_DIALOG_DATA DlgData, 376 BOOL bMoveUp) 377 { 378 TCHAR szDest[MAX_PATH]; 379 TCHAR szSource[MAX_PATH]; 380 HWND hwndListView; 381 DWORD dwSrcIndex, dwDestIndex, dwLastIndex; 382 383 hwndListView = GetDlgItem(hwndDlg, IDC_LIST_VARIABLE_VALUE); 384 385 dwLastIndex = ListView_GetItemCount(hwndListView) - 1; 386 dwSrcIndex = DlgData->dwSelectedValueIndex; 387 dwDestIndex = bMoveUp ? (dwSrcIndex - 1) : (dwSrcIndex + 1); 388 389 if ((bMoveUp && dwSrcIndex > 0) || (!bMoveUp && dwSrcIndex < dwLastIndex)) 390 { 391 ListView_GetItemText(hwndListView, 392 dwSrcIndex, 393 0, 394 szDest, 395 _countof(szDest)); 396 ListView_GetItemText(hwndListView, 397 dwDestIndex, 398 0, 399 szSource, 400 _countof(szSource)); 401 402 ListView_SetItemText(hwndListView, 403 dwDestIndex, 404 0, 405 szDest); 406 ListView_SetItemText(hwndListView, 407 dwSrcIndex, 408 0, 409 szSource); 410 411 DlgData->dwSelectedValueIndex = dwDestIndex; 412 ListView_SetItemState(hwndListView, DlgData->dwSelectedValueIndex, 413 LVIS_FOCUSED | LVIS_SELECTED, 414 LVIS_FOCUSED | LVIS_SELECTED); 415 } 416 } 417 418 static VOID 419 OnEnvironmentEditDlgResize(HWND hwndDlg, 420 PEDIT_DIALOG_DATA DlgData, 421 DWORD cx, 422 DWORD cy) 423 { 424 RECT rect; 425 HDWP hdwp = NULL; 426 HWND hItemWnd; 427 428 if ((cx == DlgData->cxOld) && (cy == DlgData->cyOld)) 429 return; 430 431 if (DlgData->dwDlgID == IDD_EDIT_VARIABLE) 432 { 433 hdwp = BeginDeferWindowPos(5); 434 435 /* For the edit control */ 436 hItemWnd = GetDlgItem(hwndDlg, IDC_VARIABLE_NAME); 437 GetWindowRect(hItemWnd, &rect); 438 MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); 439 440 if (hdwp) 441 { 442 hdwp = DeferWindowPos(hdwp, 443 hItemWnd, 444 NULL, 445 0, 0, 446 (rect.right - rect.left) + (cx - DlgData->cxOld), 447 rect.bottom - rect.top, 448 SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); 449 } 450 451 hItemWnd = GetDlgItem(hwndDlg, IDC_VARIABLE_VALUE); 452 GetWindowRect(hItemWnd, &rect); 453 MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); 454 455 if (hdwp) 456 { 457 hdwp = DeferWindowPos(hdwp, 458 hItemWnd, 459 NULL, 460 0, 0, 461 (rect.right - rect.left) + (cx - DlgData->cxOld), 462 rect.bottom - rect.top, 463 SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); 464 } 465 } 466 else if (DlgData->dwDlgID == IDD_EDIT_VARIABLE_FANCY) 467 { 468 hdwp = BeginDeferWindowPos(11); 469 470 /* For the list view control */ 471 hItemWnd = GetDlgItem(hwndDlg, IDC_LIST_VARIABLE_VALUE); 472 GetWindowRect(hItemWnd, &rect); 473 MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); 474 475 if (hdwp) 476 { 477 hdwp = DeferWindowPos(hdwp, 478 hItemWnd, 479 NULL, 480 0, 0, 481 (rect.right - rect.left) + (cx - DlgData->cxOld), 482 (rect.bottom - rect.top) + (cy - DlgData->cyOld), 483 SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); 484 ListView_SetColumnWidth(hItemWnd, 0, (rect.right - rect.left) + (cx - DlgData->cxOld)); 485 } 486 487 /* For the buttons */ 488 hItemWnd = GetDlgItem(hwndDlg, IDC_BUTTON_BROWSE_FOLDER); 489 GetWindowRect(hItemWnd, &rect); 490 MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); 491 492 if (hdwp) 493 { 494 hdwp = DeferWindowPos(hdwp, 495 hItemWnd, 496 NULL, 497 rect.left + (cx - DlgData->cxOld), 498 rect.top, 499 0, 0, 500 SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); 501 } 502 503 hItemWnd = GetDlgItem(hwndDlg, IDC_BUTTON_NEW); 504 GetWindowRect(hItemWnd, &rect); 505 MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); 506 507 if (hdwp) 508 { 509 hdwp = DeferWindowPos(hdwp, 510 hItemWnd, 511 NULL, 512 rect.left + (cx - DlgData->cxOld), 513 rect.top, 514 0, 0, 515 SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); 516 } 517 518 hItemWnd = GetDlgItem(hwndDlg, IDC_BUTTON_EDIT); 519 GetWindowRect(hItemWnd, &rect); 520 MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); 521 522 if (hdwp) 523 { 524 hdwp = DeferWindowPos(hdwp, 525 hItemWnd, 526 NULL, 527 rect.left + (cx - DlgData->cxOld), 528 rect.top, 529 0, 0, 530 SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); 531 } 532 533 hItemWnd = GetDlgItem(hwndDlg, IDC_BUTTON_DELETE); 534 GetWindowRect(hItemWnd, &rect); 535 MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); 536 537 if (hdwp) 538 { 539 hdwp = DeferWindowPos(hdwp, 540 hItemWnd, 541 NULL, 542 rect.left + (cx - DlgData->cxOld), 543 rect.top, 544 0, 0, 545 SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); 546 } 547 548 hItemWnd = GetDlgItem(hwndDlg, IDC_BUTTON_MOVE_UP); 549 GetWindowRect(hItemWnd, &rect); 550 MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); 551 552 if (hdwp) 553 { 554 hdwp = DeferWindowPos(hdwp, 555 hItemWnd, 556 NULL, 557 rect.left + (cx - DlgData->cxOld), 558 rect.top, 559 0, 0, 560 SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); 561 } 562 563 hItemWnd = GetDlgItem(hwndDlg, IDC_BUTTON_MOVE_DOWN); 564 GetWindowRect(hItemWnd, &rect); 565 MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); 566 567 if (hdwp) 568 { 569 hdwp = DeferWindowPos(hdwp, 570 hItemWnd, 571 NULL, 572 rect.left + (cx - DlgData->cxOld), 573 rect.top, 574 0, 0, 575 SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); 576 } 577 578 hItemWnd = GetDlgItem(hwndDlg, IDC_BUTTON_EDIT_TEXT); 579 GetWindowRect(hItemWnd, &rect); 580 MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); 581 582 if (hdwp) 583 { 584 hdwp = DeferWindowPos(hdwp, 585 hItemWnd, 586 NULL, 587 rect.left + (cx - DlgData->cxOld), 588 rect.top, 589 0, 0, 590 SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); 591 } 592 } 593 594 hItemWnd = GetDlgItem(hwndDlg, IDOK); 595 GetWindowRect(hItemWnd, &rect); 596 MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); 597 598 if (hdwp) 599 { 600 hdwp = DeferWindowPos(hdwp, 601 hItemWnd, 602 NULL, 603 rect.left + (cx - DlgData->cxOld), 604 rect.top + (cy - DlgData->cyOld), 605 0, 0, 606 SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); 607 } 608 609 hItemWnd = GetDlgItem(hwndDlg, IDCANCEL); 610 GetWindowRect(hItemWnd, &rect); 611 MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); 612 613 if (hdwp) 614 { 615 hdwp = DeferWindowPos(hdwp, 616 hItemWnd, 617 NULL, 618 rect.left + (cx - DlgData->cxOld), 619 rect.top + (cy - DlgData->cyOld), 620 0, 0, 621 SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); 622 } 623 624 /* For the size grip */ 625 hItemWnd = GetDlgItem(hwndDlg, IDC_DIALOG_GRIP); 626 GetWindowRect(hItemWnd, &rect); 627 MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); 628 629 if (hdwp) 630 { 631 hdwp = DeferWindowPos(hdwp, 632 hItemWnd, 633 NULL, 634 rect.left + (cx - DlgData->cxOld), 635 rect.top + (cy - DlgData->cyOld), 636 0, 0, 637 SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); 638 } 639 640 if (hdwp) 641 { 642 EndDeferWindowPos(hdwp); 643 } 644 645 DlgData->cxOld = cx; 646 DlgData->cyOld = cy; 647 } 648 649 static BOOL 650 OnBeginLabelEdit(NMLVDISPINFO* pnmv) 651 { 652 HWND hwndEdit; 653 654 hwndEdit = ListView_GetEditControl(pnmv->hdr.hwndFrom); 655 if (hwndEdit == NULL) 656 { 657 return TRUE; 658 } 659 660 SendMessage(hwndEdit, EM_SETLIMITTEXT, MAX_PATH - 1, 0); 661 662 return FALSE; 663 } 664 665 static BOOL 666 OnEndLabelEdit(NMLVDISPINFO* pnmv) 667 { 668 HWND hwndEdit; 669 TCHAR szOldDir[MAX_PATH]; 670 TCHAR szNewDir[MAX_PATH]; 671 672 hwndEdit = ListView_GetEditControl(pnmv->hdr.hwndFrom); 673 if (hwndEdit == NULL) 674 { 675 return TRUE; 676 } 677 678 /* Leave, if there is no valid listview item */ 679 if (pnmv->item.iItem == -1) 680 { 681 return FALSE; 682 } 683 684 ListView_GetItemText(pnmv->hdr.hwndFrom, 685 pnmv->item.iItem, 0, 686 szOldDir, 687 _countof(szOldDir)); 688 689 SendMessage(hwndEdit, WM_GETTEXT, _countof(szNewDir), (LPARAM)szNewDir); 690 691 /* If there is nothing in the text box then remove the item */ 692 if (_tcslen(szNewDir) == 0) 693 { 694 ListView_DeleteItem(pnmv->hdr.hwndFrom, pnmv->item.iItem); 695 ListView_SetItemState(pnmv->hdr.hwndFrom, pnmv->item.iItem - 1, 696 LVIS_FOCUSED | LVIS_SELECTED, 697 LVIS_FOCUSED | LVIS_SELECTED); 698 return FALSE; 699 } 700 701 /* If nothing has been changed then just bail out */ 702 if (_tcscmp(szOldDir, szNewDir) == 0) 703 { 704 return FALSE; 705 } 706 707 ListView_SetItemText(pnmv->hdr.hwndFrom, 708 pnmv->item.iItem, 0, 709 szNewDir); 710 711 return TRUE; 712 } 713 714 static BOOL 715 OnNotifyEditVariableDlg(HWND hwndDlg, PEDIT_DIALOG_DATA DlgData, NMHDR *phdr) 716 { 717 LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)phdr; 718 719 switch (phdr->idFrom) 720 { 721 case IDC_LIST_VARIABLE_VALUE: 722 switch (phdr->code) 723 { 724 case NM_CLICK: 725 { 726 /* Detect if an item is selected */ 727 DlgData->bIsItemSelected = (lpnmlv->iItem != -1); 728 if (lpnmlv->iItem != -1) 729 { 730 DlgData->dwSelectedValueIndex = lpnmlv->iItem; 731 } 732 break; 733 } 734 735 case NM_DBLCLK: 736 { 737 /* Either simulate IDC_BUTTON_NEW or edit an item depending upon the condition */ 738 if (lpnmlv->iItem == -1) 739 { 740 SendMessage(GetDlgItem(hwndDlg, IDC_BUTTON_NEW), BM_CLICK, 0, 0); 741 } 742 else 743 { 744 ListView_EditLabel(GetDlgItem(hwndDlg, IDC_LIST_VARIABLE_VALUE), DlgData->dwSelectedValueIndex); 745 } 746 break; 747 } 748 749 case LVN_BEGINLABELEDIT: 750 { 751 return OnBeginLabelEdit((NMLVDISPINFO*)phdr); 752 } 753 754 case LVN_ENDLABELEDIT: 755 { 756 return OnEndLabelEdit((NMLVDISPINFO*)phdr); 757 } 758 } 759 break; 760 } 761 762 return FALSE; 763 } 764 765 static INT_PTR CALLBACK 766 EditVariableDlgProc(HWND hwndDlg, 767 UINT uMsg, 768 WPARAM wParam, 769 LPARAM lParam) 770 { 771 PEDIT_DIALOG_DATA DlgData; 772 HWND hwndListView; 773 774 DlgData = (PEDIT_DIALOG_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER); 775 hwndListView = GetDlgItem(hwndDlg, IDC_LIST_VARIABLE_VALUE); 776 777 switch (uMsg) 778 { 779 case WM_INITDIALOG: 780 { 781 RECT rect; 782 783 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)lParam); 784 DlgData = (PEDIT_DIALOG_DATA)lParam; 785 786 GetClientRect(hwndDlg, &rect); 787 DlgData->cxOld = rect.right - rect.left; 788 DlgData->cyOld = rect.bottom - rect.top; 789 790 GetWindowRect(hwndDlg, &rect); 791 DlgData->cxMin = rect.right - rect.left; 792 DlgData->cyMin = rect.bottom - rect.top; 793 794 /* Either get the values from list box or from edit box */ 795 if (DlgData->dwDlgID == IDD_EDIT_VARIABLE_FANCY) 796 { 797 /* Subclass the listview control first */ 798 SetWindowSubclass(hwndListView, ListViewSubclassProc, 1, 0); 799 800 if (DlgData->VarData->lpRawValue != NULL) 801 { 802 AddValuesToList(hwndDlg, DlgData); 803 } 804 } 805 else 806 { 807 if (DlgData->VarData->lpName != NULL) 808 { 809 SendDlgItemMessage(hwndDlg, IDC_VARIABLE_NAME, WM_SETTEXT, 0, (LPARAM)DlgData->VarData->lpName); 810 } 811 812 if (DlgData->VarData->lpRawValue != NULL) 813 { 814 SendDlgItemMessage(hwndDlg, IDC_VARIABLE_VALUE, WM_SETTEXT, 0, (LPARAM)DlgData->VarData->lpRawValue); 815 } 816 } 817 break; 818 } 819 820 case WM_SIZE: 821 { 822 OnEnvironmentEditDlgResize(hwndDlg, DlgData, LOWORD(lParam), HIWORD(lParam)); 823 SetWindowLongPtrW(hwndDlg, DWLP_MSGRESULT, 0); 824 return TRUE; 825 } 826 827 case WM_SIZING: 828 { 829 /* Forbid resizing the dialog smaller than its minimal size */ 830 PRECT pRect = (PRECT)lParam; 831 832 if ((wParam == WMSZ_LEFT) || (wParam == WMSZ_TOPLEFT) || (wParam == WMSZ_BOTTOMLEFT)) 833 { 834 if (pRect->right - pRect->left < DlgData->cxMin) 835 pRect->left = pRect->right - DlgData->cxMin; 836 } 837 else 838 if ((wParam == WMSZ_RIGHT) || (wParam == WMSZ_TOPRIGHT) || (wParam == WMSZ_BOTTOMRIGHT)) 839 { 840 if (pRect->right - pRect->left < DlgData->cxMin) 841 pRect->right = pRect->left + DlgData->cxMin; 842 } 843 844 if ((wParam == WMSZ_TOP) || (wParam == WMSZ_TOPLEFT) || (wParam == WMSZ_TOPRIGHT)) 845 { 846 if (pRect->bottom - pRect->top < DlgData->cyMin) 847 pRect->top = pRect->bottom - DlgData->cyMin; 848 } 849 else 850 if ((wParam == WMSZ_BOTTOM) || (wParam == WMSZ_BOTTOMLEFT) || (wParam == WMSZ_BOTTOMRIGHT)) 851 { 852 if (pRect->bottom - pRect->top < DlgData->cyMin) 853 pRect->bottom = pRect->top + DlgData->cyMin; 854 } 855 856 /* Make sure the normal variable edit dialog doesn't change its height */ 857 if (DlgData->dwDlgID == IDD_EDIT_VARIABLE) 858 { 859 if ((wParam == WMSZ_TOP) || (wParam == WMSZ_TOPLEFT) || (wParam == WMSZ_TOPRIGHT)) 860 { 861 if (pRect->bottom - pRect->top > DlgData->cyMin) 862 pRect->top = pRect->bottom - DlgData->cyMin; 863 } 864 else 865 if ((wParam == WMSZ_BOTTOM) || (wParam == WMSZ_BOTTOMLEFT) || (wParam == WMSZ_BOTTOMRIGHT)) 866 { 867 if (pRect->bottom - pRect->top > DlgData->cyMin) 868 pRect->bottom = pRect->top + DlgData->cyMin; 869 } 870 } 871 872 SetWindowLongPtrW(hwndDlg, DWLP_MSGRESULT, TRUE); 873 return TRUE; 874 } 875 876 case WM_NOTIFY: 877 { 878 return OnNotifyEditVariableDlg(hwndDlg, DlgData, (NMHDR*)lParam); 879 } 880 881 case WM_COMMAND: 882 switch (LOWORD(wParam)) 883 { 884 case IDOK: 885 { 886 LPTSTR p; 887 DWORD dwValueLength; 888 889 /* Either set the values to the list box or to the edit box */ 890 if (DlgData->dwDlgID == IDD_EDIT_VARIABLE_FANCY) 891 { 892 dwValueLength = GatherDataFromListView(hwndListView, DlgData->VarData); 893 } 894 else 895 { 896 dwValueLength = GatherDataFromEditBox(hwndDlg, DlgData->VarData); 897 } 898 899 if (dwValueLength == 0) 900 { 901 break; 902 } 903 904 if (DlgData->VarData->lpCookedValue != NULL) 905 { 906 GlobalFree(DlgData->VarData->lpCookedValue); 907 DlgData->VarData->lpCookedValue = NULL; 908 } 909 910 p = _tcschr(DlgData->VarData->lpRawValue, _T('%')); 911 if (p && _tcschr(++p, _T('%'))) 912 { 913 DlgData->VarData->dwType = REG_EXPAND_SZ; 914 915 DlgData->VarData->lpCookedValue = GlobalAlloc(GPTR, 2 * MAX_PATH * sizeof(TCHAR)); 916 if (!DlgData->VarData->lpCookedValue) 917 return FALSE; 918 919 ExpandEnvironmentStrings(DlgData->VarData->lpRawValue, 920 DlgData->VarData->lpCookedValue, 921 2 * MAX_PATH); 922 } 923 else 924 { 925 DlgData->VarData->dwType = REG_SZ; 926 927 DlgData->VarData->lpCookedValue = GlobalAlloc(GPTR, (dwValueLength + 1) * sizeof(TCHAR)); 928 if (!DlgData->VarData->lpCookedValue) 929 return FALSE; 930 931 _tcscpy(DlgData->VarData->lpCookedValue, DlgData->VarData->lpRawValue); 932 } 933 934 EndDialog(hwndDlg, 1); 935 return TRUE; 936 } 937 938 case IDCANCEL: 939 EndDialog(hwndDlg, 0); 940 return TRUE; 941 942 case IDC_BUTTON_BROWSE_FILE: 943 { 944 BrowseRequiredFile(hwndDlg); 945 break; 946 } 947 948 case IDC_BUTTON_BROWSE_FOLDER: 949 { 950 BrowseRequiredFolder(hwndDlg, DlgData); 951 break; 952 } 953 954 case IDC_BUTTON_DELETE: 955 { 956 DWORD dwLastIndex; 957 958 dwLastIndex = ListView_GetItemCount(hwndListView) - 1; 959 ListView_DeleteItem(hwndListView, DlgData->dwSelectedValueIndex); 960 961 if (dwLastIndex == DlgData->dwSelectedValueIndex) 962 { 963 DlgData->dwSelectedValueIndex--; 964 } 965 966 ListView_SetItemState(hwndListView, DlgData->dwSelectedValueIndex, 967 LVIS_FOCUSED | LVIS_SELECTED, 968 LVIS_FOCUSED | LVIS_SELECTED); 969 break; 970 } 971 972 case IDC_BUTTON_MOVE_UP: 973 { 974 MoveListItem(hwndDlg, DlgData, TRUE); 975 break; 976 } 977 978 case IDC_BUTTON_MOVE_DOWN: 979 { 980 MoveListItem(hwndDlg, DlgData, FALSE); 981 break; 982 } 983 984 case IDC_BUTTON_EDIT_TEXT: 985 { 986 if (ResourceMessageBox(hApplet, 987 hwndDlg, 988 MB_OKCANCEL | MB_ICONWARNING | MB_DEFBUTTON1, 989 IDS_ENVIRONMENT_WARNING_TITLE, 990 IDS_ENVIRONMENT_WARNING) == IDOK) 991 { 992 EndDialog(hwndDlg, -1); 993 } 994 break; 995 } 996 997 case IDC_BUTTON_NEW: 998 { 999 DlgData->dwSelectedValueIndex = ListView_GetItemCount(hwndListView); 1000 AddEmptyItem(hwndListView, DlgData->dwSelectedValueIndex); 1001 ListView_EditLabel(hwndListView, DlgData->dwSelectedValueIndex); 1002 break; 1003 } 1004 1005 case IDC_BUTTON_EDIT: 1006 { 1007 ListView_EditLabel(hwndListView, DlgData->dwSelectedValueIndex); 1008 break; 1009 } 1010 } 1011 break; 1012 } 1013 1014 return FALSE; 1015 } 1016 1017 1018 static VOID 1019 GetEnvironmentVariables(HWND hwndListView, 1020 HKEY hRootKey, 1021 LPTSTR lpSubKeyName) 1022 { 1023 HKEY hKey; 1024 DWORD dwValues; 1025 DWORD dwMaxValueNameLength; 1026 DWORD dwMaxValueDataLength; 1027 DWORD i; 1028 LPTSTR lpName; 1029 LPTSTR lpData; 1030 LPTSTR lpExpandData; 1031 DWORD dwNameLength; 1032 DWORD dwDataLength; 1033 DWORD dwType; 1034 PVARIABLE_DATA VarData; 1035 1036 LV_ITEM lvi; 1037 int iItem; 1038 1039 if (RegOpenKeyEx(hRootKey, 1040 lpSubKeyName, 1041 0, 1042 KEY_READ, 1043 &hKey)) 1044 return; 1045 1046 if (RegQueryInfoKey(hKey, 1047 NULL, 1048 NULL, 1049 NULL, 1050 NULL, 1051 NULL, 1052 NULL, 1053 &dwValues, 1054 &dwMaxValueNameLength, 1055 &dwMaxValueDataLength, 1056 NULL, 1057 NULL)) 1058 { 1059 RegCloseKey(hKey); 1060 return; 1061 } 1062 1063 lpName = GlobalAlloc(GPTR, (dwMaxValueNameLength + 1) * sizeof(TCHAR)); 1064 if (lpName == NULL) 1065 { 1066 RegCloseKey(hKey); 1067 return; 1068 } 1069 1070 lpData = GlobalAlloc(GPTR, (dwMaxValueDataLength + 1) * sizeof(TCHAR)); 1071 if (lpData == NULL) 1072 { 1073 GlobalFree(lpName); 1074 RegCloseKey(hKey); 1075 return; 1076 } 1077 1078 lpExpandData = GlobalAlloc(GPTR, 2048 * sizeof(TCHAR)); 1079 if (lpExpandData == NULL) 1080 { 1081 GlobalFree(lpName); 1082 GlobalFree(lpData); 1083 RegCloseKey(hKey); 1084 return; 1085 } 1086 1087 for (i = 0; i < dwValues; i++) 1088 { 1089 dwNameLength = dwMaxValueNameLength + 1; 1090 dwDataLength = dwMaxValueDataLength + 1; 1091 1092 if (RegEnumValue(hKey, 1093 i, 1094 lpName, 1095 &dwNameLength, 1096 NULL, 1097 &dwType, 1098 (LPBYTE)lpData, 1099 &dwDataLength)) 1100 { 1101 GlobalFree(lpExpandData); 1102 GlobalFree(lpName); 1103 GlobalFree(lpData); 1104 RegCloseKey(hKey); 1105 return; 1106 } 1107 1108 if (dwType != REG_SZ && dwType != REG_EXPAND_SZ) 1109 continue; 1110 1111 VarData = GlobalAlloc(GPTR, sizeof(VARIABLE_DATA)); 1112 1113 VarData->dwType = dwType; 1114 1115 VarData->lpName = GlobalAlloc(GPTR, (dwNameLength + 1) * sizeof(TCHAR)); 1116 _tcscpy(VarData->lpName, lpName); 1117 1118 VarData->lpRawValue = GlobalAlloc(GPTR, (dwDataLength + 1) * sizeof(TCHAR)); 1119 _tcscpy(VarData->lpRawValue, lpData); 1120 1121 ExpandEnvironmentStrings(lpData, lpExpandData, 2048); 1122 1123 VarData->lpCookedValue = GlobalAlloc(GPTR, (_tcslen(lpExpandData) + 1) * sizeof(TCHAR)); 1124 _tcscpy(VarData->lpCookedValue, lpExpandData); 1125 1126 memset(&lvi, 0x00, sizeof(lvi)); 1127 lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_PARAM; 1128 lvi.lParam = (LPARAM)VarData; 1129 lvi.pszText = VarData->lpName; 1130 lvi.state = (i == 0) ? LVIS_SELECTED : 0; 1131 iItem = ListView_InsertItem(hwndListView, &lvi); 1132 1133 ListView_SetItemText(hwndListView, iItem, 1, VarData->lpCookedValue); 1134 } 1135 1136 GlobalFree(lpExpandData); 1137 GlobalFree(lpName); 1138 GlobalFree(lpData); 1139 RegCloseKey(hKey); 1140 } 1141 1142 1143 static VOID 1144 SetEnvironmentDialogListViewColumns(HWND hwndListView) 1145 { 1146 RECT rect; 1147 LV_COLUMN column; 1148 TCHAR szStr[32]; 1149 1150 GetClientRect(hwndListView, &rect); 1151 1152 memset(&column, 0x00, sizeof(column)); 1153 column.mask=LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM | LVCF_TEXT; 1154 column.fmt=LVCFMT_LEFT; 1155 column.cx = (INT)((rect.right - rect.left) * 0.32); 1156 column.iSubItem = 0; 1157 LoadString(hApplet, IDS_VARIABLE, szStr, sizeof(szStr) / sizeof(szStr[0])); 1158 column.pszText = szStr; 1159 (void)ListView_InsertColumn(hwndListView, 0, &column); 1160 1161 column.cx = (INT)((rect.right - rect.left) * 0.63); 1162 column.iSubItem = 1; 1163 LoadString(hApplet, IDS_VALUE, szStr, sizeof(szStr) / sizeof(szStr[0])); 1164 column.pszText = szStr; 1165 (void)ListView_InsertColumn(hwndListView, 1, &column); 1166 } 1167 1168 1169 static VOID 1170 OnInitEnvironmentDialog(HWND hwndDlg) 1171 { 1172 HWND hwndListView; 1173 1174 /* Set user environment variables */ 1175 hwndListView = GetDlgItem(hwndDlg, IDC_USER_VARIABLE_LIST); 1176 1177 (void)ListView_SetExtendedListViewStyle(hwndListView, LVS_EX_FULLROWSELECT); 1178 1179 SetEnvironmentDialogListViewColumns(hwndListView); 1180 1181 GetEnvironmentVariables(hwndListView, 1182 HKEY_CURRENT_USER, 1183 _T("Environment")); 1184 1185 (void)ListView_SetColumnWidth(hwndListView, 2, LVSCW_AUTOSIZE_USEHEADER); 1186 1187 ListView_SetItemState(hwndListView, 0, 1188 LVIS_FOCUSED | LVIS_SELECTED, 1189 LVIS_FOCUSED | LVIS_SELECTED); 1190 1191 (void)ListView_Update(hwndListView,0); 1192 1193 /* Set system environment variables */ 1194 hwndListView = GetDlgItem(hwndDlg, IDC_SYSTEM_VARIABLE_LIST); 1195 1196 (void)ListView_SetExtendedListViewStyle(hwndListView, LVS_EX_FULLROWSELECT); 1197 1198 SetEnvironmentDialogListViewColumns(hwndListView); 1199 1200 GetEnvironmentVariables(hwndListView, 1201 HKEY_LOCAL_MACHINE, 1202 _T("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment")); 1203 1204 (void)ListView_SetColumnWidth(hwndListView, 2, LVSCW_AUTOSIZE_USEHEADER); 1205 1206 ListView_SetItemState(hwndListView, 0, 1207 LVIS_FOCUSED | LVIS_SELECTED, 1208 LVIS_FOCUSED | LVIS_SELECTED); 1209 1210 (void)ListView_Update(hwndListView, 0); 1211 } 1212 1213 1214 static VOID 1215 OnNewVariable(HWND hwndDlg, 1216 INT iDlgItem) 1217 { 1218 HWND hwndListView; 1219 PEDIT_DIALOG_DATA DlgData; 1220 LV_ITEM lvi; 1221 INT iItem; 1222 1223 DlgData = GlobalAlloc(GPTR, sizeof(EDIT_DIALOG_DATA)); 1224 if (!DlgData) 1225 return; 1226 1227 hwndListView = GetDlgItem(hwndDlg, iDlgItem); 1228 DlgData->dwDlgID = IDD_EDIT_VARIABLE; 1229 DlgData->dwSelectedValueIndex = -1; 1230 1231 DlgData->VarData = GlobalAlloc(GPTR, sizeof(VARIABLE_DATA)); 1232 if (!DlgData->VarData) 1233 return; 1234 1235 if (DialogBoxParam(hApplet, 1236 MAKEINTRESOURCE(DlgData->dwDlgID), 1237 hwndDlg, 1238 EditVariableDlgProc, 1239 (LPARAM)DlgData) <= 0) 1240 { 1241 if (DlgData->VarData->lpName != NULL) 1242 GlobalFree(DlgData->VarData->lpName); 1243 1244 if (DlgData->VarData->lpRawValue != NULL) 1245 GlobalFree(DlgData->VarData->lpRawValue); 1246 1247 if (DlgData->VarData->lpCookedValue != NULL) 1248 GlobalFree(DlgData->VarData->lpCookedValue); 1249 1250 GlobalFree(DlgData); 1251 } 1252 else 1253 { 1254 if (DlgData->VarData->lpName != NULL && (DlgData->VarData->lpCookedValue || DlgData->VarData->lpRawValue)) 1255 { 1256 ZeroMemory(&lvi, sizeof(lvi)); 1257 lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_PARAM; 1258 lvi.lParam = (LPARAM)DlgData->VarData; 1259 lvi.pszText = DlgData->VarData->lpName; 1260 lvi.state = 0; 1261 iItem = ListView_InsertItem(hwndListView, &lvi); 1262 1263 ListView_SetItemText(hwndListView, iItem, 1, DlgData->VarData->lpCookedValue); 1264 } 1265 } 1266 } 1267 1268 1269 static VOID 1270 OnEditVariable(HWND hwndDlg, 1271 INT iDlgItem) 1272 { 1273 HWND hwndListView; 1274 PEDIT_DIALOG_DATA DlgData; 1275 LV_ITEM lvi; 1276 INT iItem; 1277 INT iRet; 1278 1279 DlgData = GlobalAlloc(GPTR, sizeof(EDIT_DIALOG_DATA)); 1280 if (!DlgData) 1281 return; 1282 1283 DlgData->dwDlgID = IDD_EDIT_VARIABLE; 1284 DlgData->dwSelectedValueIndex = -1; 1285 1286 hwndListView = GetDlgItem(hwndDlg, iDlgItem); 1287 1288 iItem = GetSelectedListViewItem(hwndListView); 1289 if (iItem != -1) 1290 { 1291 ZeroMemory(&lvi, sizeof(lvi)); 1292 lvi.mask = LVIF_PARAM; 1293 lvi.iItem = iItem; 1294 1295 if (ListView_GetItem(hwndListView, &lvi)) 1296 { 1297 DlgData->VarData = (PVARIABLE_DATA)lvi.lParam; 1298 1299 /* If the value has multiple values and directories then edit value with fancy dialog box */ 1300 if (DetermineDialogBoxType(DlgData->VarData->lpRawValue)) 1301 DlgData->dwDlgID = IDD_EDIT_VARIABLE_FANCY; 1302 1303 iRet = DialogBoxParam(hApplet, 1304 MAKEINTRESOURCE(DlgData->dwDlgID), 1305 hwndDlg, 1306 EditVariableDlgProc, 1307 (LPARAM)DlgData); 1308 1309 /* If iRet is less than 0 edit the value and name normally */ 1310 if (iRet < 0) 1311 { 1312 DlgData->dwDlgID = IDD_EDIT_VARIABLE; 1313 iRet = DialogBoxParam(hApplet, 1314 MAKEINTRESOURCE(DlgData->dwDlgID), 1315 hwndDlg, 1316 EditVariableDlgProc, 1317 (LPARAM)DlgData); 1318 } 1319 1320 if (iRet > 0) 1321 { 1322 ListView_SetItemText(hwndListView, iItem, 0, DlgData->VarData->lpName); 1323 ListView_SetItemText(hwndListView, iItem, 1, DlgData->VarData->lpCookedValue); 1324 } 1325 } 1326 1327 GlobalFree(DlgData); 1328 } 1329 } 1330 1331 1332 static VOID 1333 OnDeleteVariable(HWND hwndDlg, 1334 INT iDlgItem) 1335 { 1336 HWND hwndListView; 1337 PVARIABLE_DATA VarData; 1338 LV_ITEM lvi; 1339 INT iItem; 1340 1341 hwndListView = GetDlgItem(hwndDlg, iDlgItem); 1342 1343 iItem = GetSelectedListViewItem(hwndListView); 1344 if (iItem != -1) 1345 { 1346 memset(&lvi, 0x00, sizeof(lvi)); 1347 lvi.mask = LVIF_PARAM; 1348 lvi.iItem = iItem; 1349 1350 if (ListView_GetItem(hwndListView, &lvi)) 1351 { 1352 VarData = (PVARIABLE_DATA)lvi.lParam; 1353 if (VarData != NULL) 1354 { 1355 if (VarData->lpName != NULL) 1356 GlobalFree(VarData->lpName); 1357 1358 if (VarData->lpRawValue != NULL) 1359 GlobalFree(VarData->lpRawValue); 1360 1361 if (VarData->lpCookedValue != NULL) 1362 GlobalFree(VarData->lpCookedValue); 1363 1364 GlobalFree(VarData); 1365 lvi.lParam = 0; 1366 } 1367 } 1368 1369 (void)ListView_DeleteItem(hwndListView, iItem); 1370 1371 /* Select the previous item */ 1372 if (iItem > 0) 1373 iItem--; 1374 1375 ListView_SetItemState(hwndListView, iItem, 1376 LVIS_FOCUSED | LVIS_SELECTED, 1377 LVIS_FOCUSED | LVIS_SELECTED); 1378 } 1379 } 1380 1381 static VOID 1382 OnEnvironmentDlgResize(HWND hwndDlg, 1383 PENVIRONMENT_DIALOG_DATA DlgData, 1384 DWORD cx, 1385 DWORD cy) 1386 { 1387 RECT rect; 1388 INT Colx, y = 0; 1389 HDWP hdwp = NULL; 1390 HWND hItemWnd; 1391 1392 if ((cx == DlgData->cxOld) && (cy == DlgData->cyOld)) 1393 return; 1394 1395 hdwp = BeginDeferWindowPos(13); 1396 1397 if (cy >= DlgData->cyOld) 1398 y += (cy - DlgData->cyOld + 1) / 2; 1399 else 1400 y -= (DlgData->cyOld - cy + 1) / 2; 1401 1402 /* For the group box controls */ 1403 hItemWnd = GetDlgItem(hwndDlg, IDC_USER_VARIABLE_GROUP); 1404 GetWindowRect(hItemWnd, &rect); 1405 MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); 1406 1407 if (hdwp) 1408 { 1409 hdwp = DeferWindowPos(hdwp, 1410 hItemWnd, 1411 NULL, 1412 0, 0, 1413 (rect.right - rect.left) + (cx - DlgData->cxOld), 1414 (rect.bottom - rect.top) + y, 1415 SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); 1416 } 1417 1418 hItemWnd = GetDlgItem(hwndDlg, IDC_SYSTEM_VARIABLE_GROUP); 1419 GetWindowRect(hItemWnd, &rect); 1420 MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); 1421 1422 if (hdwp) 1423 { 1424 hdwp = DeferWindowPos(hdwp, 1425 hItemWnd, 1426 NULL, 1427 rect.left, rect.top + y, 1428 (rect.right - rect.left) + (cx - DlgData->cxOld), 1429 (rect.bottom - rect.top) + y, 1430 SWP_NOZORDER | SWP_NOACTIVATE); 1431 } 1432 1433 /* For the list view controls */ 1434 hItemWnd = GetDlgItem(hwndDlg, IDC_USER_VARIABLE_LIST); 1435 GetWindowRect(hItemWnd, &rect); 1436 MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); 1437 1438 if (hdwp) 1439 { 1440 hdwp = DeferWindowPos(hdwp, 1441 hItemWnd, 1442 NULL, 1443 0, 0, 1444 (rect.right - rect.left) + (cx - DlgData->cxOld), 1445 (rect.bottom - rect.top) + y, 1446 SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); 1447 Colx = ListView_GetColumnWidth(hItemWnd, 1); 1448 ListView_SetColumnWidth(hItemWnd, 1, Colx + (cx - DlgData->cxOld)); 1449 } 1450 1451 hItemWnd = GetDlgItem(hwndDlg, IDC_SYSTEM_VARIABLE_LIST); 1452 GetWindowRect(hItemWnd, &rect); 1453 MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); 1454 1455 if (hdwp) 1456 { 1457 hdwp = DeferWindowPos(hdwp, 1458 hItemWnd, 1459 NULL, 1460 rect.left, rect.top + y, 1461 (rect.right - rect.left) + (cx - DlgData->cxOld), 1462 (rect.bottom - rect.top) + y, 1463 SWP_NOZORDER | SWP_NOACTIVATE); 1464 Colx = ListView_GetColumnWidth(hItemWnd, 1); 1465 ListView_SetColumnWidth(hItemWnd, 1, Colx + (cx - DlgData->cxOld)); 1466 } 1467 1468 /* For the buttons */ 1469 hItemWnd = GetDlgItem(hwndDlg, IDC_USER_VARIABLE_NEW); 1470 GetWindowRect(hItemWnd, &rect); 1471 MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); 1472 1473 if (hdwp) 1474 { 1475 hdwp = DeferWindowPos(hdwp, 1476 hItemWnd, 1477 NULL, 1478 rect.left + (cx - DlgData->cxOld), 1479 rect.top + y, 1480 0, 0, 1481 SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); 1482 } 1483 1484 hItemWnd = GetDlgItem(hwndDlg, IDC_USER_VARIABLE_EDIT); 1485 GetWindowRect(hItemWnd, &rect); 1486 MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); 1487 1488 if (hdwp) 1489 { 1490 hdwp = DeferWindowPos(hdwp, 1491 hItemWnd, 1492 NULL, 1493 rect.left + (cx - DlgData->cxOld), 1494 rect.top + y, 1495 0, 0, 1496 SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); 1497 } 1498 1499 hItemWnd = GetDlgItem(hwndDlg, IDC_USER_VARIABLE_DELETE); 1500 GetWindowRect(hItemWnd, &rect); 1501 MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); 1502 1503 if (hdwp) 1504 { 1505 hdwp = DeferWindowPos(hdwp, 1506 hItemWnd, 1507 NULL, 1508 rect.left + (cx - DlgData->cxOld), 1509 rect.top + y, 1510 0, 0, 1511 SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); 1512 } 1513 1514 hItemWnd = GetDlgItem(hwndDlg, IDC_SYSTEM_VARIABLE_NEW); 1515 GetWindowRect(hItemWnd, &rect); 1516 MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); 1517 1518 if (hdwp) 1519 { 1520 hdwp = DeferWindowPos(hdwp, 1521 hItemWnd, 1522 NULL, 1523 rect.left + (cx - DlgData->cxOld), 1524 rect.top + y * 2, 1525 0, 0, 1526 SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); 1527 } 1528 1529 hItemWnd = GetDlgItem(hwndDlg, IDC_SYSTEM_VARIABLE_EDIT); 1530 GetWindowRect(hItemWnd, &rect); 1531 MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); 1532 1533 if (hdwp) 1534 { 1535 hdwp = DeferWindowPos(hdwp, 1536 hItemWnd, 1537 NULL, 1538 rect.left + (cx - DlgData->cxOld), 1539 rect.top + y * 2, 1540 0, 0, 1541 SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); 1542 } 1543 1544 hItemWnd = GetDlgItem(hwndDlg, IDC_SYSTEM_VARIABLE_DELETE); 1545 GetWindowRect(hItemWnd, &rect); 1546 MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); 1547 1548 if (hdwp) 1549 { 1550 hdwp = DeferWindowPos(hdwp, 1551 hItemWnd, 1552 NULL, 1553 rect.left + (cx - DlgData->cxOld), 1554 rect.top + y * 2, 1555 0, 0, 1556 SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); 1557 } 1558 1559 hItemWnd = GetDlgItem(hwndDlg, IDOK); 1560 GetWindowRect(hItemWnd, &rect); 1561 MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); 1562 1563 if (hdwp) 1564 { 1565 hdwp = DeferWindowPos(hdwp, 1566 hItemWnd, 1567 NULL, 1568 rect.left + (cx - DlgData->cxOld), 1569 rect.top + (cy - DlgData->cyOld), 1570 0, 0, 1571 SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); 1572 } 1573 1574 hItemWnd = GetDlgItem(hwndDlg, IDCANCEL); 1575 GetWindowRect(hItemWnd, &rect); 1576 MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); 1577 1578 if (hdwp) 1579 { 1580 hdwp = DeferWindowPos(hdwp, 1581 hItemWnd, 1582 NULL, 1583 rect.left + (cx - DlgData->cxOld), 1584 rect.top + (cy - DlgData->cyOld), 1585 0, 0, 1586 SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); 1587 } 1588 1589 /* For the size grip */ 1590 hItemWnd = GetDlgItem(hwndDlg, IDC_DIALOG_GRIP); 1591 GetWindowRect(hItemWnd, &rect); 1592 MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); 1593 1594 if (hdwp) 1595 { 1596 hdwp = DeferWindowPos(hdwp, 1597 hItemWnd, 1598 NULL, 1599 rect.left + (cx - DlgData->cxOld), 1600 rect.top + (cy - DlgData->cyOld), 1601 0, 0, 1602 SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); 1603 } 1604 1605 if (hdwp) 1606 { 1607 EndDeferWindowPos(hdwp); 1608 } 1609 1610 DlgData->cxOld = cx; 1611 DlgData->cyOld = cy; 1612 } 1613 1614 static VOID 1615 ReleaseListViewItems(HWND hwndDlg, 1616 INT iDlgItem) 1617 { 1618 HWND hwndListView; 1619 PVARIABLE_DATA VarData; 1620 LV_ITEM lvi; 1621 INT nItemCount; 1622 INT i; 1623 1624 hwndListView = GetDlgItem(hwndDlg, iDlgItem); 1625 1626 memset(&lvi, 0x00, sizeof(lvi)); 1627 1628 nItemCount = ListView_GetItemCount(hwndListView); 1629 for (i = 0; i < nItemCount; i++) 1630 { 1631 lvi.mask = LVIF_PARAM; 1632 lvi.iItem = i; 1633 1634 if (ListView_GetItem(hwndListView, &lvi)) 1635 { 1636 VarData = (PVARIABLE_DATA)lvi.lParam; 1637 if (VarData != NULL) 1638 { 1639 if (VarData->lpName != NULL) 1640 GlobalFree(VarData->lpName); 1641 1642 if (VarData->lpRawValue != NULL) 1643 GlobalFree(VarData->lpRawValue); 1644 1645 if (VarData->lpCookedValue != NULL) 1646 GlobalFree(VarData->lpCookedValue); 1647 1648 GlobalFree(VarData); 1649 lvi.lParam = 0; 1650 } 1651 } 1652 } 1653 } 1654 1655 1656 static VOID 1657 SetAllVars(HWND hwndDlg, 1658 INT iDlgItem) 1659 { 1660 HWND hwndListView; 1661 PVARIABLE_DATA VarData; 1662 LV_ITEM lvi; 1663 INT iItem; 1664 HKEY hKey; 1665 DWORD dwValueCount; 1666 DWORD dwMaxValueNameLength; 1667 LPTSTR *aValueArray; 1668 DWORD dwNameLength; 1669 DWORD i; 1670 TCHAR szBuffer[256]; 1671 LPTSTR lpBuffer; 1672 1673 memset(&lvi, 0x00, sizeof(lvi)); 1674 1675 /* Get the handle to the list box with all system vars in it */ 1676 hwndListView = GetDlgItem(hwndDlg, iDlgItem); 1677 /* First item is 0 */ 1678 iItem = 0; 1679 /* Set up struct to retrieve item */ 1680 lvi.mask = LVIF_PARAM; 1681 lvi.iItem = iItem; 1682 1683 /* Open or create the key */ 1684 if (RegCreateKeyEx((iDlgItem == IDC_SYSTEM_VARIABLE_LIST ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER), 1685 (iDlgItem == IDC_SYSTEM_VARIABLE_LIST ? _T("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment") : _T("Environment")), 1686 0, 1687 NULL, 1688 REG_OPTION_NON_VOLATILE, 1689 KEY_WRITE | KEY_READ, 1690 NULL, 1691 &hKey, 1692 NULL)) 1693 { 1694 return; 1695 } 1696 1697 /* Get the number of values and the maximum value name length */ 1698 if (RegQueryInfoKey(hKey, 1699 NULL, 1700 NULL, 1701 NULL, 1702 NULL, 1703 NULL, 1704 NULL, 1705 &dwValueCount, 1706 &dwMaxValueNameLength, 1707 NULL, 1708 NULL, 1709 NULL)) 1710 { 1711 RegCloseKey(hKey); 1712 return; 1713 } 1714 1715 if (dwValueCount > 0) 1716 { 1717 /* Allocate the value array */ 1718 aValueArray = GlobalAlloc(GPTR, dwValueCount * sizeof(LPTSTR)); 1719 if (aValueArray != NULL) 1720 { 1721 /* Get all value names */ 1722 for (i = 0; i < dwValueCount; i++) 1723 { 1724 dwNameLength = 256; 1725 if (!RegEnumValue(hKey, 1726 i, 1727 szBuffer, 1728 &dwNameLength, 1729 NULL, 1730 NULL, 1731 NULL, 1732 NULL)) 1733 { 1734 /* Allocate a value name buffer, fill it and attach it to the array */ 1735 lpBuffer = (LPTSTR)GlobalAlloc(GPTR, (dwNameLength + 1) * sizeof(TCHAR)); 1736 if (lpBuffer != NULL) 1737 { 1738 _tcscpy(lpBuffer, szBuffer); 1739 aValueArray[i] = lpBuffer; 1740 } 1741 } 1742 } 1743 1744 /* Delete all values */ 1745 for (i = 0; i < dwValueCount; i++) 1746 { 1747 if (aValueArray[i] != NULL) 1748 { 1749 /* Delete the value */ 1750 RegDeleteValue(hKey, 1751 aValueArray[i]); 1752 1753 /* Free the value name */ 1754 GlobalFree(aValueArray[i]); 1755 } 1756 } 1757 1758 /* Free the value array */ 1759 GlobalFree(aValueArray); 1760 } 1761 } 1762 1763 /* Loop through all variables */ 1764 while (ListView_GetItem(hwndListView, &lvi)) 1765 { 1766 /* Get the data in each item */ 1767 VarData = (PVARIABLE_DATA)lvi.lParam; 1768 if (VarData != NULL) 1769 { 1770 /* Set the new value */ 1771 if (RegSetValueEx(hKey, 1772 VarData->lpName, 1773 0, 1774 VarData->dwType, 1775 (LPBYTE)VarData->lpRawValue, 1776 (DWORD)(_tcslen(VarData->lpRawValue) + 1) * sizeof(TCHAR))) 1777 { 1778 RegCloseKey(hKey); 1779 return; 1780 } 1781 } 1782 1783 /* Fill struct for next item */ 1784 lvi.mask = LVIF_PARAM; 1785 lvi.iItem = ++iItem; 1786 } 1787 1788 RegCloseKey(hKey); 1789 } 1790 1791 1792 static BOOL 1793 OnNotify(HWND hwndDlg, NMHDR *phdr) 1794 { 1795 switch (phdr->code) 1796 { 1797 case NM_DBLCLK: 1798 if (phdr->idFrom == IDC_USER_VARIABLE_LIST || 1799 phdr->idFrom == IDC_SYSTEM_VARIABLE_LIST) 1800 { 1801 OnEditVariable(hwndDlg, (INT)phdr->idFrom); 1802 return TRUE; 1803 } 1804 break; 1805 1806 case LVN_KEYDOWN: 1807 if (((LPNMLVKEYDOWN)phdr)->wVKey == VK_DELETE && 1808 (phdr->idFrom == IDC_USER_VARIABLE_LIST || 1809 phdr->idFrom == IDC_SYSTEM_VARIABLE_LIST)) 1810 { 1811 OnDeleteVariable(hwndDlg, (INT)phdr->idFrom); 1812 return TRUE; 1813 } 1814 break; 1815 } 1816 1817 return FALSE; 1818 } 1819 1820 1821 /* Environment dialog procedure */ 1822 INT_PTR CALLBACK 1823 EnvironmentDlgProc(HWND hwndDlg, 1824 UINT uMsg, 1825 WPARAM wParam, 1826 LPARAM lParam) 1827 { 1828 PENVIRONMENT_DIALOG_DATA DlgData; 1829 DlgData = (PENVIRONMENT_DIALOG_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER); 1830 1831 switch (uMsg) 1832 { 1833 case WM_INITDIALOG: 1834 { 1835 RECT rect; 1836 1837 DlgData = GlobalAlloc(GPTR, sizeof(ENVIRONMENT_DIALOG_DATA)); 1838 if (!DlgData) 1839 { 1840 EndDialog(hwndDlg, 0); 1841 return (INT_PTR)TRUE; 1842 } 1843 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)DlgData); 1844 1845 GetClientRect(hwndDlg, &rect); 1846 DlgData->cxOld = rect.right - rect.left; 1847 DlgData->cyOld = rect.bottom - rect.top; 1848 1849 GetWindowRect(hwndDlg, &rect); 1850 DlgData->cxMin = rect.right - rect.left; 1851 DlgData->cyMin = rect.bottom - rect.top; 1852 1853 OnInitEnvironmentDialog(hwndDlg); 1854 break; 1855 } 1856 1857 case WM_SIZE: 1858 { 1859 OnEnvironmentDlgResize(hwndDlg, DlgData, LOWORD(lParam), HIWORD(lParam)); 1860 SetWindowLongPtrW(hwndDlg, DWLP_MSGRESULT, 0); 1861 return TRUE; 1862 } 1863 1864 case WM_SIZING: 1865 { 1866 /* Forbid resizing the dialog smaller than its minimal size */ 1867 PRECT pRect = (PRECT)lParam; 1868 1869 if ((wParam == WMSZ_LEFT) || (wParam == WMSZ_TOPLEFT) || (wParam == WMSZ_BOTTOMLEFT)) 1870 { 1871 if (pRect->right - pRect->left < DlgData->cxMin) 1872 pRect->left = pRect->right - DlgData->cxMin; 1873 } 1874 else 1875 if ((wParam == WMSZ_RIGHT) || (wParam == WMSZ_TOPRIGHT) || (wParam == WMSZ_BOTTOMRIGHT)) 1876 { 1877 if (pRect->right - pRect->left < DlgData->cxMin) 1878 pRect->right = pRect->left + DlgData->cxMin; 1879 } 1880 1881 if ((wParam == WMSZ_TOP) || (wParam == WMSZ_TOPLEFT) || (wParam == WMSZ_TOPRIGHT)) 1882 { 1883 if (pRect->bottom - pRect->top < DlgData->cyMin) 1884 pRect->top = pRect->bottom - DlgData->cyMin; 1885 } 1886 else 1887 if ((wParam == WMSZ_BOTTOM) || (wParam == WMSZ_BOTTOMLEFT) || (wParam == WMSZ_BOTTOMRIGHT)) 1888 { 1889 if (pRect->bottom - pRect->top < DlgData->cyMin) 1890 pRect->bottom = pRect->top + DlgData->cyMin; 1891 } 1892 1893 SetWindowLongPtrW(hwndDlg, DWLP_MSGRESULT, TRUE); 1894 return TRUE; 1895 } 1896 1897 case WM_COMMAND: 1898 switch (LOWORD(wParam)) 1899 { 1900 case IDC_USER_VARIABLE_NEW: 1901 OnNewVariable(hwndDlg, IDC_USER_VARIABLE_LIST); 1902 return TRUE; 1903 1904 case IDC_USER_VARIABLE_EDIT: 1905 OnEditVariable(hwndDlg, IDC_USER_VARIABLE_LIST); 1906 return TRUE; 1907 1908 case IDC_USER_VARIABLE_DELETE: 1909 OnDeleteVariable(hwndDlg, IDC_USER_VARIABLE_LIST); 1910 return TRUE; 1911 1912 case IDC_SYSTEM_VARIABLE_NEW: 1913 OnNewVariable(hwndDlg, IDC_SYSTEM_VARIABLE_LIST); 1914 return TRUE; 1915 1916 case IDC_SYSTEM_VARIABLE_EDIT: 1917 OnEditVariable(hwndDlg, IDC_SYSTEM_VARIABLE_LIST); 1918 return TRUE; 1919 1920 case IDC_SYSTEM_VARIABLE_DELETE: 1921 OnDeleteVariable(hwndDlg, IDC_SYSTEM_VARIABLE_LIST); 1922 return TRUE; 1923 1924 case IDOK: 1925 SetAllVars(hwndDlg, IDC_USER_VARIABLE_LIST); 1926 SetAllVars(hwndDlg, IDC_SYSTEM_VARIABLE_LIST); 1927 SendMessage(HWND_BROADCAST, WM_WININICHANGE, 1928 0, (LPARAM)_T("Environment")); 1929 EndDialog(hwndDlg, 0); 1930 return TRUE; 1931 1932 case IDCANCEL: 1933 EndDialog(hwndDlg, 0); 1934 return TRUE; 1935 } 1936 break; 1937 1938 case WM_DESTROY: 1939 ReleaseListViewItems(hwndDlg, IDC_USER_VARIABLE_LIST); 1940 ReleaseListViewItems(hwndDlg, IDC_SYSTEM_VARIABLE_LIST); 1941 GlobalFree(DlgData); 1942 break; 1943 1944 case WM_NOTIFY: 1945 return OnNotify(hwndDlg, (NMHDR*)lParam); 1946 } 1947 1948 return FALSE; 1949 } 1950 1951 /* EOF */ 1952