Reactos
at listview 1299 lines 43 kB view raw
1/* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS Display Control Panel 4 * FILE: dll/cpl/desk/background.c 5 * PURPOSE: Background property page 6 * 7 * PROGRAMMERS: Trevor McCort (lycan359@gmail.com) 8 * Alexey Minnekhanov (minlexx@rambler.ru) 9 */ 10 11#include "desk.h" 12 13#include <shellapi.h> 14#include <shlwapi.h> 15#include <windowsx.h> 16 17#define MAX_BACKGROUNDS 100 18 19typedef enum 20{ 21 PLACEMENT_CENTER = 0, 22 PLACEMENT_STRETCH, 23 PLACEMENT_TILE, 24 PLACEMENT_FIT, 25 PLACEMENT_FILL 26} PLACEMENT; 27 28/* The tile placement is stored in different registry 29 * key, but due to a condition in win32k it needs to be 30 * zero when stored in the same key as others. 31 */ 32typedef enum 33{ 34 PLACEMENT_VALUE_CENTER = 0, 35 PLACEMENT_VALUE_STRETCH = 2, 36 PLACEMENT_VALUE_TILE = 0, 37 PLACEMENT_VALUE_FIT = 6, 38 PLACEMENT_VALUE_FILL = 10 39} PLACEMENT_VALUE; 40 41typedef struct 42{ 43 BOOL bWallpaper; /* Is this background a wallpaper */ 44 45 TCHAR szFilename[MAX_PATH]; 46 TCHAR szDisplayName[256]; 47 48} BackgroundItem; 49 50typedef struct _BACKGROUND_DATA 51{ 52 BOOL bWallpaperChanged; 53 BOOL bClrBackgroundChanged; 54 55 BackgroundItem backgroundItems[MAX_BACKGROUNDS]; 56 57 PDIBITMAP pWallpaperBitmap; 58 59 int placementSelection; 60 int backgroundSelection; 61 62 COLORREF custom_colors[16]; 63 64 int listViewItemCount; 65 66 ULONG_PTR gdipToken; 67 68 DESKTOP_DATA desktopData; 69} BACKGROUND_DATA, *PBACKGROUND_DATA; 70 71GLOBAL_DATA g_GlobalData; 72 73 74HRESULT 75GdipGetEncoderClsid(PCWSTR MimeType, CLSID *pClsid) 76{ 77 UINT num; 78 UINT size; 79 UINT i; 80 ImageCodecInfo *codecInfo; 81 82 if (GdipGetImageEncodersSize(&num, &size) != Ok || 83 size == 0) 84 { 85 return E_FAIL; 86 } 87 88 codecInfo = HeapAlloc(GetProcessHeap(), 0, size); 89 if (!codecInfo) 90 { 91 return E_OUTOFMEMORY; 92 } 93 94 if (GdipGetImageEncoders(num, size, codecInfo) != Ok) 95 { 96 HeapFree(GetProcessHeap(), 0, codecInfo); 97 return E_FAIL; 98 } 99 100 for (i = 0; i < num; i++) 101 { 102 if (!_wcsicmp(codecInfo[i].MimeType, MimeType)) 103 { 104 *pClsid = codecInfo[i].Clsid; 105 HeapFree(GetProcessHeap(), 0, codecInfo); 106 return S_OK; 107 } 108 } 109 110 HeapFree(GetProcessHeap(), 0, codecInfo); 111 return E_FAIL; 112} 113 114 115LPWSTR 116GdipGetSupportedFileExtensions(VOID) 117{ 118 ImageCodecInfo *codecInfo; 119 UINT num; 120 UINT size; 121 UINT i; 122 LPWSTR lpBuffer = NULL; 123 124 if (GdipGetImageDecodersSize(&num, &size) != Ok || 125 size == 0) 126 { 127 return NULL; 128 } 129 130 codecInfo = HeapAlloc(GetProcessHeap(), 0, size); 131 if (!codecInfo) 132 { 133 return NULL; 134 } 135 136 if (GdipGetImageDecoders(num, size, codecInfo) != Ok) 137 { 138 HeapFree(GetProcessHeap(), 0, codecInfo); 139 return NULL; 140 } 141 142 size = 0; 143 for (i = 0; i < num; ++i) 144 { 145 size = size + (UINT)wcslen(codecInfo[i].FilenameExtension) + 1; 146 } 147 148 size = (size + 1) * sizeof(WCHAR); 149 150 lpBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); 151 if (!lpBuffer) 152 { 153 HeapFree(GetProcessHeap(), 0, codecInfo); 154 return NULL; 155 } 156 157 for (i = 0; i < num; ++i) 158 { 159 if (!lstrcmpiW(codecInfo[i].FilenameExtension, L"*.ico")) 160 continue; 161 162 StringCbCatW(lpBuffer, size, codecInfo[i].FilenameExtension); 163 if (i < (num - 1)) 164 { 165 StringCbCatW(lpBuffer, size, L";"); 166 } 167 } 168 169 HeapFree(GetProcessHeap(), 0, codecInfo); 170 171 return lpBuffer; 172} 173 174 175static UINT 176AddWallpapersFromDirectory(UINT uCounter, HWND hwndBackgroundList, BackgroundItem *backgroundItem, PBACKGROUND_DATA pData, LPCTSTR wallpaperFilename, LPCTSTR wallpaperDirectory) 177{ 178 WIN32_FIND_DATA fd; 179 HANDLE hFind; 180 TCHAR szSearchPath[MAX_PATH]; 181 LPTSTR szFileTypes = NULL; 182 TCHAR separators[] = TEXT(";"); 183 TCHAR *token; 184 HRESULT hr; 185 SHFILEINFO sfi; 186 UINT i = uCounter; 187 LV_ITEM listItem; 188 HIMAGELIST himl; 189 190 szFileTypes = GdipGetSupportedFileExtensions(); 191 if (!szFileTypes) 192 { 193 return i; 194 } 195 196 himl = ListView_GetImageList(hwndBackgroundList, LVSIL_SMALL); 197 198 token = _tcstok(szFileTypes, separators); 199 while (token != NULL) 200 { 201 if (!PathCombine(szSearchPath, wallpaperDirectory, token)) 202 { 203 HeapFree(GetProcessHeap(), 0, szFileTypes); 204 return i; 205 } 206 207 hFind = FindFirstFile(szSearchPath, &fd); 208 while (hFind != INVALID_HANDLE_VALUE) 209 { 210 TCHAR filename[MAX_PATH]; 211 212 if (!PathCombine(filename, wallpaperDirectory, fd.cFileName)) 213 { 214 FindClose(hFind); 215 HeapFree(GetProcessHeap(), 0, szFileTypes); 216 return i; 217 } 218 219 /* Don't add any hidden bitmaps. Also don't add current wallpaper once more. */ 220 if (((fd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) == 0) && (_tcsicmp(wallpaperFilename, filename) != 0)) 221 { 222 SHGetFileInfo(filename, 223 0, 224 &sfi, 225 sizeof(sfi), 226 SHGFI_ICON | SHGFI_SMALLICON | SHGFI_DISPLAYNAME); 227 sfi.iIcon = ImageList_AddIcon(himl, sfi.hIcon); 228 i++; 229 230 backgroundItem = &pData->backgroundItems[pData->listViewItemCount]; 231 232 backgroundItem->bWallpaper = TRUE; 233 234 hr = StringCbCopy(backgroundItem->szDisplayName, sizeof(backgroundItem->szDisplayName), sfi.szDisplayName); 235 if (FAILED(hr)) 236 { 237 FindClose(hFind); 238 HeapFree(GetProcessHeap(), 0, szFileTypes); 239 return i; 240 } 241 242 PathRemoveExtension(backgroundItem->szDisplayName); 243 244 hr = StringCbCopy(backgroundItem->szFilename, sizeof(backgroundItem->szFilename), filename); 245 if (FAILED(hr)) 246 { 247 FindClose(hFind); 248 HeapFree(GetProcessHeap(), 0, szFileTypes); 249 return i; 250 } 251 252 ZeroMemory(&listItem, sizeof(LV_ITEM)); 253 listItem.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE | LVIF_IMAGE; 254 listItem.pszText = backgroundItem->szDisplayName; 255 listItem.state = 0; 256 listItem.iImage = sfi.iIcon; 257 listItem.iItem = pData->listViewItemCount; 258 listItem.lParam = pData->listViewItemCount; 259 260 (void)ListView_InsertItem(hwndBackgroundList, &listItem); 261 262 pData->listViewItemCount++; 263 } 264 265 if (!FindNextFile(hFind, &fd)) 266 break; 267 } 268 269 token = _tcstok(NULL, separators); 270 FindClose(hFind); 271 } 272 273 HeapFree(GetProcessHeap(), 0, szFileTypes); 274 275 return i; 276} 277 278 279/* Add the images in the C:\ReactOS, the wallpaper directory and the current wallpaper if any */ 280static VOID 281AddListViewItems(HWND hwndDlg, PBACKGROUND_DATA pData) 282{ 283 TCHAR szSearchPath[MAX_PATH]; 284 LV_ITEM listItem; 285 LV_COLUMN dummy; 286 RECT clientRect; 287 HKEY regKey; 288 SHFILEINFO sfi; 289 HIMAGELIST himl; 290 TCHAR wallpaperFilename[MAX_PATH]; 291 TCHAR originalWallpaper[MAX_PATH]; 292 DWORD bufferSize = sizeof(wallpaperFilename); 293 TCHAR buffer[MAX_PATH]; 294 DWORD varType = REG_SZ; 295 LONG result; 296 UINT i = 0; 297 BackgroundItem *backgroundItem = NULL; 298 HWND hwndBackgroundList; 299 HRESULT hr; 300 HICON hIcon; 301 INT cx, cy; 302 HINSTANCE hShell32; 303 304 hwndBackgroundList = GetDlgItem(hwndDlg, IDC_BACKGROUND_LIST); 305 306 GetClientRect(hwndBackgroundList, &clientRect); 307 308 cx = GetSystemMetrics(SM_CXSMICON); 309 cy = GetSystemMetrics(SM_CYSMICON); 310 himl = ImageList_Create(cx, cy, ILC_COLOR32 | ILC_MASK, 0, 0); 311 312 /* Load (None) icon */ 313#define IDI_SHELL_NO 200 314 hShell32 = GetModuleHandleW(L"shell32.dll"); 315 hIcon = (HICON)LoadImageW(hShell32, MAKEINTRESOURCEW(IDI_SHELL_NO), IMAGE_ICON, cx, cy, 0); 316#undef IDI_SHELL_NO 317 318 ListView_SetImageList(hwndBackgroundList, himl, LVSIL_SMALL); 319 320 /* Add a new column to the list */ 321 ZeroMemory(&dummy, sizeof(LV_COLUMN)); 322 dummy.mask = LVCF_SUBITEM | LVCF_WIDTH; 323 dummy.iSubItem = 0; 324 dummy.cx = (clientRect.right - clientRect.left) - GetSystemMetrics(SM_CXVSCROLL); 325 (void)ListView_InsertColumn(hwndBackgroundList, 0, &dummy); 326 327 /* Add the "None" item */ 328 backgroundItem = &pData->backgroundItems[pData->listViewItemCount]; 329 backgroundItem->bWallpaper = FALSE; 330 LoadString(hApplet, 331 IDS_NONE, 332 backgroundItem->szDisplayName, 333 sizeof(backgroundItem->szDisplayName) / sizeof(TCHAR)); 334 335 ZeroMemory(&listItem, sizeof(LV_ITEM)); 336 listItem.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE | LVIF_IMAGE; 337 listItem.state = 0; 338 listItem.pszText = backgroundItem->szDisplayName; 339 listItem.iImage = ImageList_AddIcon(himl, hIcon); 340 listItem.iItem = pData->listViewItemCount; 341 listItem.lParam = pData->listViewItemCount; 342 hIcon = NULL; 343 344 (void)ListView_InsertItem(hwndBackgroundList, &listItem); 345 ListView_SetItemState(hwndBackgroundList, 346 pData->listViewItemCount, 347 LVIS_SELECTED, 348 LVIS_SELECTED); 349 350 pData->listViewItemCount++; 351 352 /* Add current wallpaper if any */ 353 result = RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Desktop"), 0, KEY_QUERY_VALUE, &regKey); 354 if (result == ERROR_SUCCESS) 355 { 356 result = RegQueryValueEx(regKey, TEXT("Wallpaper"), 0, &varType, (LPBYTE)wallpaperFilename, &bufferSize); 357 if ((result == ERROR_SUCCESS) && (_tcslen(wallpaperFilename) > 0)) 358 { 359 bufferSize = sizeof(originalWallpaper); 360 result = RegQueryValueEx(regKey, TEXT("OriginalWallpaper"), 0, &varType, (LPBYTE)originalWallpaper, &bufferSize); 361 362 /* If Wallpaper and OriginalWallpaper are the same, try to retrieve ConvertedWallpaper and use it instead of Wallpaper */ 363 if ((result == ERROR_SUCCESS) && (_tcslen(originalWallpaper) > 0) && (_tcsicmp(wallpaperFilename, originalWallpaper) == 0)) 364 { 365 bufferSize = sizeof(originalWallpaper); 366 result = RegQueryValueEx(regKey, TEXT("ConvertedWallpaper"), 0, &varType, (LPBYTE)originalWallpaper, &bufferSize); 367 368 if ((result == ERROR_SUCCESS) && (_tcslen(originalWallpaper) > 0)) 369 { 370 hr = StringCbCopy(wallpaperFilename, sizeof(wallpaperFilename), originalWallpaper); 371 if (FAILED(hr)) 372 { 373 RegCloseKey(regKey); 374 return; 375 } 376 } 377 } 378 379 /* Allow environment variables in file name */ 380 if (ExpandEnvironmentStrings(wallpaperFilename, buffer, MAX_PATH)) 381 { 382 hr = StringCbCopy(wallpaperFilename, sizeof(wallpaperFilename), buffer); 383 if (FAILED(hr)) 384 { 385 RegCloseKey(regKey); 386 return; 387 } 388 } 389 390 if (!SHGetFileInfoW(wallpaperFilename, 0, &sfi, sizeof(sfi), 391 SHGFI_ICON | SHGFI_SMALLICON | SHGFI_DISPLAYNAME)) 392 { 393 RegCloseKey(regKey); 394 return; 395 } 396 397 sfi.iIcon = ImageList_AddIcon(himl, sfi.hIcon); 398 DestroyIcon(sfi.hIcon); 399 400 backgroundItem = &pData->backgroundItems[pData->listViewItemCount]; 401 backgroundItem->bWallpaper = TRUE; 402 403 hr = StringCbCopy(backgroundItem->szDisplayName, sizeof(backgroundItem->szDisplayName), sfi.szDisplayName); 404 if (FAILED(hr)) 405 { 406 RegCloseKey(regKey); 407 return; 408 } 409 410 PathRemoveExtension(backgroundItem->szDisplayName); 411 412 hr = StringCbCopy(backgroundItem->szFilename, sizeof(backgroundItem->szFilename), wallpaperFilename); 413 if (FAILED(hr)) 414 { 415 RegCloseKey(regKey); 416 return; 417 } 418 419 ZeroMemory(&listItem, sizeof(listItem)); 420 listItem.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE | LVIF_IMAGE; 421 listItem.state = 0; 422 listItem.pszText = backgroundItem->szDisplayName; 423 listItem.iImage = sfi.iIcon; 424 listItem.iItem = pData->listViewItemCount; 425 listItem.lParam = pData->listViewItemCount; 426 (void)ListView_InsertItem(hwndBackgroundList, &listItem); 427 428 ListView_SetItemState(hwndBackgroundList, 429 pData->listViewItemCount, 430 LVIS_SELECTED, 431 LVIS_SELECTED); 432 i++; 433 pData->listViewItemCount++; 434 } 435 436 RegCloseKey(regKey); 437 } 438 439 /* Add all the images in the C:\ReactOS directory. */ 440 if (GetWindowsDirectory(szSearchPath, MAX_PATH)) 441 { 442 i = AddWallpapersFromDirectory(i, hwndBackgroundList, backgroundItem, pData, wallpaperFilename, szSearchPath); 443 } 444 445 /* Add all the images in the wallpaper directory. */ 446 if (SHRegGetPath(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion"), TEXT("WallPaperDir"), szSearchPath, 0) == ERROR_SUCCESS) 447 { 448 i = AddWallpapersFromDirectory(i, hwndBackgroundList, backgroundItem, pData, wallpaperFilename, szSearchPath); 449 } 450} 451 452 453static VOID 454InitBackgroundDialog(HWND hwndDlg, PBACKGROUND_DATA pData) 455{ 456 TCHAR szString[256]; 457 HKEY regKey; 458 TCHAR szBuffer[3]; 459 DWORD bufferSize = sizeof(szBuffer); 460 461 AddListViewItems(hwndDlg, pData); 462 463 LoadString(hApplet, IDS_CENTER, szString, sizeof(szString) / sizeof(TCHAR)); 464 SendDlgItemMessage(hwndDlg, IDC_PLACEMENT_COMBO, CB_INSERTSTRING, PLACEMENT_CENTER, (LPARAM)szString); 465 466 LoadString(hApplet, IDS_STRETCH, szString, sizeof(szString) / sizeof(TCHAR)); 467 SendDlgItemMessage(hwndDlg, IDC_PLACEMENT_COMBO, CB_INSERTSTRING, PLACEMENT_STRETCH, (LPARAM)szString); 468 469 LoadString(hApplet, IDS_TILE, szString, sizeof(szString) / sizeof(TCHAR)); 470 SendDlgItemMessage(hwndDlg, IDC_PLACEMENT_COMBO, CB_INSERTSTRING, PLACEMENT_TILE, (LPARAM)szString); 471 472 LoadString(hApplet, IDS_FIT, szString, sizeof(szString) / sizeof(TCHAR)); 473 SendDlgItemMessage(hwndDlg, IDC_PLACEMENT_COMBO, CB_INSERTSTRING, PLACEMENT_FIT, (LPARAM)szString); 474 475 LoadString(hApplet, IDS_FILL, szString, sizeof(szString) / sizeof(TCHAR)); 476 SendDlgItemMessage(hwndDlg, IDC_PLACEMENT_COMBO, CB_INSERTSTRING, PLACEMENT_FILL, (LPARAM)szString); 477 478 SendDlgItemMessage(hwndDlg, IDC_PLACEMENT_COMBO, CB_SETCURSEL, PLACEMENT_CENTER, 0); 479 pData->placementSelection = PLACEMENT_CENTER; 480 481 /* Load the default settings from the registry */ 482 if (RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Desktop"), 0, KEY_QUERY_VALUE, &regKey) != ERROR_SUCCESS) 483 { 484 return; 485 } 486 487 if (RegQueryValueEx(regKey, TEXT("WallpaperStyle"), 0, NULL, (LPBYTE)szBuffer, &bufferSize) == ERROR_SUCCESS) 488 { 489 if (_ttoi(szBuffer) == PLACEMENT_VALUE_CENTER) 490 { 491 SendDlgItemMessage(hwndDlg, IDC_PLACEMENT_COMBO, CB_SETCURSEL, PLACEMENT_CENTER, 0); 492 pData->placementSelection = PLACEMENT_CENTER; 493 } 494 495 if (_ttoi(szBuffer) == PLACEMENT_VALUE_STRETCH) 496 { 497 SendDlgItemMessage(hwndDlg, IDC_PLACEMENT_COMBO, CB_SETCURSEL, PLACEMENT_STRETCH, 0); 498 pData->placementSelection = PLACEMENT_STRETCH; 499 } 500 501 if (_ttoi(szBuffer) == PLACEMENT_VALUE_FIT) 502 { 503 SendDlgItemMessage(hwndDlg, IDC_PLACEMENT_COMBO, CB_SETCURSEL, PLACEMENT_FIT, 0); 504 pData->placementSelection = PLACEMENT_FIT; 505 } 506 507 if (_ttoi(szBuffer) == PLACEMENT_VALUE_FILL) 508 { 509 SendDlgItemMessage(hwndDlg, IDC_PLACEMENT_COMBO, CB_SETCURSEL, PLACEMENT_FILL, 0); 510 pData->placementSelection = PLACEMENT_FILL; 511 } 512 } 513 514 if (RegQueryValueEx(regKey, TEXT("TileWallpaper"), 0, NULL, (LPBYTE)szBuffer, &bufferSize) == ERROR_SUCCESS) 515 { 516 if (_ttoi(szBuffer) == 1) 517 { 518 SendDlgItemMessage(hwndDlg, IDC_PLACEMENT_COMBO, CB_SETCURSEL, PLACEMENT_TILE, 0); 519 pData->placementSelection = PLACEMENT_TILE; 520 } 521 } 522 523 RegCloseKey(regKey); 524} 525 526 527static VOID 528OnColorButton(HWND hwndDlg, PBACKGROUND_DATA pData) 529{ 530 /* Load custom colors from Registry */ 531 HKEY hKey = NULL; 532 LONG res = ERROR_SUCCESS; 533 CHOOSECOLOR cc; 534 535 res = RegCreateKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Appearance"), 0, NULL, 536 REG_OPTION_NON_VOLATILE, KEY_QUERY_VALUE, NULL, &hKey, NULL); 537 /* Now the key is either created or opened existing, if res == ERROR_SUCCESS */ 538 if (res == ERROR_SUCCESS) 539 { 540 /* Key opened */ 541 DWORD dwType = REG_BINARY; 542 DWORD cbData = sizeof(pData->custom_colors); 543 res = RegQueryValueEx(hKey, TEXT("CustomColors"), NULL, &dwType, 544 (LPBYTE)pData->custom_colors, &cbData); 545 RegCloseKey(hKey); 546 hKey = NULL; 547 } 548 549 /* Launch ChooseColor() dialog */ 550 551 cc.lStructSize = sizeof(CHOOSECOLOR); 552 cc.hwndOwner = hwndDlg; 553 cc.hInstance = NULL; 554 cc.rgbResult = g_GlobalData.desktop_color; 555 cc.lpCustColors = pData->custom_colors; 556 cc.Flags = CC_ANYCOLOR | /* Causes the dialog box to display all available colors in the set of basic colors. */ 557 CC_FULLOPEN | /* opens dialog in full size */ 558 CC_RGBINIT ; /* init chosen color by rgbResult value */ 559 cc.lCustData = 0; 560 cc.lpfnHook = NULL; 561 cc.lpTemplateName = NULL; 562 if (ChooseColor(&cc)) 563 { 564 /* Save selected color to var */ 565 g_GlobalData.desktop_color = cc.rgbResult; 566 pData->bClrBackgroundChanged = TRUE; 567 568 /* Apply button will be activated */ 569 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 570 571 /* Window will be updated :) */ 572 InvalidateRect(GetDlgItem(hwndDlg, IDC_BACKGROUND_PREVIEW), NULL, TRUE); 573 InvalidateRect(GetDlgItem(hwndDlg, IDC_COLOR_BUTTON), NULL, TRUE); 574 575 /* Save custom colors to reg. To this moment key must be created already. See above */ 576 res = RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Appearance"), 0, 577 KEY_SET_VALUE, &hKey); 578 if (res == ERROR_SUCCESS) 579 { 580 /* Key opened */ 581 RegSetValueEx(hKey, TEXT("CustomColors"), 0, REG_BINARY, 582 (LPBYTE)pData->custom_colors, sizeof(pData->custom_colors)); 583 RegCloseKey(hKey); 584 hKey = NULL; 585 } 586 } 587} 588 589 590/* 591 * ListView_FindItem() Macro: Searches for a list-view item with the specified 592 * characteristics. Returns the index of the item if successful, or -1 otherwise 593 */ 594static BOOL 595CheckListViewFilenameExists(HWND hwndList, LPCTSTR tszFileName) 596{ 597 LVFINDINFO lvfi; 598 int retVal; 599 600 lvfi.flags = LVFI_STRING; /* Search item by EXACT string */ 601 lvfi.psz = tszFileName; /* String to search */ 602 603 /* Other items of this structure are not valid, besacuse flags are not set. */ 604 retVal = ListView_FindItem(hwndList, -1, &lvfi); 605 if (retVal != -1) 606 return TRUE; /* item found! */ 607 608 return FALSE; /* item not found. */ 609} 610 611 612static VOID 613OnBrowseButton(HWND hwndDlg, PBACKGROUND_DATA pData) 614{ 615 OPENFILENAME ofn; 616 TCHAR filename[MAX_PATH]; 617 TCHAR fileTitle[256]; 618 TCHAR initialDir[MAX_PATH]; 619 LPTSTR filter; 620 LPTSTR extensions; 621 BackgroundItem *backgroundItem = NULL; 622 SHFILEINFO sfi; 623 LV_ITEM listItem; 624 HWND hwndBackgroundList; 625 TCHAR *p; 626 HRESULT hr; 627 TCHAR filterdesc[MAX_PATH]; 628 TCHAR *c; 629 size_t sizeRemain; 630 SIZE_T buffersize; 631 BOOL success; 632 HIMAGELIST himl; 633 634 hwndBackgroundList = GetDlgItem(hwndDlg, IDC_BACKGROUND_LIST); 635 himl = ListView_GetImageList(hwndBackgroundList, LVSIL_SMALL); 636 SHGetFolderPathW(NULL, CSIDL_MYPICTURES, NULL, 0, initialDir); 637 638 ZeroMemory(&ofn, sizeof(OPENFILENAME)); 639 640 ofn.lStructSize = sizeof(OPENFILENAME); 641 ofn.hwndOwner = hwndDlg; 642 ofn.lpstrFile = filename; 643 644 LoadString(hApplet, IDS_BACKGROUND_COMDLG_FILTER, filterdesc, sizeof(filterdesc) / sizeof(TCHAR)); 645 646 extensions = GdipGetSupportedFileExtensions(); 647 if (!extensions) 648 { 649 return; 650 } 651 652 buffersize = (_tcslen(extensions) * 2 + 6) * sizeof(TCHAR) + sizeof(filterdesc); 653 654 filter = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, buffersize); 655 if (!filter) 656 { 657 HeapFree(GetProcessHeap(), 0, extensions); 658 return; 659 } 660 661 sizeRemain = buffersize; 662 c = filter; 663 664 if (FAILED(StringCbPrintfEx(c, sizeRemain, &c, &sizeRemain, 0, L"%ls (%ls)", filterdesc, extensions))) 665 { 666 HeapFree(GetProcessHeap(), 0, extensions); 667 HeapFree(GetProcessHeap(), 0, filter); 668 return; 669 } 670 671 c++; 672 sizeRemain -= sizeof(*c); 673 674 if (FAILED(StringCbPrintfEx(c, sizeRemain, &c, &sizeRemain, 0, L"%ls", extensions))) 675 { 676 HeapFree(GetProcessHeap(), 0, extensions); 677 HeapFree(GetProcessHeap(), 0, filter); 678 return; 679 } 680 681 HeapFree(GetProcessHeap(), 0, extensions); 682 683 /* Set lpstrFile[0] to '\0' so that GetOpenFileName does not 684 * use the contents of szFile to initialize itself */ 685 ofn.lpstrFile[0] = TEXT('\0'); 686 ofn.nMaxFile = MAX_PATH; 687 ofn.lpstrFilter = filter; 688 ofn.nFilterIndex = 0; 689 ofn.lpstrFileTitle = fileTitle; 690 ofn.nMaxFileTitle = 256; 691 ofn.lpstrInitialDir = initialDir; 692 ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_EXPLORER; 693 694 success = GetOpenFileName(&ofn); 695 HeapFree(GetProcessHeap(), 0, filter); 696 697 if (success) 698 { 699 /* Check if there is already a entry that holds this filename */ 700 if (CheckListViewFilenameExists(hwndBackgroundList, ofn.lpstrFileTitle) != FALSE) 701 return; 702 703 if (pData->listViewItemCount > (MAX_BACKGROUNDS - 1)) 704 return; 705 706 SHGetFileInfo(filename, 707 0, 708 &sfi, 709 sizeof(sfi), 710 SHGFI_ICON | SHGFI_SMALLICON | SHGFI_DISPLAYNAME); 711 sfi.iIcon = ImageList_AddIcon(himl, sfi.hIcon); 712 713 backgroundItem = &pData->backgroundItems[pData->listViewItemCount]; 714 715 backgroundItem->bWallpaper = TRUE; 716 717 hr = StringCbCopy(backgroundItem->szDisplayName, sizeof(backgroundItem->szDisplayName), sfi.szDisplayName); 718 if (FAILED(hr)) 719 return; 720 p = _tcsrchr(backgroundItem->szDisplayName, _T('.')); 721 if (p) 722 *p = (TCHAR)0; 723 hr = StringCbCopy(backgroundItem->szFilename, sizeof(backgroundItem->szFilename), filename); 724 if (FAILED(hr)) 725 return; 726 727 ZeroMemory(&listItem, sizeof(LV_ITEM)); 728 listItem.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE | LVIF_IMAGE; 729 listItem.state = 0; 730 listItem.pszText = backgroundItem->szDisplayName; 731 listItem.iImage = sfi.iIcon; 732 listItem.iItem = pData->listViewItemCount; 733 listItem.lParam = pData->listViewItemCount; 734 735 (void)ListView_InsertItem(hwndBackgroundList, &listItem); 736 ListView_SetItemState(hwndBackgroundList, 737 pData->listViewItemCount, 738 LVIS_SELECTED, 739 LVIS_SELECTED); 740 SendMessage(hwndBackgroundList, WM_VSCROLL, SB_BOTTOM, 0); 741 742 pData->listViewItemCount++; 743 } 744} 745 746 747static VOID 748ListViewItemChanged(HWND hwndDlg, PBACKGROUND_DATA pData, int itemIndex) 749{ 750 BackgroundItem *backgroundItem = NULL; 751 752 pData->backgroundSelection = itemIndex; 753 backgroundItem = &pData->backgroundItems[pData->backgroundSelection]; 754 755 if (pData->pWallpaperBitmap != NULL) 756 { 757 DibFreeImage(pData->pWallpaperBitmap); 758 pData->pWallpaperBitmap = NULL; 759 } 760 761 if (backgroundItem->bWallpaper != FALSE) 762 { 763 pData->pWallpaperBitmap = DibLoadImage(backgroundItem->szFilename); 764 765 if (pData->pWallpaperBitmap == NULL) 766 return; 767 } 768 769 pData->bWallpaperChanged = TRUE; 770 771 InvalidateRect(GetDlgItem(hwndDlg, IDC_BACKGROUND_PREVIEW), 772 NULL, TRUE); 773 774 EnableWindow(GetDlgItem(hwndDlg, IDC_PLACEMENT_COMBO), 775 backgroundItem->bWallpaper); 776 777 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 778} 779 780 781static VOID 782DrawBackgroundPreview(LPDRAWITEMSTRUCT draw, PBACKGROUND_DATA pData) 783{ 784 float scaleX; 785 float scaleY; 786 int scaledWidth; 787 int scaledHeight; 788 int posX, desX; 789 int posY, desY; 790 int fitFillScaleNum, fitFillScaleDen; 791 int fitFillWidth, fitFillHeight; 792 HBRUSH hBrush; 793 int x; 794 int y; 795 HDC hDC; 796 HGDIOBJ hOldObj; 797 RECT rcItem = { 798 MONITOR_LEFT, 799 MONITOR_TOP, 800 MONITOR_RIGHT, 801 MONITOR_BOTTOM 802 }; 803 804 hDC = CreateCompatibleDC(draw->hDC); 805 hOldObj = SelectObject(hDC, g_GlobalData.hMonitorBitmap); 806 807 if (pData->backgroundItems[pData->backgroundSelection].bWallpaper == FALSE) 808 { 809 /* Update desktop background color image */ 810 hBrush = CreateSolidBrush(g_GlobalData.desktop_color); 811 FillRect(hDC, &rcItem, hBrush); 812 DeleteObject(hBrush); 813 } 814 else 815 if (pData->pWallpaperBitmap != NULL) 816 { 817 scaleX = ((float)GetSystemMetrics(SM_CXSCREEN) - 1) / (float)MONITOR_WIDTH; 818 scaleY = ((float)GetSystemMetrics(SM_CYSCREEN) - 1) / (float)MONITOR_HEIGHT; 819 820 scaledWidth = (int)(pData->pWallpaperBitmap->width / scaleX); 821 scaledHeight = (int)(pData->pWallpaperBitmap->height / scaleY); 822 823 FillRect(hDC, &rcItem, GetSysColorBrush(COLOR_BACKGROUND)); 824 825 SetStretchBltMode(hDC, COLORONCOLOR); 826 827 switch (pData->placementSelection) 828 { 829 case PLACEMENT_CENTER: 830 posX = (MONITOR_WIDTH - scaledWidth + 1) / 2; 831 posY = (MONITOR_HEIGHT - scaledHeight + 1) / 2; 832 desX = 0; 833 desY = 0; 834 835 if (posX < 0) { desX = -posX / 2; posX = 0; } 836 if (posY < 0) { desY = -posY / 2; posY = 0; } 837 838 if (scaledWidth > MONITOR_WIDTH) 839 scaledWidth = MONITOR_WIDTH; 840 841 if (scaledHeight > MONITOR_HEIGHT) 842 scaledHeight = MONITOR_HEIGHT; 843 844 StretchDIBits(hDC, 845 MONITOR_LEFT+posX, 846 MONITOR_TOP+posY, 847 scaledWidth, 848 scaledHeight, 849 desX, 850 desY, 851 pData->pWallpaperBitmap->width - (int)(desX * scaleX), 852 pData->pWallpaperBitmap->height - (int)(desY * scaleY), 853 pData->pWallpaperBitmap->bits, 854 pData->pWallpaperBitmap->info, 855 DIB_RGB_COLORS, 856 SRCCOPY); 857 break; 858 859 case PLACEMENT_STRETCH: 860 StretchDIBits(hDC, 861 MONITOR_LEFT, 862 MONITOR_TOP, 863 MONITOR_WIDTH, 864 MONITOR_HEIGHT, 865 0, 866 0, 867 pData->pWallpaperBitmap->width, 868 pData->pWallpaperBitmap->height, 869 pData->pWallpaperBitmap->bits, 870 pData->pWallpaperBitmap->info, 871 DIB_RGB_COLORS, 872 SRCCOPY); 873 break; 874 875 case PLACEMENT_TILE: 876 for (y = 0; y < MONITOR_HEIGHT; y += scaledHeight) 877 { 878 for (x = 0; x < MONITOR_WIDTH; x += scaledWidth) 879 { 880 if ((MONITOR_WIDTH-x) >= scaledWidth) 881 posX = scaledWidth; 882 else 883 posX = MONITOR_WIDTH-x; 884 885 886 if ((MONITOR_HEIGHT-y) >= scaledHeight) 887 posY = scaledHeight; 888 else 889 posY = MONITOR_HEIGHT-y; 890 891 StretchDIBits(hDC, 892 MONITOR_LEFT + x, 893 MONITOR_TOP + y, 894 posX, 895 posY, 896 0, 897 0, 898 pData->pWallpaperBitmap->width * posX / scaledWidth, 899 pData->pWallpaperBitmap->height * posY / scaledHeight, 900 pData->pWallpaperBitmap->bits, 901 pData->pWallpaperBitmap->info, 902 DIB_RGB_COLORS, 903 SRCCOPY); 904 } 905 906 } 907 908 break; 909 910 case PLACEMENT_FIT: 911 if ((MONITOR_WIDTH * scaledHeight) <= (MONITOR_HEIGHT * scaledWidth)) 912 { 913 fitFillScaleNum = MONITOR_WIDTH; 914 fitFillScaleDen = scaledWidth; 915 } 916 else 917 { 918 fitFillScaleNum = MONITOR_HEIGHT; 919 fitFillScaleDen = scaledHeight; 920 } 921 922 fitFillWidth = MulDiv(scaledWidth, fitFillScaleNum, fitFillScaleDen); 923 fitFillHeight = MulDiv(scaledHeight, fitFillScaleNum, fitFillScaleDen); 924 925 posX = (MONITOR_WIDTH - fitFillWidth) / 2; 926 posY = (MONITOR_HEIGHT - fitFillHeight) / 2; 927 928 StretchDIBits(hDC, 929 MONITOR_LEFT + posX, 930 MONITOR_TOP + posY, 931 fitFillWidth, 932 fitFillHeight, 933 0, 934 0, 935 pData->pWallpaperBitmap->width, 936 pData->pWallpaperBitmap->height, 937 pData->pWallpaperBitmap->bits, 938 pData->pWallpaperBitmap->info, 939 DIB_RGB_COLORS, 940 SRCCOPY); 941 break; 942 943 case PLACEMENT_FILL: 944 if ((MONITOR_WIDTH * scaledHeight) > (MONITOR_HEIGHT * scaledWidth)) 945 { 946 fitFillScaleNum = MONITOR_WIDTH; 947 fitFillScaleDen = scaledWidth; 948 } 949 else 950 { 951 fitFillScaleNum = MONITOR_HEIGHT; 952 fitFillScaleDen = scaledHeight; 953 } 954 955 fitFillWidth = MulDiv(scaledWidth, fitFillScaleNum, fitFillScaleDen); 956 fitFillHeight = MulDiv(scaledHeight, fitFillScaleNum, fitFillScaleDen); 957 958 desX = (((fitFillWidth - MONITOR_WIDTH) * pData->pWallpaperBitmap->width) / (2 * fitFillWidth)); 959 desY = (((fitFillHeight - MONITOR_HEIGHT) * pData->pWallpaperBitmap->height) / (2 * fitFillHeight)); 960 961 StretchDIBits(hDC, 962 MONITOR_LEFT, 963 MONITOR_TOP, 964 MONITOR_WIDTH, 965 MONITOR_HEIGHT, 966 desX, 967 desY, 968 (MONITOR_WIDTH * pData->pWallpaperBitmap->width) / fitFillWidth, 969 (MONITOR_HEIGHT * pData->pWallpaperBitmap->height) / fitFillHeight, 970 pData->pWallpaperBitmap->bits, 971 pData->pWallpaperBitmap->info, 972 DIB_RGB_COLORS, 973 SRCCOPY); 974 break; 975 } 976 } 977 978 GdiTransparentBlt(draw->hDC, 979 draw->rcItem.left, draw->rcItem.top, 980 draw->rcItem.right - draw->rcItem.left + 1, 981 draw->rcItem.bottom - draw->rcItem.top + 1, 982 hDC, 983 0, 0, 984 g_GlobalData.bmMonWidth, g_GlobalData.bmMonHeight, 985 MONITOR_ALPHA); 986 987 SelectObject(hDC, hOldObj); 988 DeleteDC(hDC); 989} 990 991 992static VOID 993SetWallpaper(PBACKGROUND_DATA pData) 994{ 995 HKEY regKey; 996 TCHAR szWallpaper[MAX_PATH]; 997 GpImage *image; 998 CLSID encoderClsid; 999 GUID guidFormat; 1000 size_t length = 0; 1001 GpStatus status; 1002 1003 if (FAILED(SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, szWallpaper))) 1004 { 1005 return; 1006 } 1007 1008 if (FAILED(StringCbCat(szWallpaper, sizeof(szWallpaper), TEXT("\\Wallpaper1.bmp")))) 1009 { 1010 return; 1011 } 1012 1013 if (RegCreateKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Desktop"), 0, NULL, 1014 REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &regKey, NULL) != ERROR_SUCCESS) 1015 { 1016 return; 1017 } 1018 1019 if (pData->placementSelection == PLACEMENT_TILE) 1020 { 1021 RegSetValueEx(regKey, TEXT("TileWallpaper"), 0, REG_SZ, (LPBYTE)TEXT("1"), sizeof(TCHAR) * 2); 1022 RegSetValueEx(regKey, TEXT("WallpaperStyle"), 0, REG_SZ, (LPBYTE)TEXT("0"), sizeof(TCHAR) * 2); 1023 } 1024 1025 if (pData->placementSelection == PLACEMENT_CENTER) 1026 { 1027 RegSetValueEx(regKey, TEXT("TileWallpaper"), 0, REG_SZ, (LPBYTE)TEXT("0"), sizeof(TCHAR) * 2); 1028 RegSetValueEx(regKey, TEXT("WallpaperStyle"), 0, REG_SZ, (LPBYTE)TEXT("0"), sizeof(TCHAR) * 2); 1029 } 1030 1031 if (pData->placementSelection == PLACEMENT_STRETCH) 1032 { 1033 RegSetValueEx(regKey, TEXT("TileWallpaper"), 0, REG_SZ, (LPBYTE)TEXT("0"), sizeof(TCHAR) * 2); 1034 RegSetValueEx(regKey, TEXT("WallpaperStyle"), 0, REG_SZ, (LPBYTE)TEXT("2"), sizeof(TCHAR) * 2); 1035 } 1036 1037 if (pData->placementSelection == PLACEMENT_FIT) 1038 { 1039 RegSetValueEx(regKey, TEXT("TileWallpaper"), 0, REG_SZ, (LPBYTE)TEXT("0"), sizeof(TCHAR) * 2); 1040 RegSetValueEx(regKey, TEXT("WallpaperStyle"), 0, REG_SZ, (LPBYTE)TEXT("6"), sizeof(TCHAR) * 2); 1041 } 1042 1043 if (pData->placementSelection == PLACEMENT_FILL) 1044 { 1045 RegSetValueEx(regKey, TEXT("TileWallpaper"), 0, REG_SZ, (LPBYTE)TEXT("0"), sizeof(TCHAR) * 2); 1046 RegSetValueEx(regKey, TEXT("WallpaperStyle"), 0, REG_SZ, (LPBYTE)TEXT("10"), sizeof(TCHAR) * 3); 1047 } 1048 1049 if (pData->backgroundItems[pData->backgroundSelection].bWallpaper != FALSE) 1050 { 1051 GdipLoadImageFromFile(pData->backgroundItems[pData->backgroundSelection].szFilename, &image); 1052 if (!image) 1053 { 1054 RegCloseKey(regKey); 1055 return; 1056 } 1057 1058 GdipGetImageRawFormat(image, &guidFormat); 1059 if (IsEqualGUID(&guidFormat, &ImageFormatBMP)) 1060 { 1061 GdipDisposeImage(image); 1062 RegCloseKey(regKey); 1063 SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, pData->backgroundItems[pData->backgroundSelection].szFilename, SPIF_UPDATEINIFILE); 1064 return; 1065 } 1066 1067 if (FAILED(GdipGetEncoderClsid(L"image/bmp", &encoderClsid))) 1068 { 1069 GdipDisposeImage(image); 1070 RegCloseKey(regKey); 1071 return; 1072 } 1073 1074 status = GdipSaveImageToFile(image, szWallpaper, &encoderClsid, NULL); 1075 1076 GdipDisposeImage(image); 1077 1078 if (status != Ok) 1079 { 1080 RegCloseKey(regKey); 1081 return; 1082 } 1083 1084 if (SUCCEEDED(StringCchLength(pData->backgroundItems[pData->backgroundSelection].szFilename, MAX_PATH, &length))) 1085 { 1086 RegSetValueEx(regKey, 1087 TEXT("ConvertedWallpaper"), 1088 0, 1089 REG_SZ, 1090 (LPBYTE)pData->backgroundItems[pData->backgroundSelection].szFilename, 1091 (DWORD)((length + 1) * sizeof(TCHAR))); 1092 } 1093 1094 if (SUCCEEDED(StringCchLength(szWallpaper, MAX_PATH, &length))) 1095 { 1096 RegSetValueEx(regKey, 1097 TEXT("OriginalWallpaper"), 1098 0, 1099 REG_SZ, 1100 (LPBYTE)szWallpaper, 1101 (DWORD)((length + 1) * sizeof(TCHAR))); 1102 } 1103 1104 SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, szWallpaper, SPIF_UPDATEINIFILE); 1105 } 1106 else 1107 { 1108 SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, (void*) TEXT(""), SPIF_UPDATEINIFILE); 1109 } 1110 1111 RegCloseKey(regKey); 1112} 1113 1114 1115/* Change system color */ 1116static VOID 1117SetDesktopBackColor(HWND hwndDlg, PBACKGROUND_DATA pData) 1118{ 1119 HKEY hKey; 1120 INT iElement = COLOR_BACKGROUND; 1121 TCHAR clText[16]; 1122 BYTE red, green, blue; 1123 1124 if (!SetSysColors(1, &iElement, &g_GlobalData.desktop_color)) 1125 { 1126 /* FIXME: these error texts can need internationalization? */ 1127 MessageBox(hwndDlg, TEXT("SetSysColor() failed!"), 1128 TEXT("Error!"), MB_ICONSTOP ); 1129 } 1130 1131 if (RegCreateKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Colors"), 0, NULL, 1132 REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hKey, NULL) != ERROR_SUCCESS) 1133 { 1134 return; 1135 } 1136 1137 red = GetRValue(g_GlobalData.desktop_color); 1138 green = GetGValue(g_GlobalData.desktop_color); 1139 blue = GetBValue(g_GlobalData.desktop_color); 1140 1141 /* Format string to be set to registry */ 1142 StringCbPrintf(clText, sizeof(clText), TEXT("%d %d %d"), red, green, blue); 1143 RegSetValueEx(hKey, TEXT("Background"), 0, REG_SZ, (LPBYTE)clText, 1144 (wcslen(clText) + 1) * sizeof(TCHAR)); 1145 1146 RegCloseKey(hKey); 1147} 1148 1149static VOID 1150OnCustomButton(HWND hwndDlg, PBACKGROUND_DATA pData) 1151{ 1152 HPROPSHEETPAGE hpsp[1] = {0}; 1153 PROPSHEETHEADER psh = {sizeof(psh)}; 1154 PROPSHEETPAGE psp = {sizeof(psp)}; 1155 1156 psh.dwFlags = PSH_NOAPPLYNOW; 1157 psh.hwndParent = GetParent(hwndDlg); 1158 psh.hInstance = hApplet; 1159 psh.pszCaption = MAKEINTRESOURCE(IDS_DESKTOP_ITEMS); 1160 psh.phpage = hpsp; 1161 1162 psp.dwFlags = PSP_DEFAULT; 1163 psp.hInstance = hApplet; 1164 psp.pszTemplate = MAKEINTRESOURCE(IDD_DESKTOP_GENERAL); 1165 psp.pfnDlgProc = DesktopPageProc; 1166 psp.lParam = (LPARAM)&pData->desktopData; 1167 1168 hpsp[0] = CreatePropertySheetPage(&psp); 1169 if (!hpsp[0]) 1170 return; 1171 1172 psh.nPages++; 1173 1174 if (PropertySheet(&psh) > 0) 1175 { 1176 if (SaveDesktopSettings(&pData->desktopData)) 1177 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 1178 } 1179} 1180 1181 1182INT_PTR CALLBACK 1183BackgroundPageProc(HWND hwndDlg, 1184 UINT uMsg, 1185 WPARAM wParam, 1186 LPARAM lParam) 1187{ 1188 PBACKGROUND_DATA pData; 1189 struct GdiplusStartupInput gdipStartup; 1190 1191 pData = (PBACKGROUND_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER); 1192 1193 switch (uMsg) 1194 { 1195 case WM_INITDIALOG: 1196 pData = (PBACKGROUND_DATA)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BACKGROUND_DATA)); 1197 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pData); 1198 gdipStartup.GdiplusVersion = 1; 1199 gdipStartup.DebugEventCallback = NULL; 1200 gdipStartup.SuppressBackgroundThread = FALSE; 1201 gdipStartup.SuppressExternalCodecs = FALSE; 1202 GdiplusStartup(&pData->gdipToken, &gdipStartup, NULL); 1203 InitBackgroundDialog(hwndDlg, pData); 1204 InitDesktopSettings(&pData->desktopData); 1205 break; 1206 1207 case WM_COMMAND: 1208 { 1209 DWORD controlId = LOWORD(wParam); 1210 DWORD command = HIWORD(wParam); 1211 1212 switch (controlId) 1213 { 1214 case IDC_COLOR_BUTTON: 1215 if (command == BN_CLICKED) 1216 OnColorButton(hwndDlg, pData); 1217 break; 1218 1219 case IDC_BROWSE_BUTTON: 1220 if (command == BN_CLICKED) 1221 OnBrowseButton(hwndDlg, pData); 1222 break; 1223 1224 case IDC_PLACEMENT_COMBO: 1225 if (command == CBN_SELCHANGE) 1226 { 1227 pData->placementSelection = (int)SendDlgItemMessage(hwndDlg, IDC_PLACEMENT_COMBO, CB_GETCURSEL, 0, 0); 1228 1229 InvalidateRect(GetDlgItem(hwndDlg, IDC_BACKGROUND_PREVIEW), NULL, TRUE); 1230 1231 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 1232 } 1233 break; 1234 1235 case IDC_DESKTOP_CUSTOM: 1236 if (command == BN_CLICKED) 1237 OnCustomButton(hwndDlg, pData); 1238 break; 1239 } 1240 } break; 1241 1242 case WM_DRAWITEM: 1243 { 1244 LPDRAWITEMSTRUCT drawItem = (LPDRAWITEMSTRUCT)lParam; 1245 1246 if (drawItem->CtlID == IDC_BACKGROUND_PREVIEW) 1247 DrawBackgroundPreview(drawItem, pData); 1248 } 1249 break; 1250 1251 case WM_NOTIFY: 1252 { 1253 LPNMHDR lpnm = (LPNMHDR)lParam; 1254 1255 switch(lpnm->code) 1256 { 1257 case PSN_APPLY: 1258 if (pData->bWallpaperChanged) 1259 SetWallpaper(pData); 1260 if (pData->bClrBackgroundChanged) 1261 SetDesktopBackColor(hwndDlg, pData); 1262 if (pData->desktopData.bSettingsChanged) 1263 SetDesktopSettings(&pData->desktopData); 1264 SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)_T("")); 1265 return TRUE; 1266 1267 case LVN_ITEMCHANGED: 1268 { 1269 LPNMLISTVIEW nm = (LPNMLISTVIEW)lParam; 1270 1271 if ((nm->uNewState & LVIS_SELECTED) == 0) 1272 return FALSE; 1273 1274 ListViewItemChanged(hwndDlg, pData, nm->iItem); 1275 } 1276 break; 1277 1278 case NM_CUSTOMDRAW: 1279 if (lpnm->idFrom == IDC_COLOR_BUTTON) 1280 { 1281 return SetDlgMsgResult(hwndDlg, 0, ClrBtn_CustomDraw((NMCUSTOMDRAW*)lpnm, 1282 g_GlobalData.desktop_color)); 1283 } 1284 break; 1285 } 1286 } 1287 break; 1288 1289 case WM_DESTROY: 1290 if (pData->pWallpaperBitmap != NULL) 1291 DibFreeImage(pData->pWallpaperBitmap); 1292 1293 GdiplusShutdown(pData->gdipToken); 1294 HeapFree(GetProcessHeap(), 0, pData); 1295 break; 1296 } 1297 1298 return FALSE; 1299}