user: SetDesktopWallPaper() should call SystemParametersInfoA()

Andrew Ziem ahziem1 at mailbolt.com
Mon Jul 17 09:42:32 CDT 2006


This patch is based on advice from Alexandre Julliard regarding
a previous patch.

This uncommited patch (which adds tests) is still valid:
http://www.winehq.org/pipermail/wine-patches/2006-July/028495.html
---
 dlls/user/desktop.c      |   84 ++-------------------------------
 dlls/user/sysparams.c    |  118 ++++++++++++++++++++++++++++++++++++++++++++++
 dlls/user/user_private.h |    4 ++
 3 files changed, 125 insertions(+), 81 deletions(-)

diff --git a/dlls/user/desktop.c b/dlls/user/desktop.c
index 2252f99..ae1a7e6 100644
--- a/dlls/user/desktop.c
+++ b/dlls/user/desktop.c
@@ -34,9 +34,9 @@ #include "controls.h"
 #include "wine/winuser16.h"
 
 static HBRUSH hbrushPattern;
-static HBITMAP hbitmapWallPaper;
-static SIZE bitmapSize;
-static BOOL fTileWallPaper;
+HBITMAP hbitmapWallPaper; /* desktop wallpaper */
+SIZE bitmapSize; /* size of desktop wallpaper */
+BOOL fTileWallPaper;
 
 static LRESULT WINAPI DesktopWndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam );
 
@@ -56,60 +56,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;
-}
-
 
 
 /***********************************************************************
@@ -203,29 +149,7 @@ 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 );
 }
 
 
diff --git a/dlls/user/sysparams.c b/dlls/user/sysparams.c
index de0677f..521a4b9 100644
--- a/dlls/user/sysparams.c
+++ b/dlls/user/sysparams.c
@@ -744,6 +744,79 @@ 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;
+}
+
 /* 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 +1387,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 */
@@ -2387,6 +2501,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];
diff --git a/dlls/user/user_private.h b/dlls/user/user_private.h
index ffb2796..ef6e2cb 100644
--- a/dlls/user/user_private.h
+++ b/dlls/user/user_private.h
@@ -280,4 +280,8 @@ #include "poppack.h"
 
 extern void CURSORICON_FreeModuleIcons( HMODULE16 hModule );
 
+extern HBITMAP hbitmapWallPaper;
+extern BOOL fTileWallPaper;
+extern SIZE bitmapSize;
+
 #endif /* __WINE_USER_PRIVATE_H */
-- 
1.4.0




More information about the wine-patches mailing list