Vytis Girdžijauskas (cman AT cman DOT us)
[reactos.git] / reactos / dll / cpl / desk / background.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS Display Control Panel
5 * FILE: lib/cpl/desk/background.c
6 * PURPOSE: Background property page
7 *
8 * PROGRAMMERS: Trevor McCort (lycan359@gmail.com)
9 * Alexey Minnekhanov (minlexx@rambler.ru)
10 */
11
12 #include "desk.h"
13
14 #define MAX_BACKGROUNDS 100
15
16 #define PLACEMENT_CENTER 0
17 #define PLACEMENT_STRETCH 1
18 #define PLACEMENT_TILE 2
19
20 typedef struct
21 {
22 BOOL bWallpaper; /* Is this background a wallpaper */
23
24 TCHAR szFilename[MAX_PATH];
25 TCHAR szDisplayName[256];
26
27 } BackgroundItem;
28
29 typedef struct _GLOBAL_DATA
30 {
31 BackgroundItem backgroundItems[MAX_BACKGROUNDS];
32
33 PDIBITMAP pWallpaperBitmap;
34
35 int placementSelection;
36 int backgroundSelection;
37
38 COLORREF backgroundDesktopColor;
39 COLORREF custom_colors[16];
40
41 int listViewItemCount;
42
43 HBITMAP hBitmap;
44 int cxSource;
45 int cySource;
46 } GLOBAL_DATA, *PGLOBAL_DATA;
47
48
49
50 /* Add the images in the C:\ReactOS directory and the current wallpaper if any */
51 static VOID
52 AddListViewItems(HWND hwndDlg, PGLOBAL_DATA pGlobalData)
53 {
54 WIN32_FIND_DATA fd;
55 HANDLE hFind;
56 TCHAR szSearchPath[MAX_PATH];
57 TCHAR szFileTypes[MAX_PATH];
58 LV_ITEM listItem;
59 LV_COLUMN dummy;
60 RECT clientRect;
61 HKEY regKey;
62 SHFILEINFO sfi;
63 HIMAGELIST himl;
64 TCHAR wallpaperFilename[MAX_PATH];
65 DWORD bufferSize = sizeof(wallpaperFilename);
66 TCHAR buffer[MAX_PATH];
67 DWORD varType = REG_SZ;
68 LONG result;
69 UINT i = 0;
70 BackgroundItem *backgroundItem = NULL;
71 TCHAR separators[] = TEXT(";");
72 TCHAR *token;
73 HWND hwndBackgroundList;
74 TCHAR *p;
75
76 hwndBackgroundList = GetDlgItem(hwndDlg, IDC_BACKGROUND_LIST);
77
78 GetClientRect(hwndBackgroundList, &clientRect);
79
80 /* Add a new column to the list */
81 ZeroMemory(&dummy, sizeof(LV_COLUMN));
82 dummy.mask = LVCF_SUBITEM | LVCF_WIDTH;
83 dummy.iSubItem = 0;
84 dummy.cx = (clientRect.right - clientRect.left) - GetSystemMetrics(SM_CXVSCROLL);
85 (void)ListView_InsertColumn(hwndBackgroundList, 0, &dummy);
86
87 /* Add the "None" item */
88 backgroundItem = &pGlobalData->backgroundItems[pGlobalData->listViewItemCount];
89 backgroundItem->bWallpaper = FALSE;
90 LoadString(hApplet,
91 IDS_NONE,
92 backgroundItem->szDisplayName,
93 sizeof(backgroundItem->szDisplayName) / sizeof(TCHAR));
94
95 ZeroMemory(&listItem, sizeof(LV_ITEM));
96 listItem.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE | LVIF_IMAGE;
97 listItem.state = LVIS_SELECTED;
98 listItem.pszText = backgroundItem->szDisplayName;
99 listItem.iImage = -1;
100 listItem.iItem = pGlobalData->listViewItemCount;
101 listItem.lParam = pGlobalData->listViewItemCount;
102
103 (void)ListView_InsertItem(hwndBackgroundList, &listItem);
104 ListView_SetItemState(hwndBackgroundList, pGlobalData->listViewItemCount, LVIS_SELECTED, LVIS_SELECTED);
105
106 pGlobalData->listViewItemCount++;
107
108 /* Add current wallpaper if any */
109 RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Desktop"), 0, KEY_ALL_ACCESS, &regKey);
110
111 result = RegQueryValueEx(regKey, TEXT("Wallpaper"), 0, &varType, (LPBYTE)wallpaperFilename, &bufferSize);
112 if ((result == ERROR_SUCCESS) && (_tcslen(wallpaperFilename) > 0))
113 {
114 /* Allow environment variables in file name */
115 if (ExpandEnvironmentStrings(wallpaperFilename, buffer, MAX_PATH))
116 {
117 _tcscpy(wallpaperFilename, buffer);
118 }
119
120 himl = (HIMAGELIST)SHGetFileInfo(wallpaperFilename,
121 0,
122 &sfi,
123 sizeof(sfi),
124 SHGFI_SYSICONINDEX | SHGFI_SMALLICON |
125 SHGFI_DISPLAYNAME);
126
127 if (himl != NULL)
128 {
129 if (i++ == 0)
130 {
131 (void)ListView_SetImageList(hwndBackgroundList, himl, LVSIL_SMALL);
132 }
133
134 backgroundItem = &pGlobalData->backgroundItems[pGlobalData->listViewItemCount];
135
136 backgroundItem->bWallpaper = TRUE;
137
138 _tcscpy(backgroundItem->szDisplayName, sfi.szDisplayName);
139 p = _tcsrchr(backgroundItem->szDisplayName, _T('.'));
140 if (p)
141 *p = (TCHAR)0;
142 _tcscpy(backgroundItem->szFilename, wallpaperFilename);
143
144 ZeroMemory(&listItem, sizeof(LV_ITEM));
145 listItem.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE | LVIF_IMAGE;
146 listItem.state = LVIS_SELECTED;
147 listItem.pszText = backgroundItem->szDisplayName;
148 listItem.iImage = sfi.iIcon;
149 listItem.iItem = pGlobalData->listViewItemCount;
150 listItem.lParam = pGlobalData->listViewItemCount;
151
152 (void)ListView_InsertItem(hwndBackgroundList, &listItem);
153 ListView_SetItemState(hwndBackgroundList, pGlobalData->listViewItemCount, LVIS_SELECTED, LVIS_SELECTED);
154
155 pGlobalData->listViewItemCount++;
156 }
157 }
158
159 RegCloseKey(regKey);
160
161 /* Add all the images in the C:\ReactOS directory. */
162
163 LoadString(hApplet, IDS_SUPPORTED_EXT, szFileTypes, sizeof(szFileTypes) / sizeof(TCHAR));
164
165 token = _tcstok(szFileTypes, separators);
166 while (token != NULL)
167 {
168 GetWindowsDirectory(szSearchPath, MAX_PATH);
169 _tcscat(szSearchPath, TEXT("\\"));
170 _tcscat(szSearchPath, token);
171
172 hFind = FindFirstFile(szSearchPath, &fd);
173 while (hFind != INVALID_HANDLE_VALUE)
174 {
175 TCHAR filename[MAX_PATH];
176
177 GetWindowsDirectory(filename, MAX_PATH);
178
179 _tcscat(filename, TEXT("\\"));
180 _tcscat(filename, fd.cFileName);
181
182 /* Don't add any hidden bitmaps. Also don't add current wallpaper once more. */
183 if (((fd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) == 0) && (_tcscmp(wallpaperFilename, filename) != 0))
184 {
185 himl = (HIMAGELIST)SHGetFileInfo(filename,
186 0,
187 &sfi,
188 sizeof(sfi),
189 SHGFI_SYSICONINDEX | SHGFI_SMALLICON |
190 SHGFI_DISPLAYNAME);
191
192 if (himl == NULL)
193 break;
194
195 if (i++ == 0)
196 {
197 (void)ListView_SetImageList(hwndBackgroundList, himl, LVSIL_SMALL);
198 }
199
200 backgroundItem = &pGlobalData->backgroundItems[pGlobalData->listViewItemCount];
201
202 backgroundItem->bWallpaper = TRUE;
203
204 _tcscpy(backgroundItem->szDisplayName, sfi.szDisplayName);
205 p = _tcsrchr(backgroundItem->szDisplayName, _T('.'));
206 if (p)
207 *p = (TCHAR)0;
208 _tcscpy(backgroundItem->szFilename, filename);
209
210 ZeroMemory(&listItem, sizeof(LV_ITEM));
211 listItem.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE | LVIF_IMAGE;
212 listItem.pszText = backgroundItem->szDisplayName;
213 listItem.state = 0;
214 listItem.iImage = sfi.iIcon;
215 listItem.iItem = pGlobalData->listViewItemCount;
216 listItem.lParam = pGlobalData->listViewItemCount;
217
218 (void)ListView_InsertItem(hwndBackgroundList, &listItem);
219
220 pGlobalData->listViewItemCount++;
221 }
222
223 if(!FindNextFile(hFind, &fd))
224 hFind = INVALID_HANDLE_VALUE;
225 }
226
227 token = _tcstok(NULL, separators);
228 }
229 }
230
231
232 static VOID
233 InitBackgroundDialog(HWND hwndDlg, PGLOBAL_DATA pGlobalData)
234 {
235 TCHAR szString[256];
236 HKEY regKey;
237 TCHAR szBuffer[2];
238 DWORD bufferSize = sizeof(szBuffer);
239 DWORD varType = REG_SZ;
240 LONG result;
241 BITMAP bitmap;
242
243 pGlobalData->backgroundDesktopColor = GetSysColor(COLOR_BACKGROUND);
244
245 AddListViewItems(hwndDlg, pGlobalData);
246
247 LoadString(hApplet, IDS_CENTER, szString, sizeof(szString) / sizeof(TCHAR));
248 SendDlgItemMessage(hwndDlg, IDC_PLACEMENT_COMBO, CB_INSERTSTRING, PLACEMENT_CENTER, (LPARAM)szString);
249
250 LoadString(hApplet, IDS_STRETCH, szString, sizeof(szString) / sizeof(TCHAR));
251 SendDlgItemMessage(hwndDlg, IDC_PLACEMENT_COMBO, CB_INSERTSTRING, PLACEMENT_STRETCH, (LPARAM)szString);
252
253 LoadString(hApplet, IDS_TILE, szString, sizeof(szString) / sizeof(TCHAR));
254 SendDlgItemMessage(hwndDlg, IDC_PLACEMENT_COMBO, CB_INSERTSTRING, PLACEMENT_TILE, (LPARAM)szString);
255
256 /* Load the default settings from the registry */
257 result = RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Desktop"), 0, KEY_ALL_ACCESS, &regKey);
258 if (result != ERROR_SUCCESS)
259 {
260 /* reg key open failed; maybe it does not exist? create it! */
261 DWORD dwDisposition = 0;
262 result = RegCreateKeyEx( HKEY_CURRENT_USER, TEXT("Control Panel\\Desktop"), 0, NULL, 0, KEY_ALL_ACCESS, NULL,
263 &regKey, &dwDisposition );
264 /* now the key must be created & opened and regKey points to opened key */
265 /* On error result will not contain ERROR_SUCCESS. I don't know how to handle */
266 /* this case :( */
267 }
268
269 result = RegQueryValueEx(regKey, TEXT("WallpaperStyle"), 0, &varType, (LPBYTE)szBuffer, &bufferSize);
270 if (result == ERROR_SUCCESS)
271 {
272 if (_ttoi(szBuffer) == 0)
273 {
274 SendDlgItemMessage(hwndDlg, IDC_PLACEMENT_COMBO, CB_SETCURSEL, PLACEMENT_CENTER, 0);
275 pGlobalData->placementSelection = PLACEMENT_CENTER;
276 }
277
278 if (_ttoi(szBuffer) == 2)
279 {
280 SendDlgItemMessage(hwndDlg, IDC_PLACEMENT_COMBO, CB_SETCURSEL, PLACEMENT_STRETCH, 0);
281 pGlobalData->placementSelection = PLACEMENT_STRETCH;
282 }
283 }
284 else
285 {
286 SendDlgItemMessage(hwndDlg, IDC_PLACEMENT_COMBO, CB_SETCURSEL, PLACEMENT_CENTER, 0);
287 pGlobalData->placementSelection = PLACEMENT_CENTER;
288 }
289
290 result = RegQueryValueEx(regKey, TEXT("TileWallpaper"), 0, &varType, (LPBYTE)szBuffer, &bufferSize);
291 if (result == ERROR_SUCCESS)
292 {
293 if (_ttoi(szBuffer) == 1)
294 {
295 SendDlgItemMessage(hwndDlg, IDC_PLACEMENT_COMBO, CB_SETCURSEL, PLACEMENT_TILE, 0);
296 pGlobalData->placementSelection = PLACEMENT_TILE;
297 }
298 }
299
300 RegCloseKey(regKey);
301
302 pGlobalData->hBitmap = (HBITMAP) LoadImage(hApplet, MAKEINTRESOURCE(IDC_MONITOR), IMAGE_BITMAP, 0, 0, LR_LOADTRANSPARENT);
303 if (pGlobalData->hBitmap != NULL)
304 {
305 GetObject(pGlobalData->hBitmap, sizeof(BITMAP), &bitmap);
306
307 pGlobalData->cxSource = bitmap.bmWidth;
308 pGlobalData->cySource = bitmap.bmHeight;
309 }
310 }
311
312
313 static VOID
314 OnColorButton(HWND hwndDlg, PGLOBAL_DATA pGlobalData)
315 {
316 /* Load custom colors from Registry */
317 HKEY hKey = NULL;
318 LONG res = ERROR_SUCCESS;
319 CHOOSECOLOR cc;
320
321 res = RegCreateKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Appearance"), 0, NULL, 0,
322 KEY_ALL_ACCESS, NULL, &hKey, NULL);
323 /* Now the key is either created or opened existing, if res == ERROR_SUCCESS */
324 if (res == ERROR_SUCCESS)
325 {
326 /* Key opened */
327 DWORD dwType = REG_BINARY;
328 DWORD cbData = sizeof(pGlobalData->custom_colors);
329 res = RegQueryValueEx(hKey, TEXT("CustomColors"), NULL, &dwType,
330 (LPBYTE)pGlobalData->custom_colors, &cbData);
331 RegCloseKey(hKey);
332 hKey = NULL;
333 }
334
335 /* Launch ChooseColor() dialog */
336
337 cc.lStructSize = sizeof(CHOOSECOLOR);
338 cc.hwndOwner = hwndDlg;
339 cc.hInstance = NULL;
340 cc.rgbResult = pGlobalData->backgroundDesktopColor;
341 cc.lpCustColors = pGlobalData->custom_colors;
342 cc.Flags = CC_ANYCOLOR | /* Causes the dialog box to display all available colors in the set of basic colors. */
343 CC_FULLOPEN | /* opens dialog in full size */
344 CC_RGBINIT ; /* init chosen color by rgbResult value */
345 cc.lCustData = 0;
346 cc.lpfnHook = NULL;
347 cc.lpTemplateName = NULL;
348 if (ChooseColor(&cc))
349 {
350 /* Save selected color to var */
351 pGlobalData->backgroundDesktopColor = cc.rgbResult;
352
353 /* Allpy buuton will be activated */
354 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
355
356 /* Window will be updated :) */
357 InvalidateRect(GetDlgItem(hwndDlg, IDC_BACKGROUND_PREVIEW), NULL, TRUE);
358
359 /* Save custom colors to reg. To this moment key must be ceated already. See above */
360 res = RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Appearance"), 0,
361 KEY_WRITE, &hKey);
362 if (res == ERROR_SUCCESS)
363 {
364 /* Key opened */
365 RegSetValueEx(hKey, TEXT("CustomColors"), 0, REG_BINARY,
366 (const BYTE *)pGlobalData->custom_colors, sizeof(pGlobalData->custom_colors));
367 RegCloseKey(hKey);
368 hKey = NULL;
369 }
370 }
371 }
372
373
374 /*
375 * ListView_FindItem() Macro: Searches for a list-view item with the specified
376 * characteristics. Returns the index of the item if successful, or -1 otherwise
377 */
378 static BOOL
379 CheckListViewFilenameExists(HWND hwndList, LPCTSTR tszFileName)
380 {
381 LVFINDINFO lvfi;
382 int retVal;
383
384 lvfi.flags = LVFI_STRING; /* search item by EXACT string */
385 lvfi.psz = tszFileName; /* string to search */
386
387 /* other items of this structure are not valid, besacuse flags are not set. */
388 retVal = ListView_FindItem(hwndList, -1, &lvfi);
389 if (retVal != -1)
390 return TRUE; /* item found! */
391
392 return FALSE; /* item not found. */
393 }
394
395
396 static VOID
397 OnBrowseButton(HWND hwndDlg, PGLOBAL_DATA pGlobalData)
398 {
399 OPENFILENAME ofn;
400 TCHAR filename[MAX_PATH];
401 TCHAR fileTitle[256];
402 TCHAR filter[MAX_PATH];
403 BackgroundItem *backgroundItem = NULL;
404 SHFILEINFO sfi;
405 LV_ITEM listItem;
406 HWND hwndBackgroundList;
407 TCHAR *p;
408
409 hwndBackgroundList = GetDlgItem(hwndDlg, IDC_BACKGROUND_LIST);
410
411 ZeroMemory(&ofn, sizeof(OPENFILENAME));
412
413 ofn.lStructSize = sizeof(OPENFILENAME);
414 ofn.hwndOwner = hwndDlg;
415 ofn.lpstrFile = filename;
416
417 LoadString(hApplet, IDS_BACKGROUND_COMDLG_FILTER, filter, sizeof(filter) / sizeof(TCHAR));
418
419 /* Set lpstrFile[0] to '\0' so that GetOpenFileName does not
420 * use the contents of szFile to initialize itself */
421 ofn.lpstrFile[0] = TEXT('\0');
422 ofn.nMaxFile = MAX_PATH;
423 ofn.lpstrFilter = filter;
424 ofn.nFilterIndex = 0;
425 ofn.lpstrFileTitle = fileTitle;
426 ofn.nMaxFileTitle = 256;
427 ofn.lpstrInitialDir = NULL;
428 ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
429
430 if (GetOpenFileName(&ofn) == TRUE)
431 {
432 /* Check if there is already a entry that holds this filename */
433 if (CheckListViewFilenameExists(hwndBackgroundList, ofn.lpstrFileTitle) == TRUE)
434 return;
435
436 if (pGlobalData->listViewItemCount > (MAX_BACKGROUNDS - 1))
437 return;
438
439 SHGetFileInfo(filename,
440 0,
441 &sfi,
442 sizeof(sfi),
443 SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_DISPLAYNAME);
444
445 backgroundItem = &pGlobalData->backgroundItems[pGlobalData->listViewItemCount];
446
447 backgroundItem->bWallpaper = TRUE;
448
449 _tcscpy(backgroundItem->szDisplayName, sfi.szDisplayName);
450 p = _tcsrchr(backgroundItem->szDisplayName, _T('.'));
451 if (p)
452 *p = (TCHAR)0;
453 _tcscpy(backgroundItem->szFilename, filename);
454
455 ZeroMemory(&listItem, sizeof(LV_ITEM));
456 listItem.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE | LVIF_IMAGE;
457 listItem.state = LVIS_SELECTED;
458 listItem.pszText = backgroundItem->szDisplayName;
459 listItem.iImage = sfi.iIcon;
460 listItem.iItem = pGlobalData->listViewItemCount;
461 listItem.lParam = pGlobalData->listViewItemCount;
462
463 (void)ListView_InsertItem(hwndBackgroundList, &listItem);
464 SendMessage(hwndBackgroundList, WM_VSCROLL, SB_BOTTOM, 0);
465
466 pGlobalData->listViewItemCount++;
467 }
468 }
469
470
471 static VOID
472 ListViewItemChanged(HWND hwndDlg, PGLOBAL_DATA pGlobalData, int itemIndex)
473 {
474 BackgroundItem *backgroundItem = NULL;
475
476 pGlobalData->backgroundSelection = itemIndex;
477 backgroundItem = &pGlobalData->backgroundItems[pGlobalData->backgroundSelection];
478
479 if (pGlobalData->pWallpaperBitmap != NULL)
480 {
481 DibFreeImage(pGlobalData->pWallpaperBitmap);
482 pGlobalData->pWallpaperBitmap = NULL;
483 }
484
485 if (backgroundItem->bWallpaper == TRUE)
486 {
487 pGlobalData->pWallpaperBitmap = DibLoadImage(backgroundItem->szFilename);
488
489 if (pGlobalData->pWallpaperBitmap == NULL)
490 return;
491 }
492
493 InvalidateRect(GetDlgItem(hwndDlg, IDC_BACKGROUND_PREVIEW),
494 NULL, TRUE);
495
496 EnableWindow(GetDlgItem(hwndDlg, IDC_PLACEMENT_COMBO),
497 backgroundItem->bWallpaper);
498
499 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
500 }
501
502
503 static VOID
504 DrawBackgroundPreview(LPDRAWITEMSTRUCT draw, PGLOBAL_DATA pGlobalData)
505 {
506 float scaleX;
507 float scaleY;
508 int scaledWidth;
509 int scaledHeight;
510 int posX;
511 int posY;
512 HBRUSH hBrush;
513 int x;
514 int y;
515
516 if (pGlobalData->backgroundItems[pGlobalData->backgroundSelection].bWallpaper == FALSE)
517 {
518 /* update desktop background color image */
519 hBrush = CreateSolidBrush(pGlobalData->backgroundDesktopColor);
520 FillRect(draw->hDC, &draw->rcItem, hBrush);
521 DeleteObject(hBrush);
522 return;
523 }
524
525 if (pGlobalData->pWallpaperBitmap == NULL)
526 return;
527
528 scaleX = ((float)GetSystemMetrics(SM_CXSCREEN) - 1) / (float)draw->rcItem.right;
529 scaleY = ((float)GetSystemMetrics(SM_CYSCREEN) - 1) / (float)draw->rcItem.bottom;
530
531 scaledWidth = pGlobalData->pWallpaperBitmap->width / scaleX;
532 scaledHeight = pGlobalData->pWallpaperBitmap->height / scaleY;
533
534 posX = (draw->rcItem.right / 2) - (scaledWidth / 2);
535 posY = (draw->rcItem.bottom / 2) - (scaledHeight / 2);
536
537 FillRect(draw->hDC, &draw->rcItem, GetSysColorBrush(COLOR_BACKGROUND));
538
539 SetStretchBltMode(draw->hDC, COLORONCOLOR);
540
541 switch (pGlobalData->placementSelection)
542 {
543 case PLACEMENT_CENTER:
544 StretchDIBits(draw->hDC,
545 posX,
546 posY,
547 scaledWidth,
548 scaledHeight,
549 0,
550 0,
551 pGlobalData->pWallpaperBitmap->width,
552 pGlobalData->pWallpaperBitmap->height,
553 pGlobalData->pWallpaperBitmap->bits,
554 pGlobalData->pWallpaperBitmap->info,
555 DIB_RGB_COLORS,
556 SRCCOPY);
557 break;
558
559 case PLACEMENT_STRETCH:
560 StretchDIBits(draw->hDC,
561 0,
562 0,
563 draw->rcItem.right,
564 draw->rcItem.bottom,
565 0,
566 0,
567 pGlobalData->pWallpaperBitmap->width,
568 pGlobalData->pWallpaperBitmap->height,
569 pGlobalData->pWallpaperBitmap->bits,
570 pGlobalData->pWallpaperBitmap->info,
571 DIB_RGB_COLORS,
572 SRCCOPY);
573 break;
574
575 case PLACEMENT_TILE:
576 for (y = 0; y < draw->rcItem.bottom; y += scaledHeight)
577 {
578 for (x = 0; x < draw->rcItem.right; x += scaledWidth)
579 {
580 StretchDIBits(draw->hDC,
581 x,
582 y,
583 scaledWidth,
584 scaledHeight,
585 0,
586 0,
587 pGlobalData->pWallpaperBitmap->width,
588 pGlobalData->pWallpaperBitmap->height,
589 pGlobalData->pWallpaperBitmap->bits,
590 pGlobalData->pWallpaperBitmap->info,
591 DIB_RGB_COLORS,
592 SRCCOPY);
593 }
594 }
595 break;
596 }
597 }
598
599
600 static VOID
601 SetWallpaper(PGLOBAL_DATA pGlobalData)
602 {
603 HKEY regKey;
604
605 RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Desktop"), 0, KEY_ALL_ACCESS, &regKey);
606
607 if (pGlobalData->placementSelection == PLACEMENT_TILE)
608 {
609 RegSetValueEx(regKey, TEXT("TileWallpaper"), 0, REG_SZ, (BYTE *)TEXT("1"), sizeof(TCHAR) * 2);
610 RegSetValueEx(regKey, TEXT("WallpaperStyle"), 0, REG_SZ, (BYTE *)TEXT("0"), sizeof(TCHAR) * 2);
611 }
612
613 if (pGlobalData->placementSelection == PLACEMENT_CENTER)
614 {
615 RegSetValueEx(regKey, TEXT("TileWallpaper"), 0, REG_SZ, (BYTE *)TEXT("0"), sizeof(TCHAR) * 2);
616 RegSetValueEx(regKey, TEXT("WallpaperStyle"), 0, REG_SZ, (BYTE *)TEXT("0"), sizeof(TCHAR) * 2);
617 }
618
619 if (pGlobalData->placementSelection == PLACEMENT_STRETCH)
620 {
621 RegSetValueEx(regKey, TEXT("TileWallpaper"), 0, REG_SZ, (BYTE *)TEXT("0"), sizeof(TCHAR) * 2);
622 RegSetValueEx(regKey, TEXT("WallpaperStyle"), 0, REG_SZ, (BYTE *)TEXT("2"), sizeof(TCHAR) * 2);
623 }
624
625 RegCloseKey(regKey);
626
627 if (pGlobalData->backgroundItems[pGlobalData->backgroundSelection].bWallpaper == TRUE)
628 {
629 SystemParametersInfo(SPI_SETDESKWALLPAPER,
630 0,
631 pGlobalData->backgroundItems[pGlobalData->backgroundSelection].szFilename,
632 SPIF_UPDATEINIFILE);
633 }
634 else
635 {
636 SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, (void*) TEXT(""), SPIF_UPDATEINIFILE);
637 }
638 }
639
640
641 /* Change system color */
642 static VOID
643 SetDesktopBackColor(HWND hwndDlg, PGLOBAL_DATA pGlobalData)
644 {
645 INT iElement = COLOR_BACKGROUND;
646 HKEY hKey;
647 LONG result;
648 TCHAR clText[16];
649 DWORD red, green, blue;
650
651 if( !SetSysColors( 1, &iElement, &pGlobalData->backgroundDesktopColor ) )
652 MessageBox(hwndDlg, TEXT("SetSysColor() failed!"), /* these error texts can need internationalization? */
653 TEXT("Error!"), MB_ICONSTOP );
654 /* Write color to registry key: HKEY_CURRENT_USER\Control Panel\Colors\Background */
655 hKey = NULL;
656 result = ERROR_SUCCESS;
657 result = RegOpenKeyEx( HKEY_CURRENT_USER, TEXT("Control Panel\\Colors"), 0, KEY_WRITE, &hKey );
658 if( result != ERROR_SUCCESS )
659 {
660 /* Key open failed; maybe it does not exist? create it! */
661 result = RegCreateKeyEx( HKEY_CURRENT_USER, TEXT("Control Panel\\Colors"), 0, NULL, 0,
662 KEY_ALL_ACCESS, NULL, &hKey, NULL );
663 /* Now key must be created and opened and hKey must point at newly created key */
664 /* On error result will not contain ERROR_SUCCESS. I don't know how to handle */
665 /* this case :( */
666 }
667 red = GetRValue(pGlobalData->backgroundDesktopColor);
668 green = GetGValue(pGlobalData->backgroundDesktopColor);
669 blue = GetBValue(pGlobalData->backgroundDesktopColor);
670 _stprintf(clText, TEXT("%d %d %d"), red, green, blue ); /* format string to be set to registry */
671 RegSetValueEx(hKey, TEXT("Background"), 0, REG_SZ, (BYTE *)clText, lstrlen( clText )*sizeof(TCHAR) + sizeof(TCHAR) );
672 RegCloseKey(hKey);
673 }
674
675
676 INT_PTR CALLBACK
677 BackgroundPageProc(HWND hwndDlg,
678 UINT uMsg,
679 WPARAM wParam,
680 LPARAM lParam)
681 {
682 PGLOBAL_DATA pGlobalData;
683
684 pGlobalData = (PGLOBAL_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
685
686 switch (uMsg)
687 {
688 case WM_INITDIALOG:
689 pGlobalData = (GLOBAL_DATA*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(GLOBAL_DATA));
690 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pGlobalData);
691 InitBackgroundDialog(hwndDlg, pGlobalData);
692 break;
693
694 case WM_COMMAND:
695 {
696 DWORD controlId = LOWORD(wParam);
697 DWORD command = HIWORD(wParam);
698
699 switch (controlId)
700 {
701 case IDC_COLOR_BUTTON:
702 if (command == BN_CLICKED)
703 OnColorButton(hwndDlg, pGlobalData);
704 break;
705
706 case IDC_BROWSE_BUTTON:
707 if (command == BN_CLICKED)
708 OnBrowseButton(hwndDlg, pGlobalData);
709 break;
710
711 case IDC_PLACEMENT_COMBO:
712 if (command == CBN_SELCHANGE)
713 {
714 pGlobalData->placementSelection = (int)SendDlgItemMessage(hwndDlg, IDC_PLACEMENT_COMBO, CB_GETCURSEL, 0, 0);
715
716 InvalidateRect(GetDlgItem(hwndDlg, IDC_BACKGROUND_PREVIEW), NULL, TRUE);
717
718 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
719 }
720 break;
721 }
722 } break;
723
724 case WM_PAINT:
725 {
726 PAINTSTRUCT ps;
727 HDC hdc, hdcMem;
728
729 hdc = BeginPaint(hwndDlg, &ps);
730
731 hdcMem = CreateCompatibleDC(hdc);
732 SelectObject(hdcMem, pGlobalData->hBitmap);
733 /*
734 TransparentBlt(hdc, 98, 0,
735 pGlobalData->cxSource, pGlobalData->cySource, hdcMem, 0, 0,
736 pGlobalData->cxSource, pGlobalData->cySource, 0xFF80FF);
737 */
738 DeleteDC(hdcMem);
739 EndPaint(hwndDlg, &ps);
740 }
741 break;
742
743 case WM_DRAWITEM:
744 {
745 LPDRAWITEMSTRUCT drawItem;
746 drawItem = (LPDRAWITEMSTRUCT)lParam;
747
748 if (drawItem->CtlID == IDC_BACKGROUND_PREVIEW)
749 {
750 DrawBackgroundPreview(drawItem, pGlobalData);
751 }
752
753 }
754 break;
755
756 case WM_NOTIFY:
757 {
758 LPNMHDR lpnm = (LPNMHDR)lParam;
759
760 switch(lpnm->code)
761 {
762 case PSN_APPLY:
763 SetWallpaper(pGlobalData);
764 SetDesktopBackColor(hwndDlg, pGlobalData);
765 return TRUE;
766
767 case LVN_ITEMCHANGED:
768 {
769 LPNMLISTVIEW nm = (LPNMLISTVIEW)lParam;
770
771 if ((nm->uNewState & LVIS_SELECTED) == 0)
772 return FALSE;
773
774 ListViewItemChanged(hwndDlg, pGlobalData, nm->iItem);
775
776 } break;
777 }
778 }
779 break;
780
781 case WM_DESTROY:
782 if (pGlobalData->pWallpaperBitmap != NULL)
783 DibFreeImage(pGlobalData->pWallpaperBitmap);
784
785 DeleteObject(pGlobalData->hBitmap);
786 HeapFree(GetProcessHeap(), 0, pGlobalData);
787 break;
788 }
789
790 return FALSE;
791 }
792
793