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
)
308 void OnBrowseButton()
311 TCHAR filename
[MAX_PATH
];
312 TCHAR fileTitle
[256];
313 TCHAR filter
[MAX_PATH
];
314 BackgroundItem
*backgroundItem
= NULL
;
318 ZeroMemory(&ofn
, sizeof(OPENFILENAME
));
320 ofn
.lStructSize
= sizeof(OPENFILENAME
);
321 ofn
.hwndOwner
= g_hBackgroundPage
;
322 ofn
.lpstrFile
= filename
;
324 LoadString(hApplet
, IDS_BACKGROUND_COMDLG_FILTER
, filter
, sizeof(filter
) / sizeof(TCHAR
));
326 /* Set lpstrFile[0] to '\0' so that GetOpenFileName does not
327 * use the contents of szFile to initialize itself */
328 ofn
.lpstrFile
[0] = TEXT('\0');
329 ofn
.nMaxFile
= MAX_PATH
;
330 ofn
.lpstrFilter
= filter
;
331 ofn
.nFilterIndex
= 0;
332 ofn
.lpstrFileTitle
= fileTitle
;
333 ofn
.nMaxFileTitle
= 256;
334 ofn
.lpstrInitialDir
= NULL
;
335 ofn
.Flags
= OFN_PATHMUSTEXIST
| OFN_FILEMUSTEXIST
;
337 if(GetOpenFileName(&ofn
) == TRUE
)
339 /* Check if there is already a entry that holds this filename */
340 if(CheckListBoxFilename(g_hBackgroundList
, filename
) == TRUE
)
343 if(g_listViewItemCount
> (MAX_BACKGROUNDS
- 1))
346 SHGetFileInfo(filename
,
350 SHGFI_SYSICONINDEX
| SHGFI_SMALLICON
| SHGFI_DISPLAYNAME
);
352 backgroundItem
= &g_backgroundItems
[g_listViewItemCount
];
354 backgroundItem
->bWallpaper
= TRUE
;
356 _tcscpy(backgroundItem
->szDisplayName
, sfi
.szDisplayName
);
357 _tcscpy(backgroundItem
->szFilename
, filename
);
359 ZeroMemory(&listItem
, sizeof(LV_ITEM
));
360 listItem
.mask
= LVIF_TEXT
| LVIF_PARAM
| LVIF_STATE
| LVIF_IMAGE
;
362 listItem
.pszText
= backgroundItem
->szDisplayName
;
363 listItem
.iImage
= sfi
.iIcon
;
364 listItem
.iItem
= g_listViewItemCount
;
365 listItem
.lParam
= g_listViewItemCount
;
367 (void)ListView_InsertItem(g_hBackgroundList
, &listItem
);
369 g_listViewItemCount
++;
373 void ListViewItemChanged(int itemIndex
)
375 BackgroundItem
*backgroundItem
= NULL
;
377 g_backgroundSelection
= itemIndex
;
378 backgroundItem
= &g_backgroundItems
[g_backgroundSelection
];
380 if(g_pWallpaperBitmap
!= NULL
)
382 DibFreeImage(g_pWallpaperBitmap
);
383 g_pWallpaperBitmap
= NULL
;
386 if(backgroundItem
->bWallpaper
== TRUE
)
388 g_pWallpaperBitmap
= DibLoadImage(backgroundItem
->szFilename
);
390 if(g_pWallpaperBitmap
== NULL
)
396 InvalidateRect(g_hBackgroundPreview
, NULL
, TRUE
);
398 EnableWindow(g_hColorButton
, (backgroundItem
->bWallpaper
== FALSE
? TRUE
: FALSE
));
399 EnableWindow(g_hPlacementCombo
, backgroundItem
->bWallpaper
);
401 PropSheet_Changed(GetParent(g_hBackgroundPage
), g_hBackgroundPage
);
404 void DrawBackgroundPreview(LPDRAWITEMSTRUCT draw
)
413 if(g_backgroundItems
[g_backgroundSelection
].bWallpaper
== FALSE
)
415 FillRect(draw
->hDC
, &draw
->rcItem
, GetSysColorBrush(COLOR_BACKGROUND
));
419 if(g_pWallpaperBitmap
== NULL
)
422 scaleX
= ((float)GetSystemMetrics(SM_CXSCREEN
) - 1) / (float)draw
->rcItem
.right
;
423 scaleY
= ((float)GetSystemMetrics(SM_CYSCREEN
) - 1) / (float)draw
->rcItem
.bottom
;
425 scaledWidth
= g_pWallpaperBitmap
->width
/ scaleX
;
426 scaledHeight
= g_pWallpaperBitmap
->height
/ scaleY
;
428 posX
= (draw
->rcItem
.right
/ 2) - (scaledWidth
/ 2);
429 posY
= (draw
->rcItem
.bottom
/ 2) - (scaledHeight
/ 2);
431 FillRect(draw
->hDC
, &draw
->rcItem
, GetSysColorBrush(COLOR_BACKGROUND
));
433 SetStretchBltMode(draw
->hDC
, COLORONCOLOR
);
435 if(g_placementSelection
== PLACEMENT_CENTER
)
437 StretchDIBits(draw
->hDC
,
444 g_pWallpaperBitmap
->width
,
445 g_pWallpaperBitmap
->height
,
446 g_pWallpaperBitmap
->bits
,
447 g_pWallpaperBitmap
->info
,
452 if(g_placementSelection
== PLACEMENT_STRETCH
)
454 StretchDIBits(draw
->hDC
,
461 g_pWallpaperBitmap
->width
,
462 g_pWallpaperBitmap
->height
,
463 g_pWallpaperBitmap
->bits
,
464 g_pWallpaperBitmap
->info
,
469 if(g_placementSelection
== PLACEMENT_TILE
)
474 for(y
= 0; y
< draw
->rcItem
.bottom
; y
+= scaledHeight
)
476 for(x
= 0; x
< draw
->rcItem
.right
; x
+= scaledWidth
)
478 StretchDIBits(draw
->hDC
,
485 g_pWallpaperBitmap
->width
,
486 g_pWallpaperBitmap
->height
,
487 g_pWallpaperBitmap
->bits
,
488 g_pWallpaperBitmap
->info
,
500 RegOpenKeyEx(HKEY_CURRENT_USER
, TEXT("Control Panel\\Desktop"), 0, KEY_ALL_ACCESS
, ®Key
);
502 if(g_placementSelection
== PLACEMENT_TILE
)
504 RegSetValueEx(regKey
, TEXT("TileWallpaper"), 0, REG_SZ
, (BYTE
*)TEXT("1"), sizeof(TCHAR
) * 2);
505 RegSetValueEx(regKey
, TEXT("WallpaperStyle"), 0, REG_SZ
, (BYTE
*)TEXT("0"), sizeof(TCHAR
) * 2);
508 if(g_placementSelection
== PLACEMENT_CENTER
)
510 RegSetValueEx(regKey
, TEXT("TileWallpaper"), 0, REG_SZ
, (BYTE
*)TEXT("0"), sizeof(TCHAR
) * 2);
511 RegSetValueEx(regKey
, TEXT("WallpaperStyle"), 0, REG_SZ
, (BYTE
*)TEXT("0"), sizeof(TCHAR
) * 2);
514 if(g_placementSelection
== PLACEMENT_STRETCH
)
516 RegSetValueEx(regKey
, TEXT("TileWallpaper"), 0, REG_SZ
, (BYTE
*)TEXT("0"), sizeof(TCHAR
) * 2);
517 RegSetValueEx(regKey
, TEXT("WallpaperStyle"), 0, REG_SZ
, (BYTE
*)TEXT("2"), sizeof(TCHAR
) * 2);
522 if(g_backgroundItems
[g_backgroundSelection
].bWallpaper
== TRUE
)
524 SystemParametersInfo(SPI_SETDESKWALLPAPER
,
526 g_backgroundItems
[g_backgroundSelection
].szFilename
,
531 SystemParametersInfo(SPI_SETDESKWALLPAPER
, 0, TEXT(""), SPIF_UPDATEINIFILE
);
535 INT_PTR CALLBACK
BackgroundPageProc(HWND hwndDlg
,
540 g_hBackgroundPage
= hwndDlg
;
546 InitBackgroundDialog();
551 DWORD controlId
= LOWORD(wParam
);
552 DWORD command
= HIWORD(wParam
);
556 case IDC_COLOR_BUTTON
:
558 if(command
== BN_CLICKED
)
563 case IDC_BROWSE_BUTTON
:
565 if(command
== BN_CLICKED
)
570 case IDC_PLACEMENT_COMBO
:
572 if(command
== CBN_SELCHANGE
)
574 g_placementSelection
= SendMessage(g_hPlacementCombo
, CB_GETCURSEL
, 0, 0);
576 InvalidateRect(g_hBackgroundPreview
, NULL
, TRUE
);
578 PropSheet_Changed(GetParent(g_hBackgroundPage
), g_hBackgroundPage
);
590 hdc
= BeginPaint(hwndDlg
, &ps
);
592 hdcMem
= CreateCompatibleDC(hdc
);
593 SelectObject(hdcMem
, hBitmap
);
595 BitBlt(hdc
, 98, 0, cxSource
, cySource
, hdcMem
, 0, 0, SRCCOPY
);
598 EndPaint(hwndDlg
, &ps
);
604 LPDRAWITEMSTRUCT drawItem
;
605 drawItem
= (LPDRAWITEMSTRUCT
)lParam
;
607 if(drawItem
->CtlID
== IDC_BACKGROUND_PREVIEW
)
609 DrawBackgroundPreview(drawItem
);
616 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
627 case LVN_ITEMCHANGED
:
629 LPNMLISTVIEW nm
= (LPNMLISTVIEW
)lParam
;
631 if((nm
->uNewState
& LVIS_SELECTED
) == 0)
634 ListViewItemChanged(nm
->iItem
);
646 if(g_pWallpaperBitmap
!= NULL
)
647 DibFreeImage(g_pWallpaperBitmap
);
649 DeleteObject(hBitmap
);