[user32]
[reactos.git] / reactos / dll / win32 / user32 / windows / window.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS user32.dll
4 * FILE: lib/user32/windows/window.c
5 * PURPOSE: Window management
6 * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
7 * UPDATE HISTORY:
8 * 06-06-2001 CSH Created
9 */
10
11 /* INCLUDES ******************************************************************/
12 #define DEBUG
13 #include <user32.h>
14
15 #include <wine/debug.h>
16 WINE_DEFAULT_DEBUG_CHANNEL(user32);
17
18 LRESULT DefWndNCPaint(HWND hWnd, HRGN hRgn, BOOL Active);
19 void MDI_CalcDefaultChildPos( HWND hwndClient, INT total, LPPOINT lpPos, INT delta, UINT *id );
20
21 #define CW_USEDEFAULT16 0x00008000
22
23 /* FUNCTIONS *****************************************************************/
24
25
26 NTSTATUS WINAPI
27 User32CallSendAsyncProcForKernel(PVOID Arguments, ULONG ArgumentLength)
28 {
29 PSENDASYNCPROC_CALLBACK_ARGUMENTS CallbackArgs;
30
31 TRACE("User32CallSendAsyncProcKernel()\n");
32
33 CallbackArgs = (PSENDASYNCPROC_CALLBACK_ARGUMENTS)Arguments;
34
35 if (ArgumentLength != sizeof(SENDASYNCPROC_CALLBACK_ARGUMENTS))
36 {
37 return(STATUS_INFO_LENGTH_MISMATCH);
38 }
39
40 CallbackArgs->Callback(CallbackArgs->Wnd,
41 CallbackArgs->Msg,
42 CallbackArgs->Context,
43 CallbackArgs->Result);
44 return(STATUS_SUCCESS);
45 }
46
47
48 /*
49 * @unimplemented
50 */
51 BOOL WINAPI
52 AllowSetForegroundWindow(DWORD dwProcessId)
53 {
54 static BOOL show_message = TRUE;
55 if (show_message)
56 {
57 UNIMPLEMENTED;
58 show_message = FALSE;
59 }
60 return TRUE;
61 }
62
63
64 /*
65 * @unimplemented
66 */
67 HDWP WINAPI
68 BeginDeferWindowPos(int nNumWindows)
69 {
70 if (nNumWindows < 0)
71 {
72 SetLastError(ERROR_INVALID_PARAMETER);
73 return 0;
74 }
75 #if 0
76 UNIMPLEMENTED;
77 return (HDWP)0;
78 #else
79 return (HDWP)1;
80 #endif
81 }
82
83
84 /*
85 * @implemented
86 */
87 BOOL WINAPI
88 BringWindowToTop(HWND hWnd)
89 {
90 return NtUserSetWindowPos(hWnd,
91 HWND_TOP,
92 0,
93 0,
94 0,
95 0,
96 SWP_NOSIZE | SWP_NOMOVE);
97 }
98
99
100 VOID WINAPI
101 SwitchToThisWindow(HWND hwnd, BOOL fUnknown)
102 {
103 ShowWindow(hwnd, SW_SHOW);
104 }
105
106
107 /*
108 * @implemented
109 */
110 HWND WINAPI
111 ChildWindowFromPoint(HWND hWndParent,
112 POINT Point)
113 {
114 return (HWND) NtUserChildWindowFromPointEx(hWndParent, Point.x, Point.y, 0);
115 }
116
117
118 /*
119 * @implemented
120 */
121 HWND WINAPI
122 ChildWindowFromPointEx(HWND hwndParent,
123 POINT pt,
124 UINT uFlags)
125 {
126 return (HWND) NtUserChildWindowFromPointEx(hwndParent, pt.x, pt.y, uFlags);
127 }
128
129
130 /*
131 * @implemented
132 */
133 BOOL WINAPI
134 CloseWindow(HWND hWnd)
135 {
136 SendMessageA(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0);
137
138 return (BOOL)(hWnd);
139 }
140
141 VOID
142 FORCEINLINE
143 RtlInitLargeString(
144 OUT PLARGE_STRING plstr,
145 LPCVOID psz,
146 BOOL bUnicode)
147 {
148 if(bUnicode)
149 {
150 RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING)plstr, (PWSTR)psz, 0);
151 }
152 else
153 {
154 RtlInitLargeAnsiString((PLARGE_ANSI_STRING)plstr, (PSTR)psz, 0);
155 }
156 }
157
158 VOID
159 NTAPI
160 RtlFreeLargeString(
161 IN PLARGE_STRING LargeString)
162 {
163 if (LargeString->Buffer)
164 {
165 RtlFreeHeap(GetProcessHeap(), 0, LargeString->Buffer);
166 RtlZeroMemory(LargeString, sizeof(LARGE_STRING));
167 }
168 }
169
170 HWND WINAPI
171 User32CreateWindowEx(DWORD dwExStyle,
172 LPCSTR lpClassName,
173 LPCSTR lpWindowName,
174 DWORD dwStyle,
175 int x,
176 int y,
177 int nWidth,
178 int nHeight,
179 HWND hWndParent,
180 HMENU hMenu,
181 HINSTANCE hInstance,
182 LPVOID lpParam,
183 BOOL Unicode)
184 {
185 LARGE_STRING WindowName;
186 LARGE_STRING lstrClassName, *plstrClassName;
187 UNICODE_STRING ClassName;
188 WNDCLASSEXA wceA;
189 WNDCLASSEXW wceW;
190 HWND Handle = NULL;
191
192 #if 0
193 DbgPrint("[window] User32CreateWindowEx style %d, exstyle %d, parent %d\n", dwStyle, dwExStyle, hWndParent);
194 #endif
195
196 if (!RegisterDefaultClasses)
197 {
198 ERR("User32CreateWindowEx RegisterSystemControls\n");
199 RegisterSystemControls();
200 }
201
202 if (IS_ATOM(lpClassName))
203 {
204 plstrClassName = (PVOID)lpClassName;
205 }
206 else
207 {
208 if(Unicode)
209 RtlInitUnicodeString(&ClassName, (PCWSTR)lpClassName);
210 else
211 {
212 if (!RtlCreateUnicodeStringFromAsciiz(&ClassName, (PCSZ)lpClassName))
213 {
214 SetLastError(ERROR_OUTOFMEMORY);
215 return (HWND)0;
216 }
217 }
218
219 /* Copy it to a LARGE_STRING */
220 lstrClassName.Buffer = ClassName.Buffer;
221 lstrClassName.Length = ClassName.Length;
222 lstrClassName.MaximumLength = ClassName.MaximumLength;
223 plstrClassName = &lstrClassName;
224 }
225
226 /* Initialize a LARGE_STRING */
227 RtlInitLargeString(&WindowName, lpWindowName, Unicode);
228
229 // HACK: The current implementation expects the Window name to be UNICODE
230 if (!Unicode)
231 {
232 NTSTATUS Status;
233 PSTR AnsiBuffer = WindowName.Buffer;
234 ULONG AnsiLength = WindowName.Length;
235
236 WindowName.Length = 0;
237 WindowName.MaximumLength = AnsiLength * sizeof(WCHAR);
238 WindowName.Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
239 0,
240 WindowName.MaximumLength);
241 if (!WindowName.Buffer)
242 {
243 SetLastError(ERROR_OUTOFMEMORY);
244 goto cleanup;
245 }
246
247 Status = RtlMultiByteToUnicodeN(WindowName.Buffer,
248 WindowName.MaximumLength,
249 &WindowName.Length,
250 AnsiBuffer,
251 AnsiLength);
252 if (!NT_SUCCESS(Status))
253 {
254 goto cleanup;
255 }
256 }
257
258 if(!hMenu && (dwStyle & (WS_OVERLAPPEDWINDOW | WS_POPUP)))
259 {
260 if(Unicode)
261 {
262 wceW.cbSize = sizeof(WNDCLASSEXW);
263 if(GetClassInfoExW(hInstance, (LPCWSTR)lpClassName, &wceW) && wceW.lpszMenuName)
264 {
265 hMenu = LoadMenuW(hInstance, wceW.lpszMenuName);
266 }
267 }
268 else
269 {
270 wceA.cbSize = sizeof(WNDCLASSEXA);
271 if(GetClassInfoExA(hInstance, lpClassName, &wceA) && wceA.lpszMenuName)
272 {
273 hMenu = LoadMenuA(hInstance, wceA.lpszMenuName);
274 }
275 }
276 }
277
278 if (!Unicode) dwExStyle |= WS_EX_SETANSICREATOR;
279
280 Handle = NtUserCreateWindowEx(dwExStyle,
281 plstrClassName,
282 NULL,
283 &WindowName,
284 dwStyle,
285 x,
286 y,
287 nWidth,
288 nHeight,
289 hWndParent,
290 hMenu,
291 hInstance,
292 lpParam,
293 0,
294 NULL);
295
296 #if 0
297 DbgPrint("[window] NtUserCreateWindowEx() == %d\n", Handle);
298 #endif
299 cleanup:
300 if(!Unicode)
301 {
302 if (!IS_ATOM(lpClassName))
303 {
304 RtlFreeUnicodeString(&ClassName);
305 }
306
307 RtlFreeLargeString(&WindowName);
308 }
309
310 return Handle;
311 }
312
313
314 /*
315 * @implemented
316 */
317 HWND WINAPI
318 CreateWindowExA(DWORD dwExStyle,
319 LPCSTR lpClassName,
320 LPCSTR lpWindowName,
321 DWORD dwStyle,
322 int x,
323 int y,
324 int nWidth,
325 int nHeight,
326 HWND hWndParent,
327 HMENU hMenu,
328 HINSTANCE hInstance,
329 LPVOID lpParam)
330 {
331 MDICREATESTRUCTA mdi;
332 HWND hwnd;
333
334 if (!RegisterDefaultClasses)
335 {
336 ERR("CreateWindowExA RegisterSystemControls\n");
337 RegisterSystemControls();
338 }
339
340 if (dwExStyle & WS_EX_MDICHILD)
341 {
342 POINT mPos[2];
343 UINT id = 0;
344 HWND top_child;
345 PWND WndParent;
346 PCLS pcls;
347
348 if(!(WndParent = ValidateHwnd(hWndParent)) ||
349 !(pcls = DesktopPtrToUser(WndParent->pcls)))
350 return 0;
351
352 if (pcls->fnid != FNID_MDICLIENT)
353 {
354 ERR("WS_EX_MDICHILD, but parent %p is not MDIClient\n", hWndParent);
355 return 0;
356 }
357
358 /* lpParams of WM_[NC]CREATE is different for MDI children.
359 * MDICREATESTRUCT members have the originally passed values.
360 */
361 mdi.szClass = lpClassName;
362 mdi.szTitle = lpWindowName;
363 mdi.hOwner = hInstance;
364 mdi.x = x;
365 mdi.y = y;
366 mdi.cx = nWidth;
367 mdi.cy = nHeight;
368 mdi.style = dwStyle;
369 mdi.lParam = (LPARAM)lpParam;
370
371 lpParam = (LPVOID)&mdi;
372
373 if (GetWindowLongPtrW(hWndParent, GWL_STYLE) & MDIS_ALLCHILDSTYLES)
374 {
375 if (dwStyle & WS_POPUP)
376 {
377 WARN("WS_POPUP with MDIS_ALLCHILDSTYLES is not allowed\n");
378 return(0);
379 }
380 dwStyle |= (WS_CHILD | WS_CLIPSIBLINGS);
381 }
382 else
383 {
384 dwStyle &= ~WS_POPUP;
385 dwStyle |= (WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CAPTION |
386 WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX);
387 }
388
389 top_child = GetWindow(hWndParent, GW_CHILD);
390
391 if (top_child)
392 {
393 /* Restore current maximized child */
394 if((dwStyle & WS_VISIBLE) && IsZoomed(top_child))
395 {
396 TRACE("Restoring current maximized child %p\n", top_child);
397 SendMessageW( top_child, WM_SETREDRAW, FALSE, 0 );
398 ShowWindow(top_child, SW_RESTORE);
399 SendMessageW( top_child, WM_SETREDRAW, TRUE, 0 );
400 }
401 }
402
403 MDI_CalcDefaultChildPos(hWndParent, -1, mPos, 0, &id);
404
405 if (!(dwStyle & WS_POPUP)) hMenu = (HMENU)id;
406
407 if (dwStyle & (WS_CHILD | WS_POPUP))
408 {
409 if (x == CW_USEDEFAULT || x == CW_USEDEFAULT16)
410 {
411 x = mPos[0].x;
412 y = mPos[0].y;
413 }
414 if (nWidth == CW_USEDEFAULT || nWidth == CW_USEDEFAULT16 || !nWidth)
415 nWidth = mPos[1].x;
416 if (nHeight == CW_USEDEFAULT || nHeight == CW_USEDEFAULT16 || !nHeight)
417 nHeight = mPos[1].y;
418 }
419 }
420
421 hwnd = User32CreateWindowEx(dwExStyle,
422 lpClassName,
423 lpWindowName,
424 dwStyle,
425 x,
426 y,
427 nWidth,
428 nHeight,
429 hWndParent,
430 hMenu,
431 hInstance,
432 lpParam,
433 FALSE);
434 return hwnd;
435 }
436
437
438 /*
439 * @implemented
440 */
441 HWND WINAPI
442 CreateWindowExW(DWORD dwExStyle,
443 LPCWSTR lpClassName,
444 LPCWSTR lpWindowName,
445 DWORD dwStyle,
446 int x,
447 int y,
448 int nWidth,
449 int nHeight,
450 HWND hWndParent,
451 HMENU hMenu,
452 HINSTANCE hInstance,
453 LPVOID lpParam)
454 {
455 MDICREATESTRUCTW mdi;
456 HWND hwnd;
457
458 if (!RegisterDefaultClasses)
459 {
460 ERR("CreateWindowExW RegisterSystemControls\n");
461 RegisterSystemControls();
462 }
463
464 if (dwExStyle & WS_EX_MDICHILD)
465 {
466 POINT mPos[2];
467 UINT id = 0;
468 HWND top_child;
469 PWND WndParent;
470 PCLS pcls;
471
472 WndParent = ValidateHwnd(hWndParent);
473
474 if(!WndParent)
475 return 0;
476
477 pcls = DesktopPtrToUser(WndParent->pcls);
478
479 if(!pcls)
480 return 0;
481
482 if (pcls->fnid != FNID_MDICLIENT)
483 {
484 ERR("WS_EX_MDICHILD, but parent %p is not MDIClient\n", hWndParent);
485 return 0;
486 }
487
488 /* lpParams of WM_[NC]CREATE is different for MDI children.
489 * MDICREATESTRUCT members have the originally passed values.
490 */
491 mdi.szClass = lpClassName;
492 mdi.szTitle = lpWindowName;
493 mdi.hOwner = hInstance;
494 mdi.x = x;
495 mdi.y = y;
496 mdi.cx = nWidth;
497 mdi.cy = nHeight;
498 mdi.style = dwStyle;
499 mdi.lParam = (LPARAM)lpParam;
500
501 lpParam = (LPVOID)&mdi;
502
503 if (GetWindowLongPtrW(hWndParent, GWL_STYLE) & MDIS_ALLCHILDSTYLES)
504 {
505 if (dwStyle & WS_POPUP)
506 {
507 WARN("WS_POPUP with MDIS_ALLCHILDSTYLES is not allowed\n");
508 return(0);
509 }
510 dwStyle |= (WS_CHILD | WS_CLIPSIBLINGS);
511 }
512 else
513 {
514 dwStyle &= ~WS_POPUP;
515 dwStyle |= (WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CAPTION |
516 WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX);
517 }
518
519 top_child = GetWindow(hWndParent, GW_CHILD);
520
521 if (top_child)
522 {
523 /* Restore current maximized child */
524 if((dwStyle & WS_VISIBLE) && IsZoomed(top_child))
525 {
526 TRACE("Restoring current maximized child %p\n", top_child);
527 SendMessageW( top_child, WM_SETREDRAW, FALSE, 0 );
528 ShowWindow(top_child, SW_RESTORE);
529 SendMessageW( top_child, WM_SETREDRAW, TRUE, 0 );
530 }
531 }
532
533 MDI_CalcDefaultChildPos(hWndParent, -1, mPos, 0, &id);
534
535 if (!(dwStyle & WS_POPUP)) hMenu = (HMENU)id;
536
537 if (dwStyle & (WS_CHILD | WS_POPUP))
538 {
539 if (x == CW_USEDEFAULT || x == CW_USEDEFAULT16)
540 {
541 x = mPos[0].x;
542 y = mPos[0].y;
543 }
544 if (nWidth == CW_USEDEFAULT || nWidth == CW_USEDEFAULT16 || !nWidth)
545 nWidth = mPos[1].x;
546 if (nHeight == CW_USEDEFAULT || nHeight == CW_USEDEFAULT16 || !nHeight)
547 nHeight = mPos[1].y;
548 }
549 }
550
551 hwnd = User32CreateWindowEx(dwExStyle,
552 (LPCSTR) lpClassName,
553 (LPCSTR) lpWindowName,
554 dwStyle,
555 x,
556 y,
557 nWidth,
558 nHeight,
559 hWndParent,
560 hMenu,
561 hInstance,
562 lpParam,
563 TRUE);
564 return hwnd;
565 }
566
567 /*
568 * @unimplemented
569 */
570 HDWP WINAPI
571 DeferWindowPos(HDWP hWinPosInfo,
572 HWND hWnd,
573 HWND hWndInsertAfter,
574 int x,
575 int y,
576 int cx,
577 int cy,
578 UINT uFlags)
579 {
580 #if 0
581 return NtUserDeferWindowPos(hWinPosInfo, hWnd, hWndInsertAfter, x, y, cx, cy, uFlags);
582 #else
583 SetWindowPos(hWnd, hWndInsertAfter, x, y, cx, cy, uFlags);
584 return hWinPosInfo;
585 #endif
586 }
587
588
589 /*
590 * @unimplemented
591 */
592 BOOL WINAPI
593 EndDeferWindowPos(HDWP hWinPosInfo)
594 {
595 #if 0
596 UNIMPLEMENTED;
597 return FALSE;
598 #else
599 return TRUE;
600 #endif
601 }
602
603
604 /*
605 * @implemented
606 */
607 HWND WINAPI
608 GetDesktopWindow(VOID)
609 {
610 PWND Wnd;
611 HWND Ret = NULL;
612
613 _SEH2_TRY
614 {
615 Wnd = GetThreadDesktopWnd();
616 if (Wnd != NULL)
617 Ret = UserHMGetHandle(Wnd);
618 }
619 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
620 {
621 /* Do nothing */
622 }
623 _SEH2_END;
624
625 return Ret;
626 }
627
628
629 static BOOL
630 User32EnumWindows(HDESK hDesktop,
631 HWND hWndparent,
632 WNDENUMPROC lpfn,
633 LPARAM lParam,
634 DWORD dwThreadId,
635 BOOL bChildren)
636 {
637 DWORD i, dwCount = 0;
638 HWND* pHwnd = NULL;
639 HANDLE hHeap;
640 NTSTATUS Status;
641
642 if (!lpfn)
643 {
644 SetLastError ( ERROR_INVALID_PARAMETER );
645 return FALSE;
646 }
647
648 /* FIXME instead of always making two calls, should we use some
649 sort of persistent buffer and only grow it ( requiring a 2nd
650 call ) when the buffer wasn't already big enough? */
651 /* first get how many window entries there are */
652 Status = NtUserBuildHwndList(hDesktop,
653 hWndparent,
654 bChildren,
655 dwThreadId,
656 lParam,
657 NULL,
658 &dwCount);
659 if (!NT_SUCCESS(Status))
660 return FALSE;
661
662 /* allocate buffer to receive HWND handles */
663 hHeap = GetProcessHeap();
664 pHwnd = HeapAlloc(hHeap, 0, sizeof(HWND)*(dwCount+1));
665 if (!pHwnd)
666 {
667 SetLastError ( ERROR_NOT_ENOUGH_MEMORY );
668 return FALSE;
669 }
670
671 /* now call kernel again to fill the buffer this time */
672 Status = NtUserBuildHwndList(hDesktop,
673 hWndparent,
674 bChildren,
675 dwThreadId,
676 lParam,
677 pHwnd,
678 &dwCount);
679 if (!NT_SUCCESS(Status))
680 {
681 if (pHwnd)
682 HeapFree(hHeap, 0, pHwnd);
683 return FALSE;
684 }
685
686 /* call the user's callback function until we're done or
687 they tell us to quit */
688 for ( i = 0; i < dwCount; i++ )
689 {
690 /* FIXME I'm only getting NULLs from Thread Enumeration, and it's
691 * probably because I'm not doing it right in NtUserBuildHwndList.
692 * Once that's fixed, we shouldn't have to check for a NULL HWND
693 * here
694 */
695 if (!(ULONG)pHwnd[i]) /* don't enumerate a NULL HWND */
696 continue;
697 if (!(*lpfn)(pHwnd[i], lParam))
698 {
699 HeapFree ( hHeap, 0, pHwnd );
700 return FALSE;
701 }
702 }
703 if (pHwnd)
704 HeapFree(hHeap, 0, pHwnd);
705 return TRUE;
706 }
707
708
709 /*
710 * @implemented
711 */
712 BOOL WINAPI
713 EnumChildWindows(HWND hWndParent,
714 WNDENUMPROC lpEnumFunc,
715 LPARAM lParam)
716 {
717 if (!hWndParent)
718 {
719 return EnumWindows(lpEnumFunc, lParam);
720 }
721 return User32EnumWindows(NULL, hWndParent, lpEnumFunc, lParam, 0, TRUE);
722 }
723
724
725 /*
726 * @implemented
727 */
728 BOOL WINAPI
729 EnumThreadWindows(DWORD dwThreadId,
730 WNDENUMPROC lpfn,
731 LPARAM lParam)
732 {
733 if (!dwThreadId)
734 dwThreadId = GetCurrentThreadId();
735 return User32EnumWindows(NULL, NULL, lpfn, lParam, dwThreadId, FALSE);
736 }
737
738
739 /*
740 * @implemented
741 */
742 BOOL WINAPI
743 EnumWindows(WNDENUMPROC lpEnumFunc,
744 LPARAM lParam)
745 {
746 return User32EnumWindows(NULL, NULL, lpEnumFunc, lParam, 0, FALSE);
747 }
748
749
750 /*
751 * @implemented
752 */
753 BOOL WINAPI
754 EnumDesktopWindows(HDESK hDesktop,
755 WNDENUMPROC lpfn,
756 LPARAM lParam)
757 {
758 return User32EnumWindows(hDesktop, NULL, lpfn, lParam, 0, FALSE);
759 }
760
761
762 /*
763 * @implemented
764 */
765 HWND WINAPI
766 FindWindowExA(HWND hwndParent,
767 HWND hwndChildAfter,
768 LPCSTR lpszClass,
769 LPCSTR lpszWindow)
770 {
771 UNICODE_STRING ucClassName, *pucClassName = NULL;
772 UNICODE_STRING ucWindowName, *pucWindowName = NULL;
773 HWND Result;
774
775 if (IS_ATOM(lpszClass))
776 {
777 ucClassName.Buffer = (LPWSTR)lpszClass;
778 ucClassName.Length = 0;
779 pucClassName = &ucClassName;
780 }
781 else if (lpszClass != NULL)
782 {
783 if (!RtlCreateUnicodeStringFromAsciiz(&ucClassName,
784 (LPSTR)lpszClass))
785 {
786 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
787 return NULL;
788 }
789 pucClassName = &ucClassName;
790 }
791
792 if (lpszWindow != NULL)
793 {
794 if (!RtlCreateUnicodeStringFromAsciiz(&ucWindowName,
795 (LPSTR)lpszWindow))
796 {
797 if (!IS_ATOM(lpszClass) && lpszClass != NULL)
798 RtlFreeUnicodeString(&ucWindowName);
799
800 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
801 return NULL;
802 }
803
804 pucWindowName = &ucWindowName;
805 }
806
807 Result = NtUserFindWindowEx(hwndParent,
808 hwndChildAfter,
809 pucClassName,
810 pucWindowName,
811 0);
812
813 if (!IS_ATOM(lpszClass) && lpszClass != NULL)
814 RtlFreeUnicodeString(&ucClassName);
815 if (lpszWindow != NULL)
816 RtlFreeUnicodeString(&ucWindowName);
817
818 return Result;
819 }
820
821
822 /*
823 * @implemented
824 */
825 HWND WINAPI
826 FindWindowExW(HWND hwndParent,
827 HWND hwndChildAfter,
828 LPCWSTR lpszClass,
829 LPCWSTR lpszWindow)
830 {
831 UNICODE_STRING ucClassName, *pucClassName = NULL;
832 UNICODE_STRING ucWindowName, *pucWindowName = NULL;
833
834 if (IS_ATOM(lpszClass))
835 {
836 ucClassName.Length = 0;
837 ucClassName.Buffer = (LPWSTR)lpszClass;
838 pucClassName = &ucClassName;
839 }
840 else if (lpszClass != NULL)
841 {
842 RtlInitUnicodeString(&ucClassName,
843 lpszClass);
844 pucClassName = &ucClassName;
845 }
846
847 if (lpszWindow != NULL)
848 {
849 RtlInitUnicodeString(&ucWindowName,
850 lpszWindow);
851 pucWindowName = &ucWindowName;
852 }
853
854 return NtUserFindWindowEx(hwndParent,
855 hwndChildAfter,
856 pucClassName,
857 pucWindowName,
858 0);
859 }
860
861
862 /*
863 * @implemented
864 */
865 HWND WINAPI
866 FindWindowA(LPCSTR lpClassName, LPCSTR lpWindowName)
867 {
868 //FIXME: FindWindow does not search children, but FindWindowEx does.
869 // what should we do about this?
870 return FindWindowExA (NULL, NULL, lpClassName, lpWindowName);
871 }
872
873
874 /*
875 * @implemented
876 */
877 HWND WINAPI
878 FindWindowW(LPCWSTR lpClassName, LPCWSTR lpWindowName)
879 {
880 /*
881
882 There was a FIXME here earlier, but I think it is just a documentation unclarity.
883
884 FindWindow only searches top level windows. What they mean is that child
885 windows of other windows than the desktop can be searched.
886 FindWindowExW never does a recursive search.
887
888 / Joakim
889 */
890
891 return FindWindowExW(NULL, NULL, lpClassName, lpWindowName);
892 }
893
894
895
896 /*
897 * @unimplemented
898 */
899 BOOL WINAPI
900 GetAltTabInfoA(HWND hwnd,
901 int iItem,
902 PALTTABINFO pati,
903 LPSTR pszItemText,
904 UINT cchItemText)
905 {
906 UNIMPLEMENTED;
907 return FALSE;
908 }
909
910
911 /*
912 * @unimplemented
913 */
914 BOOL WINAPI
915 GetAltTabInfoW(HWND hwnd,
916 int iItem,
917 PALTTABINFO pati,
918 LPWSTR pszItemText,
919 UINT cchItemText)
920 {
921 UNIMPLEMENTED;
922 return FALSE;
923 }
924
925
926 /*
927 * @implemented
928 */
929 HWND WINAPI
930 GetAncestor(HWND hwnd, UINT gaFlags)
931 {
932 HWND Ret = NULL;
933 PWND Ancestor, Wnd;
934
935 Wnd = ValidateHwnd(hwnd);
936 if (!Wnd)
937 return NULL;
938
939 _SEH2_TRY
940 {
941 Ancestor = NULL;
942 switch (gaFlags)
943 {
944 case GA_PARENT:
945 if (Wnd->spwndParent != NULL)
946 Ancestor = DesktopPtrToUser(Wnd->spwndParent);
947 break;
948
949 default:
950 /* FIXME: Call win32k for now */
951 Wnd = NULL;
952 break;
953 }
954
955 if (Ancestor != NULL)
956 Ret = UserHMGetHandle(Ancestor);
957 }
958 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
959 {
960 /* Do nothing */
961 }
962 _SEH2_END;
963
964 if (!Wnd) /* Fall back */
965 Ret = NtUserGetAncestor(hwnd, gaFlags);
966
967 return Ret;
968 }
969
970
971 /*
972 * @implemented
973 */
974 BOOL WINAPI
975 GetClientRect(HWND hWnd, LPRECT lpRect)
976 {
977 PWND Wnd = ValidateHwnd(hWnd);
978
979 if (Wnd != NULL)
980 {
981 lpRect->left = lpRect->top = 0;
982 lpRect->right = Wnd->rcClient.right - Wnd->rcClient.left;
983 lpRect->bottom = Wnd->rcClient.bottom - Wnd->rcClient.top;
984 return TRUE;
985 }
986
987 return FALSE;
988 }
989
990
991 /*
992 * @implemented
993 */
994 HWND WINAPI
995 GetLastActivePopup(HWND hWnd)
996 {
997 PWND Wnd;
998 HWND Ret = hWnd;
999
1000 Wnd = ValidateHwnd(hWnd);
1001 if (Wnd != NULL)
1002 {
1003 _SEH2_TRY
1004 {
1005 if (Wnd->hWndLastActive)
1006 Ret = Wnd->hWndLastActive;
1007 }
1008 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
1009 {
1010 /* Do nothing */
1011 }
1012 _SEH2_END;
1013 }
1014 return Ret;
1015 }
1016
1017
1018 /*
1019 * @implemented
1020 */
1021 HWND WINAPI
1022 GetParent(HWND hWnd)
1023 {
1024 PWND Wnd, WndParent;
1025 HWND Ret = NULL;
1026
1027 Wnd = ValidateHwnd(hWnd);
1028 if (Wnd != NULL)
1029 {
1030 _SEH2_TRY
1031 {
1032 WndParent = NULL;
1033 if (Wnd->style & WS_CHILD)
1034 {
1035 if (Wnd->spwndParent != NULL)
1036 WndParent = DesktopPtrToUser(Wnd->spwndParent);
1037 }
1038 else if (Wnd->style & WS_POPUP)
1039 {
1040 if (Wnd->spwndOwner != NULL)
1041 WndParent = DesktopPtrToUser(Wnd->spwndOwner);
1042 }
1043
1044 if (WndParent != NULL)
1045 Ret = UserHMGetHandle(WndParent);
1046 }
1047 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
1048 {
1049 /* Do nothing */
1050 }
1051 _SEH2_END;
1052 }
1053
1054 return Ret;
1055 }
1056
1057
1058 /*
1059 * @unimplemented
1060 */
1061 BOOL WINAPI
1062 GetProcessDefaultLayout(DWORD *pdwDefaultLayout)
1063 {
1064 if (!pdwDefaultLayout)
1065 {
1066 SetLastError(ERROR_INVALID_PARAMETER);
1067 return FALSE;
1068 }
1069
1070 UNIMPLEMENTED;
1071
1072 *pdwDefaultLayout = 0;
1073 return TRUE;
1074 }
1075
1076
1077 /*
1078 * @implemented
1079 */
1080 HWND WINAPI
1081 GetWindow(HWND hWnd,
1082 UINT uCmd)
1083 {
1084 PWND Wnd, FoundWnd;
1085 HWND Ret = NULL;
1086
1087 Wnd = ValidateHwnd(hWnd);
1088 if (!Wnd)
1089 return NULL;
1090
1091 _SEH2_TRY
1092 {
1093 FoundWnd = NULL;
1094 switch (uCmd)
1095 {
1096 case GW_OWNER:
1097 if (Wnd->spwndOwner != NULL)
1098 FoundWnd = DesktopPtrToUser(Wnd->spwndOwner);
1099 break;
1100
1101 case GW_HWNDFIRST:
1102 if(Wnd->spwndParent != NULL)
1103 {
1104 FoundWnd = DesktopPtrToUser(Wnd->spwndParent);
1105 if (FoundWnd->spwndChild != NULL)
1106 FoundWnd = DesktopPtrToUser(FoundWnd->spwndChild);
1107 }
1108 break;
1109 case GW_HWNDNEXT:
1110 if (Wnd->spwndNext != NULL)
1111 FoundWnd = DesktopPtrToUser(Wnd->spwndNext);
1112 break;
1113
1114 case GW_HWNDPREV:
1115 if (Wnd->spwndPrev != NULL)
1116 FoundWnd = DesktopPtrToUser(Wnd->spwndPrev);
1117 break;
1118
1119 case GW_CHILD:
1120 if (Wnd->spwndChild != NULL)
1121 FoundWnd = DesktopPtrToUser(Wnd->spwndChild);
1122 break;
1123
1124 case GW_HWNDLAST:
1125 FoundWnd = Wnd;
1126 while ( FoundWnd->spwndNext != NULL)
1127 FoundWnd = DesktopPtrToUser(FoundWnd->spwndNext);
1128 break;
1129
1130 default:
1131 Wnd = NULL;
1132 break;
1133 }
1134
1135 if (FoundWnd != NULL)
1136 Ret = UserHMGetHandle(FoundWnd);
1137 }
1138 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
1139 {
1140 /* Do nothing */
1141 }
1142 _SEH2_END;
1143
1144 return Ret;
1145 }
1146
1147
1148 /*
1149 * @implemented
1150 */
1151 HWND WINAPI
1152 GetTopWindow(HWND hWnd)
1153 {
1154 if (!hWnd) hWnd = GetDesktopWindow();
1155 return GetWindow(hWnd, GW_CHILD);
1156 }
1157
1158
1159 /*
1160 * @implemented
1161 */
1162 BOOL WINAPI
1163 GetWindowInfo(HWND hWnd,
1164 PWINDOWINFO pwi)
1165 {
1166 PWND pWnd;
1167 PCLS pCls = NULL;
1168 SIZE Size = {0,0};
1169 BOOL Ret = FALSE;
1170
1171 if ( !pwi || pwi->cbSize != sizeof(WINDOWINFO))
1172 SetLastError(ERROR_INVALID_PARAMETER); // Just set the error and go!
1173
1174 pWnd = ValidateHwnd(hWnd);
1175 if (!pWnd)
1176 return Ret;
1177
1178 UserGetWindowBorders(pWnd->style, pWnd->ExStyle, &Size, FALSE);
1179
1180 _SEH2_TRY
1181 {
1182 pCls = DesktopPtrToUser(pWnd->pcls);
1183 pwi->rcWindow = pWnd->rcWindow;
1184 pwi->rcClient = pWnd->rcClient;
1185 pwi->dwStyle = pWnd->style;
1186 pwi->dwExStyle = pWnd->ExStyle;
1187 pwi->cxWindowBorders = Size.cx;
1188 pwi->cyWindowBorders = Size.cy;
1189 pwi->dwWindowStatus = 0;
1190 if (pWnd->state & WNDS_ACTIVEFRAME)
1191 pwi->dwWindowStatus = WS_ACTIVECAPTION;
1192 pwi->atomWindowType = (pCls ? pCls->atomClassName : 0 );
1193
1194 if ( pWnd->state2 & WNDS2_WIN50COMPAT )
1195 {
1196 pwi->wCreatorVersion = 0x500;
1197 }
1198 else if ( pWnd->state2 & WNDS2_WIN40COMPAT )
1199 {
1200 pwi->wCreatorVersion = 0x400;
1201 }
1202 else if ( pWnd->state2 & WNDS2_WIN31COMPAT )
1203 {
1204 pwi->wCreatorVersion = 0x30A;
1205 }
1206 else
1207 {
1208 pwi->wCreatorVersion = 0x300;
1209 }
1210
1211 Ret = TRUE;
1212 }
1213 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
1214 {
1215 /* Do nothing */
1216 }
1217 _SEH2_END;
1218
1219 return Ret;
1220 }
1221
1222
1223 /*
1224 * @implemented
1225 */
1226 UINT WINAPI
1227 GetWindowModuleFileNameA(HWND hwnd,
1228 LPSTR lpszFileName,
1229 UINT cchFileNameMax)
1230 {
1231 PWND Wnd = ValidateHwnd(hwnd);
1232
1233 if (!Wnd)
1234 return 0;
1235
1236 return GetModuleFileNameA(Wnd->hModule, lpszFileName, cchFileNameMax);
1237 }
1238
1239
1240 /*
1241 * @implemented
1242 */
1243 UINT WINAPI
1244 GetWindowModuleFileNameW(HWND hwnd,
1245 LPWSTR lpszFileName,
1246 UINT cchFileNameMax)
1247 {
1248 PWND Wnd = ValidateHwnd(hwnd);
1249
1250 if (!Wnd)
1251 return 0;
1252
1253 return GetModuleFileNameW( Wnd->hModule, lpszFileName, cchFileNameMax );
1254 }
1255
1256
1257 /*
1258 * @implemented
1259 */
1260 BOOL WINAPI
1261 GetWindowRect(HWND hWnd,
1262 LPRECT lpRect)
1263 {
1264 PWND Wnd = ValidateHwnd(hWnd);
1265
1266 if (Wnd != NULL)
1267 {
1268 *lpRect = Wnd->rcWindow;
1269 return TRUE;
1270 }
1271
1272 return FALSE;
1273 }
1274
1275
1276 /*
1277 * @implemented
1278 */
1279 int WINAPI
1280 GetWindowTextA(HWND hWnd, LPSTR lpString, int nMaxCount)
1281 {
1282 PWND Wnd;
1283 PCWSTR Buffer;
1284 INT Length = 0;
1285
1286 if (lpString == NULL)
1287 return 0;
1288
1289 Wnd = ValidateHwnd(hWnd);
1290 if (!Wnd)
1291 return 0;
1292
1293 _SEH2_TRY
1294 {
1295 if (!TestWindowProcess( Wnd))
1296 {
1297 if (nMaxCount > 0)
1298 {
1299 /* do not send WM_GETTEXT messages to other processes */
1300 Length = Wnd->strName.Length / sizeof(WCHAR);
1301 if (Length != 0)
1302 {
1303 Buffer = DesktopPtrToUser(Wnd->strName.Buffer);
1304 if (Buffer != NULL)
1305 {
1306 if (!WideCharToMultiByte(CP_ACP,
1307 0,
1308 Buffer,
1309 Length + 1,
1310 lpString,
1311 nMaxCount,
1312 NULL,
1313 NULL))
1314 {
1315 lpString[nMaxCount - 1] = '\0';
1316 }
1317 }
1318 else
1319 {
1320 Length = 0;
1321 lpString[0] = '\0';
1322 }
1323 }
1324 else
1325 lpString[0] = '\0';
1326 }
1327
1328 Wnd = NULL; /* Don't send a message */
1329 }
1330 }
1331 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
1332 {
1333 lpString[0] = '\0';
1334 Length = 0;
1335 Wnd = NULL; /* Don't send a message */
1336 }
1337 _SEH2_END;
1338
1339 if (Wnd != NULL)
1340 Length = SendMessageA(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
1341
1342 return Length;
1343 }
1344
1345
1346 /*
1347 * @implemented
1348 */
1349 int WINAPI
1350 GetWindowTextLengthA(HWND hWnd)
1351 {
1352 return(SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0));
1353 }
1354
1355
1356 /*
1357 * @implemented
1358 */
1359 int WINAPI
1360 GetWindowTextLengthW(HWND hWnd)
1361 {
1362 return(SendMessageW(hWnd, WM_GETTEXTLENGTH, 0, 0));
1363 }
1364
1365
1366 /*
1367 * @implemented
1368 */
1369 int WINAPI
1370 GetWindowTextW(HWND hWnd, LPWSTR lpString, int nMaxCount)
1371 {
1372 PWND Wnd;
1373 PCWSTR Buffer;
1374 INT Length = 0;
1375
1376 if (lpString == NULL)
1377 return 0;
1378
1379 Wnd = ValidateHwnd(hWnd);
1380 if (!Wnd)
1381 return 0;
1382
1383 _SEH2_TRY
1384 {
1385 if (!TestWindowProcess( Wnd))
1386 {
1387 if (nMaxCount > 0)
1388 {
1389 /* do not send WM_GETTEXT messages to other processes */
1390 Length = Wnd->strName.Length / sizeof(WCHAR);
1391 if (Length != 0)
1392 {
1393 Buffer = DesktopPtrToUser(Wnd->strName.Buffer);
1394 if (Buffer != NULL)
1395 {
1396 RtlCopyMemory(lpString,
1397 Buffer,
1398 (Length + 1) * sizeof(WCHAR));
1399 }
1400 else
1401 {
1402 Length = 0;
1403 lpString[0] = '\0';
1404 }
1405 }
1406 else
1407 lpString[0] = '\0';
1408 }
1409
1410 Wnd = NULL; /* Don't send a message */
1411 }
1412 }
1413 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
1414 {
1415 lpString[0] = '\0';
1416 Length = 0;
1417 Wnd = NULL; /* Don't send a message */
1418 }
1419 _SEH2_END;
1420
1421 if (Wnd != NULL)
1422 Length = SendMessageW(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
1423
1424 return Length;
1425 }
1426
1427 DWORD WINAPI
1428 GetWindowThreadProcessId(HWND hWnd,
1429 LPDWORD lpdwProcessId)
1430 {
1431 DWORD Ret = 0;
1432 PTHREADINFO ti;
1433 PWND pWnd = ValidateHwnd(hWnd);
1434
1435 if (!pWnd) return Ret;
1436
1437 ti = pWnd->head.pti;
1438
1439 if (ti)
1440 {
1441 if (ti == GetW32ThreadInfo())
1442 { // We are current.
1443 //FIXME("Current!\n");
1444 if (lpdwProcessId)
1445 *lpdwProcessId = (DWORD)NtCurrentTeb()->ClientId.UniqueProcess;
1446 Ret = (DWORD)NtCurrentTeb()->ClientId.UniqueThread;
1447 }
1448 else
1449 { // Ask kernel for info.
1450 //FIXME("Kernel call!\n");
1451 if (lpdwProcessId)
1452 *lpdwProcessId = NtUserQueryWindow(hWnd, QUERY_WINDOW_UNIQUE_PROCESS_ID);
1453 Ret = NtUserQueryWindow(hWnd, QUERY_WINDOW_UNIQUE_THREAD_ID);
1454 }
1455 }
1456 return Ret;
1457 }
1458
1459
1460 /*
1461 * @implemented
1462 */
1463 BOOL WINAPI
1464 IsChild(HWND hWndParent,
1465 HWND hWnd)
1466 {
1467 PWND WndParent, Wnd;
1468 BOOL Ret = FALSE;
1469
1470 WndParent = ValidateHwnd(hWndParent);
1471 if (!WndParent)
1472 return FALSE;
1473 Wnd = ValidateHwnd(hWnd);
1474 if (!Wnd)
1475 return FALSE;
1476
1477 _SEH2_TRY
1478 {
1479 while (Wnd != NULL)
1480 {
1481 if (Wnd->spwndParent != NULL)
1482 {
1483 Wnd = DesktopPtrToUser(Wnd->spwndParent);
1484 if (Wnd == WndParent)
1485 {
1486 Ret = TRUE;
1487 break;
1488 }
1489 }
1490 else
1491 break;
1492 }
1493 }
1494 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
1495 {
1496 /* Do nothing */
1497 }
1498 _SEH2_END;
1499
1500 return Ret;
1501 }
1502
1503
1504 /*
1505 * @implemented
1506 */
1507 BOOL WINAPI
1508 IsIconic(HWND hWnd)
1509 {
1510 PWND Wnd = ValidateHwnd(hWnd);
1511
1512 if (Wnd != NULL)
1513 return (Wnd->style & WS_MINIMIZE) != 0;
1514
1515 return FALSE;
1516 }
1517
1518
1519 /*
1520 * @implemented
1521 */
1522 BOOL WINAPI
1523 IsWindow(HWND hWnd)
1524 {
1525 PWND Wnd = ValidateHwndNoErr(hWnd);
1526 if (Wnd != NULL)
1527 {
1528 /* FIXME: If window is being destroyed return FALSE! */
1529 return TRUE;
1530 }
1531
1532 return FALSE;
1533 }
1534
1535
1536 /*
1537 * @implemented
1538 */
1539 BOOL WINAPI
1540 IsWindowUnicode(HWND hWnd)
1541 {
1542 PWND Wnd = ValidateHwnd(hWnd);
1543
1544 if (Wnd != NULL)
1545 return Wnd->Unicode;
1546
1547 return FALSE;
1548 }
1549
1550
1551 /*
1552 * @implemented
1553 */
1554 BOOL WINAPI
1555 IsWindowVisible(HWND hWnd)
1556 {
1557 BOOL Ret = FALSE;
1558 PWND Wnd = ValidateHwnd(hWnd);
1559
1560 if (Wnd != NULL)
1561 {
1562 _SEH2_TRY
1563 {
1564 Ret = TRUE;
1565
1566 do
1567 {
1568 if (!(Wnd->style & WS_VISIBLE))
1569 {
1570 Ret = FALSE;
1571 break;
1572 }
1573
1574 if (Wnd->spwndParent != NULL)
1575 Wnd = DesktopPtrToUser(Wnd->spwndParent);
1576 else
1577 break;
1578
1579 } while (Wnd != NULL);
1580 }
1581 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
1582 {
1583 Ret = FALSE;
1584 }
1585 _SEH2_END;
1586 }
1587
1588 return Ret;
1589 }
1590
1591
1592 /*
1593 * @implemented
1594 */
1595 BOOL WINAPI
1596 IsWindowEnabled(HWND hWnd)
1597 {
1598 // AG: I don't know if child windows are affected if the parent is
1599 // disabled. I think they stop processing messages but stay appearing
1600 // as enabled.
1601
1602 return !(GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_DISABLED);
1603 }
1604
1605
1606 /*
1607 * @implemented
1608 */
1609 BOOL WINAPI
1610 IsZoomed(HWND hWnd)
1611 {
1612 return (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_MAXIMIZE) != 0;
1613 }
1614
1615
1616 /*
1617 * @unimplemented
1618 */
1619 BOOL WINAPI
1620 LockSetForegroundWindow(UINT uLockCode)
1621 {
1622 UNIMPLEMENTED;
1623 return TRUE;
1624 }
1625
1626
1627 /*
1628 * @implemented
1629 */
1630 BOOL WINAPI
1631 AnimateWindow(HWND hwnd,
1632 DWORD dwTime,
1633 DWORD dwFlags)
1634 {
1635 /* FIXME Add animation code */
1636
1637 /* If trying to show/hide and it's already *
1638 * shown/hidden or invalid window, fail with *
1639 * invalid parameter */
1640
1641 BOOL visible;
1642 visible = IsWindowVisible(hwnd);
1643 if(!IsWindow(hwnd) ||
1644 (visible && !(dwFlags & AW_HIDE)) ||
1645 (!visible && (dwFlags & AW_HIDE)))
1646 {
1647 SetLastError(ERROR_INVALID_PARAMETER);
1648 return FALSE;
1649 }
1650
1651 ShowWindow(hwnd, (dwFlags & AW_HIDE) ? SW_HIDE : ((dwFlags & AW_ACTIVATE) ? SW_SHOW : SW_SHOWNA));
1652
1653 return TRUE;
1654 }
1655
1656
1657 /*
1658 * @implemented
1659 */
1660 BOOL WINAPI
1661 OpenIcon(HWND hWnd)
1662 {
1663 if (!(GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_MINIMIZE))
1664 return FALSE;
1665
1666 ShowWindow(hWnd,SW_RESTORE);
1667 return TRUE;
1668 }
1669
1670
1671 /*
1672 * @implemented
1673 */
1674 HWND WINAPI
1675 RealChildWindowFromPoint(HWND hwndParent,
1676 POINT ptParentClientCoords)
1677 {
1678 return ChildWindowFromPointEx(hwndParent, ptParentClientCoords, CWP_SKIPTRANSPARENT);
1679 }
1680
1681 /*
1682 * @unimplemented
1683 */
1684 BOOL WINAPI
1685 SetForegroundWindow(HWND hWnd)
1686 {
1687 return NtUserCallHwndLock(hWnd, HWNDLOCK_ROUTINE_SETFOREGROUNDWINDOW);
1688 }
1689
1690
1691 /*
1692 * @unimplemented
1693 */
1694 BOOL WINAPI
1695 SetProcessDefaultLayout(DWORD dwDefaultLayout)
1696 {
1697 if (dwDefaultLayout == 0)
1698 return TRUE;
1699
1700 UNIMPLEMENTED;
1701 return FALSE;
1702 }
1703
1704
1705 /*
1706 * @implemented
1707 */
1708 BOOL WINAPI
1709 SetWindowTextA(HWND hWnd,
1710 LPCSTR lpString)
1711 {
1712 DWORD ProcessId;
1713 if(!GetWindowThreadProcessId(hWnd, &ProcessId))
1714 {
1715 return FALSE;
1716 }
1717
1718 if(ProcessId != GetCurrentProcessId())
1719 {
1720 /* do not send WM_GETTEXT messages to other processes */
1721
1722 DefSetText(hWnd, (PCWSTR)lpString, TRUE);
1723
1724 if ((GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION)
1725 {
1726 DefWndNCPaint(hWnd, (HRGN)1, -1);
1727 }
1728 return TRUE;
1729 }
1730
1731 return SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)lpString);
1732 }
1733
1734
1735 /*
1736 * @implemented
1737 */
1738 BOOL WINAPI
1739 SetWindowTextW(HWND hWnd,
1740 LPCWSTR lpString)
1741 {
1742 DWORD ProcessId;
1743 if(!GetWindowThreadProcessId(hWnd, &ProcessId))
1744 {
1745 return FALSE;
1746 }
1747
1748 if(ProcessId != GetCurrentProcessId())
1749 {
1750 /* do not send WM_GETTEXT messages to other processes */
1751
1752 DefSetText(hWnd, lpString, FALSE);
1753
1754 if ((GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION)
1755 {
1756 DefWndNCPaint(hWnd, (HRGN)1, -1);
1757 }
1758 return TRUE;
1759 }
1760
1761 return SendMessageW(hWnd, WM_SETTEXT, 0, (LPARAM)lpString);
1762 }
1763
1764
1765 /*
1766 * @implemented
1767 */
1768 BOOL WINAPI
1769 ShowOwnedPopups(HWND hWnd,
1770 BOOL fShow)
1771 {
1772 return (BOOL)NtUserCallTwoParam((DWORD_PTR)hWnd, fShow, TWOPARAM_ROUTINE_SHOWOWNEDPOPUPS);
1773 }
1774
1775
1776 /*
1777 * @implemented
1778 */
1779 BOOL WINAPI
1780 UpdateLayeredWindow( HWND hwnd,
1781 HDC hdcDst,
1782 POINT *pptDst,
1783 SIZE *psize,
1784 HDC hdcSrc,
1785 POINT *pptSrc,
1786 COLORREF crKey,
1787 BLENDFUNCTION *pbl,
1788 DWORD dwFlags)
1789 {
1790 if ( dwFlags & ULW_EX_NORESIZE)
1791 dwFlags = ~(ULW_EX_NORESIZE|ULW_OPAQUE|ULW_ALPHA|ULW_COLORKEY);
1792 return NtUserUpdateLayeredWindow( hwnd,
1793 hdcDst,
1794 pptDst,
1795 psize,
1796 hdcSrc,
1797 pptSrc,
1798 crKey,
1799 pbl,
1800 dwFlags,
1801 NULL);
1802 }
1803
1804 /*
1805 * @implemented
1806 */
1807 BOOL WINAPI
1808 UpdateLayeredWindowIndirect(HWND hwnd,
1809 const UPDATELAYEREDWINDOWINFO *info)
1810 {
1811 if (info && info->cbSize == sizeof(info))
1812 {
1813 return NtUserUpdateLayeredWindow( hwnd,
1814 info->hdcDst,
1815 (POINT *)info->pptDst,
1816 (SIZE *)info->psize,
1817 info->hdcSrc,
1818 (POINT *)info->pptSrc,
1819 info->crKey,
1820 (BLENDFUNCTION *)info->pblend,
1821 info->dwFlags,
1822 (RECT *)info->prcDirty);
1823 }
1824 SetLastError(ERROR_INVALID_PARAMETER);
1825 return FALSE;
1826 }
1827
1828
1829 /*
1830 * @implemented
1831 */
1832 HWND WINAPI
1833 WindowFromPoint(POINT Point)
1834 {
1835 //TODO: Determine what the actual parameters to
1836 // NtUserWindowFromPoint are.
1837 return NtUserWindowFromPoint(Point.x, Point.y);
1838 }
1839
1840
1841 /*
1842 * @implemented
1843 */
1844 int WINAPI
1845 MapWindowPoints(HWND hWndFrom, HWND hWndTo, LPPOINT lpPoints, UINT cPoints)
1846 {
1847 PWND FromWnd, ToWnd;
1848 POINT Delta;
1849 UINT i;
1850
1851 FromWnd = ValidateHwndOrDesk(hWndFrom);
1852 if (!FromWnd)
1853 return 0;
1854
1855 ToWnd = ValidateHwndOrDesk(hWndTo);
1856 if (!ToWnd)
1857 return 0;
1858
1859 Delta.x = FromWnd->rcClient.left - ToWnd->rcClient.left;
1860 Delta.y = FromWnd->rcClient.top - ToWnd->rcClient.top;
1861
1862 for (i = 0; i != cPoints; i++)
1863 {
1864 lpPoints[i].x += Delta.x;
1865 lpPoints[i].y += Delta.y;
1866 }
1867
1868 return MAKELONG(LOWORD(Delta.x), LOWORD(Delta.y));
1869 }
1870
1871
1872 /*
1873 * @implemented
1874 */
1875 BOOL WINAPI
1876 ScreenToClient(HWND hWnd, LPPOINT lpPoint)
1877 {
1878 PWND Wnd, DesktopWnd;
1879
1880 Wnd = ValidateHwnd(hWnd);
1881 if (!Wnd)
1882 return FALSE;
1883
1884 DesktopWnd = GetThreadDesktopWnd();
1885
1886 lpPoint->x += DesktopWnd->rcClient.left - Wnd->rcClient.left;
1887 lpPoint->y += DesktopWnd->rcClient.top - Wnd->rcClient.top;
1888
1889 return TRUE;
1890 }
1891
1892
1893 /*
1894 * @implemented
1895 */
1896 BOOL WINAPI
1897 ClientToScreen(HWND hWnd, LPPOINT lpPoint)
1898 {
1899 PWND Wnd, DesktopWnd;
1900
1901 Wnd = ValidateHwnd(hWnd);
1902 if (!Wnd)
1903 return FALSE;
1904
1905 DesktopWnd = GetThreadDesktopWnd();
1906
1907 lpPoint->x += Wnd->rcClient.left - DesktopWnd->rcClient.left;
1908 lpPoint->y += Wnd->rcClient.top - DesktopWnd->rcClient.top;
1909
1910 return TRUE;
1911 }
1912
1913
1914 /*
1915 * @implemented
1916 */
1917 BOOL WINAPI
1918 SetWindowContextHelpId(HWND hwnd,
1919 DWORD dwContextHelpId)
1920 {
1921 return NtUserSetWindowContextHelpId(hwnd, dwContextHelpId);
1922 }
1923
1924
1925 /*
1926 * @implemented
1927 */
1928 DWORD WINAPI
1929 GetWindowContextHelpId(HWND hwnd)
1930 {
1931 return NtUserCallHwnd(hwnd, HWND_ROUTINE_GETWNDCONTEXTHLPID);
1932 }
1933
1934 /*
1935 * @implemented
1936 */
1937 int WINAPI
1938 InternalGetWindowText(HWND hWnd, LPWSTR lpString, int nMaxCount)
1939 {
1940 INT Ret = NtUserInternalGetWindowText(hWnd, lpString, nMaxCount);
1941 if (Ret == 0)
1942 *lpString = L'\0';
1943 return Ret;
1944 }
1945
1946 /*
1947 * @implemented
1948 */
1949 BOOL WINAPI
1950 IsHungAppWindow(HWND hwnd)
1951 {
1952 return (NtUserQueryWindow(hwnd, QUERY_WINDOW_ISHUNG) != 0);
1953 }
1954
1955 /*
1956 * @implemented
1957 */
1958 VOID WINAPI
1959 SetLastErrorEx(DWORD dwErrCode, DWORD dwType)
1960 {
1961 SetLastError(dwErrCode);
1962 }
1963
1964 /*
1965 * @implemented
1966 */
1967 HWND WINAPI
1968 GetFocus(VOID)
1969 {
1970 return (HWND)NtUserGetThreadState(THREADSTATE_FOCUSWINDOW);
1971 }
1972
1973 DWORD WINAPI
1974 GetRealWindowOwner(HWND hwnd)
1975 {
1976 return NtUserQueryWindow(hwnd, QUERY_WINDOW_REAL_ID);
1977 }
1978
1979 /*
1980 * @implemented
1981 */
1982 HWND WINAPI
1983 SetTaskmanWindow(HWND hWnd)
1984 {
1985 return NtUserCallHwndOpt(hWnd, HWNDOPT_ROUTINE_SETTASKMANWINDOW);
1986 }
1987
1988 /*
1989 * @implemented
1990 */
1991 HWND WINAPI
1992 SetProgmanWindow(HWND hWnd)
1993 {
1994 return NtUserCallHwndOpt(hWnd, HWNDOPT_ROUTINE_SETPROGMANWINDOW);
1995 }
1996
1997 /*
1998 * @implemented
1999 */
2000 HWND WINAPI
2001 GetProgmanWindow(VOID)
2002 {
2003 return (HWND)NtUserGetThreadState(THREADSTATE_PROGMANWINDOW);
2004 }
2005
2006 /*
2007 * @implemented
2008 */
2009 HWND WINAPI
2010 GetTaskmanWindow(VOID)
2011 {
2012 return (HWND)NtUserGetThreadState(THREADSTATE_TASKMANWINDOW);
2013 }
2014
2015 /*
2016 * @implemented
2017 */
2018 BOOL WINAPI
2019 ScrollWindow(HWND hWnd,
2020 int dx,
2021 int dy,
2022 CONST RECT *lpRect,
2023 CONST RECT *prcClip)
2024 {
2025 return NtUserScrollWindowEx(hWnd,
2026 dx,
2027 dy,
2028 lpRect,
2029 prcClip,
2030 0,
2031 NULL,
2032 (lpRect ? 0 : SW_SCROLLCHILDREN) | SW_INVALIDATE) != ERROR;
2033 }
2034
2035
2036 /*
2037 * @implemented
2038 */
2039 INT WINAPI
2040 ScrollWindowEx(HWND hWnd,
2041 int dx,
2042 int dy,
2043 CONST RECT *prcScroll,
2044 CONST RECT *prcClip,
2045 HRGN hrgnUpdate,
2046 LPRECT prcUpdate,
2047 UINT flags)
2048 {
2049 return NtUserScrollWindowEx(hWnd,
2050 dx,
2051 dy,
2052 prcScroll,
2053 prcClip,
2054 hrgnUpdate,
2055 prcUpdate,
2056 flags);
2057 }
2058
2059 /*
2060 * @implemented
2061 */
2062 BOOL WINAPI
2063 AnyPopup(VOID)
2064 {
2065 return NtUserAnyPopup();
2066 }
2067
2068 /*
2069 * @implemented
2070 */
2071 BOOL WINAPI
2072 IsWindowInDestroy(HWND hWnd)
2073 {
2074 return NtUserIsWindowInDestroy(hWnd);
2075 }
2076
2077 /*
2078 * @implemented
2079 */
2080 VOID WINAPI
2081 DisableProcessWindowsGhosting(VOID)
2082 {
2083 NtUserEnableProcessWindowGhosting(FALSE);
2084 }
2085
2086 /* EOF */
2087