/* $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; }