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 /* Add the images in the C:\ReactOS directory and the current wallpaper if any */
47 void AddListViewItems()
51 TCHAR szSearchPath
[MAX_PATH
];
52 TCHAR szFileTypes
[MAX_PATH
];
59 TCHAR wallpaperFilename
[MAX_PATH
];
60 DWORD bufferSize
= sizeof(wallpaperFilename
);
61 DWORD varType
= REG_SZ
;
64 BackgroundItem
*backgroundItem
= NULL
;
65 TCHAR separators
[] = TEXT(";");
68 GetClientRect(g_hBackgroundList
, &clientRect
);
70 ZeroMemory(&dummy
, sizeof(LV_COLUMN
));
71 dummy
.mask
= LVCF_SUBITEM
| LVCF_WIDTH
;
73 dummy
.cx
= (clientRect
.right
- clientRect
.left
) - GetSystemMetrics(SM_CXVSCROLL
);
75 (void)ListView_InsertColumn(g_hBackgroundList
, 0, &dummy
);
77 /* Add the "None" item */
79 backgroundItem
= &g_backgroundItems
[g_listViewItemCount
];
81 backgroundItem
->bWallpaper
= FALSE
;
85 backgroundItem
->szDisplayName
,
86 sizeof(backgroundItem
->szDisplayName
) / sizeof(TCHAR
));
88 ZeroMemory(&listItem
, sizeof(LV_ITEM
));
89 listItem
.mask
= LVIF_TEXT
| LVIF_PARAM
| LVIF_STATE
| LVIF_IMAGE
;
90 listItem
.state
= LVIS_SELECTED
;
91 listItem
.pszText
= backgroundItem
->szDisplayName
;
93 listItem
.iItem
= g_listViewItemCount
;
94 listItem
.lParam
= g_listViewItemCount
;
96 (void)ListView_InsertItem(g_hBackgroundList
, &listItem
);
97 ListView_SetItemState(g_hBackgroundList
, g_listViewItemCount
, LVIS_SELECTED
, LVIS_SELECTED
);
99 g_listViewItemCount
++;
101 /* Add current wallpaper if any */
103 RegOpenKeyEx(HKEY_CURRENT_USER
, TEXT("Control Panel\\Desktop"), 0, KEY_ALL_ACCESS
, ®Key
);
105 result
= RegQueryValueEx(regKey
, TEXT("Wallpaper"), 0, &varType
, (LPBYTE
)wallpaperFilename
, &bufferSize
);
107 if((result
== ERROR_SUCCESS
) && (_tcslen(wallpaperFilename
) > 0))
109 himl
= (HIMAGELIST
)SHGetFileInfo(wallpaperFilename
,
113 SHGFI_SYSICONINDEX
| SHGFI_SMALLICON
|
120 g_hShellImageList
= himl
;
121 (void)ListView_SetImageList(g_hBackgroundList
, himl
, LVSIL_SMALL
);
124 backgroundItem
= &g_backgroundItems
[g_listViewItemCount
];
126 backgroundItem
->bWallpaper
= TRUE
;
128 _tcscpy(backgroundItem
->szDisplayName
, sfi
.szDisplayName
);
129 _tcscpy(backgroundItem
->szFilename
, wallpaperFilename
);
131 ZeroMemory(&listItem
, sizeof(LV_ITEM
));
132 listItem
.mask
= LVIF_TEXT
| LVIF_PARAM
| LVIF_STATE
| LVIF_IMAGE
;
133 listItem
.state
= LVIS_SELECTED
;
134 listItem
.pszText
= backgroundItem
->szDisplayName
;
135 listItem
.iImage
= sfi
.iIcon
;
136 listItem
.iItem
= g_listViewItemCount
;
137 listItem
.lParam
= g_listViewItemCount
;
139 (void)ListView_InsertItem(g_hBackgroundList
, &listItem
);
140 ListView_SetItemState(g_hBackgroundList
, g_listViewItemCount
, LVIS_SELECTED
, LVIS_SELECTED
);
142 g_listViewItemCount
++;
148 /* Add all the images in the C:\ReactOS directory. */
150 LoadString(hApplet
, IDS_SUPPORTED_EXT
, szFileTypes
, sizeof(szFileTypes
) / sizeof(TCHAR
));
153 token
= _tcstok ( szFileTypes
, separators
);
154 while ( token
!= NULL
)
156 GetWindowsDirectory(szSearchPath
, MAX_PATH
);
157 _tcscat(szSearchPath
, TEXT("\\"));
158 _tcscat(szSearchPath
, token
);
160 hFind
= FindFirstFile(szSearchPath
, &fd
);
161 while(hFind
!= INVALID_HANDLE_VALUE
)
163 /* Don't add any hidden bitmaps */
164 if((fd
.dwFileAttributes
& FILE_ATTRIBUTE_HIDDEN
) == 0)
166 TCHAR filename
[MAX_PATH
];
168 GetWindowsDirectory(filename
, MAX_PATH
);
170 _tcscat(filename
, TEXT("\\"));
171 _tcscat(filename
, fd
.cFileName
);
173 himl
= (HIMAGELIST
)SHGetFileInfo(filename
,
177 SHGFI_SYSICONINDEX
| SHGFI_SMALLICON
|
187 g_hShellImageList
= himl
;
188 (void)ListView_SetImageList(g_hBackgroundList
, himl
, LVSIL_SMALL
);
191 backgroundItem
= &g_backgroundItems
[g_listViewItemCount
];
193 backgroundItem
->bWallpaper
= TRUE
;
195 _tcscpy(backgroundItem
->szDisplayName
, sfi
.szDisplayName
);
196 _tcscpy(backgroundItem
->szFilename
, filename
);
198 ZeroMemory(&listItem
, sizeof(LV_ITEM
));
199 listItem
.mask
= LVIF_TEXT
| LVIF_PARAM
| LVIF_STATE
| LVIF_IMAGE
;
200 listItem
.pszText
= backgroundItem
->szDisplayName
;
202 listItem
.iImage
= sfi
.iIcon
;
203 listItem
.iItem
= g_listViewItemCount
;
204 listItem
.lParam
= g_listViewItemCount
;
206 (void)ListView_InsertItem(g_hBackgroundList
, &listItem
);
208 g_listViewItemCount
++;
211 if(!FindNextFile(hFind
, &fd
))
212 hFind
= INVALID_HANDLE_VALUE
;
215 token
= _tcstok ( NULL
, separators
);
221 void InitBackgroundDialog()
226 DWORD bufferSize
= sizeof(szBuffer
);
227 DWORD varType
= REG_SZ
;
230 g_hBackgroundList
= GetDlgItem(g_hBackgroundPage
, IDC_BACKGROUND_LIST
);
231 g_hBackgroundPreview
= GetDlgItem(g_hBackgroundPage
, IDC_BACKGROUND_PREVIEW
);
232 g_hPlacementCombo
= GetDlgItem(g_hBackgroundPage
, IDC_PLACEMENT_COMBO
);
233 g_hColorButton
= GetDlgItem(g_hBackgroundPage
, IDC_COLOR_BUTTON
);
237 LoadString(hApplet
, IDS_CENTER
, szString
, sizeof(szString
) / sizeof(TCHAR
));
238 SendMessage(g_hPlacementCombo
, CB_INSERTSTRING
, PLACEMENT_CENTER
, (LPARAM
)szString
);
240 LoadString(hApplet
, IDS_STRETCH
, szString
, sizeof(szString
) / sizeof(TCHAR
));
241 SendMessage(g_hPlacementCombo
, CB_INSERTSTRING
, PLACEMENT_STRETCH
, (LPARAM
)szString
);
243 LoadString(hApplet
, IDS_TILE
, szString
, sizeof(szString
) / sizeof(TCHAR
));
244 SendMessage(g_hPlacementCombo
, CB_INSERTSTRING
, PLACEMENT_TILE
, (LPARAM
)szString
);
246 /* Load the default settings from the registry */
247 RegOpenKeyEx(HKEY_CURRENT_USER
, TEXT("Control Panel\\Desktop"), 0, KEY_ALL_ACCESS
, ®Key
);
249 result
= RegQueryValueEx(regKey
, TEXT("WallpaperStyle"), 0, &varType
, (LPBYTE
)szBuffer
, &bufferSize
);
251 if(result
== ERROR_SUCCESS
)
253 if(_ttoi(szBuffer
) == 0)
255 SendMessage(g_hPlacementCombo
, CB_SETCURSEL
, PLACEMENT_CENTER
, 0);
256 g_placementSelection
= PLACEMENT_CENTER
;
259 if(_ttoi(szBuffer
) == 2)
261 SendMessage(g_hPlacementCombo
, CB_SETCURSEL
, PLACEMENT_STRETCH
, 0);
262 g_placementSelection
= PLACEMENT_STRETCH
;
267 SendMessage(g_hPlacementCombo
, CB_SETCURSEL
, PLACEMENT_CENTER
, 0);
268 g_placementSelection
= PLACEMENT_CENTER
;
271 result
= RegQueryValueEx(regKey
, TEXT("TileWallpaper"), 0, &varType
, (LPBYTE
)szBuffer
, &bufferSize
);
273 if(result
== ERROR_SUCCESS
)
275 if(_ttoi(szBuffer
) == 1)
277 SendMessage(g_hPlacementCombo
, CB_SETCURSEL
, PLACEMENT_TILE
, 0);
278 g_placementSelection
= PLACEMENT_TILE
;
287 MessageBox(NULL
, TEXT("That button doesn't do anything yet"), TEXT("Whoops"), MB_OK
);
290 BOOL
CheckListBoxFilename(HWND list
, TCHAR
*filename
)
295 void OnBrowseButton()
298 TCHAR filename
[MAX_PATH
];
299 TCHAR fileTitle
[256];
300 TCHAR filter
[MAX_PATH
];
301 BackgroundItem
*backgroundItem
= NULL
;
305 ZeroMemory(&ofn
, sizeof(OPENFILENAME
));
307 ofn
.lStructSize
= sizeof(OPENFILENAME
);
308 ofn
.hwndOwner
= g_hBackgroundPage
;
309 ofn
.lpstrFile
= filename
;
311 LoadString(hApplet
, IDS_BACKGROUND_COMDLG_FILTER
, filter
, sizeof(filter
) / sizeof(TCHAR
));
313 /* Set lpstrFile[0] to '\0' so that GetOpenFileName does not
314 * use the contents of szFile to initialize itself */
315 ofn
.lpstrFile
[0] = TEXT('\0');
316 ofn
.nMaxFile
= MAX_PATH
;
317 ofn
.lpstrFilter
= filter
;
318 ofn
.nFilterIndex
= 0;
319 ofn
.lpstrFileTitle
= fileTitle
;
320 ofn
.nMaxFileTitle
= 256;
321 ofn
.lpstrInitialDir
= NULL
;
322 ofn
.Flags
= OFN_PATHMUSTEXIST
| OFN_FILEMUSTEXIST
;
324 if(GetOpenFileName(&ofn
) == TRUE
)
326 /* Check if there is already a entry that holds this filename */
327 if(CheckListBoxFilename(g_hBackgroundList
, filename
) == TRUE
)
330 if(g_listViewItemCount
> (MAX_BACKGROUNDS
- 1))
333 SHGetFileInfo(filename
,
337 SHGFI_SYSICONINDEX
| SHGFI_SMALLICON
| SHGFI_DISPLAYNAME
);
339 backgroundItem
= &g_backgroundItems
[g_listViewItemCount
];
341 backgroundItem
->bWallpaper
= TRUE
;
343 _tcscpy(backgroundItem
->szDisplayName
, sfi
.szDisplayName
);
344 _tcscpy(backgroundItem
->szFilename
, filename
);
346 ZeroMemory(&listItem
, sizeof(LV_ITEM
));
347 listItem
.mask
= LVIF_TEXT
| LVIF_PARAM
| LVIF_STATE
| LVIF_IMAGE
;
349 listItem
.pszText
= backgroundItem
->szDisplayName
;
350 listItem
.iImage
= sfi
.iIcon
;
351 listItem
.iItem
= g_listViewItemCount
;
352 listItem
.lParam
= g_listViewItemCount
;
354 (void)ListView_InsertItem(g_hBackgroundList
, &listItem
);
356 g_listViewItemCount
++;
360 void ListViewItemChanged(int itemIndex
)
362 BackgroundItem
*backgroundItem
= NULL
;
364 g_backgroundSelection
= itemIndex
;
365 backgroundItem
= &g_backgroundItems
[g_backgroundSelection
];
367 if(g_pWallpaperBitmap
!= NULL
)
369 DibFreeImage(g_pWallpaperBitmap
);
370 g_pWallpaperBitmap
= NULL
;
373 if(backgroundItem
->bWallpaper
== TRUE
)
375 g_pWallpaperBitmap
= DibLoadImage(backgroundItem
->szFilename
);
377 if(g_pWallpaperBitmap
== NULL
)
383 InvalidateRect(g_hBackgroundPreview
, NULL
, TRUE
);
385 EnableWindow(g_hColorButton
, (backgroundItem
->bWallpaper
== FALSE
? TRUE
: FALSE
));
386 EnableWindow(g_hPlacementCombo
, backgroundItem
->bWallpaper
);
388 PropSheet_Changed(GetParent(g_hBackgroundPage
), g_hBackgroundPage
);
391 void DrawBackgroundPreview(LPDRAWITEMSTRUCT draw
)
400 if(g_backgroundItems
[g_backgroundSelection
].bWallpaper
== FALSE
)
402 FillRect(draw
->hDC
, &draw
->rcItem
, GetSysColorBrush(COLOR_BACKGROUND
));
406 if(g_pWallpaperBitmap
== NULL
)
409 scaleX
= ((float)GetSystemMetrics(SM_CXSCREEN
) - 1) / (float)draw
->rcItem
.right
;
410 scaleY
= ((float)GetSystemMetrics(SM_CYSCREEN
) - 1) / (float)draw
->rcItem
.bottom
;
412 scaledWidth
= g_pWallpaperBitmap
->width
/ scaleX
;
413 scaledHeight
= g_pWallpaperBitmap
->height
/ scaleY
;
415 posX
= (draw
->rcItem
.right
/ 2) - (scaledWidth
/ 2);
416 posY
= (draw
->rcItem
.bottom
/ 2) - (scaledHeight
/ 2);
418 FillRect(draw
->hDC
, &draw
->rcItem
, GetSysColorBrush(COLOR_BACKGROUND
));
420 SetStretchBltMode(draw
->hDC
, COLORONCOLOR
);
422 if(g_placementSelection
== PLACEMENT_CENTER
)
424 StretchDIBits(draw
->hDC
,
431 g_pWallpaperBitmap
->width
,
432 g_pWallpaperBitmap
->height
,
433 g_pWallpaperBitmap
->bits
,
434 g_pWallpaperBitmap
->info
,
439 if(g_placementSelection
== PLACEMENT_STRETCH
)
441 StretchDIBits(draw
->hDC
,
448 g_pWallpaperBitmap
->width
,
449 g_pWallpaperBitmap
->height
,
450 g_pWallpaperBitmap
->bits
,
451 g_pWallpaperBitmap
->info
,
456 if(g_placementSelection
== PLACEMENT_TILE
)
461 for(y
= 0; y
< draw
->rcItem
.bottom
; y
+= scaledHeight
)
463 for(x
= 0; x
< draw
->rcItem
.right
; x
+= scaledWidth
)
465 StretchDIBits(draw
->hDC
,
472 g_pWallpaperBitmap
->width
,
473 g_pWallpaperBitmap
->height
,
474 g_pWallpaperBitmap
->bits
,
475 g_pWallpaperBitmap
->info
,
487 RegOpenKeyEx(HKEY_CURRENT_USER
, TEXT("Control Panel\\Desktop"), 0, KEY_ALL_ACCESS
, ®Key
);
489 if(g_placementSelection
== PLACEMENT_TILE
)
491 RegSetValueEx(regKey
, TEXT("TileWallpaper"), 0, REG_SZ
, (BYTE
*)TEXT("1"), sizeof(TCHAR
) * 2);
492 RegSetValueEx(regKey
, TEXT("WallpaperStyle"), 0, REG_SZ
, (BYTE
*)TEXT("0"), sizeof(TCHAR
) * 2);
495 if(g_placementSelection
== PLACEMENT_CENTER
)
497 RegSetValueEx(regKey
, TEXT("TileWallpaper"), 0, REG_SZ
, (BYTE
*)TEXT("0"), sizeof(TCHAR
) * 2);
498 RegSetValueEx(regKey
, TEXT("WallpaperStyle"), 0, REG_SZ
, (BYTE
*)TEXT("0"), sizeof(TCHAR
) * 2);
501 if(g_placementSelection
== PLACEMENT_STRETCH
)
503 RegSetValueEx(regKey
, TEXT("TileWallpaper"), 0, REG_SZ
, (BYTE
*)TEXT("0"), sizeof(TCHAR
) * 2);
504 RegSetValueEx(regKey
, TEXT("WallpaperStyle"), 0, REG_SZ
, (BYTE
*)TEXT("2"), sizeof(TCHAR
) * 2);
509 if(g_backgroundItems
[g_backgroundSelection
].bWallpaper
== TRUE
)
511 SystemParametersInfo(SPI_SETDESKWALLPAPER
,
513 g_backgroundItems
[g_backgroundSelection
].szFilename
,
518 SystemParametersInfo(SPI_SETDESKWALLPAPER
, 0, TEXT(""), SPIF_UPDATEINIFILE
);
522 INT_PTR CALLBACK
BackgroundPageProc(HWND hwndDlg
,
527 g_hBackgroundPage
= hwndDlg
;
533 InitBackgroundDialog();
538 DWORD controlId
= LOWORD(wParam
);
539 DWORD command
= HIWORD(wParam
);
543 case IDC_COLOR_BUTTON
:
545 if(command
== BN_CLICKED
)
550 case IDC_BROWSE_BUTTON
:
552 if(command
== BN_CLICKED
)
557 case IDC_PLACEMENT_COMBO
:
559 if(command
== CBN_SELCHANGE
)
561 g_placementSelection
= SendMessage(g_hPlacementCombo
, CB_GETCURSEL
, 0, 0);
563 InvalidateRect(g_hBackgroundPreview
, NULL
, TRUE
);
565 PropSheet_Changed(GetParent(g_hBackgroundPage
), g_hBackgroundPage
);
574 LPDRAWITEMSTRUCT drawItem
;
575 drawItem
= (LPDRAWITEMSTRUCT
)lParam
;
577 if(drawItem
->CtlID
== IDC_BACKGROUND_PREVIEW
)
579 DrawBackgroundPreview(drawItem
);
586 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
597 case LVN_ITEMCHANGED
:
599 LPNMLISTVIEW nm
= (LPNMLISTVIEW
)lParam
;
601 if((nm
->uNewState
& LVIS_SELECTED
) == 0)
604 ListViewItemChanged(nm
->iItem
);
616 if(g_pWallpaperBitmap
!= NULL
)
617 DibFreeImage(g_pWallpaperBitmap
);