2 * Desktop window class.
4 * Copyright 1994 Alexandre Julliard
17 #include "wine/winuser16.h"
20 /***********************************************************************
23 * Load a bitmap from a file. Used by SetDeskWallPaper().
25 static HBITMAP
DESKTOP_LoadBitmap( HDC hdc
, const char *filename
)
27 BITMAPFILEHEADER
*fileHeader
;
28 BITMAPINFO
*bitmapInfo
;
34 /* Read all the file into memory */
36 if ((file
= _lopen( filename
, OF_READ
)) == HFILE_ERROR
)
38 UINT len
= GetWindowsDirectoryA( NULL
, 0 );
39 if (!(buffer
= HeapAlloc( GetProcessHeap(), 0,
40 len
+ strlen(filename
) + 2 )))
42 GetWindowsDirectoryA( buffer
, len
+ 1 );
43 strcat( buffer
, "\\" );
44 strcat( buffer
, filename
);
45 file
= _lopen( buffer
, OF_READ
);
46 HeapFree( GetProcessHeap(), 0, buffer
);
48 if (file
== HFILE_ERROR
) return 0;
49 size
= _llseek( file
, 0, 2 );
50 if (!(buffer
= HeapAlloc( GetProcessHeap(), 0, size
)))
55 _llseek( file
, 0, 0 );
56 size
= _lread( file
, buffer
, size
);
58 fileHeader
= (BITMAPFILEHEADER
*)buffer
;
59 bitmapInfo
= (BITMAPINFO
*)(buffer
+ sizeof(BITMAPFILEHEADER
));
61 /* Check header content */
62 if ((fileHeader
->bfType
!= 0x4d42) || (size
< fileHeader
->bfSize
))
64 HeapFree( GetProcessHeap(), 0, buffer
);
67 hbitmap
= CreateDIBitmap( hdc
, &bitmapInfo
->bmiHeader
, CBM_INIT
,
68 buffer
+ fileHeader
->bfOffBits
,
69 bitmapInfo
, DIB_RGB_COLORS
);
70 HeapFree( GetProcessHeap(), 0, buffer
);
75 /***********************************************************************
76 * DESKTOP_DoEraseBkgnd
78 * Handle the WM_ERASEBKGND message.
80 static LRESULT
DESKTOP_DoEraseBkgnd( HWND hwnd
, HDC hdc
,
84 WND
* Wnd
= WIN_FindWndPtr( hwnd
);
86 if (Wnd
->hrgnUpdate
> 1) DeleteObject( Wnd
->hrgnUpdate
);
89 WIN_ReleaseWndPtr(Wnd
);
91 GetClientRect( hwnd
, &rect
);
93 /* Paint desktop pattern (only if wall paper does not cover everything) */
95 if (!desktopPtr
->hbitmapWallPaper
||
96 (!desktopPtr
->fTileWallPaper
&& ((desktopPtr
->bitmapSize
.cx
< rect
.right
) ||
97 (desktopPtr
->bitmapSize
.cy
< rect
.bottom
))))
99 /* Set colors in case pattern is a monochrome bitmap */
100 SetBkColor( hdc
, RGB(0,0,0) );
101 SetTextColor( hdc
, GetSysColor(COLOR_BACKGROUND
) );
102 FillRect( hdc
, &rect
, desktopPtr
->hbrushPattern
);
105 /* Paint wall paper */
107 if (desktopPtr
->hbitmapWallPaper
)
110 HDC hMemDC
= CreateCompatibleDC( hdc
);
112 SelectObject( hMemDC
, desktopPtr
->hbitmapWallPaper
);
114 if (desktopPtr
->fTileWallPaper
)
116 for (y
= 0; y
< rect
.bottom
; y
+= desktopPtr
->bitmapSize
.cy
)
117 for (x
= 0; x
< rect
.right
; x
+= desktopPtr
->bitmapSize
.cx
)
118 BitBlt( hdc
, x
, y
, desktopPtr
->bitmapSize
.cx
,
119 desktopPtr
->bitmapSize
.cy
, hMemDC
, 0, 0, SRCCOPY
);
123 x
= (rect
.left
+ rect
.right
- desktopPtr
->bitmapSize
.cx
) / 2;
124 y
= (rect
.top
+ rect
.bottom
- desktopPtr
->bitmapSize
.cy
) / 2;
127 BitBlt( hdc
, x
, y
, desktopPtr
->bitmapSize
.cx
,
128 desktopPtr
->bitmapSize
.cy
, hMemDC
, 0, 0, SRCCOPY
);
137 /***********************************************************************
138 * DesktopWndProc_locked
140 * Window procedure for the desktop window.
142 static inline LRESULT WINAPI
DesktopWndProc_locked( WND
*wndPtr
, UINT message
,
143 WPARAM wParam
, LPARAM lParam
)
145 DESKTOP
*desktopPtr
= (DESKTOP
*)wndPtr
->wExtra
;
146 HWND hwnd
= wndPtr
->hwndSelf
;
148 /* Most messages are ignored (we DON'T call DefWindowProc) */
152 /* Warning: this message is sent directly by */
153 /* WIN_CreateDesktopWindow() and does not contain a valid lParam */
155 desktopPtr
->hbrushPattern
= 0;
156 desktopPtr
->hbitmapWallPaper
= 0;
158 SetDeskWallPaper( (LPSTR
)-1 );
162 if(!USER_Driver
.pIsSingleWindow())
164 return DESKTOP_DoEraseBkgnd( hwnd
, (HDC
)wParam
, desktopPtr
);
167 if ((wParam
& 0xfff0) != SC_CLOSE
)
169 ExitWindows16( 0, 0 );
172 return (LRESULT
)SetCursor16( LoadCursor16( 0, IDC_ARROW16
) );
178 /***********************************************************************
181 * This is just a wrapper for the DesktopWndProc which does windows
182 * locking and unlocking.
184 LRESULT WINAPI
DesktopWndProc( HWND hwnd
, UINT message
,
185 WPARAM wParam
, LPARAM lParam
)
187 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
188 LRESULT retvalue
= DesktopWndProc_locked(wndPtr
,message
,wParam
,lParam
);
190 WIN_ReleaseWndPtr(wndPtr
);
194 /***********************************************************************
195 * PaintDesktop (USER32.415)
198 BOOL WINAPI
PaintDesktop(HDC hdc
)
201 HWND hwnd
= GetDesktopWindow();
202 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
203 DESKTOP
*desktopPtr
= (DESKTOP
*)wndPtr
->wExtra
;
204 retvalue
= DESKTOP_DoEraseBkgnd( hwnd
, hdc
, desktopPtr
);
205 WIN_ReleaseWndPtr(wndPtr
);
210 /***********************************************************************
211 * SetDeskPattern (USER.279)
213 BOOL16 WINAPI
SetDeskPattern(void)
216 GetProfileStringA( "desktop", "Pattern", "(None)", buffer
, 100 );
217 return DESKTOP_SetPattern( buffer
);
221 /***********************************************************************
222 * SetDeskWallPaper16 (USER.285)
224 BOOL16 WINAPI
SetDeskWallPaper16( LPCSTR filename
)
226 return SetDeskWallPaper( filename
);
230 /***********************************************************************
231 * SetDeskWallPaper (USER32.475)
233 * FIXME: is there a unicode version?
235 BOOL WINAPI
SetDeskWallPaper( LPCSTR filename
)
240 WND
*wndPtr
= WIN_GetDesktop();
241 DESKTOP
*desktopPtr
= (DESKTOP
*)wndPtr
->wExtra
;
243 if (filename
== (LPSTR
)-1)
245 GetProfileStringA( "desktop", "WallPaper", "(None)", buffer
, 256 );
249 hbitmap
= DESKTOP_LoadBitmap( hdc
, filename
);
251 if (desktopPtr
->hbitmapWallPaper
) DeleteObject( desktopPtr
->hbitmapWallPaper
);
252 desktopPtr
->hbitmapWallPaper
= hbitmap
;
253 desktopPtr
->fTileWallPaper
= GetProfileIntA( "desktop", "TileWallPaper", 0 );
257 GetObjectA( hbitmap
, sizeof(bmp
), &bmp
);
258 desktopPtr
->bitmapSize
.cx
= (bmp
.bmWidth
!= 0) ? bmp
.bmWidth
: 1;
259 desktopPtr
->bitmapSize
.cy
= (bmp
.bmHeight
!= 0) ? bmp
.bmHeight
: 1;
261 WIN_ReleaseDesktop();
266 /***********************************************************************
269 * Set the desktop pattern.
271 BOOL
DESKTOP_SetPattern( LPCSTR pattern
)
273 WND
*wndPtr
= WIN_GetDesktop();
274 DESKTOP
*desktopPtr
= (DESKTOP
*)wndPtr
->wExtra
;
277 if (desktopPtr
->hbrushPattern
) DeleteObject( desktopPtr
->hbrushPattern
);
278 memset( pat
, 0, sizeof(pat
) );
279 if (pattern
&& sscanf( pattern
, " %d %d %d %d %d %d %d %d",
280 &pat
[0], &pat
[1], &pat
[2], &pat
[3],
281 &pat
[4], &pat
[5], &pat
[6], &pat
[7] ))
287 for (i
= 0; i
< 8; i
++) pattern
[i
] = pat
[i
] & 0xffff;
288 hbitmap
= CreateBitmap( 8, 8, 1, 1, (LPSTR
)pattern
);
289 desktopPtr
->hbrushPattern
= CreatePatternBrush( hbitmap
);
290 DeleteObject( hbitmap
);
292 else desktopPtr
->hbrushPattern
= CreateSolidBrush( GetSysColor(COLOR_BACKGROUND
) );
293 WIN_ReleaseDesktop();