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
8 * PROGRAMMERS: Trevor McCort (lycan359@gmail.com)
13 #define MAX_BACKGROUNDS 100
15 #define PLACEMENT_CENTER 0
16 #define PLACEMENT_STRETCH 1
17 #define PLACEMENT_TILE 2
21 BOOL bWallpaper
; /* Is this background a wallpaper */
23 TCHAR szFilename
[MAX_PATH
];
24 TCHAR szDisplayName
[256];
28 BackgroundItem g_backgroundItems
[MAX_BACKGROUNDS
];
30 DIBitmap
*g_pWallpaperBitmap
= NULL
;
32 int g_placementSelection
= 0;
33 int g_backgroundSelection
= 0;
35 int g_listViewItemCount
= 0;
37 HWND g_hBackgroundPage
= NULL
;
38 HWND g_hBackgroundList
= NULL
;
39 HWND g_hBackgroundPreview
= NULL
;
41 HWND g_hPlacementCombo
= NULL
;
42 HWND g_hColorButton
= NULL
;
44 HIMAGELIST g_hShellImageList
= NULL
;
46 static HBITMAP hBitmap
= NULL
;
47 static int cxSource
, cySource
;
49 /* Add the images in the C:\ReactOS directory and the current wallpaper if any */
50 void AddListViewItems()
54 TCHAR szSearchPath
[MAX_PATH
];
55 TCHAR szFileTypes
[MAX_PATH
];
62 TCHAR wallpaperFilename
[MAX_PATH
];
63 DWORD bufferSize
= sizeof(wallpaperFilename
);
64 DWORD varType
= REG_SZ
;
67 BackgroundItem
*backgroundItem
= NULL
;
68 TCHAR separators
[] = TEXT(";");
71 GetClientRect(g_hBackgroundList
, &clientRect
);
73 ZeroMemory(&dummy
, sizeof(LV_COLUMN
));
74 dummy
.mask
= LVCF_SUBITEM
| LVCF_WIDTH
;
76 dummy
.cx
= (clientRect
.right
- clientRect
.left
) - GetSystemMetrics(SM_CXVSCROLL
);
78 (void)ListView_InsertColumn(g_hBackgroundList
, 0, &dummy
);
80 /* Add the "None" item */
82 backgroundItem
= &g_backgroundItems
[g_listViewItemCount
];
84 backgroundItem
->bWallpaper
= FALSE
;
88 backgroundItem
->szDisplayName
,
89 sizeof(backgroundItem
->szDisplayName
) / sizeof(TCHAR
));
91 ZeroMemory(&listItem
, sizeof(LV_ITEM
));
92 listItem
.mask
= LVIF_TEXT
| LVIF_PARAM
| LVIF_STATE
| LVIF_IMAGE
;
93 listItem
.state
= LVIS_SELECTED
;
94 listItem
.pszText
= backgroundItem
->szDisplayName
;
96 listItem
.iItem
= g_listViewItemCount
;
97 listItem
.lParam
= g_listViewItemCount
;
99 (void)ListView_InsertItem(g_hBackgroundList
, &listItem
);
100 ListView_SetItemState(g_hBackgroundList
, g_listViewItemCount
, LVIS_SELECTED
, LVIS_SELECTED
);
102 g_listViewItemCount
++;
104 /* Add current wallpaper if any */
106 RegOpenKeyEx(HKEY_CURRENT_USER
, TEXT("Control Panel\\Desktop"), 0, KEY_ALL_ACCESS
, ®Key
);
108 result
= RegQueryValueEx(regKey
, TEXT("Wallpaper"), 0, &varType
, (LPBYTE
)wallpaperFilename
, &bufferSize
);
110 if((result
== ERROR_SUCCESS
) && (_tcslen(wallpaperFilename
) > 0))
112 himl
= (HIMAGELIST
)SHGetFileInfo(wallpaperFilename
,
116 SHGFI_SYSICONINDEX
| SHGFI_SMALLICON
|
123 g_hShellImageList
= himl
;
124 (void)ListView_SetImageList(g_hBackgroundList
, himl
, LVSIL_SMALL
);
127 backgroundItem
= &g_backgroundItems
[g_listViewItemCount
];
129 backgroundItem
->bWallpaper
= TRUE
;
131 _tcscpy(backgroundItem
->szDisplayName
, sfi
.szDisplayName
);
132 _tcscpy(backgroundItem
->szFilename
, wallpaperFilename
);
134 ZeroMemory(&listItem
, sizeof(LV_ITEM
));
135 listItem
.mask
= LVIF_TEXT
| LVIF_PARAM
| LVIF_STATE
| LVIF_IMAGE
;
136 listItem
.state
= LVIS_SELECTED
;
137 listItem
.pszText
= backgroundItem
->szDisplayName
;
138 listItem
.iImage
= sfi
.iIcon
;
139 listItem
.iItem
= g_listViewItemCount
;
140 listItem
.lParam
= g_listViewItemCount
;
142 (void)ListView_InsertItem(g_hBackgroundList
, &listItem
);
143 ListView_SetItemState(g_hBackgroundList
, g_listViewItemCount
, LVIS_SELECTED
, LVIS_SELECTED
);
145 g_listViewItemCount
++;
151 /* Add all the images in the C:\ReactOS directory. */
153 LoadString(hApplet
, IDS_SUPPORTED_EXT
, szFileTypes
, sizeof(szFileTypes
) / sizeof(TCHAR
));
156 token
= _tcstok ( szFileTypes
, separators
);
157 while ( token
!= NULL
)
159 GetWindowsDirectory(szSearchPath
, MAX_PATH
);
160 _tcscat(szSearchPath
, TEXT("\\"));
161 _tcscat(szSearchPath
, token
);
163 hFind
= FindFirstFile(szSearchPath
, &fd
);
164 while(hFind
!= INVALID_HANDLE_VALUE
)
166 /* Don't add any hidden bitmaps */
167 if((fd
.dwFileAttributes
& FILE_ATTRIBUTE_HIDDEN
) == 0)
169 TCHAR filename
[MAX_PATH
];
171 GetWindowsDirectory(filename
, MAX_PATH
);
173 _tcscat(filename
, TEXT("\\"));
174 _tcscat(filename
, fd
.cFileName
);
176 himl
= (HIMAGELIST
)SHGetFileInfo(filename
,
180 SHGFI_SYSICONINDEX
| SHGFI_SMALLICON
|
190 g_hShellImageList
= himl
;
191 (void)ListView_SetImageList(g_hBackgroundList
, himl
, LVSIL_SMALL
);
194 backgroundItem
= &g_backgroundItems
[g_listViewItemCount
];
196 backgroundItem
->bWallpaper
= TRUE
;
198 _tcscpy(backgroundItem
->szDisplayName
, sfi
.szDisplayName
);
199 _tcscpy(backgroundItem
->szFilename
, filename
);
201 ZeroMemory(&listItem
, sizeof(LV_ITEM
));
202 listItem
.mask
= LVIF_TEXT
| LVIF_PARAM
| LVIF_STATE
| LVIF_IMAGE
;
203 listItem
.pszText
= backgroundItem
->szDisplayName
;
205 listItem
.iImage
= sfi
.iIcon
;
206 listItem
.iItem
= g_listViewItemCount
;
207 listItem
.lParam
= g_listViewItemCount
;
209 (void)ListView_InsertItem(g_hBackgroundList
, &listItem
);
211 g_listViewItemCount
++;
214 if(!FindNextFile(hFind
, &fd
))
215 hFind
= INVALID_HANDLE_VALUE
;
218 token
= _tcstok ( NULL
, separators
);
224 void InitBackgroundDialog()
229 DWORD bufferSize
= sizeof(szBuffer
);
230 DWORD varType
= REG_SZ
;
234 g_hBackgroundList
= GetDlgItem(g_hBackgroundPage
, IDC_BACKGROUND_LIST
);
235 g_hBackgroundPreview
= GetDlgItem(g_hBackgroundPage
, IDC_BACKGROUND_PREVIEW
);
236 g_hPlacementCombo
= GetDlgItem(g_hBackgroundPage
, IDC_PLACEMENT_COMBO
);
237 g_hColorButton
= GetDlgItem(g_hBackgroundPage
, IDC_COLOR_BUTTON
);
241 LoadString(hApplet
, IDS_CENTER
, szString
, sizeof(szString
) / sizeof(TCHAR
));
242 SendMessage(g_hPlacementCombo
, CB_INSERTSTRING
, PLACEMENT_CENTER
, (LPARAM
)szString
);
244 LoadString(hApplet
, IDS_STRETCH
, szString
, sizeof(szString
) / sizeof(TCHAR
));
245 SendMessage(g_hPlacementCombo
, CB_INSERTSTRING
, PLACEMENT_STRETCH
, (LPARAM
)szString
);
247 LoadString(hApplet
, IDS_TILE
, szString
, sizeof(szString
) / sizeof(TCHAR
));
248 SendMessage(g_hPlacementCombo
, CB_INSERTSTRING
, PLACEMENT_TILE
, (LPARAM
)szString
);
250 /* Load the default settings from the registry */
251 RegOpenKeyEx(HKEY_CURRENT_USER
, TEXT("Control Panel\\Desktop"), 0, KEY_ALL_ACCESS
, ®Key
);
253 result
= RegQueryValueEx(regKey
, TEXT("WallpaperStyle"), 0, &varType
, (LPBYTE
)szBuffer
, &bufferSize
);
255 if(result
== ERROR_SUCCESS
)
257 if(_ttoi(szBuffer
) == 0)
259 SendMessage(g_hPlacementCombo
, CB_SETCURSEL
, PLACEMENT_CENTER
, 0);
260 g_placementSelection
= PLACEMENT_CENTER
;
263 if(_ttoi(szBuffer
) == 2)
265 SendMessage(g_hPlacementCombo
, CB_SETCURSEL
, PLACEMENT_STRETCH
, 0);
266 g_placementSelection
= PLACEMENT_STRETCH
;
271 SendMessage(g_hPlacementCombo
, CB_SETCURSEL
, PLACEMENT_CENTER
, 0);
272 g_placementSelection
= PLACEMENT_CENTER
;
275 result
= RegQueryValueEx(regKey
, TEXT("TileWallpaper"), 0, &varType
, (LPBYTE
)szBuffer
, &bufferSize
);
277 if(result
== ERROR_SUCCESS
)
279 if(_ttoi(szBuffer
) == 1)
281 SendMessage(g_hPlacementCombo
, CB_SETCURSEL
, PLACEMENT_TILE
, 0);
282 g_placementSelection
= PLACEMENT_TILE
;
288 hBitmap
= LoadImage(hApplet
, MAKEINTRESOURCE(IDC_MONITOR
), IMAGE_BITMAP
, 0, 0, LR_LOADTRANSPARENT
);
291 GetObject(hBitmap
, sizeof(BITMAP
), &bitmap
);
293 cxSource
= bitmap
.bmWidth
;
294 cySource
= bitmap
.bmHeight
;
300 MessageBox(NULL
, TEXT("That button doesn't do anything yet"), TEXT("Whoops"), MB_OK
);
303 BOOL
CheckListBoxFilename(HWND list
, TCHAR
*filename
)
305 UNREFERENCED_PARAMETER(filename
);
306 UNREFERENCED_PARAMETER(list
);
310 void OnBrowseButton()
313 TCHAR filename
[MAX_PATH
];
314 TCHAR fileTitle
[256];
315 TCHAR filter
[MAX_PATH
];
316 BackgroundItem
*backgroundItem
= NULL
;
320 ZeroMemory(&ofn
, sizeof(OPENFILENAME
));
322 ofn
.lStructSize
= sizeof(OPENFILENAME
);
323 ofn
.hwndOwner
= g_hBackgroundPage
;
324 ofn
.lpstrFile
= filename
;
326 LoadString(hApplet
, IDS_BACKGROUND_COMDLG_FILTER
, filter
, sizeof(filter
) / sizeof(TCHAR
));
328 /* Set lpstrFile[0] to '\0' so that GetOpenFileName does not
329 * use the contents of szFile to initialize itself */
330 ofn
.lpstrFile
[0] = TEXT('\0');
331 ofn
.nMaxFile
= MAX_PATH
;
332 ofn
.lpstrFilter
= filter
;
333 ofn
.nFilterIndex
= 0;
334 ofn
.lpstrFileTitle
= fileTitle
;
335 ofn
.nMaxFileTitle
= 256;
336 ofn
.lpstrInitialDir
= NULL
;
337 ofn
.Flags
= OFN_PATHMUSTEXIST
| OFN_FILEMUSTEXIST
;
339 if(GetOpenFileName(&ofn
) == TRUE
)
341 /* Check if there is already a entry that holds this filename */
342 if(CheckListBoxFilename(g_hBackgroundList
, filename
) == TRUE
)
345 if(g_listViewItemCount
> (MAX_BACKGROUNDS
- 1))
348 SHGetFileInfo(filename
,
352 SHGFI_SYSICONINDEX
| SHGFI_SMALLICON
| SHGFI_DISPLAYNAME
);
354 backgroundItem
= &g_backgroundItems
[g_listViewItemCount
];
356 backgroundItem
->bWallpaper
= TRUE
;
358 _tcscpy(backgroundItem
->szDisplayName
, sfi
.szDisplayName
);
359 _tcscpy(backgroundItem
->szFilename
, filename
);
361 ZeroMemory(&listItem
, sizeof(LV_ITEM
));
362 listItem
.mask
= LVIF_TEXT
| LVIF_PARAM
| LVIF_STATE
| LVIF_IMAGE
;
364 listItem
.pszText
= backgroundItem
->szDisplayName
;
365 listItem
.iImage
= sfi
.iIcon
;
366 listItem
.iItem
= g_listViewItemCount
;
367 listItem
.lParam
= g_listViewItemCount
;
369 (void)ListView_InsertItem(g_hBackgroundList
, &listItem
);
371 g_listViewItemCount
++;
375 void ListViewItemChanged(int itemIndex
)
377 BackgroundItem
*backgroundItem
= NULL
;
379 g_backgroundSelection
= itemIndex
;
380 backgroundItem
= &g_backgroundItems
[g_backgroundSelection
];
382 if(g_pWallpaperBitmap
!= NULL
)
384 DibFreeImage(g_pWallpaperBitmap
);
385 g_pWallpaperBitmap
= NULL
;
388 if(backgroundItem
->bWallpaper
== TRUE
)
390 g_pWallpaperBitmap
= DibLoadImage(backgroundItem
->szFilename
);
392 if(g_pWallpaperBitmap
== NULL
)
398 InvalidateRect(g_hBackgroundPreview
, NULL
, TRUE
);
400 EnableWindow(g_hColorButton
, (backgroundItem
->bWallpaper
== FALSE
? TRUE
: FALSE
));
401 EnableWindow(g_hPlacementCombo
, backgroundItem
->bWallpaper
);
403 PropSheet_Changed(GetParent(g_hBackgroundPage
), g_hBackgroundPage
);
406 void DrawBackgroundPreview(LPDRAWITEMSTRUCT draw
)
415 if(g_backgroundItems
[g_backgroundSelection
].bWallpaper
== FALSE
)
417 FillRect(draw
->hDC
, &draw
->rcItem
, GetSysColorBrush(COLOR_BACKGROUND
));
421 if(g_pWallpaperBitmap
== NULL
)
424 scaleX
= ((float)GetSystemMetrics(SM_CXSCREEN
) - 1) / (float)draw
->rcItem
.right
;
425 scaleY
= ((float)GetSystemMetrics(SM_CYSCREEN
) - 1) / (float)draw
->rcItem
.bottom
;
427 scaledWidth
= g_pWallpaperBitmap
->width
/ scaleX
;
428 scaledHeight
= g_pWallpaperBitmap
->height
/ scaleY
;
430 posX
= (draw
->rcItem
.right
/ 2) - (scaledWidth
/ 2);
431 posY
= (draw
->rcItem
.bottom
/ 2) - (scaledHeight
/ 2);
433 FillRect(draw
->hDC
, &draw
->rcItem
, GetSysColorBrush(COLOR_BACKGROUND
));
435 SetStretchBltMode(draw
->hDC
, COLORONCOLOR
);
437 if(g_placementSelection
== PLACEMENT_CENTER
)
439 StretchDIBits(draw
->hDC
,
446 g_pWallpaperBitmap
->width
,
447 g_pWallpaperBitmap
->height
,
448 g_pWallpaperBitmap
->bits
,
449 g_pWallpaperBitmap
->info
,
454 if(g_placementSelection
== PLACEMENT_STRETCH
)
456 StretchDIBits(draw
->hDC
,
463 g_pWallpaperBitmap
->width
,
464 g_pWallpaperBitmap
->height
,
465 g_pWallpaperBitmap
->bits
,
466 g_pWallpaperBitmap
->info
,
471 if(g_placementSelection
== PLACEMENT_TILE
)
476 for(y
= 0; y
< draw
->rcItem
.bottom
; y
+= scaledHeight
)
478 for(x
= 0; x
< draw
->rcItem
.right
; x
+= scaledWidth
)
480 StretchDIBits(draw
->hDC
,
487 g_pWallpaperBitmap
->width
,
488 g_pWallpaperBitmap
->height
,
489 g_pWallpaperBitmap
->bits
,
490 g_pWallpaperBitmap
->info
,
502 RegOpenKeyEx(HKEY_CURRENT_USER
, TEXT("Control Panel\\Desktop"), 0, KEY_ALL_ACCESS
, ®Key
);
504 if(g_placementSelection
== PLACEMENT_TILE
)
506 RegSetValueEx(regKey
, TEXT("TileWallpaper"), 0, REG_SZ
, (BYTE
*)TEXT("1"), sizeof(TCHAR
) * 2);
507 RegSetValueEx(regKey
, TEXT("WallpaperStyle"), 0, REG_SZ
, (BYTE
*)TEXT("0"), sizeof(TCHAR
) * 2);
510 if(g_placementSelection
== PLACEMENT_CENTER
)
512 RegSetValueEx(regKey
, TEXT("TileWallpaper"), 0, REG_SZ
, (BYTE
*)TEXT("0"), sizeof(TCHAR
) * 2);
513 RegSetValueEx(regKey
, TEXT("WallpaperStyle"), 0, REG_SZ
, (BYTE
*)TEXT("0"), sizeof(TCHAR
) * 2);
516 if(g_placementSelection
== PLACEMENT_STRETCH
)
518 RegSetValueEx(regKey
, TEXT("TileWallpaper"), 0, REG_SZ
, (BYTE
*)TEXT("0"), sizeof(TCHAR
) * 2);
519 RegSetValueEx(regKey
, TEXT("WallpaperStyle"), 0, REG_SZ
, (BYTE
*)TEXT("2"), sizeof(TCHAR
) * 2);
524 if(g_backgroundItems
[g_backgroundSelection
].bWallpaper
== TRUE
)
526 SystemParametersInfo(SPI_SETDESKWALLPAPER
,
528 g_backgroundItems
[g_backgroundSelection
].szFilename
,
533 SystemParametersInfo(SPI_SETDESKWALLPAPER
, 0, TEXT(""), SPIF_UPDATEINIFILE
);
537 INT_PTR CALLBACK
BackgroundPageProc(HWND hwndDlg
,
542 g_hBackgroundPage
= hwndDlg
;
548 InitBackgroundDialog();
553 DWORD controlId
= LOWORD(wParam
);
554 DWORD command
= HIWORD(wParam
);
558 case IDC_COLOR_BUTTON
:
560 if(command
== BN_CLICKED
)
565 case IDC_BROWSE_BUTTON
:
567 if(command
== BN_CLICKED
)
572 case IDC_PLACEMENT_COMBO
:
574 if(command
== CBN_SELCHANGE
)
576 g_placementSelection
= (int)SendMessage(g_hPlacementCombo
, CB_GETCURSEL
, 0, 0);
578 InvalidateRect(g_hBackgroundPreview
, NULL
, TRUE
);
580 PropSheet_Changed(GetParent(g_hBackgroundPage
), g_hBackgroundPage
);
592 hdc
= BeginPaint(hwndDlg
, &ps
);
594 hdcMem
= CreateCompatibleDC(hdc
);
595 SelectObject(hdcMem
, hBitmap
);
597 TransparentBlt(hdc
, 98, 0, cxSource
, cySource
, hdcMem
, 0, 0, cxSource
, cySource
, 0xFF80FF);
600 EndPaint(hwndDlg
, &ps
);
606 LPDRAWITEMSTRUCT drawItem
;
607 drawItem
= (LPDRAWITEMSTRUCT
)lParam
;
609 if(drawItem
->CtlID
== IDC_BACKGROUND_PREVIEW
)
611 DrawBackgroundPreview(drawItem
);
618 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
629 case LVN_ITEMCHANGED
:
631 LPNMLISTVIEW nm
= (LPNMLISTVIEW
)lParam
;
633 if((nm
->uNewState
& LVIS_SELECTED
) == 0)
636 ListViewItemChanged(nm
->iItem
);
648 if(g_pWallpaperBitmap
!= NULL
)
649 DibFreeImage(g_pWallpaperBitmap
);
651 DeleteObject(hBitmap
);