3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS user32.dll
5 * FILE: lib/user32/misc/desktop.c
7 * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
9 * 06-06-2001 CSH Created
14 #include <wine/debug.h>
15 WINE_DEFAULT_DEBUG_CHANNEL(user32
);
17 #define DESKTOP_CLASS_ATOM MAKEINTATOMA(32769) /* Desktop */
18 static LRESULT WINAPI
DesktopWndProc( HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
);
20 /*********************************************************************
21 * desktop class descriptor
23 const struct builtin_class_descr DESKTOP_builtin_class
=
25 (LPCWSTR
) DESKTOP_CLASS_ATOM
, /* name */
26 CS_DBLCLKS
, /* style */
27 NULL
, /* procA (winproc is Unicode only) */
28 (WNDPROC
) DesktopWndProc
, /* procW */
30 IDC_ARROW
, /* cursor */
31 (HBRUSH
)(COLOR_BACKGROUND
+1) /* brush */
37 DesktopWndProc( HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
39 FIXME("Desktop Class Atom!\n");
40 if (message
== WM_NCCREATE
) return TRUE
;
41 return 0; /* all other messages are ignored */
46 LogFontA2W(LPLOGFONTW pW
, CONST LOGFONTA
*pA
)
48 #define COPYS(f,len) MultiByteToWideChar ( CP_THREAD_ACP, 0, pA->f, len, pW->f, len )
49 #define COPYN(f) pW->f = pA->f
60 COPYN(lfOutPrecision
);
61 COPYN(lfClipPrecision
);
63 COPYN(lfPitchAndFamily
);
64 COPYS(lfFaceName
,LF_FACESIZE
);
72 LogFontW2A(LPLOGFONTA pA
, CONST LOGFONTW
*pW
)
74 #define COPYS(f,len) WideCharToMultiByte ( CP_THREAD_ACP, 0, pW->f, len, pA->f, len, NULL, NULL )
75 #define COPYN(f) pA->f = pW->f
86 COPYN(lfOutPrecision
);
87 COPYN(lfClipPrecision
);
89 COPYN(lfPitchAndFamily
);
90 COPYS(lfFaceName
,LF_FACESIZE
);
100 GetSystemMetrics(int nIndex
)
103 // FIXME("Global Sever Data -> %x\n",g_psi);
104 if (nIndex
< 0 || nIndex
>= SM_CMETRICS
) return 0;
105 return g_psi
->SystemMetrics
[nIndex
];
112 BOOL WINAPI
SetDeskWallpaper(LPCSTR filename
)
114 return SystemParametersInfoA(SPI_SETDESKWALLPAPER
,0,(PVOID
)filename
,TRUE
);
120 SystemParametersInfoA(UINT uiAction
,
127 case SPI_GETHIGHCONTRAST
:
128 case SPI_SETHIGHCONTRAST
:
129 case SPI_GETSOUNDSENTRY
:
130 case SPI_SETSOUNDSENTRY
:
132 /* FIXME: Support this accessibility SPI actions */
133 FIXME("FIXME: Unsupported SPI Code: %lx \n",uiAction
);
137 case SPI_GETNONCLIENTMETRICS
:
139 LPNONCLIENTMETRICSA pnclma
= (LPNONCLIENTMETRICSA
)pvParam
;
140 NONCLIENTMETRICSW nclmw
;
141 if(pnclma
->cbSize
!= sizeof(NONCLIENTMETRICSA
))
143 SetLastError(ERROR_INVALID_PARAMETER
);
146 nclmw
.cbSize
= sizeof(NONCLIENTMETRICSW
);
148 if (!SystemParametersInfoW(uiAction
, sizeof(NONCLIENTMETRICSW
),
152 pnclma
->iBorderWidth
= nclmw
.iBorderWidth
;
153 pnclma
->iScrollWidth
= nclmw
.iScrollWidth
;
154 pnclma
->iScrollHeight
= nclmw
.iScrollHeight
;
155 pnclma
->iCaptionWidth
= nclmw
.iCaptionWidth
;
156 pnclma
->iCaptionHeight
= nclmw
.iCaptionHeight
;
157 pnclma
->iSmCaptionWidth
= nclmw
.iSmCaptionWidth
;
158 pnclma
->iSmCaptionHeight
= nclmw
.iSmCaptionHeight
;
159 pnclma
->iMenuWidth
= nclmw
.iMenuWidth
;
160 pnclma
->iMenuHeight
= nclmw
.iMenuHeight
;
161 LogFontW2A(&(pnclma
->lfCaptionFont
), &(nclmw
.lfCaptionFont
));
162 LogFontW2A(&(pnclma
->lfSmCaptionFont
), &(nclmw
.lfSmCaptionFont
));
163 LogFontW2A(&(pnclma
->lfMenuFont
), &(nclmw
.lfMenuFont
));
164 LogFontW2A(&(pnclma
->lfStatusFont
), &(nclmw
.lfStatusFont
));
165 LogFontW2A(&(pnclma
->lfMessageFont
), &(nclmw
.lfMessageFont
));
168 case SPI_SETNONCLIENTMETRICS
:
170 LPNONCLIENTMETRICSA pnclma
= (LPNONCLIENTMETRICSA
)pvParam
;
171 NONCLIENTMETRICSW nclmw
;
172 if(pnclma
->cbSize
!= sizeof(NONCLIENTMETRICSA
))
174 SetLastError(ERROR_INVALID_PARAMETER
);
177 nclmw
.cbSize
= sizeof(NONCLIENTMETRICSW
);
178 nclmw
.iBorderWidth
= pnclma
->iBorderWidth
;
179 nclmw
.iScrollWidth
= pnclma
->iScrollWidth
;
180 nclmw
.iScrollHeight
= pnclma
->iScrollHeight
;
181 nclmw
.iCaptionWidth
= pnclma
->iCaptionWidth
;
182 nclmw
.iCaptionHeight
= pnclma
->iCaptionHeight
;
183 nclmw
.iSmCaptionWidth
= pnclma
->iSmCaptionWidth
;
184 nclmw
.iSmCaptionHeight
= pnclma
->iSmCaptionHeight
;
185 nclmw
.iMenuWidth
= pnclma
->iMenuWidth
;
186 nclmw
.iMenuHeight
= pnclma
->iMenuHeight
;
187 LogFontA2W(&(nclmw
.lfCaptionFont
), &(pnclma
->lfCaptionFont
));
188 LogFontA2W(&(nclmw
.lfSmCaptionFont
), &(pnclma
->lfSmCaptionFont
));
189 LogFontA2W(&(nclmw
.lfMenuFont
), &(pnclma
->lfMenuFont
));
190 LogFontA2W(&(nclmw
.lfStatusFont
), &(pnclma
->lfStatusFont
));
191 LogFontA2W(&(nclmw
.lfMessageFont
), &(pnclma
->lfMessageFont
));
193 return SystemParametersInfoW(uiAction
, sizeof(NONCLIENTMETRICSW
),
196 case SPI_GETICONMETRICS
:
198 LPICONMETRICSA picma
= (LPICONMETRICSA
)pvParam
;
200 if(picma
->cbSize
!= sizeof(ICONMETRICSA
))
202 SetLastError(ERROR_INVALID_PARAMETER
);
205 icmw
.cbSize
= sizeof(ICONMETRICSW
);
206 if (!SystemParametersInfoW(uiAction
, sizeof(ICONMETRICSW
),
210 picma
->iHorzSpacing
= icmw
.iHorzSpacing
;
211 picma
->iVertSpacing
= icmw
.iVertSpacing
;
212 picma
->iTitleWrap
= icmw
.iTitleWrap
;
213 LogFontW2A(&(picma
->lfFont
), &(icmw
.lfFont
));
216 case SPI_SETICONMETRICS
:
218 LPICONMETRICSA picma
= (LPICONMETRICSA
)pvParam
;
220 if(picma
->cbSize
!= sizeof(ICONMETRICSA
))
222 SetLastError(ERROR_INVALID_PARAMETER
);
225 icmw
.cbSize
= sizeof(ICONMETRICSW
);
226 icmw
.iHorzSpacing
= picma
->iHorzSpacing
;
227 icmw
.iVertSpacing
= picma
->iVertSpacing
;
228 icmw
.iTitleWrap
= picma
->iTitleWrap
;
229 LogFontA2W(&(icmw
.lfFont
), &(picma
->lfFont
));
231 return SystemParametersInfoW(uiAction
, sizeof(ICONMETRICSW
),
234 case SPI_GETICONTITLELOGFONT
:
237 if (!SystemParametersInfoW(uiAction
, 0, &lfw
, fWinIni
))
239 LogFontW2A(pvParam
, &lfw
);
242 case SPI_SETICONTITLELOGFONT
:
244 LPLOGFONTA plfa
= (LPLOGFONTA
)pvParam
;
246 LogFontA2W(&lfw
,plfa
);
247 return SystemParametersInfoW(uiAction
, 0, &lfw
, fWinIni
);
249 case SPI_GETDESKWALLPAPER
:
255 /* Get the desktop bitmap handle, this does NOT return the file name! */
256 if(!NtUserSystemParametersInfo(SPI_GETDESKWALLPAPER
, 0, &hbmWallpaper
, 0))
258 /* Return an empty string, no wallpapaper is set */
259 *(CHAR
*)pvParam
= '\0';
264 /* FIXME - Read the registry key for now, but what happens if the wallpaper was
265 changed without SPIF_UPDATEINIFILE?! */
266 if(RegOpenKeyExW(HKEY_CURRENT_USER
,
267 L
"Control Panel\\Desktop",
268 0, KEY_QUERY_VALUE
, &hKey
) == ERROR_SUCCESS
)
272 if(RegQueryValueExA(hKey
,
277 &Size
) == ERROR_SUCCESS
286 case SPI_SETDESKWALLPAPER
:
288 HBITMAP hNewWallpaper
;
290 LPSTR lpWallpaper
= (LPSTR
)pvParam
;
292 if(lpWallpaper
!= NULL
&& *lpWallpaper
!= '\0')
294 hNewWallpaper
= LoadImageA(0, lpWallpaper
, IMAGE_BITMAP
, 0, 0, LR_LOADFROMFILE
);
295 if(hNewWallpaper
== NULL
)
302 hNewWallpaper
= NULL
;
306 /* Set the wallpaper bitmap */
307 if(!NtUserSystemParametersInfo(SPI_SETDESKWALLPAPER
, 0, &hNewWallpaper
, fWinIni
& SPIF_SENDCHANGE
))
309 if(hNewWallpaper
!= NULL
)
310 DeleteObject(hNewWallpaper
);
313 /* Do not use the bitmap handle anymore, it doesn't belong to our process anymore! */
316 if(fWinIni
& SPIF_UPDATEINIFILE
)
318 /* Save the path to the file in the registry */
320 if(RegOpenKeyExW(HKEY_CURRENT_USER
,
321 L
"Control Panel\\Desktop",
322 0, KEY_SET_VALUE
, &hKey
) == ERROR_SUCCESS
)
324 Ret
= RegSetValueExA(hKey
, "Wallpaper", 0, REG_SZ
, (LPBYTE
)(lpWallpaper
!= NULL
? lpWallpaper
: ""),
325 (lpWallpaper
!= NULL
? (lstrlenA(lpWallpaper
) + 1) * sizeof(CHAR
) : sizeof(CHAR
)) == ERROR_SUCCESS
);
330 RedrawWindow(GetShellWindow(), NULL
, NULL
, RDW_INVALIDATE
| RDW_ERASE
);
335 return NtUserSystemParametersInfo(uiAction
, uiParam
, pvParam
, fWinIni
);
343 SystemParametersInfoW(UINT uiAction
,
350 case SPI_GETHIGHCONTRAST
:
351 case SPI_SETHIGHCONTRAST
:
352 case SPI_GETSOUNDSENTRY
:
353 case SPI_SETSOUNDSENTRY
:
355 /* FIXME: Support this accessibility SPI actions */
356 FIXME("FIXME: Unsupported SPI Code: %lx \n",uiAction
);
359 case SPI_GETDESKWALLPAPER
:
365 /* Get the desktop bitmap handle, this does NOT return the file name! */
366 if(!NtUserSystemParametersInfo(SPI_GETDESKWALLPAPER
, 0, &hbmWallpaper
, 0))
368 /* Return an empty string, no wallpapaper is set */
369 *(WCHAR
*)pvParam
= L
'\0';
374 /* FIXME - Read the registry key for now, but what happens if the wallpaper was
375 changed without SPIF_UPDATEINIFILE?! */
376 if(RegOpenKeyExW(HKEY_CURRENT_USER
,
377 L
"Control Panel\\Desktop",
378 0, KEY_QUERY_VALUE
, &hKey
) == ERROR_SUCCESS
)
381 Size
= uiParam
* sizeof(WCHAR
);
382 if(RegQueryValueExW(hKey
,
387 &Size
) == ERROR_SUCCESS
396 case SPI_SETDESKWALLPAPER
:
398 HBITMAP hNewWallpaper
;
400 LPWSTR lpWallpaper
= (LPWSTR
)pvParam
;
402 if(lpWallpaper
!= NULL
&& *lpWallpaper
!= L
'\0')
404 hNewWallpaper
= LoadImageW(0, lpWallpaper
, IMAGE_BITMAP
, 0, 0, LR_LOADFROMFILE
);
406 if(hNewWallpaper
== NULL
)
413 hNewWallpaper
= NULL
;
417 /* Set the wallpaper bitmap */
418 if(!NtUserSystemParametersInfo(SPI_SETDESKWALLPAPER
, 0, &hNewWallpaper
, fWinIni
& SPIF_SENDCHANGE
))
420 /* Do not use the bitmap handle anymore, it doesn't belong to our process anymore! */
422 if(fWinIni
& SPIF_UPDATEINIFILE
)
424 /* Save the path to the file in the registry */
427 if(RegOpenKeyExW(HKEY_CURRENT_USER
,
428 L
"Control Panel\\Desktop",
429 0, KEY_SET_VALUE
, &hKey
) == ERROR_SUCCESS
)
431 Ret
= (RegSetValueExW(hKey
, L
"Wallpaper", 0, REG_SZ
, (lpWallpaper
!= NULL
? (LPBYTE
)lpWallpaper
: (LPBYTE
)L
""),
432 (lpWallpaper
!= NULL
? (lstrlenW(lpWallpaper
) + 1) * sizeof(WCHAR
) : sizeof(WCHAR
))) == ERROR_SUCCESS
);
437 RedrawWindow(GetShellWindow(), NULL
, NULL
, RDW_INVALIDATE
| RDW_ERASE
);
442 return NtUserSystemParametersInfo(uiAction
, uiParam
, pvParam
, fWinIni
);
454 return NtUserCloseDesktop(hDesktop
);
462 CreateDesktopA(LPCSTR lpszDesktop
,
466 ACCESS_MASK dwDesiredAccess
,
467 LPSECURITY_ATTRIBUTES lpsa
)
469 UNICODE_STRING DesktopNameU
;
471 LPDEVMODEW DevmodeW
= NULL
;
475 /* After conversion, the buffer is zero-terminated */
476 RtlCreateUnicodeStringFromAsciiz(&DesktopNameU
, lpszDesktop
);
480 RtlInitUnicodeString(&DesktopNameU
, NULL
);
484 DevmodeW
= GdiConvertToDevmodeW(pDevmode
);
486 hDesktop
= CreateDesktopW(DesktopNameU
.Buffer
,
493 /* Free the string, if it was allocated */
494 if (lpszDesktop
) RtlFreeUnicodeString(&DesktopNameU
);
504 CreateDesktopW(LPCWSTR lpszDesktop
,
508 ACCESS_MASK dwDesiredAccess
,
509 LPSECURITY_ATTRIBUTES lpsa
)
511 UNICODE_STRING DesktopName
;
515 hWinSta
= NtUserGetProcessWindowStation();
517 RtlInitUnicodeString(&DesktopName
, lpszDesktop
);
519 hDesktop
= NtUserCreateDesktop(&DesktopName
,
535 HWINSTA WindowStation
,
536 DESKTOPENUMPROCA EnumFunc
,
539 return EnumNamesA(WindowStation
, EnumFunc
, Context
, TRUE
);
549 HWINSTA WindowStation
,
550 DESKTOPENUMPROCW EnumFunc
,
553 return EnumNamesW(WindowStation
, EnumFunc
, Context
, TRUE
);
565 return NtUserGetThreadDesktop(dwThreadId
, 0);
578 ACCESS_MASK dwDesiredAccess
)
580 UNICODE_STRING DesktopNameU
;
585 /* After conversion, the buffer is zero-terminated */
586 RtlCreateUnicodeStringFromAsciiz(&DesktopNameU
, lpszDesktop
);
590 RtlInitUnicodeString(&DesktopNameU
, NULL
);
593 hDesktop
= OpenDesktopW(DesktopNameU
.Buffer
,
598 /* Free the string, if it was allocated */
599 if (lpszDesktop
) RtlFreeUnicodeString(&DesktopNameU
);
614 ACCESS_MASK dwDesiredAccess
)
616 UNICODE_STRING DesktopName
;
618 RtlInitUnicodeString(&DesktopName
, lpszDesktop
);
620 return NtUserOpenDesktop(
635 ACCESS_MASK dwDesiredAccess
)
637 return NtUserOpenInputDesktop(
652 return NtUserPaintDesktop(hdc
);
664 return NtUserSetThreadDesktop(hDesktop
);
676 return NtUserSwitchDesktop(hDesktop
);
684 SetShellWindowEx(HWND hwndShell
, HWND hwndShellListView
)
686 return NtUserSetShellWindowEx(hwndShell
, hwndShellListView
);
694 SetShellWindow(HWND hwndShell
)
696 return SetShellWindowEx(hwndShell
, hwndShell
);
707 pdi
= GetThreadDesktopInfo();
708 if (pdi
) return pdi
->hShellWindow
;