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)
22 #define MAX_BACKGROUNDS 100
24 #define PLACEMENT_CENTER 0
25 #define PLACEMENT_STRETCH 1
26 #define PLACEMENT_TILE 2
30 BOOL bWallpaper
; /* Is this background a wallpaper */
32 TCHAR szFilename
[MAX_PATH
];
33 TCHAR szDisplayName
[256];
37 BackgroundItem g_backgroundItems
[MAX_BACKGROUNDS
];
39 DIBitmap
*g_pWallpaperBitmap
= NULL
;
41 int g_placementSelection
= 0;
42 int g_backgroundSelection
= 0;
44 int g_listViewItemCount
= 0;
46 HWND g_hBackgroundPage
= NULL
;
47 HWND g_hBackgroundList
= NULL
;
48 HWND g_hBackgroundPreview
= NULL
;
50 HWND g_hPlacementCombo
= NULL
;
51 HWND g_hColorButton
= NULL
;
53 HIMAGELIST g_hShellImageList
= NULL
;
55 /* Add the images in the C:\ReactOS directory and the current wallpaper if any */
56 void AddListViewItems()
60 TCHAR szSearchPath
[MAX_PATH
];
61 TCHAR szFileTypes
[MAX_PATH
];
68 TCHAR wallpaperFilename
[MAX_PATH
];
69 DWORD bufferSize
= sizeof(wallpaperFilename
);
70 DWORD varType
= REG_SZ
;
73 BackgroundItem
*backgroundItem
= NULL
;
74 TCHAR separators
[] = TEXT(";");
77 GetClientRect(g_hBackgroundList
, &clientRect
);
79 ZeroMemory(&dummy
, sizeof(LV_COLUMN
));
80 dummy
.mask
= LVCF_SUBITEM
| LVCF_WIDTH
;
82 dummy
.cx
= (clientRect
.right
- clientRect
.left
) - GetSystemMetrics(SM_CXVSCROLL
);
84 ListView_InsertColumn(g_hBackgroundList
, 0, &dummy
);
86 /* Add the "None" item */
88 backgroundItem
= &g_backgroundItems
[g_listViewItemCount
];
90 backgroundItem
->bWallpaper
= FALSE
;
94 backgroundItem
->szDisplayName
,
95 sizeof(backgroundItem
->szDisplayName
) / sizeof(TCHAR
));
97 ZeroMemory(&listItem
, sizeof(LV_ITEM
));
98 listItem
.mask
= LVIF_TEXT
| LVIF_PARAM
| LVIF_STATE
| LVIF_IMAGE
;
99 listItem
.state
= LVIS_SELECTED
;
100 listItem
.pszText
= backgroundItem
->szDisplayName
;
101 listItem
.iImage
= -1;
102 listItem
.iItem
= g_listViewItemCount
;
103 listItem
.lParam
= g_listViewItemCount
;
105 ListView_InsertItem(g_hBackgroundList
, &listItem
);
106 ListView_SetItemState(g_hBackgroundList
, g_listViewItemCount
, LVIS_SELECTED
, LVIS_SELECTED
);
108 g_listViewItemCount
++;
110 /* Add current wallpaper if any */
112 RegOpenKeyEx(HKEY_CURRENT_USER
, TEXT("Control Panel\\Desktop"), 0, KEY_ALL_ACCESS
, ®Key
);
114 result
= RegQueryValueEx(regKey
, TEXT("Wallpaper"), 0, &varType
, (LPBYTE
)wallpaperFilename
, &bufferSize
);
116 if((result
== ERROR_SUCCESS
) && (_tcslen(wallpaperFilename
) > 0))
118 himl
= (HIMAGELIST
)SHGetFileInfo(wallpaperFilename
,
122 SHGFI_SYSICONINDEX
| SHGFI_SMALLICON
|
129 g_hShellImageList
= himl
;
130 ListView_SetImageList(g_hBackgroundList
, himl
, LVSIL_SMALL
);
133 backgroundItem
= &g_backgroundItems
[g_listViewItemCount
];
135 backgroundItem
->bWallpaper
= TRUE
;
137 _tcscpy(backgroundItem
->szDisplayName
, sfi
.szDisplayName
);
138 _tcscpy(backgroundItem
->szFilename
, wallpaperFilename
);
140 ZeroMemory(&listItem
, sizeof(LV_ITEM
));
141 listItem
.mask
= LVIF_TEXT
| LVIF_PARAM
| LVIF_STATE
| LVIF_IMAGE
;
142 listItem
.state
= LVIS_SELECTED
;
143 listItem
.pszText
= backgroundItem
->szDisplayName
;
144 listItem
.iImage
= sfi
.iIcon
;
145 listItem
.iItem
= g_listViewItemCount
;
146 listItem
.lParam
= g_listViewItemCount
;
148 ListView_InsertItem(g_hBackgroundList
, &listItem
);
149 ListView_SetItemState(g_hBackgroundList
, g_listViewItemCount
, LVIS_SELECTED
, LVIS_SELECTED
);
151 g_listViewItemCount
++;
157 /* Add all the images in the C:\ReactOS directory. */
159 LoadString(hApplet
, IDS_SUPPORTED_EXT
, szFileTypes
, sizeof(szFileTypes
) / sizeof(TCHAR
));
162 token
= _tcstok ( szFileTypes
, separators
);
163 while ( token
!= NULL
)
165 GetWindowsDirectory(szSearchPath
, MAX_PATH
);
166 _tcscat(szSearchPath
, TEXT("\\"));
167 _tcscat(szSearchPath
, token
);
169 hFind
= FindFirstFile(szSearchPath
, &fd
);
170 while(hFind
!= INVALID_HANDLE_VALUE
)
172 /* Don't add any hidden bitmaps */
173 if((fd
.dwFileAttributes
& FILE_ATTRIBUTE_HIDDEN
) == 0)
175 TCHAR filename
[MAX_PATH
];
177 GetWindowsDirectory(filename
, MAX_PATH
);
179 _tcscat(filename
, TEXT("\\"));
180 _tcscat(filename
, fd
.cFileName
);
182 himl
= (HIMAGELIST
)SHGetFileInfo(filename
,
186 SHGFI_SYSICONINDEX
| SHGFI_SMALLICON
|
196 g_hShellImageList
= himl
;
197 ListView_SetImageList(g_hBackgroundList
, himl
, LVSIL_SMALL
);
200 backgroundItem
= &g_backgroundItems
[g_listViewItemCount
];
202 backgroundItem
->bWallpaper
= TRUE
;
204 _tcscpy(backgroundItem
->szDisplayName
, sfi
.szDisplayName
);
205 _tcscpy(backgroundItem
->szFilename
, filename
);
207 ZeroMemory(&listItem
, sizeof(LV_ITEM
));
208 listItem
.mask
= LVIF_TEXT
| LVIF_PARAM
| LVIF_STATE
| LVIF_IMAGE
;
209 listItem
.pszText
= backgroundItem
->szDisplayName
;
211 listItem
.iImage
= sfi
.iIcon
;
212 listItem
.iItem
= g_listViewItemCount
;
213 listItem
.lParam
= g_listViewItemCount
;
215 ListView_InsertItem(g_hBackgroundList
, &listItem
);
217 g_listViewItemCount
++;
220 if(!FindNextFile(hFind
, &fd
))
221 hFind
= INVALID_HANDLE_VALUE
;
224 token
= _tcstok ( NULL
, separators
);
230 void InitBackgroundDialog()
235 DWORD bufferSize
= sizeof(szBuffer
);
236 DWORD varType
= REG_SZ
;
239 g_hBackgroundList
= GetDlgItem(g_hBackgroundPage
, IDC_BACKGROUND_LIST
);
240 g_hBackgroundPreview
= GetDlgItem(g_hBackgroundPage
, IDC_BACKGROUND_PREVIEW
);
241 g_hPlacementCombo
= GetDlgItem(g_hBackgroundPage
, IDC_PLACEMENT_COMBO
);
242 g_hColorButton
= GetDlgItem(g_hBackgroundPage
, IDC_COLOR_BUTTON
);
246 LoadString(hApplet
, IDS_CENTER
, szString
, sizeof(szString
) / sizeof(TCHAR
));
247 SendMessage(g_hPlacementCombo
, CB_INSERTSTRING
, PLACEMENT_CENTER
, (LPARAM
)szString
);
249 LoadString(hApplet
, IDS_STRETCH
, szString
, sizeof(szString
) / sizeof(TCHAR
));
250 SendMessage(g_hPlacementCombo
, CB_INSERTSTRING
, PLACEMENT_STRETCH
, (LPARAM
)szString
);
252 LoadString(hApplet
, IDS_TILE
, szString
, sizeof(szString
) / sizeof(TCHAR
));
253 SendMessage(g_hPlacementCombo
, CB_INSERTSTRING
, PLACEMENT_TILE
, (LPARAM
)szString
);
255 /* Load the default settings from the registry */
256 RegOpenKeyEx(HKEY_CURRENT_USER
, TEXT("Control Panel\\Desktop"), 0, KEY_ALL_ACCESS
, ®Key
);
258 result
= RegQueryValueEx(regKey
, TEXT("WallpaperStyle"), 0, &varType
, (LPBYTE
)szBuffer
, &bufferSize
);
260 if(result
== ERROR_SUCCESS
)
262 if(_ttoi(szBuffer
) == 0)
264 SendMessage(g_hPlacementCombo
, CB_SETCURSEL
, PLACEMENT_CENTER
, 0);
265 g_placementSelection
= PLACEMENT_CENTER
;
268 if(_ttoi(szBuffer
) == 2)
270 SendMessage(g_hPlacementCombo
, CB_SETCURSEL
, PLACEMENT_STRETCH
, 0);
271 g_placementSelection
= PLACEMENT_STRETCH
;
276 SendMessage(g_hPlacementCombo
, CB_SETCURSEL
, PLACEMENT_CENTER
, 0);
277 g_placementSelection
= PLACEMENT_CENTER
;
280 result
= RegQueryValueEx(regKey
, TEXT("TileWallpaper"), 0, &varType
, (LPBYTE
)szBuffer
, &bufferSize
);
282 if(result
== ERROR_SUCCESS
)
284 if(_ttoi(szBuffer
) == 1)
286 SendMessage(g_hPlacementCombo
, CB_SETCURSEL
, PLACEMENT_TILE
, 0);
287 g_placementSelection
= PLACEMENT_TILE
;
296 MessageBox(NULL
, TEXT("That button doesn't do anything yet"), TEXT("Whoops"), MB_OK
);
299 BOOL
CheckListBoxFilename(HWND list
, TCHAR
*filename
)
304 void OnBrowseButton()
307 TCHAR filename
[MAX_PATH
];
308 TCHAR fileTitle
[256];
309 TCHAR filter
[MAX_PATH
];
310 BackgroundItem
*backgroundItem
= NULL
;
314 ZeroMemory(&ofn
, sizeof(OPENFILENAME
));
316 ofn
.lStructSize
= sizeof(OPENFILENAME
);
317 ofn
.hwndOwner
= g_hBackgroundPage
;
318 ofn
.lpstrFile
= filename
;
320 LoadString(hApplet
, IDS_BACKGROUND_COMDLG_FILTER
, filter
, sizeof(filter
) / sizeof(TCHAR
));
322 /* Set lpstrFile[0] to '\0' so that GetOpenFileName does not
323 * use the contents of szFile to initialize itself */
324 ofn
.lpstrFile
[0] = TEXT('\0');
325 ofn
.nMaxFile
= MAX_PATH
;
326 ofn
.lpstrFilter
= filter
;
327 ofn
.nFilterIndex
= 0;
328 ofn
.lpstrFileTitle
= fileTitle
;
329 ofn
.nMaxFileTitle
= 256;
330 ofn
.lpstrInitialDir
= NULL
;
331 ofn
.Flags
= OFN_PATHMUSTEXIST
| OFN_FILEMUSTEXIST
;
333 if(GetOpenFileName(&ofn
) == TRUE
)
335 /* Check if there is already a entry that holds this filename */
336 if(CheckListBoxFilename(g_hBackgroundList
, filename
) == TRUE
)
339 if(g_listViewItemCount
> (MAX_BACKGROUNDS
- 1))
342 SHGetFileInfo(filename
,
346 SHGFI_SYSICONINDEX
| SHGFI_SMALLICON
| SHGFI_DISPLAYNAME
);
348 backgroundItem
= &g_backgroundItems
[g_listViewItemCount
];
350 backgroundItem
->bWallpaper
= TRUE
;
352 _tcscpy(backgroundItem
->szDisplayName
, sfi
.szDisplayName
);
353 _tcscpy(backgroundItem
->szFilename
, filename
);
355 ZeroMemory(&listItem
, sizeof(LV_ITEM
));
356 listItem
.mask
= LVIF_TEXT
| LVIF_PARAM
| LVIF_STATE
| LVIF_IMAGE
;
358 listItem
.pszText
= backgroundItem
->szDisplayName
;
359 listItem
.iImage
= sfi
.iIcon
;
360 listItem
.iItem
= g_listViewItemCount
;
361 listItem
.lParam
= g_listViewItemCount
;
363 ListView_InsertItem(g_hBackgroundList
, &listItem
);
365 g_listViewItemCount
++;
369 void ListViewItemChanged(int itemIndex
)
371 BackgroundItem
*backgroundItem
= NULL
;
373 g_backgroundSelection
= itemIndex
;
374 backgroundItem
= &g_backgroundItems
[g_backgroundSelection
];
376 if(g_pWallpaperBitmap
!= NULL
)
378 DibFreeImage(g_pWallpaperBitmap
);
379 g_pWallpaperBitmap
= NULL
;
382 if(backgroundItem
->bWallpaper
== TRUE
)
384 g_pWallpaperBitmap
= DibLoadImage(backgroundItem
->szFilename
);
386 if(g_pWallpaperBitmap
== NULL
)
392 InvalidateRect(g_hBackgroundPreview
, NULL
, TRUE
);
394 EnableWindow(g_hColorButton
, (backgroundItem
->bWallpaper
== FALSE
? TRUE
: FALSE
));
395 EnableWindow(g_hPlacementCombo
, backgroundItem
->bWallpaper
);
397 PropSheet_Changed(GetParent(g_hBackgroundPage
), g_hBackgroundPage
);
400 void DrawBackgroundPreview(LPDRAWITEMSTRUCT draw
)
409 if(g_backgroundItems
[g_backgroundSelection
].bWallpaper
== FALSE
)
411 FillRect(draw
->hDC
, &draw
->rcItem
, GetSysColorBrush(COLOR_BACKGROUND
));
415 if(g_pWallpaperBitmap
== NULL
)
418 scaleX
= ((float)GetSystemMetrics(SM_CXSCREEN
) - 1) / (float)draw
->rcItem
.right
;
419 scaleY
= ((float)GetSystemMetrics(SM_CYSCREEN
) - 1) / (float)draw
->rcItem
.bottom
;
421 scaledWidth
= g_pWallpaperBitmap
->width
/ scaleX
;
422 scaledHeight
= g_pWallpaperBitmap
->height
/ scaleY
;
424 posX
= (draw
->rcItem
.right
/ 2) - (scaledWidth
/ 2);
425 posY
= (draw
->rcItem
.bottom
/ 2) - (scaledHeight
/ 2);
427 FillRect(draw
->hDC
, &draw
->rcItem
, GetSysColorBrush(COLOR_BACKGROUND
));
429 SetStretchBltMode(draw
->hDC
, COLORONCOLOR
);
431 if(g_placementSelection
== PLACEMENT_CENTER
)
433 StretchDIBits(draw
->hDC
,
440 g_pWallpaperBitmap
->width
,
441 g_pWallpaperBitmap
->height
,
442 g_pWallpaperBitmap
->bits
,
443 g_pWallpaperBitmap
->info
,
448 if(g_placementSelection
== PLACEMENT_STRETCH
)
450 StretchDIBits(draw
->hDC
,
457 g_pWallpaperBitmap
->width
,
458 g_pWallpaperBitmap
->height
,
459 g_pWallpaperBitmap
->bits
,
460 g_pWallpaperBitmap
->info
,
465 if(g_placementSelection
== PLACEMENT_TILE
)
470 for(y
= 0; y
< draw
->rcItem
.bottom
; y
+= scaledHeight
)
472 for(x
= 0; x
< draw
->rcItem
.right
; x
+= scaledWidth
)
474 StretchDIBits(draw
->hDC
,
481 g_pWallpaperBitmap
->width
,
482 g_pWallpaperBitmap
->height
,
483 g_pWallpaperBitmap
->bits
,
484 g_pWallpaperBitmap
->info
,
496 RegOpenKeyEx(HKEY_CURRENT_USER
, TEXT("Control Panel\\Desktop"), 0, KEY_ALL_ACCESS
, ®Key
);
498 if(g_placementSelection
== PLACEMENT_TILE
)
500 RegSetValueEx(regKey
, TEXT("TileWallpaper"), 0, REG_SZ
, (BYTE
*)TEXT("1"), sizeof(TCHAR
) * 2);
501 RegSetValueEx(regKey
, TEXT("WallpaperStyle"), 0, REG_SZ
, (BYTE
*)TEXT("0"), sizeof(TCHAR
) * 2);
504 if(g_placementSelection
== PLACEMENT_CENTER
)
506 RegSetValueEx(regKey
, TEXT("TileWallpaper"), 0, REG_SZ
, (BYTE
*)TEXT("0"), sizeof(TCHAR
) * 2);
507 RegSetValueEx(regKey
, TEXT("WallpaperStyle"), 0, REG_SZ
, (BYTE
*)TEXT("0"), sizeof(TCHAR
) * 2);
510 if(g_placementSelection
== PLACEMENT_STRETCH
)
512 RegSetValueEx(regKey
, TEXT("TileWallpaper"), 0, REG_SZ
, (BYTE
*)TEXT("0"), sizeof(TCHAR
) * 2);
513 RegSetValueEx(regKey
, TEXT("WallpaperStyle"), 0, REG_SZ
, (BYTE
*)TEXT("2"), sizeof(TCHAR
) * 2);
518 if(g_backgroundItems
[g_backgroundSelection
].bWallpaper
== TRUE
)
520 SystemParametersInfo(SPI_SETDESKWALLPAPER
,
522 g_backgroundItems
[g_backgroundSelection
].szFilename
,
527 SystemParametersInfo(SPI_SETDESKWALLPAPER
, 0, TEXT(""), SPIF_UPDATEINIFILE
);
531 INT_PTR CALLBACK
BackgroundPageProc(HWND hwndDlg
,
536 g_hBackgroundPage
= hwndDlg
;
542 InitBackgroundDialog();
547 DWORD controlId
= LOWORD(wParam
);
548 DWORD command
= HIWORD(wParam
);
552 case IDC_COLOR_BUTTON
:
554 if(command
== BN_CLICKED
)
559 case IDC_BROWSE_BUTTON
:
561 if(command
== BN_CLICKED
)
566 case IDC_PLACEMENT_COMBO
:
568 if(command
== CBN_SELCHANGE
)
570 g_placementSelection
= SendMessage(g_hPlacementCombo
, CB_GETCURSEL
, 0, 0);
572 InvalidateRect(g_hBackgroundPreview
, NULL
, TRUE
);
574 PropSheet_Changed(GetParent(g_hBackgroundPage
), g_hBackgroundPage
);
583 LPDRAWITEMSTRUCT drawItem
;
584 drawItem
= (LPDRAWITEMSTRUCT
)lParam
;
586 if(drawItem
->CtlID
== IDC_BACKGROUND_PREVIEW
)
588 DrawBackgroundPreview(drawItem
);
595 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
606 case LVN_ITEMCHANGED
:
608 LPNMLISTVIEW nm
= (LPNMLISTVIEW
)lParam
;
610 if((nm
->uNewState
& LVIS_SELECTED
) == 0)
613 ListViewItemChanged(nm
->iItem
);
625 if(g_pWallpaperBitmap
!= NULL
)
626 DibFreeImage(g_pWallpaperBitmap
);