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
7 * PROGRAMMERS: Trevor McCort (lycan359@gmail.com)
8 * Alexey Minnekhanov (minlexx@rambler.ru)
15 #define MAX_BACKGROUNDS 100
17 #define PLACEMENT_CENTER 0
18 #define PLACEMENT_STRETCH 1
19 #define PLACEMENT_TILE 2
21 /* The values in these macros are dependant on the
22 * layout of the monitor image and they must be adjusted
23 * if that image will be changed.
25 #define MONITOR_LEFT 18
26 #define MONITOR_TOP 18
27 #define MONITOR_RIGHT 168
28 #define MONITOR_BOTTOM 128
30 #define MONITOR_WIDTH (MONITOR_RIGHT-MONITOR_LEFT)
31 #define MONITOR_HEIGHT (MONITOR_BOTTOM-MONITOR_TOP)
35 BOOL bWallpaper
; /* Is this background a wallpaper */
37 TCHAR szFilename
[MAX_PATH
];
38 TCHAR szDisplayName
[256];
44 BOOL bWallpaperChanged
;
45 BOOL bClrBackgroundChanged
;
47 BackgroundItem backgroundItems
[MAX_BACKGROUNDS
];
49 PDIBITMAP pWallpaperBitmap
;
51 int placementSelection
;
52 int backgroundSelection
;
54 COLORREF custom_colors
[16];
56 int listViewItemCount
;
63 GLOBAL_DATA g_GlobalData
;
66 /* Add the images in the C:\ReactOS directory and the current wallpaper if any */
68 AddListViewItems(HWND hwndDlg
, PDATA pData
)
72 TCHAR szSearchPath
[MAX_PATH
];
73 TCHAR szFileTypes
[MAX_PATH
];
80 TCHAR wallpaperFilename
[MAX_PATH
];
81 DWORD bufferSize
= sizeof(wallpaperFilename
);
82 TCHAR buffer
[MAX_PATH
];
83 DWORD varType
= REG_SZ
;
86 BackgroundItem
*backgroundItem
= NULL
;
87 TCHAR separators
[] = TEXT(";");
89 HWND hwndBackgroundList
;
93 hwndBackgroundList
= GetDlgItem(hwndDlg
, IDC_BACKGROUND_LIST
);
95 GetClientRect(hwndBackgroundList
, &clientRect
);
97 /* Add a new column to the list */
98 ZeroMemory(&dummy
, sizeof(LV_COLUMN
));
99 dummy
.mask
= LVCF_SUBITEM
| LVCF_WIDTH
;
101 dummy
.cx
= (clientRect
.right
- clientRect
.left
) - GetSystemMetrics(SM_CXVSCROLL
);
102 (void)ListView_InsertColumn(hwndBackgroundList
, 0, &dummy
);
104 /* Add the "None" item */
105 backgroundItem
= &pData
->backgroundItems
[pData
->listViewItemCount
];
106 backgroundItem
->bWallpaper
= FALSE
;
109 backgroundItem
->szDisplayName
,
110 sizeof(backgroundItem
->szDisplayName
) / sizeof(TCHAR
));
112 ZeroMemory(&listItem
, sizeof(LV_ITEM
));
113 listItem
.mask
= LVIF_TEXT
| LVIF_PARAM
| LVIF_STATE
| LVIF_IMAGE
;
115 listItem
.pszText
= backgroundItem
->szDisplayName
;
116 listItem
.iImage
= -1;
117 listItem
.iItem
= pData
->listViewItemCount
;
118 listItem
.lParam
= pData
->listViewItemCount
;
120 (void)ListView_InsertItem(hwndBackgroundList
, &listItem
);
121 ListView_SetItemState(hwndBackgroundList
,
122 pData
->listViewItemCount
,
126 pData
->listViewItemCount
++;
128 /* Add current wallpaper if any */
129 result
= RegOpenKeyEx(HKEY_CURRENT_USER
, TEXT("Control Panel\\Desktop"), 0, KEY_ALL_ACCESS
, ®Key
);
130 if (result
== ERROR_SUCCESS
)
132 result
= RegQueryValueEx(regKey
, TEXT("Wallpaper"), 0, &varType
, (LPBYTE
)wallpaperFilename
, &bufferSize
);
133 if ((result
== ERROR_SUCCESS
) && (_tcslen(wallpaperFilename
) > 0))
135 /* Allow environment variables in file name */
136 if (ExpandEnvironmentStrings(wallpaperFilename
, buffer
, MAX_PATH
))
138 hr
= StringCbCopy(wallpaperFilename
, sizeof(wallpaperFilename
), buffer
);
146 himl
= (HIMAGELIST
)SHGetFileInfo(wallpaperFilename
,
150 SHGFI_SYSICONINDEX
| SHGFI_SMALLICON
|
157 (void)ListView_SetImageList(hwndBackgroundList
, himl
, LVSIL_SMALL
);
160 backgroundItem
= &pData
->backgroundItems
[pData
->listViewItemCount
];
162 backgroundItem
->bWallpaper
= TRUE
;
164 hr
= StringCbCopy(backgroundItem
->szDisplayName
, sizeof(backgroundItem
->szDisplayName
), sfi
.szDisplayName
);
171 p
= _tcsrchr(backgroundItem
->szDisplayName
, _T('.'));
175 hr
= StringCbCopy(backgroundItem
->szFilename
, sizeof(backgroundItem
->szFilename
), wallpaperFilename
);
182 ZeroMemory(&listItem
, sizeof(LV_ITEM
));
183 listItem
.mask
= LVIF_TEXT
| LVIF_PARAM
| LVIF_STATE
| LVIF_IMAGE
;
185 listItem
.pszText
= backgroundItem
->szDisplayName
;
186 listItem
.iImage
= sfi
.iIcon
;
187 listItem
.iItem
= pData
->listViewItemCount
;
188 listItem
.lParam
= pData
->listViewItemCount
;
190 (void)ListView_InsertItem(hwndBackgroundList
, &listItem
);
191 ListView_SetItemState(hwndBackgroundList
,
192 pData
->listViewItemCount
,
196 pData
->listViewItemCount
++;
203 /* Add all the images in the C:\ReactOS directory. */
205 LoadString(hApplet
, IDS_SUPPORTED_EXT
, szFileTypes
, sizeof(szFileTypes
) / sizeof(TCHAR
));
207 token
= _tcstok(szFileTypes
, separators
);
208 while (token
!= NULL
)
210 GetWindowsDirectory(szSearchPath
, MAX_PATH
);
212 hr
= StringCbCat(szSearchPath
, sizeof(szSearchPath
), TEXT("\\"));
215 hr
= StringCbCat(szSearchPath
, sizeof(szSearchPath
), token
);
219 hFind
= FindFirstFile(szSearchPath
, &fd
);
220 while (hFind
!= INVALID_HANDLE_VALUE
)
222 TCHAR filename
[MAX_PATH
];
224 GetWindowsDirectory(filename
, MAX_PATH
);
226 hr
= StringCbCat(filename
, sizeof(filename
), TEXT("\\"));
232 hr
= StringCbCat(filename
, sizeof(filename
), fd
.cFileName
);
239 /* Don't add any hidden bitmaps. Also don't add current wallpaper once more. */
240 if (((fd
.dwFileAttributes
& FILE_ATTRIBUTE_HIDDEN
) == 0) && (_tcscmp(wallpaperFilename
, filename
) != 0))
242 himl
= (HIMAGELIST
)SHGetFileInfo(filename
,
246 SHGFI_SYSICONINDEX
| SHGFI_SMALLICON
|
254 (void)ListView_SetImageList(hwndBackgroundList
, himl
, LVSIL_SMALL
);
257 backgroundItem
= &pData
->backgroundItems
[pData
->listViewItemCount
];
259 backgroundItem
->bWallpaper
= TRUE
;
261 hr
= StringCbCopy(backgroundItem
->szDisplayName
, sizeof(backgroundItem
->szDisplayName
), sfi
.szDisplayName
);
267 p
= _tcsrchr(backgroundItem
->szDisplayName
, _T('.'));
270 hr
= StringCbCopy(backgroundItem
->szFilename
, sizeof(backgroundItem
->szFilename
), filename
);
277 ZeroMemory(&listItem
, sizeof(LV_ITEM
));
278 listItem
.mask
= LVIF_TEXT
| LVIF_PARAM
| LVIF_STATE
| LVIF_IMAGE
;
279 listItem
.pszText
= backgroundItem
->szDisplayName
;
281 listItem
.iImage
= sfi
.iIcon
;
282 listItem
.iItem
= pData
->listViewItemCount
;
283 listItem
.lParam
= pData
->listViewItemCount
;
285 (void)ListView_InsertItem(hwndBackgroundList
, &listItem
);
287 pData
->listViewItemCount
++;
290 if(!FindNextFile(hFind
, &fd
))
291 hFind
= INVALID_HANDLE_VALUE
;
294 token
= _tcstok(NULL
, separators
);
301 InitBackgroundDialog(HWND hwndDlg
, PDATA pData
)
306 DWORD bufferSize
= sizeof(szBuffer
);
307 DWORD varType
= REG_SZ
;
311 AddListViewItems(hwndDlg
, pData
);
313 LoadString(hApplet
, IDS_CENTER
, szString
, sizeof(szString
) / sizeof(TCHAR
));
314 SendDlgItemMessage(hwndDlg
, IDC_PLACEMENT_COMBO
, CB_INSERTSTRING
, PLACEMENT_CENTER
, (LPARAM
)szString
);
316 LoadString(hApplet
, IDS_STRETCH
, szString
, sizeof(szString
) / sizeof(TCHAR
));
317 SendDlgItemMessage(hwndDlg
, IDC_PLACEMENT_COMBO
, CB_INSERTSTRING
, PLACEMENT_STRETCH
, (LPARAM
)szString
);
319 LoadString(hApplet
, IDS_TILE
, szString
, sizeof(szString
) / sizeof(TCHAR
));
320 SendDlgItemMessage(hwndDlg
, IDC_PLACEMENT_COMBO
, CB_INSERTSTRING
, PLACEMENT_TILE
, (LPARAM
)szString
);
322 /* Load the default settings from the registry */
323 result
= RegOpenKeyEx(HKEY_CURRENT_USER
, TEXT("Control Panel\\Desktop"), 0, KEY_ALL_ACCESS
, ®Key
);
324 if (result
!= ERROR_SUCCESS
)
326 /* reg key open failed; maybe it does not exist? create it! */
327 DWORD dwDisposition
= 0;
328 result
= RegCreateKeyEx( HKEY_CURRENT_USER
, TEXT("Control Panel\\Desktop"), 0, NULL
, 0, KEY_ALL_ACCESS
, NULL
,
329 ®Key
, &dwDisposition
);
330 /* Now the key must be created & opened and regKey points to opened key */
331 /* On error result will not contain ERROR_SUCCESS. I don't know how to handle */
335 result
= RegQueryValueEx(regKey
, TEXT("WallpaperStyle"), 0, &varType
, (LPBYTE
)szBuffer
, &bufferSize
);
336 if (result
== ERROR_SUCCESS
)
338 if (_ttoi(szBuffer
) == 0)
340 SendDlgItemMessage(hwndDlg
, IDC_PLACEMENT_COMBO
, CB_SETCURSEL
, PLACEMENT_CENTER
, 0);
341 pData
->placementSelection
= PLACEMENT_CENTER
;
344 if (_ttoi(szBuffer
) == 2)
346 SendDlgItemMessage(hwndDlg
, IDC_PLACEMENT_COMBO
, CB_SETCURSEL
, PLACEMENT_STRETCH
, 0);
347 pData
->placementSelection
= PLACEMENT_STRETCH
;
352 SendDlgItemMessage(hwndDlg
, IDC_PLACEMENT_COMBO
, CB_SETCURSEL
, PLACEMENT_CENTER
, 0);
353 pData
->placementSelection
= PLACEMENT_CENTER
;
356 result
= RegQueryValueEx(regKey
, TEXT("TileWallpaper"), 0, &varType
, (LPBYTE
)szBuffer
, &bufferSize
);
357 if (result
== ERROR_SUCCESS
)
359 if (_ttoi(szBuffer
) == 1)
361 SendDlgItemMessage(hwndDlg
, IDC_PLACEMENT_COMBO
, CB_SETCURSEL
, PLACEMENT_TILE
, 0);
362 pData
->placementSelection
= PLACEMENT_TILE
;
368 pData
->hBitmap
= (HBITMAP
) LoadImage(hApplet
, MAKEINTRESOURCE(IDC_MONITOR
), IMAGE_BITMAP
, 0, 0, LR_DEFAULTCOLOR
);
369 if (pData
->hBitmap
!= NULL
)
371 GetObject(pData
->hBitmap
, sizeof(BITMAP
), &bitmap
);
373 pData
->cxSource
= bitmap
.bmWidth
;
374 pData
->cySource
= bitmap
.bmHeight
;
380 OnColorButton(HWND hwndDlg
, PDATA pData
)
382 /* Load custom colors from Registry */
384 LONG res
= ERROR_SUCCESS
;
387 res
= RegCreateKeyEx(HKEY_CURRENT_USER
, TEXT("Control Panel\\Appearance"), 0, NULL
, 0,
388 KEY_ALL_ACCESS
, NULL
, &hKey
, NULL
);
389 /* Now the key is either created or opened existing, if res == ERROR_SUCCESS */
390 if (res
== ERROR_SUCCESS
)
393 DWORD dwType
= REG_BINARY
;
394 DWORD cbData
= sizeof(pData
->custom_colors
);
395 res
= RegQueryValueEx(hKey
, TEXT("CustomColors"), NULL
, &dwType
,
396 (LPBYTE
)pData
->custom_colors
, &cbData
);
401 /* Launch ChooseColor() dialog */
403 cc
.lStructSize
= sizeof(CHOOSECOLOR
);
404 cc
.hwndOwner
= hwndDlg
;
406 cc
.rgbResult
= g_GlobalData
.desktop_color
;
407 cc
.lpCustColors
= pData
->custom_colors
;
408 cc
.Flags
= CC_ANYCOLOR
| /* Causes the dialog box to display all available colors in the set of basic colors. */
409 CC_FULLOPEN
| /* opens dialog in full size */
410 CC_RGBINIT
; /* init chosen color by rgbResult value */
413 cc
.lpTemplateName
= NULL
;
414 if (ChooseColor(&cc
))
416 /* Save selected color to var */
417 g_GlobalData
.desktop_color
= cc
.rgbResult
;
418 pData
->bClrBackgroundChanged
= TRUE
;
420 /* Apply button will be activated */
421 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
423 /* Window will be updated :) */
424 InvalidateRect(GetDlgItem(hwndDlg
, IDC_BACKGROUND_PREVIEW
), NULL
, TRUE
);
426 /* Save custom colors to reg. To this moment key must be created already. See above */
427 res
= RegOpenKeyEx(HKEY_CURRENT_USER
, TEXT("Control Panel\\Appearance"), 0,
429 if (res
== ERROR_SUCCESS
)
432 RegSetValueEx(hKey
, TEXT("CustomColors"), 0, REG_BINARY
,
433 (const BYTE
*)pData
->custom_colors
, sizeof(pData
->custom_colors
));
442 * ListView_FindItem() Macro: Searches for a list-view item with the specified
443 * characteristics. Returns the index of the item if successful, or -1 otherwise
446 CheckListViewFilenameExists(HWND hwndList
, LPCTSTR tszFileName
)
451 lvfi
.flags
= LVFI_STRING
; /* Search item by EXACT string */
452 lvfi
.psz
= tszFileName
; /* String to search */
454 /* Other items of this structure are not valid, besacuse flags are not set. */
455 retVal
= ListView_FindItem(hwndList
, -1, &lvfi
);
457 return TRUE
; /* item found! */
459 return FALSE
; /* item not found. */
464 OnBrowseButton(HWND hwndDlg
, PDATA pData
)
467 TCHAR filename
[MAX_PATH
];
468 TCHAR fileTitle
[256];
469 TCHAR filter
[MAX_PATH
];
470 BackgroundItem
*backgroundItem
= NULL
;
473 HWND hwndBackgroundList
;
477 hwndBackgroundList
= GetDlgItem(hwndDlg
, IDC_BACKGROUND_LIST
);
479 ZeroMemory(&ofn
, sizeof(OPENFILENAME
));
481 ofn
.lStructSize
= sizeof(OPENFILENAME
);
482 ofn
.hwndOwner
= hwndDlg
;
483 ofn
.lpstrFile
= filename
;
485 LoadString(hApplet
, IDS_BACKGROUND_COMDLG_FILTER
, filter
, sizeof(filter
) / sizeof(TCHAR
));
487 /* Set lpstrFile[0] to '\0' so that GetOpenFileName does not
488 * use the contents of szFile to initialize itself */
489 ofn
.lpstrFile
[0] = TEXT('\0');
490 ofn
.nMaxFile
= MAX_PATH
;
491 ofn
.lpstrFilter
= filter
;
492 ofn
.nFilterIndex
= 0;
493 ofn
.lpstrFileTitle
= fileTitle
;
494 ofn
.nMaxFileTitle
= 256;
495 ofn
.lpstrInitialDir
= NULL
;
496 ofn
.Flags
= OFN_PATHMUSTEXIST
| OFN_FILEMUSTEXIST
;
498 if (GetOpenFileName(&ofn
) == TRUE
)
500 /* Check if there is already a entry that holds this filename */
501 if (CheckListViewFilenameExists(hwndBackgroundList
, ofn
.lpstrFileTitle
) == TRUE
)
504 if (pData
->listViewItemCount
> (MAX_BACKGROUNDS
- 1))
507 SHGetFileInfo(filename
,
511 SHGFI_SYSICONINDEX
| SHGFI_SMALLICON
| SHGFI_DISPLAYNAME
);
513 backgroundItem
= &pData
->backgroundItems
[pData
->listViewItemCount
];
515 backgroundItem
->bWallpaper
= TRUE
;
517 hr
= StringCbCopy(backgroundItem
->szDisplayName
, sizeof(backgroundItem
->szDisplayName
), sfi
.szDisplayName
);
520 p
= _tcsrchr(backgroundItem
->szDisplayName
, _T('.'));
523 hr
= StringCbCopy(backgroundItem
->szFilename
, sizeof(backgroundItem
->szFilename
), filename
);
527 ZeroMemory(&listItem
, sizeof(LV_ITEM
));
528 listItem
.mask
= LVIF_TEXT
| LVIF_PARAM
| LVIF_STATE
| LVIF_IMAGE
;
530 listItem
.pszText
= backgroundItem
->szDisplayName
;
531 listItem
.iImage
= sfi
.iIcon
;
532 listItem
.iItem
= pData
->listViewItemCount
;
533 listItem
.lParam
= pData
->listViewItemCount
;
535 (void)ListView_InsertItem(hwndBackgroundList
, &listItem
);
536 ListView_SetItemState(hwndBackgroundList
,
537 pData
->listViewItemCount
,
540 SendMessage(hwndBackgroundList
, WM_VSCROLL
, SB_BOTTOM
, 0);
542 pData
->listViewItemCount
++;
548 ListViewItemChanged(HWND hwndDlg
, PDATA pData
, int itemIndex
)
550 BackgroundItem
*backgroundItem
= NULL
;
552 pData
->backgroundSelection
= itemIndex
;
553 backgroundItem
= &pData
->backgroundItems
[pData
->backgroundSelection
];
555 if (pData
->pWallpaperBitmap
!= NULL
)
557 DibFreeImage(pData
->pWallpaperBitmap
);
558 pData
->pWallpaperBitmap
= NULL
;
561 if (backgroundItem
->bWallpaper
== TRUE
)
563 pData
->pWallpaperBitmap
= DibLoadImage(backgroundItem
->szFilename
);
565 if (pData
->pWallpaperBitmap
== NULL
)
569 pData
->bWallpaperChanged
= TRUE
;
571 InvalidateRect(GetDlgItem(hwndDlg
, IDC_BACKGROUND_PREVIEW
),
574 EnableWindow(GetDlgItem(hwndDlg
, IDC_PLACEMENT_COMBO
),
575 backgroundItem
->bWallpaper
);
577 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
582 DrawBackgroundPreview(LPDRAWITEMSTRUCT draw
, PDATA pData
)
602 hDC
= CreateCompatibleDC(draw
->hDC
);
603 hOldObj
= SelectObject(hDC
, pData
->hBitmap
);
605 if (pData
->backgroundItems
[pData
->backgroundSelection
].bWallpaper
== FALSE
)
607 /* Update desktop background color image */
608 hBrush
= CreateSolidBrush(g_GlobalData
.desktop_color
);
609 FillRect(hDC
, &rcItem
, hBrush
);
610 DeleteObject(hBrush
);
613 if (pData
->pWallpaperBitmap
!= NULL
)
615 scaleX
= ((float)GetSystemMetrics(SM_CXSCREEN
) - 1) / (float)MONITOR_WIDTH
;
616 scaleY
= ((float)GetSystemMetrics(SM_CYSCREEN
) - 1) / (float)MONITOR_HEIGHT
;
618 scaledWidth
= (int)(pData
->pWallpaperBitmap
->width
/ scaleX
);
619 scaledHeight
= (int)(pData
->pWallpaperBitmap
->height
/ scaleY
);
621 FillRect(hDC
, &rcItem
, GetSysColorBrush(COLOR_BACKGROUND
));
623 SetStretchBltMode(hDC
, COLORONCOLOR
);
625 switch (pData
->placementSelection
)
627 case PLACEMENT_CENTER
:
628 posX
= (MONITOR_WIDTH
- scaledWidth
+ 1) / 2;
629 posY
= (MONITOR_HEIGHT
- scaledHeight
+ 1) / 2;
633 if (posX
< 0) { desX
= -posX
/ 2; posX
= 0; }
634 if (posY
< 0) { desY
= -posY
/ 2; posY
= 0; }
636 if (scaledWidth
> MONITOR_WIDTH
)
637 scaledWidth
= MONITOR_WIDTH
;
639 if (scaledHeight
> MONITOR_HEIGHT
)
640 scaledHeight
= MONITOR_HEIGHT
;
649 pData
->pWallpaperBitmap
->width
- (int)(desX
* scaleX
),
650 pData
->pWallpaperBitmap
->height
- (int)(desY
* scaleY
),
651 pData
->pWallpaperBitmap
->bits
,
652 pData
->pWallpaperBitmap
->info
,
657 case PLACEMENT_STRETCH
:
665 pData
->pWallpaperBitmap
->width
,
666 pData
->pWallpaperBitmap
->height
,
667 pData
->pWallpaperBitmap
->bits
,
668 pData
->pWallpaperBitmap
->info
,
674 for (y
= 0; y
< MONITOR_HEIGHT
; y
+= scaledHeight
)
676 for (x
= 0; x
< MONITOR_WIDTH
; x
+= scaledWidth
)
678 if ((MONITOR_WIDTH
-x
) >= scaledWidth
)
681 posX
= MONITOR_WIDTH
-x
;
684 if ((MONITOR_HEIGHT
-y
) >= scaledHeight
)
687 posY
= MONITOR_HEIGHT
-y
;
696 pData
->pWallpaperBitmap
->width
* posX
/ scaledWidth
,
697 pData
->pWallpaperBitmap
->height
* posY
/ scaledHeight
,
698 pData
->pWallpaperBitmap
->bits
,
699 pData
->pWallpaperBitmap
->info
,
710 GdiTransparentBlt(draw
->hDC
,
711 draw
->rcItem
.left
, draw
->rcItem
.top
,
712 draw
->rcItem
.right
-draw
->rcItem
.left
+1,
713 draw
->rcItem
.bottom
-draw
->rcItem
.top
+1,
716 pData
->cxSource
, pData
->cySource
,
719 SelectObject(hDC
, hOldObj
);
725 SetWallpaper(PDATA pData
)
729 RegOpenKeyEx(HKEY_CURRENT_USER
, TEXT("Control Panel\\Desktop"), 0, KEY_ALL_ACCESS
, ®Key
);
731 if (pData
->placementSelection
== PLACEMENT_TILE
)
733 RegSetValueEx(regKey
, TEXT("TileWallpaper"), 0, REG_SZ
, (BYTE
*)TEXT("1"), sizeof(TCHAR
) * 2);
734 RegSetValueEx(regKey
, TEXT("WallpaperStyle"), 0, REG_SZ
, (BYTE
*)TEXT("0"), sizeof(TCHAR
) * 2);
737 if (pData
->placementSelection
== PLACEMENT_CENTER
)
739 RegSetValueEx(regKey
, TEXT("TileWallpaper"), 0, REG_SZ
, (BYTE
*)TEXT("0"), sizeof(TCHAR
) * 2);
740 RegSetValueEx(regKey
, TEXT("WallpaperStyle"), 0, REG_SZ
, (BYTE
*)TEXT("0"), sizeof(TCHAR
) * 2);
743 if (pData
->placementSelection
== PLACEMENT_STRETCH
)
745 RegSetValueEx(regKey
, TEXT("TileWallpaper"), 0, REG_SZ
, (BYTE
*)TEXT("0"), sizeof(TCHAR
) * 2);
746 RegSetValueEx(regKey
, TEXT("WallpaperStyle"), 0, REG_SZ
, (BYTE
*)TEXT("2"), sizeof(TCHAR
) * 2);
751 if (pData
->backgroundItems
[pData
->backgroundSelection
].bWallpaper
== TRUE
)
753 SystemParametersInfo(SPI_SETDESKWALLPAPER
,
755 pData
->backgroundItems
[pData
->backgroundSelection
].szFilename
,
760 SystemParametersInfo(SPI_SETDESKWALLPAPER
, 0, (void*) TEXT(""), SPIF_UPDATEINIFILE
);
765 /* Change system color */
767 SetDesktopBackColor(HWND hwndDlg
, DATA
*pData
)
769 INT iElement
= COLOR_BACKGROUND
;
773 BYTE red
, green
, blue
;
776 if( !SetSysColors( 1, &iElement
, &g_GlobalData
.desktop_color
) )
777 MessageBox(hwndDlg
, TEXT("SetSysColor() failed!"), /* these error texts can need internationalization? */
778 TEXT("Error!"), MB_ICONSTOP
);
780 result
= RegCreateKeyEx( HKEY_CURRENT_USER
, TEXT("Control Panel\\Colors"), 0, NULL
, 0,
781 KEY_ALL_ACCESS
, NULL
, &hKey
, &dwDispostion
);
782 if (result
!= ERROR_SUCCESS
)
784 red
= GetRValue(g_GlobalData
.desktop_color
);
785 green
= GetGValue(g_GlobalData
.desktop_color
);
786 blue
= GetBValue(g_GlobalData
.desktop_color
);
787 /* Format string to be set to registry */
788 StringCbPrintf(clText
, sizeof(clText
), TEXT("%d %d %d"), red
, green
, blue
);
789 RegSetValueEx(hKey
, TEXT("Background"), 0, REG_SZ
, (BYTE
*)clText
,
790 (lstrlen(clText
) + 1) * sizeof(TCHAR
));
796 BackgroundPageProc(HWND hwndDlg
,
803 pData
= (PDATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
808 pData
= (DATA
*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(DATA
));
809 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pData
);
810 InitBackgroundDialog(hwndDlg
, pData
);
815 DWORD controlId
= LOWORD(wParam
);
816 DWORD command
= HIWORD(wParam
);
820 case IDC_COLOR_BUTTON
:
821 if (command
== BN_CLICKED
)
822 OnColorButton(hwndDlg
, pData
);
825 case IDC_BROWSE_BUTTON
:
826 if (command
== BN_CLICKED
)
827 OnBrowseButton(hwndDlg
, pData
);
830 case IDC_PLACEMENT_COMBO
:
831 if (command
== CBN_SELCHANGE
)
833 pData
->placementSelection
= (int)SendDlgItemMessage(hwndDlg
, IDC_PLACEMENT_COMBO
, CB_GETCURSEL
, 0, 0);
835 InvalidateRect(GetDlgItem(hwndDlg
, IDC_BACKGROUND_PREVIEW
), NULL
, TRUE
);
837 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
845 LPDRAWITEMSTRUCT drawItem
;
846 drawItem
= (LPDRAWITEMSTRUCT
)lParam
;
848 if (drawItem
->CtlID
== IDC_BACKGROUND_PREVIEW
)
850 DrawBackgroundPreview(drawItem
, pData
);
858 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
863 if(pData
->bWallpaperChanged
)
865 if(pData
->bClrBackgroundChanged
)
866 SetDesktopBackColor(hwndDlg
, pData
);
867 SendMessage(HWND_BROADCAST
, WM_SETTINGCHANGE
, 0, (LPARAM
)_T(""));
870 case LVN_ITEMCHANGED
:
872 LPNMLISTVIEW nm
= (LPNMLISTVIEW
)lParam
;
874 if ((nm
->uNewState
& LVIS_SELECTED
) == 0)
877 ListViewItemChanged(hwndDlg
, pData
, nm
->iItem
);
885 if (pData
->pWallpaperBitmap
!= NULL
)
886 DibFreeImage(pData
->pWallpaperBitmap
);
888 DeleteObject(pData
->hBitmap
);
889 HeapFree(GetProcessHeap(), 0, pData
);