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