user: SetDesktopWallPaper() should call SystemParametersInfoA()
Andrew Ziem
ahziem1 at mailbolt.com
Thu Jul 20 09:18:55 CDT 2006
changelog:
user: SetDesktopWallPaper() should call SystemParametersInfoA()
This patch improves a previous patch[1] based on advice from Dmitry
Timoshkov[2].
[1] http://www.winehq.org/pipermail/wine-patches/2006-July/028761.html
[2] http://winehq.org/pipermail/wine-devel/2006-July/049640.html
This uncommited patch (which adds tests) is still valid:
http://www.winehq.org/pipermail/wine-patches/2006-July/028495.html
---
dlls/user/desktop.c | 169 --------------------------------------
dlls/user/sysparams.c | 217 ++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 215 insertions(+), 171 deletions(-)
diff --git a/dlls/user/desktop.c b/dlls/user/desktop.c
index 2252f99..212e339 100644
--- a/dlls/user/desktop.c
+++ b/dlls/user/desktop.c
@@ -33,10 +33,6 @@ #include "wingdi.h"
#include "controls.h"
#include "wine/winuser16.h"
-static HBRUSH hbrushPattern;
-static HBITMAP hbitmapWallPaper;
-static SIZE bitmapSize;
-static BOOL fTileWallPaper;
static LRESULT WINAPI DesktopWndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam );
@@ -56,60 +52,6 @@ const struct builtin_class_descr DESKTOP
};
-/***********************************************************************
- * DESKTOP_LoadBitmap
- *
- * Load a bitmap from a file. Used by SetDeskWallPaper().
- */
-static HBITMAP DESKTOP_LoadBitmap( HDC hdc, const char *filename )
-{
- BITMAPFILEHEADER *fileHeader;
- BITMAPINFO *bitmapInfo;
- HBITMAP hbitmap;
- HFILE file;
- LPSTR buffer;
- LONG size;
-
- /* Read all the file into memory */
-
- if ((file = _lopen( filename, OF_READ )) == HFILE_ERROR)
- {
- UINT len = GetWindowsDirectoryA( NULL, 0 );
- if (!(buffer = HeapAlloc( GetProcessHeap(), 0,
- len + strlen(filename) + 2 )))
- return 0;
- GetWindowsDirectoryA( buffer, len + 1 );
- strcat( buffer, "\\" );
- strcat( buffer, filename );
- file = _lopen( buffer, OF_READ );
- HeapFree( GetProcessHeap(), 0, buffer );
- }
- if (file == HFILE_ERROR) return 0;
- size = _llseek( file, 0, 2 );
- if (!(buffer = HeapAlloc( GetProcessHeap(), 0, size )))
- {
- _lclose( file );
- return 0;
- }
- _llseek( file, 0, 0 );
- size = _lread( file, buffer, size );
- _lclose( file );
- fileHeader = (BITMAPFILEHEADER *)buffer;
- bitmapInfo = (BITMAPINFO *)(buffer + sizeof(BITMAPFILEHEADER));
-
- /* Check header content */
- if ((fileHeader->bfType != 0x4d42) || (size < fileHeader->bfSize))
- {
- HeapFree( GetProcessHeap(), 0, buffer );
- return 0;
- }
- hbitmap = CreateDIBitmap( hdc, &bitmapInfo->bmiHeader, CBM_INIT,
- buffer + fileHeader->bfOffBits,
- bitmapInfo, DIB_RGB_COLORS );
- HeapFree( GetProcessHeap(), 0, buffer );
- return hbitmap;
-}
-
/***********************************************************************
@@ -121,62 +63,6 @@ static LRESULT WINAPI DesktopWndProc( HW
return 0; /* all other messages are ignored */
}
-/***********************************************************************
- * PaintDesktop (USER32.@)
- *
- */
-BOOL WINAPI PaintDesktop(HDC hdc)
-{
- HWND hwnd = GetDesktopWindow();
-
- /* check for an owning thread; otherwise don't paint anything (non-desktop mode) */
- if (GetWindowThreadProcessId( hwnd, NULL ))
- {
- RECT rect;
-
- GetClientRect( hwnd, &rect );
-
- /* Paint desktop pattern (only if wall paper does not cover everything) */
-
- if (!hbitmapWallPaper ||
- (!fTileWallPaper && ((bitmapSize.cx < rect.right) || (bitmapSize.cy < rect.bottom))))
- {
- HBRUSH brush = hbrushPattern;
- if (!brush) brush = (HBRUSH)GetClassLongPtrW( hwnd, GCLP_HBRBACKGROUND );
- /* Set colors in case pattern is a monochrome bitmap */
- SetBkColor( hdc, RGB(0,0,0) );
- SetTextColor( hdc, GetSysColor(COLOR_BACKGROUND) );
- FillRect( hdc, &rect, brush );
- }
-
- /* Paint wall paper */
-
- if (hbitmapWallPaper)
- {
- INT x, y;
- HDC hMemDC = CreateCompatibleDC( hdc );
-
- SelectObject( hMemDC, hbitmapWallPaper );
-
- if (fTileWallPaper)
- {
- for (y = 0; y < rect.bottom; y += bitmapSize.cy)
- for (x = 0; x < rect.right; x += bitmapSize.cx)
- BitBlt( hdc, x, y, bitmapSize.cx, bitmapSize.cy, hMemDC, 0, 0, SRCCOPY );
- }
- else
- {
- x = (rect.left + rect.right - bitmapSize.cx) / 2;
- y = (rect.top + rect.bottom - bitmapSize.cy) / 2;
- if (x < 0) x = 0;
- if (y < 0) y = 0;
- BitBlt( hdc, x, y, bitmapSize.cx, bitmapSize.cy, hMemDC, 0, 0, SRCCOPY );
- }
- DeleteDC( hMemDC );
- }
- }
- return TRUE;
-}
/***********************************************************************
* OldSetDeskPattern (USER.279)
@@ -203,61 +89,8 @@ BOOL16 WINAPI SetDeskWallPaper16( LPCSTR
*/
BOOL WINAPI SetDeskWallPaper( LPCSTR filename )
{
- HBITMAP hbitmap;
- HDC hdc;
- char buffer[256];
-
- if (filename == (LPSTR)-1)
- {
- GetProfileStringA( "desktop", "WallPaper", "(None)", buffer, 256 );
- filename = buffer;
- }
- hdc = GetDC( 0 );
- hbitmap = DESKTOP_LoadBitmap( hdc, filename );
- ReleaseDC( 0, hdc );
- if (hbitmapWallPaper) DeleteObject( hbitmapWallPaper );
- hbitmapWallPaper = hbitmap;
- fTileWallPaper = GetProfileIntA( "desktop", "TileWallPaper", 0 );
- if (hbitmap)
- {
- BITMAP bmp;
- GetObjectA( hbitmap, sizeof(bmp), &bmp );
- bitmapSize.cx = (bmp.bmWidth != 0) ? bmp.bmWidth : 1;
- bitmapSize.cy = (bmp.bmHeight != 0) ? bmp.bmHeight : 1;
- }
- return TRUE;
+ return SystemParametersInfoA( SPI_SETDESKWALLPAPER, 0, (PVOID)filename, 0 );
}
-/***********************************************************************
- * DESKTOP_SetPattern
- *
- * Set the desktop pattern.
- */
-BOOL DESKTOP_SetPattern( LPCWSTR pattern )
-{
- int pat[8];
-
- if (hbrushPattern) DeleteObject( hbrushPattern );
- hbrushPattern = 0;
- memset( pat, 0, sizeof(pat) );
- if (pattern)
- {
- char buffer[64];
- WideCharToMultiByte( CP_ACP, 0, pattern, -1, buffer, sizeof(buffer), NULL, NULL );
- if (sscanf( buffer, " %d %d %d %d %d %d %d %d",
- &pat[0], &pat[1], &pat[2], &pat[3],
- &pat[4], &pat[5], &pat[6], &pat[7] ))
- {
- WORD pattern[8];
- HBITMAP hbitmap;
- int i;
- for (i = 0; i < 8; i++) pattern[i] = pat[i] & 0xffff;
- hbitmap = CreateBitmap( 8, 8, 1, 1, (LPSTR)pattern );
- hbrushPattern = CreatePatternBrush( hbitmap );
- DeleteObject( hbitmap );
- }
- }
- return TRUE;
-}
diff --git a/dlls/user/sysparams.c b/dlls/user/sysparams.c
index de0677f..2cb4415 100644
--- a/dlls/user/sysparams.c
+++ b/dlls/user/sysparams.c
@@ -355,6 +355,11 @@ static const WORD wPattern55AA[] = { 0x5
HBRUSH SYSCOLOR_55AABrush = 0;
+static HBRUSH hbrushPattern;
+static HBITMAP hbitmapWallPaper; /* desktop wallpaper */
+static SIZE bitmapSize; /* size of desktop wallpaper */
+static BOOL fTileWallPaper;
+
extern void __wine_make_gdi_object_system( HGDIOBJ handle, BOOL set );
@@ -744,6 +749,169 @@ static void SYSPARAMS_SetSysColor( int i
__wine_make_gdi_object_system( SysColorPens[index], TRUE);
}
+
+
+/***********************************************************************
+ * SYSPARAMS_LoadBitmap
+ *
+ * Load a bitmap from a file. Used by
+ * SystemParametersInfoW(SPI_SETDESKWALLPAPER,...)
+ */
+static HBITMAP SYSPARAMS_LoadBitmap( HDC hdc, LPCWSTR filename )
+{
+ BITMAPFILEHEADER *fileHeader;
+ BITMAPINFO *bitmapInfo;
+ HBITMAP hbitmap;
+ DWORD size;
+ HANDLE hFile;
+ LPBYTE bmimage;
+ HANDLE fmapping;
+ const WCHAR slash[] = { '\\', 0 };
+
+ /* Read all the file into memory */
+ hFile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
+ if (INVALID_HANDLE_VALUE == hFile)
+ {
+ /* also look in Windows directory */
+ LPWSTR buffer;
+ UINT len = GetWindowsDirectoryW( NULL, 0 );
+ if (!(buffer = HeapAlloc( GetProcessHeap(), 0,
+ sizeof(WCHAR) * (len + lstrlenW(filename) + 2 ))))
+ return NULL;
+ GetWindowsDirectoryW( buffer, (len + 1) );
+ lstrcatW( buffer, slash );
+ lstrcatW( buffer, filename );
+ hFile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
+ HeapFree( GetProcessHeap(), 0, buffer );
+ }
+ if (INVALID_HANDLE_VALUE == hFile)
+ return NULL;
+
+ size = GetFileSize(hFile, NULL);
+
+ /* Map the file */
+ fmapping = CreateFileMappingW(hFile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL);
+ CloseHandle(hFile);
+ if (!fmapping)
+ {
+ WARN("CreateFileMapping error %ld\n", GetLastError() );
+ return NULL;
+ }
+
+ if (!(bmimage = MapViewOfFile(fmapping, FILE_MAP_READ, 0, 0, 0)))
+ {
+ WARN("MapViewOfFile error %ld\n", GetLastError() );
+ CloseHandle(fmapping);
+ return NULL;
+ }
+ CloseHandle(fmapping);
+
+ fileHeader = (BITMAPFILEHEADER *)bmimage;
+ bitmapInfo = (BITMAPINFO *)(bmimage + sizeof(BITMAPFILEHEADER));
+
+ /* Check header content */
+ if ((fileHeader->bfType != 0x4d42) || (size < fileHeader->bfSize))
+ {
+ UnmapViewOfFile(bmimage);
+ return 0;
+ }
+ hbitmap = CreateDIBitmap( hdc, &bitmapInfo->bmiHeader, CBM_INIT,
+ bmimage + fileHeader->bfOffBits,
+ bitmapInfo, DIB_RGB_COLORS );
+ UnmapViewOfFile(bmimage);
+ return hbitmap;
+}
+
+/***********************************************************************
+ * PaintDesktop (USER32.@)
+ *
+ */
+BOOL WINAPI PaintDesktop(HDC hdc)
+{
+ HWND hwnd = GetDesktopWindow();
+
+ /* check for an owning thread; otherwise don't paint anything (non-desktop mode) */
+ if (GetWindowThreadProcessId( hwnd, NULL ))
+ {
+ RECT rect;
+
+ GetClientRect( hwnd, &rect );
+
+ /* Paint desktop pattern (only if wall paper does not cover everything) */
+
+ if (!hbitmapWallPaper ||
+ (!fTileWallPaper && ((bitmapSize.cx < rect.right) || (bitmapSize.cy < rect.bottom))))
+ {
+ HBRUSH brush = hbrushPattern;
+ if (!brush) brush = (HBRUSH)GetClassLongPtrW( hwnd, GCLP_HBRBACKGROUND );
+ /* Set colors in case pattern is a monochrome bitmap */
+ SetBkColor( hdc, RGB(0,0,0) );
+ SetTextColor( hdc, GetSysColor(COLOR_BACKGROUND) );
+ FillRect( hdc, &rect, brush );
+ }
+
+ /* Paint wall paper */
+
+ if (hbitmapWallPaper)
+ {
+ INT x, y;
+ HDC hMemDC = CreateCompatibleDC( hdc );
+
+ SelectObject( hMemDC, hbitmapWallPaper );
+
+ if (fTileWallPaper)
+ {
+ for (y = 0; y < rect.bottom; y += bitmapSize.cy)
+ for (x = 0; x < rect.right; x += bitmapSize.cx)
+ BitBlt( hdc, x, y, bitmapSize.cx, bitmapSize.cy, hMemDC, 0, 0, SRCCOPY );
+ }
+ else
+ {
+ x = (rect.left + rect.right - bitmapSize.cx) / 2;
+ y = (rect.top + rect.bottom - bitmapSize.cy) / 2;
+ if (x < 0) x = 0;
+ if (y < 0) y = 0;
+ BitBlt( hdc, x, y, bitmapSize.cx, bitmapSize.cy, hMemDC, 0, 0, SRCCOPY );
+ }
+ DeleteDC( hMemDC );
+ }
+ }
+ return TRUE;
+}
+
+/***********************************************************************
+ * SYSPARAMS_SetPattern
+ *
+ * Set the desktop pattern.
+ */
+BOOL SYSPARAMS_SetPattern( LPCWSTR pattern )
+{
+ int pat[8];
+
+ if (hbrushPattern) DeleteObject( hbrushPattern );
+ hbrushPattern = 0;
+ memset( pat, 0, sizeof(pat) );
+ if (pattern)
+ {
+ char buffer[64];
+ WideCharToMultiByte( CP_ACP, 0, pattern, -1, buffer, sizeof(buffer), NULL, NULL );
+ if (sscanf( buffer, " %d %d %d %d %d %d %d %d",
+ &pat[0], &pat[1], &pat[2], &pat[3],
+ &pat[4], &pat[5], &pat[6], &pat[7] ))
+ {
+ WORD pattern[8];
+ HBITMAP hbitmap;
+ int i;
+
+ for (i = 0; i < 8; i++) pattern[i] = pat[i] & 0xffff;
+ hbitmap = CreateBitmap( 8, 8, 1, 1, (LPSTR)pattern );
+ hbrushPattern = CreatePatternBrush( hbitmap );
+ DeleteObject( hbitmap );
+ }
+ }
+ return TRUE;
+}
+
/* load a uint parameter from the registry */
static BOOL get_uint_param( unsigned int idx, LPCWSTR regkey, LPCWSTR value,
UINT *value_ptr, UINT *ret_ptr )
@@ -1314,8 +1482,49 @@ #define WINE_SPI_WARN(x) \
break;
case SPI_SETDESKWALLPAPER: /* 20 */
- if (!pvParam || !SetDeskWallPaper( (LPSTR)pvParam )) return FALSE;
+ {
+ HBITMAP hbitmap;
+ HDC hdc;
+ WCHAR buffer[MAX_PATH];
+ const WCHAR desktop[] = {'d','e','s','k','t','o','p',0};
+ const WCHAR WallPaper[] = {'W','a','l','l','P','a','p','e','r',0};
+ const WCHAR None[] = {'(','n','o','n','e',')',0};
+ const WCHAR TileWallPaper[] = {'T','i','l','e','W','a','l','l','P','a','p','e','r',0};
+ int def = 0;
+
+ if ((LPCWSTR)NULL == pvParam || (LPCWSTR)SETWALLPAPER_DEFAULT == pvParam)
+ {
+ /* revert to default wallpaper */
+ GetProfileStringW( desktop, WallPaper, None, buffer, MAX_PATH );
+ pvParam = buffer;
+ def = 1;
+ }
+ else if ('\0' == ((LPCWSTR)pvParam)[0])
+ {
+ /* remove wallpaper*/
+ if (hbitmapWallPaper)
+ DeleteObject( hbitmapWallPaper );
+ SYSPARAMS_Save(SPI_SETDESKWALLPAPER_REGKEY, SPI_SETDESKWALLPAPER_VALNAME, pvParam, fWinIni);
+ return TRUE;
+ }
+
+ hdc = GetDC( 0 );
+ hbitmap = SYSPARAMS_LoadBitmap( hdc, pvParam );
+ ReleaseDC( 0, hdc );
+ if (hbitmapWallPaper)
+ DeleteObject( hbitmapWallPaper );
+ hbitmapWallPaper = hbitmap;
+ fTileWallPaper = GetProfileIntW( desktop, TileWallPaper, 0 );
+ if (hbitmap)
+ {
+ BITMAP bmp;
+ GetObjectW( hbitmap, sizeof(bmp), &bmp );
+ bitmapSize.cx = (bmp.bmWidth != 0) ? bmp.bmWidth : 1;
+ bitmapSize.cy = (bmp.bmHeight != 0) ? bmp.bmHeight : 1;
+ }
SYSPARAMS_Save(SPI_SETDESKWALLPAPER_REGKEY, SPI_SETDESKWALLPAPER_VALNAME, pvParam, fWinIni);
+ return ( 0 != hbitmap || def );
+ }
break;
case SPI_SETDESKPATTERN: /* 21 */
@@ -1327,9 +1536,9 @@ #define WINE_SPI_WARN(x) \
GetProfileStringW( Desktop, Pattern,
defPattern,
buf, sizeof(buf)/sizeof(WCHAR) );
- ret = DESKTOP_SetPattern( buf );
+ ret = SYSPARAMS_SetPattern( buf );
} else
- ret = DESKTOP_SetPattern( (LPWSTR)pvParam );
+ ret = SYSPARAMS_SetPattern( (LPWSTR)pvParam );
break;
case SPI_GETKEYBOARDDELAY:
@@ -2387,6 +2596,8 @@ BOOL WINAPI SystemParametersInfoA( UINT
switch (uiAction)
{
case SPI_SETDESKWALLPAPER: /* 20 */
+ if ((LPCSTR)SETWALLPAPER_DEFAULT == pvParam)
+ pvParam = NULL;
case SPI_SETDESKPATTERN: /* 21 */
{
WCHAR buffer[256];
--
1.4.0
More information about the wine-patches
mailing list