mirror of
https://github.com/reactos/reactos.git
synced 2024-11-10 00:34:39 +00:00
6afbc8f483
svn path=/branches/reactos-yarotows/; revision=45219
793 lines
27 KiB
C
793 lines
27 KiB
C
/* $Id$
|
|
*
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
* PROJECT: ReactOS Display Control Panel
|
|
* FILE: lib/cpl/desk/background.c
|
|
* PURPOSE: Background property page
|
|
*
|
|
* PROGRAMMERS: Trevor McCort (lycan359@gmail.com)
|
|
* Alexey Minnekhanov (minlexx@rambler.ru)
|
|
*/
|
|
|
|
#include "desk.h"
|
|
|
|
#define MAX_BACKGROUNDS 100
|
|
|
|
#define PLACEMENT_CENTER 0
|
|
#define PLACEMENT_STRETCH 1
|
|
#define PLACEMENT_TILE 2
|
|
|
|
typedef struct
|
|
{
|
|
BOOL bWallpaper; /* Is this background a wallpaper */
|
|
|
|
TCHAR szFilename[MAX_PATH];
|
|
TCHAR szDisplayName[256];
|
|
|
|
} BackgroundItem;
|
|
|
|
typedef struct _GLOBAL_DATA
|
|
{
|
|
BackgroundItem backgroundItems[MAX_BACKGROUNDS];
|
|
|
|
PDIBITMAP pWallpaperBitmap;
|
|
|
|
int placementSelection;
|
|
int backgroundSelection;
|
|
|
|
COLORREF backgroundDesktopColor;
|
|
COLORREF custom_colors[16];
|
|
|
|
int listViewItemCount;
|
|
|
|
HBITMAP hBitmap;
|
|
int cxSource;
|
|
int cySource;
|
|
} GLOBAL_DATA, *PGLOBAL_DATA;
|
|
|
|
|
|
|
|
/* Add the images in the C:\ReactOS directory and the current wallpaper if any */
|
|
static VOID
|
|
AddListViewItems(HWND hwndDlg, PGLOBAL_DATA pGlobalData)
|
|
{
|
|
WIN32_FIND_DATA fd;
|
|
HANDLE hFind;
|
|
TCHAR szSearchPath[MAX_PATH];
|
|
TCHAR szFileTypes[MAX_PATH];
|
|
LV_ITEM listItem;
|
|
LV_COLUMN dummy;
|
|
RECT clientRect;
|
|
HKEY regKey;
|
|
SHFILEINFO sfi;
|
|
HIMAGELIST himl;
|
|
TCHAR wallpaperFilename[MAX_PATH];
|
|
DWORD bufferSize = sizeof(wallpaperFilename);
|
|
TCHAR buffer[MAX_PATH];
|
|
DWORD varType = REG_SZ;
|
|
LONG result;
|
|
UINT i = 0;
|
|
BackgroundItem *backgroundItem = NULL;
|
|
TCHAR separators[] = TEXT(";");
|
|
TCHAR *token;
|
|
HWND hwndBackgroundList;
|
|
TCHAR *p;
|
|
|
|
hwndBackgroundList = GetDlgItem(hwndDlg, IDC_BACKGROUND_LIST);
|
|
|
|
GetClientRect(hwndBackgroundList, &clientRect);
|
|
|
|
/* Add a new column to the list */
|
|
ZeroMemory(&dummy, sizeof(LV_COLUMN));
|
|
dummy.mask = LVCF_SUBITEM | LVCF_WIDTH;
|
|
dummy.iSubItem = 0;
|
|
dummy.cx = (clientRect.right - clientRect.left) - GetSystemMetrics(SM_CXVSCROLL);
|
|
(void)ListView_InsertColumn(hwndBackgroundList, 0, &dummy);
|
|
|
|
/* Add the "None" item */
|
|
backgroundItem = &pGlobalData->backgroundItems[pGlobalData->listViewItemCount];
|
|
backgroundItem->bWallpaper = FALSE;
|
|
LoadString(hApplet,
|
|
IDS_NONE,
|
|
backgroundItem->szDisplayName,
|
|
sizeof(backgroundItem->szDisplayName) / sizeof(TCHAR));
|
|
|
|
ZeroMemory(&listItem, sizeof(LV_ITEM));
|
|
listItem.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE | LVIF_IMAGE;
|
|
listItem.state = LVIS_SELECTED;
|
|
listItem.pszText = backgroundItem->szDisplayName;
|
|
listItem.iImage = -1;
|
|
listItem.iItem = pGlobalData->listViewItemCount;
|
|
listItem.lParam = pGlobalData->listViewItemCount;
|
|
|
|
(void)ListView_InsertItem(hwndBackgroundList, &listItem);
|
|
ListView_SetItemState(hwndBackgroundList, pGlobalData->listViewItemCount, LVIS_SELECTED, LVIS_SELECTED);
|
|
|
|
pGlobalData->listViewItemCount++;
|
|
|
|
/* Add current wallpaper if any */
|
|
RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Desktop"), 0, KEY_ALL_ACCESS, ®Key);
|
|
|
|
result = RegQueryValueEx(regKey, TEXT("Wallpaper"), 0, &varType, (LPBYTE)wallpaperFilename, &bufferSize);
|
|
if ((result == ERROR_SUCCESS) && (_tcslen(wallpaperFilename) > 0))
|
|
{
|
|
/* Allow environment variables in file name */
|
|
if (ExpandEnvironmentStrings(wallpaperFilename, buffer, MAX_PATH))
|
|
{
|
|
_tcscpy(wallpaperFilename, buffer);
|
|
}
|
|
|
|
himl = (HIMAGELIST)SHGetFileInfo(wallpaperFilename,
|
|
0,
|
|
&sfi,
|
|
sizeof(sfi),
|
|
SHGFI_SYSICONINDEX | SHGFI_SMALLICON |
|
|
SHGFI_DISPLAYNAME);
|
|
|
|
if (himl != NULL)
|
|
{
|
|
if (i++ == 0)
|
|
{
|
|
(void)ListView_SetImageList(hwndBackgroundList, himl, LVSIL_SMALL);
|
|
}
|
|
|
|
backgroundItem = &pGlobalData->backgroundItems[pGlobalData->listViewItemCount];
|
|
|
|
backgroundItem->bWallpaper = TRUE;
|
|
|
|
_tcscpy(backgroundItem->szDisplayName, sfi.szDisplayName);
|
|
p = _tcsrchr(backgroundItem->szDisplayName, _T('.'));
|
|
if (p)
|
|
*p = (TCHAR)0;
|
|
_tcscpy(backgroundItem->szFilename, wallpaperFilename);
|
|
|
|
ZeroMemory(&listItem, sizeof(LV_ITEM));
|
|
listItem.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE | LVIF_IMAGE;
|
|
listItem.state = LVIS_SELECTED;
|
|
listItem.pszText = backgroundItem->szDisplayName;
|
|
listItem.iImage = sfi.iIcon;
|
|
listItem.iItem = pGlobalData->listViewItemCount;
|
|
listItem.lParam = pGlobalData->listViewItemCount;
|
|
|
|
(void)ListView_InsertItem(hwndBackgroundList, &listItem);
|
|
ListView_SetItemState(hwndBackgroundList, pGlobalData->listViewItemCount, LVIS_SELECTED, LVIS_SELECTED);
|
|
|
|
pGlobalData->listViewItemCount++;
|
|
}
|
|
}
|
|
|
|
RegCloseKey(regKey);
|
|
|
|
/* Add all the images in the C:\ReactOS directory. */
|
|
|
|
LoadString(hApplet, IDS_SUPPORTED_EXT, szFileTypes, sizeof(szFileTypes) / sizeof(TCHAR));
|
|
|
|
token = _tcstok(szFileTypes, separators);
|
|
while (token != NULL)
|
|
{
|
|
GetWindowsDirectory(szSearchPath, MAX_PATH);
|
|
_tcscat(szSearchPath, TEXT("\\"));
|
|
_tcscat(szSearchPath, token);
|
|
|
|
hFind = FindFirstFile(szSearchPath, &fd);
|
|
while (hFind != INVALID_HANDLE_VALUE)
|
|
{
|
|
TCHAR filename[MAX_PATH];
|
|
|
|
GetWindowsDirectory(filename, MAX_PATH);
|
|
|
|
_tcscat(filename, TEXT("\\"));
|
|
_tcscat(filename, fd.cFileName);
|
|
|
|
/* Don't add any hidden bitmaps. Also don't add current wallpaper once more. */
|
|
if (((fd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) == 0) && (_tcscmp(wallpaperFilename, filename) != 0))
|
|
{
|
|
himl = (HIMAGELIST)SHGetFileInfo(filename,
|
|
0,
|
|
&sfi,
|
|
sizeof(sfi),
|
|
SHGFI_SYSICONINDEX | SHGFI_SMALLICON |
|
|
SHGFI_DISPLAYNAME);
|
|
|
|
if (himl == NULL)
|
|
break;
|
|
|
|
if (i++ == 0)
|
|
{
|
|
(void)ListView_SetImageList(hwndBackgroundList, himl, LVSIL_SMALL);
|
|
}
|
|
|
|
backgroundItem = &pGlobalData->backgroundItems[pGlobalData->listViewItemCount];
|
|
|
|
backgroundItem->bWallpaper = TRUE;
|
|
|
|
_tcscpy(backgroundItem->szDisplayName, sfi.szDisplayName);
|
|
p = _tcsrchr(backgroundItem->szDisplayName, _T('.'));
|
|
if (p)
|
|
*p = (TCHAR)0;
|
|
_tcscpy(backgroundItem->szFilename, filename);
|
|
|
|
ZeroMemory(&listItem, sizeof(LV_ITEM));
|
|
listItem.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE | LVIF_IMAGE;
|
|
listItem.pszText = backgroundItem->szDisplayName;
|
|
listItem.state = 0;
|
|
listItem.iImage = sfi.iIcon;
|
|
listItem.iItem = pGlobalData->listViewItemCount;
|
|
listItem.lParam = pGlobalData->listViewItemCount;
|
|
|
|
(void)ListView_InsertItem(hwndBackgroundList, &listItem);
|
|
|
|
pGlobalData->listViewItemCount++;
|
|
}
|
|
|
|
if(!FindNextFile(hFind, &fd))
|
|
hFind = INVALID_HANDLE_VALUE;
|
|
}
|
|
|
|
token = _tcstok(NULL, separators);
|
|
}
|
|
}
|
|
|
|
|
|
static VOID
|
|
InitBackgroundDialog(HWND hwndDlg, PGLOBAL_DATA pGlobalData)
|
|
{
|
|
TCHAR szString[256];
|
|
HKEY regKey;
|
|
TCHAR szBuffer[2];
|
|
DWORD bufferSize = sizeof(szBuffer);
|
|
DWORD varType = REG_SZ;
|
|
LONG result;
|
|
BITMAP bitmap;
|
|
|
|
pGlobalData->backgroundDesktopColor = GetSysColor(COLOR_BACKGROUND);
|
|
|
|
AddListViewItems(hwndDlg, pGlobalData);
|
|
|
|
LoadString(hApplet, IDS_CENTER, szString, sizeof(szString) / sizeof(TCHAR));
|
|
SendDlgItemMessage(hwndDlg, IDC_PLACEMENT_COMBO, CB_INSERTSTRING, PLACEMENT_CENTER, (LPARAM)szString);
|
|
|
|
LoadString(hApplet, IDS_STRETCH, szString, sizeof(szString) / sizeof(TCHAR));
|
|
SendDlgItemMessage(hwndDlg, IDC_PLACEMENT_COMBO, CB_INSERTSTRING, PLACEMENT_STRETCH, (LPARAM)szString);
|
|
|
|
LoadString(hApplet, IDS_TILE, szString, sizeof(szString) / sizeof(TCHAR));
|
|
SendDlgItemMessage(hwndDlg, IDC_PLACEMENT_COMBO, CB_INSERTSTRING, PLACEMENT_TILE, (LPARAM)szString);
|
|
|
|
/* Load the default settings from the registry */
|
|
result = RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Desktop"), 0, KEY_ALL_ACCESS, ®Key);
|
|
if (result != ERROR_SUCCESS)
|
|
{
|
|
/* reg key open failed; maybe it does not exist? create it! */
|
|
DWORD dwDisposition = 0;
|
|
result = RegCreateKeyEx( HKEY_CURRENT_USER, TEXT("Control Panel\\Desktop"), 0, NULL, 0, KEY_ALL_ACCESS, NULL,
|
|
®Key, &dwDisposition );
|
|
/* now the key must be created & opened and regKey points to opened key */
|
|
/* On error result will not contain ERROR_SUCCESS. I don't know how to handle */
|
|
/* this case :( */
|
|
}
|
|
|
|
result = RegQueryValueEx(regKey, TEXT("WallpaperStyle"), 0, &varType, (LPBYTE)szBuffer, &bufferSize);
|
|
if (result == ERROR_SUCCESS)
|
|
{
|
|
if (_ttoi(szBuffer) == 0)
|
|
{
|
|
SendDlgItemMessage(hwndDlg, IDC_PLACEMENT_COMBO, CB_SETCURSEL, PLACEMENT_CENTER, 0);
|
|
pGlobalData->placementSelection = PLACEMENT_CENTER;
|
|
}
|
|
|
|
if (_ttoi(szBuffer) == 2)
|
|
{
|
|
SendDlgItemMessage(hwndDlg, IDC_PLACEMENT_COMBO, CB_SETCURSEL, PLACEMENT_STRETCH, 0);
|
|
pGlobalData->placementSelection = PLACEMENT_STRETCH;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SendDlgItemMessage(hwndDlg, IDC_PLACEMENT_COMBO, CB_SETCURSEL, PLACEMENT_CENTER, 0);
|
|
pGlobalData->placementSelection = PLACEMENT_CENTER;
|
|
}
|
|
|
|
result = RegQueryValueEx(regKey, TEXT("TileWallpaper"), 0, &varType, (LPBYTE)szBuffer, &bufferSize);
|
|
if (result == ERROR_SUCCESS)
|
|
{
|
|
if (_ttoi(szBuffer) == 1)
|
|
{
|
|
SendDlgItemMessage(hwndDlg, IDC_PLACEMENT_COMBO, CB_SETCURSEL, PLACEMENT_TILE, 0);
|
|
pGlobalData->placementSelection = PLACEMENT_TILE;
|
|
}
|
|
}
|
|
|
|
RegCloseKey(regKey);
|
|
|
|
pGlobalData->hBitmap = (HBITMAP) LoadImage(hApplet, MAKEINTRESOURCE(IDC_MONITOR), IMAGE_BITMAP, 0, 0, LR_LOADTRANSPARENT);
|
|
if (pGlobalData->hBitmap != NULL)
|
|
{
|
|
GetObject(pGlobalData->hBitmap, sizeof(BITMAP), &bitmap);
|
|
|
|
pGlobalData->cxSource = bitmap.bmWidth;
|
|
pGlobalData->cySource = bitmap.bmHeight;
|
|
}
|
|
}
|
|
|
|
|
|
static VOID
|
|
OnColorButton(HWND hwndDlg, PGLOBAL_DATA pGlobalData)
|
|
{
|
|
/* Load custom colors from Registry */
|
|
HKEY hKey = NULL;
|
|
LONG res = ERROR_SUCCESS;
|
|
CHOOSECOLOR cc;
|
|
|
|
res = RegCreateKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Appearance"), 0, NULL, 0,
|
|
KEY_ALL_ACCESS, NULL, &hKey, NULL);
|
|
/* Now the key is either created or opened existing, if res == ERROR_SUCCESS */
|
|
if (res == ERROR_SUCCESS)
|
|
{
|
|
/* Key opened */
|
|
DWORD dwType = REG_BINARY;
|
|
DWORD cbData = sizeof(pGlobalData->custom_colors);
|
|
res = RegQueryValueEx(hKey, TEXT("CustomColors"), NULL, &dwType,
|
|
(LPBYTE)pGlobalData->custom_colors, &cbData);
|
|
RegCloseKey(hKey);
|
|
hKey = NULL;
|
|
}
|
|
|
|
/* Launch ChooseColor() dialog */
|
|
|
|
cc.lStructSize = sizeof(CHOOSECOLOR);
|
|
cc.hwndOwner = hwndDlg;
|
|
cc.hInstance = NULL;
|
|
cc.rgbResult = pGlobalData->backgroundDesktopColor;
|
|
cc.lpCustColors = pGlobalData->custom_colors;
|
|
cc.Flags = CC_ANYCOLOR | /* Causes the dialog box to display all available colors in the set of basic colors. */
|
|
CC_FULLOPEN | /* opens dialog in full size */
|
|
CC_RGBINIT ; /* init chosen color by rgbResult value */
|
|
cc.lCustData = 0;
|
|
cc.lpfnHook = NULL;
|
|
cc.lpTemplateName = NULL;
|
|
if (ChooseColor(&cc))
|
|
{
|
|
/* Save selected color to var */
|
|
pGlobalData->backgroundDesktopColor = cc.rgbResult;
|
|
|
|
/* Apply button will be activated */
|
|
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
|
|
|
|
/* Window will be updated :) */
|
|
InvalidateRect(GetDlgItem(hwndDlg, IDC_BACKGROUND_PREVIEW), NULL, TRUE);
|
|
|
|
/* Save custom colors to reg. To this moment key must be created already. See above */
|
|
res = RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Appearance"), 0,
|
|
KEY_WRITE, &hKey);
|
|
if (res == ERROR_SUCCESS)
|
|
{
|
|
/* Key opened */
|
|
RegSetValueEx(hKey, TEXT("CustomColors"), 0, REG_BINARY,
|
|
(const BYTE *)pGlobalData->custom_colors, sizeof(pGlobalData->custom_colors));
|
|
RegCloseKey(hKey);
|
|
hKey = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* ListView_FindItem() Macro: Searches for a list-view item with the specified
|
|
* characteristics. Returns the index of the item if successful, or -1 otherwise
|
|
*/
|
|
static BOOL
|
|
CheckListViewFilenameExists(HWND hwndList, LPCTSTR tszFileName)
|
|
{
|
|
LVFINDINFO lvfi;
|
|
int retVal;
|
|
|
|
lvfi.flags = LVFI_STRING; /* search item by EXACT string */
|
|
lvfi.psz = tszFileName; /* string to search */
|
|
|
|
/* other items of this structure are not valid, besacuse flags are not set. */
|
|
retVal = ListView_FindItem(hwndList, -1, &lvfi);
|
|
if (retVal != -1)
|
|
return TRUE; /* item found! */
|
|
|
|
return FALSE; /* item not found. */
|
|
}
|
|
|
|
|
|
static VOID
|
|
OnBrowseButton(HWND hwndDlg, PGLOBAL_DATA pGlobalData)
|
|
{
|
|
OPENFILENAME ofn;
|
|
TCHAR filename[MAX_PATH];
|
|
TCHAR fileTitle[256];
|
|
TCHAR filter[MAX_PATH];
|
|
BackgroundItem *backgroundItem = NULL;
|
|
SHFILEINFO sfi;
|
|
LV_ITEM listItem;
|
|
HWND hwndBackgroundList;
|
|
TCHAR *p;
|
|
|
|
hwndBackgroundList = GetDlgItem(hwndDlg, IDC_BACKGROUND_LIST);
|
|
|
|
ZeroMemory(&ofn, sizeof(OPENFILENAME));
|
|
|
|
ofn.lStructSize = sizeof(OPENFILENAME);
|
|
ofn.hwndOwner = hwndDlg;
|
|
ofn.lpstrFile = filename;
|
|
|
|
LoadString(hApplet, IDS_BACKGROUND_COMDLG_FILTER, filter, sizeof(filter) / sizeof(TCHAR));
|
|
|
|
/* Set lpstrFile[0] to '\0' so that GetOpenFileName does not
|
|
* use the contents of szFile to initialize itself */
|
|
ofn.lpstrFile[0] = TEXT('\0');
|
|
ofn.nMaxFile = MAX_PATH;
|
|
ofn.lpstrFilter = filter;
|
|
ofn.nFilterIndex = 0;
|
|
ofn.lpstrFileTitle = fileTitle;
|
|
ofn.nMaxFileTitle = 256;
|
|
ofn.lpstrInitialDir = NULL;
|
|
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
|
|
|
|
if (GetOpenFileName(&ofn) == TRUE)
|
|
{
|
|
/* Check if there is already a entry that holds this filename */
|
|
if (CheckListViewFilenameExists(hwndBackgroundList, ofn.lpstrFileTitle) == TRUE)
|
|
return;
|
|
|
|
if (pGlobalData->listViewItemCount > (MAX_BACKGROUNDS - 1))
|
|
return;
|
|
|
|
SHGetFileInfo(filename,
|
|
0,
|
|
&sfi,
|
|
sizeof(sfi),
|
|
SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_DISPLAYNAME);
|
|
|
|
backgroundItem = &pGlobalData->backgroundItems[pGlobalData->listViewItemCount];
|
|
|
|
backgroundItem->bWallpaper = TRUE;
|
|
|
|
_tcscpy(backgroundItem->szDisplayName, sfi.szDisplayName);
|
|
p = _tcsrchr(backgroundItem->szDisplayName, _T('.'));
|
|
if (p)
|
|
*p = (TCHAR)0;
|
|
_tcscpy(backgroundItem->szFilename, filename);
|
|
|
|
ZeroMemory(&listItem, sizeof(LV_ITEM));
|
|
listItem.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE | LVIF_IMAGE;
|
|
listItem.state = LVIS_SELECTED;
|
|
listItem.pszText = backgroundItem->szDisplayName;
|
|
listItem.iImage = sfi.iIcon;
|
|
listItem.iItem = pGlobalData->listViewItemCount;
|
|
listItem.lParam = pGlobalData->listViewItemCount;
|
|
|
|
(void)ListView_InsertItem(hwndBackgroundList, &listItem);
|
|
SendMessage(hwndBackgroundList, WM_VSCROLL, SB_BOTTOM, 0);
|
|
|
|
pGlobalData->listViewItemCount++;
|
|
}
|
|
}
|
|
|
|
|
|
static VOID
|
|
ListViewItemChanged(HWND hwndDlg, PGLOBAL_DATA pGlobalData, int itemIndex)
|
|
{
|
|
BackgroundItem *backgroundItem = NULL;
|
|
|
|
pGlobalData->backgroundSelection = itemIndex;
|
|
backgroundItem = &pGlobalData->backgroundItems[pGlobalData->backgroundSelection];
|
|
|
|
if (pGlobalData->pWallpaperBitmap != NULL)
|
|
{
|
|
DibFreeImage(pGlobalData->pWallpaperBitmap);
|
|
pGlobalData->pWallpaperBitmap = NULL;
|
|
}
|
|
|
|
if (backgroundItem->bWallpaper == TRUE)
|
|
{
|
|
pGlobalData->pWallpaperBitmap = DibLoadImage(backgroundItem->szFilename);
|
|
|
|
if (pGlobalData->pWallpaperBitmap == NULL)
|
|
return;
|
|
}
|
|
|
|
InvalidateRect(GetDlgItem(hwndDlg, IDC_BACKGROUND_PREVIEW),
|
|
NULL, TRUE);
|
|
|
|
EnableWindow(GetDlgItem(hwndDlg, IDC_PLACEMENT_COMBO),
|
|
backgroundItem->bWallpaper);
|
|
|
|
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
|
|
}
|
|
|
|
|
|
static VOID
|
|
DrawBackgroundPreview(LPDRAWITEMSTRUCT draw, PGLOBAL_DATA pGlobalData)
|
|
{
|
|
float scaleX;
|
|
float scaleY;
|
|
int scaledWidth;
|
|
int scaledHeight;
|
|
int posX;
|
|
int posY;
|
|
HBRUSH hBrush;
|
|
int x;
|
|
int y;
|
|
|
|
if (pGlobalData->backgroundItems[pGlobalData->backgroundSelection].bWallpaper == FALSE)
|
|
{
|
|
/* update desktop background color image */
|
|
hBrush = CreateSolidBrush(pGlobalData->backgroundDesktopColor);
|
|
FillRect(draw->hDC, &draw->rcItem, hBrush);
|
|
DeleteObject(hBrush);
|
|
return;
|
|
}
|
|
|
|
if (pGlobalData->pWallpaperBitmap == NULL)
|
|
return;
|
|
|
|
scaleX = ((float)GetSystemMetrics(SM_CXSCREEN) - 1) / (float)draw->rcItem.right;
|
|
scaleY = ((float)GetSystemMetrics(SM_CYSCREEN) - 1) / (float)draw->rcItem.bottom;
|
|
|
|
scaledWidth = pGlobalData->pWallpaperBitmap->width / scaleX;
|
|
scaledHeight = pGlobalData->pWallpaperBitmap->height / scaleY;
|
|
|
|
posX = (draw->rcItem.right / 2) - (scaledWidth / 2);
|
|
posY = (draw->rcItem.bottom / 2) - (scaledHeight / 2);
|
|
|
|
FillRect(draw->hDC, &draw->rcItem, GetSysColorBrush(COLOR_BACKGROUND));
|
|
|
|
SetStretchBltMode(draw->hDC, COLORONCOLOR);
|
|
|
|
switch (pGlobalData->placementSelection)
|
|
{
|
|
case PLACEMENT_CENTER:
|
|
StretchDIBits(draw->hDC,
|
|
posX,
|
|
posY,
|
|
scaledWidth,
|
|
scaledHeight,
|
|
0,
|
|
0,
|
|
pGlobalData->pWallpaperBitmap->width,
|
|
pGlobalData->pWallpaperBitmap->height,
|
|
pGlobalData->pWallpaperBitmap->bits,
|
|
pGlobalData->pWallpaperBitmap->info,
|
|
DIB_RGB_COLORS,
|
|
SRCCOPY);
|
|
break;
|
|
|
|
case PLACEMENT_STRETCH:
|
|
StretchDIBits(draw->hDC,
|
|
0,
|
|
0,
|
|
draw->rcItem.right,
|
|
draw->rcItem.bottom,
|
|
0,
|
|
0,
|
|
pGlobalData->pWallpaperBitmap->width,
|
|
pGlobalData->pWallpaperBitmap->height,
|
|
pGlobalData->pWallpaperBitmap->bits,
|
|
pGlobalData->pWallpaperBitmap->info,
|
|
DIB_RGB_COLORS,
|
|
SRCCOPY);
|
|
break;
|
|
|
|
case PLACEMENT_TILE:
|
|
for (y = 0; y < draw->rcItem.bottom; y += scaledHeight)
|
|
{
|
|
for (x = 0; x < draw->rcItem.right; x += scaledWidth)
|
|
{
|
|
StretchDIBits(draw->hDC,
|
|
x,
|
|
y,
|
|
scaledWidth,
|
|
scaledHeight,
|
|
0,
|
|
0,
|
|
pGlobalData->pWallpaperBitmap->width,
|
|
pGlobalData->pWallpaperBitmap->height,
|
|
pGlobalData->pWallpaperBitmap->bits,
|
|
pGlobalData->pWallpaperBitmap->info,
|
|
DIB_RGB_COLORS,
|
|
SRCCOPY);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
static VOID
|
|
SetWallpaper(PGLOBAL_DATA pGlobalData)
|
|
{
|
|
HKEY regKey;
|
|
|
|
RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Desktop"), 0, KEY_ALL_ACCESS, ®Key);
|
|
|
|
if (pGlobalData->placementSelection == PLACEMENT_TILE)
|
|
{
|
|
RegSetValueEx(regKey, TEXT("TileWallpaper"), 0, REG_SZ, (BYTE *)TEXT("1"), sizeof(TCHAR) * 2);
|
|
RegSetValueEx(regKey, TEXT("WallpaperStyle"), 0, REG_SZ, (BYTE *)TEXT("0"), sizeof(TCHAR) * 2);
|
|
}
|
|
|
|
if (pGlobalData->placementSelection == PLACEMENT_CENTER)
|
|
{
|
|
RegSetValueEx(regKey, TEXT("TileWallpaper"), 0, REG_SZ, (BYTE *)TEXT("0"), sizeof(TCHAR) * 2);
|
|
RegSetValueEx(regKey, TEXT("WallpaperStyle"), 0, REG_SZ, (BYTE *)TEXT("0"), sizeof(TCHAR) * 2);
|
|
}
|
|
|
|
if (pGlobalData->placementSelection == PLACEMENT_STRETCH)
|
|
{
|
|
RegSetValueEx(regKey, TEXT("TileWallpaper"), 0, REG_SZ, (BYTE *)TEXT("0"), sizeof(TCHAR) * 2);
|
|
RegSetValueEx(regKey, TEXT("WallpaperStyle"), 0, REG_SZ, (BYTE *)TEXT("2"), sizeof(TCHAR) * 2);
|
|
}
|
|
|
|
RegCloseKey(regKey);
|
|
|
|
if (pGlobalData->backgroundItems[pGlobalData->backgroundSelection].bWallpaper == TRUE)
|
|
{
|
|
SystemParametersInfo(SPI_SETDESKWALLPAPER,
|
|
0,
|
|
pGlobalData->backgroundItems[pGlobalData->backgroundSelection].szFilename,
|
|
SPIF_UPDATEINIFILE);
|
|
}
|
|
else
|
|
{
|
|
SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, (void*) TEXT(""), SPIF_UPDATEINIFILE);
|
|
}
|
|
}
|
|
|
|
|
|
/* Change system color */
|
|
static VOID
|
|
SetDesktopBackColor(HWND hwndDlg, PGLOBAL_DATA pGlobalData)
|
|
{
|
|
INT iElement = COLOR_BACKGROUND;
|
|
HKEY hKey;
|
|
LONG result;
|
|
TCHAR clText[16];
|
|
DWORD red, green, blue;
|
|
|
|
if( !SetSysColors( 1, &iElement, &pGlobalData->backgroundDesktopColor ) )
|
|
MessageBox(hwndDlg, TEXT("SetSysColor() failed!"), /* these error texts can need internationalization? */
|
|
TEXT("Error!"), MB_ICONSTOP );
|
|
/* Write color to registry key: HKEY_CURRENT_USER\Control Panel\Colors\Background */
|
|
hKey = NULL;
|
|
result = ERROR_SUCCESS;
|
|
result = RegOpenKeyEx( HKEY_CURRENT_USER, TEXT("Control Panel\\Colors"), 0, KEY_WRITE, &hKey );
|
|
if( result != ERROR_SUCCESS )
|
|
{
|
|
/* Key open failed; maybe it does not exist? create it! */
|
|
result = RegCreateKeyEx( HKEY_CURRENT_USER, TEXT("Control Panel\\Colors"), 0, NULL, 0,
|
|
KEY_ALL_ACCESS, NULL, &hKey, NULL );
|
|
/* Now key must be created and opened and hKey must point at newly created key */
|
|
/* On error result will not contain ERROR_SUCCESS. I don't know how to handle */
|
|
/* this case :( */
|
|
}
|
|
red = GetRValue(pGlobalData->backgroundDesktopColor);
|
|
green = GetGValue(pGlobalData->backgroundDesktopColor);
|
|
blue = GetBValue(pGlobalData->backgroundDesktopColor);
|
|
_stprintf(clText, TEXT("%d %d %d"), red, green, blue ); /* format string to be set to registry */
|
|
RegSetValueEx(hKey, TEXT("Background"), 0, REG_SZ, (BYTE *)clText, lstrlen( clText )*sizeof(TCHAR) + sizeof(TCHAR) );
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
|
|
INT_PTR CALLBACK
|
|
BackgroundPageProc(HWND hwndDlg,
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
PGLOBAL_DATA pGlobalData;
|
|
|
|
pGlobalData = (PGLOBAL_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
|
|
|
|
switch (uMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
pGlobalData = (GLOBAL_DATA*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(GLOBAL_DATA));
|
|
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pGlobalData);
|
|
InitBackgroundDialog(hwndDlg, pGlobalData);
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
{
|
|
DWORD controlId = LOWORD(wParam);
|
|
DWORD command = HIWORD(wParam);
|
|
|
|
switch (controlId)
|
|
{
|
|
case IDC_COLOR_BUTTON:
|
|
if (command == BN_CLICKED)
|
|
OnColorButton(hwndDlg, pGlobalData);
|
|
break;
|
|
|
|
case IDC_BROWSE_BUTTON:
|
|
if (command == BN_CLICKED)
|
|
OnBrowseButton(hwndDlg, pGlobalData);
|
|
break;
|
|
|
|
case IDC_PLACEMENT_COMBO:
|
|
if (command == CBN_SELCHANGE)
|
|
{
|
|
pGlobalData->placementSelection = (int)SendDlgItemMessage(hwndDlg, IDC_PLACEMENT_COMBO, CB_GETCURSEL, 0, 0);
|
|
|
|
InvalidateRect(GetDlgItem(hwndDlg, IDC_BACKGROUND_PREVIEW), NULL, TRUE);
|
|
|
|
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
|
|
}
|
|
break;
|
|
}
|
|
} break;
|
|
|
|
case WM_PAINT:
|
|
{
|
|
PAINTSTRUCT ps;
|
|
HDC hdc, hdcMem;
|
|
|
|
hdc = BeginPaint(hwndDlg, &ps);
|
|
|
|
hdcMem = CreateCompatibleDC(hdc);
|
|
SelectObject(hdcMem, pGlobalData->hBitmap);
|
|
/*
|
|
TransparentBlt(hdc, 98, 0,
|
|
pGlobalData->cxSource, pGlobalData->cySource, hdcMem, 0, 0,
|
|
pGlobalData->cxSource, pGlobalData->cySource, 0xFF80FF);
|
|
*/
|
|
DeleteDC(hdcMem);
|
|
EndPaint(hwndDlg, &ps);
|
|
}
|
|
break;
|
|
|
|
case WM_DRAWITEM:
|
|
{
|
|
LPDRAWITEMSTRUCT drawItem;
|
|
drawItem = (LPDRAWITEMSTRUCT)lParam;
|
|
|
|
if (drawItem->CtlID == IDC_BACKGROUND_PREVIEW)
|
|
{
|
|
DrawBackgroundPreview(drawItem, pGlobalData);
|
|
}
|
|
|
|
}
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
{
|
|
LPNMHDR lpnm = (LPNMHDR)lParam;
|
|
|
|
switch(lpnm->code)
|
|
{
|
|
case PSN_APPLY:
|
|
SetWallpaper(pGlobalData);
|
|
SetDesktopBackColor(hwndDlg, pGlobalData);
|
|
return TRUE;
|
|
|
|
case LVN_ITEMCHANGED:
|
|
{
|
|
LPNMLISTVIEW nm = (LPNMLISTVIEW)lParam;
|
|
|
|
if ((nm->uNewState & LVIS_SELECTED) == 0)
|
|
return FALSE;
|
|
|
|
ListViewItemChanged(hwndDlg, pGlobalData, nm->iItem);
|
|
|
|
} break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case WM_DESTROY:
|
|
if (pGlobalData->pWallpaperBitmap != NULL)
|
|
DibFreeImage(pGlobalData->pWallpaperBitmap);
|
|
|
|
DeleteObject(pGlobalData->hBitmap);
|
|
HeapFree(GetProcessHeap(), 0, pGlobalData);
|
|
break;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|