patch by Jonathon Wilson
[reactos.git] / reactos / lib / user32 / windows / window.c
1 /* $Id: window.c,v 1.58 2003/08/14 20:25:52 royce Exp $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS user32.dll
5 * FILE: lib/user32/windows/window.c
6 * PURPOSE: Window management
7 * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
8 * UPDATE HISTORY:
9 * 06-06-2001 CSH Created
10 */
11
12 /* INCLUDES ******************************************************************/
13
14 #include <windows.h>
15 #include <user32.h>
16 #include <window.h>
17 #include <string.h>
18 #include <user32/callback.h>
19 #include <user32/regcontrol.h>
20
21 #define NDEBUG
22 #include <debug.h>
23
24 static BOOL ControlsInitCalled = FALSE;
25
26 /* FUNCTIONS *****************************************************************/
27 ULONG
28 WinHasThickFrameStyle(ULONG Style, ULONG ExStyle)
29 {
30 return((Style & WS_THICKFRAME) &&
31 (!((Style & (WS_DLGFRAME | WS_BORDER)) == WS_DLGFRAME)));
32 }
33
34
35 NTSTATUS STDCALL
36 User32SendNCCALCSIZEMessageForKernel(PVOID Arguments, ULONG ArgumentLength)
37 {
38 PSENDNCCALCSIZEMESSAGE_CALLBACK_ARGUMENTS CallbackArgs;
39 SENDNCCALCSIZEMESSAGE_CALLBACK_RESULT Result;
40 WNDPROC Proc;
41
42 DPRINT("User32SendNCCALCSIZEMessageForKernel.\n");
43 CallbackArgs = (PSENDNCCALCSIZEMESSAGE_CALLBACK_ARGUMENTS)Arguments;
44 if (ArgumentLength != sizeof(SENDNCCALCSIZEMESSAGE_CALLBACK_ARGUMENTS))
45 {
46 DPRINT("Wrong length.\n");
47 return(STATUS_INFO_LENGTH_MISMATCH);
48 }
49 Proc = (WNDPROC)GetWindowLongW(CallbackArgs->Wnd, GWL_WNDPROC);
50 DPRINT("Proc %X\n", Proc);
51 /* Call the window procedure; notice kernel messages are always unicode. */
52 if (CallbackArgs->Validate)
53 {
54 Result.Result = CallWindowProcW(Proc, CallbackArgs->Wnd, WM_NCCALCSIZE,
55 TRUE,
56 (LPARAM)&CallbackArgs->Params);
57 Result.Params = CallbackArgs->Params;
58 }
59 else
60 {
61 Result.Result = CallWindowProcW(Proc, CallbackArgs->Wnd, WM_NCCALCSIZE,
62 FALSE, (LPARAM)&CallbackArgs->Rect);
63 Result.Rect = CallbackArgs->Rect;
64 }
65 DPRINT("Returning result %d.\n", Result);
66 return(ZwCallbackReturn(&Result, sizeof(Result), STATUS_SUCCESS));
67 }
68
69
70 NTSTATUS STDCALL
71 User32SendGETMINMAXINFOMessageForKernel(PVOID Arguments, ULONG ArgumentLength)
72 {
73 PSENDGETMINMAXINFO_CALLBACK_ARGUMENTS CallbackArgs;
74 SENDGETMINMAXINFO_CALLBACK_RESULT Result;
75 WNDPROC Proc;
76
77 DPRINT("User32SendGETMINAXINFOMessageForKernel.\n");
78 CallbackArgs = (PSENDGETMINMAXINFO_CALLBACK_ARGUMENTS)Arguments;
79 if (ArgumentLength != sizeof(SENDGETMINMAXINFO_CALLBACK_ARGUMENTS))
80 {
81 DPRINT("Wrong length.\n");
82 return(STATUS_INFO_LENGTH_MISMATCH);
83 }
84 Proc = (WNDPROC)GetWindowLongW(CallbackArgs->Wnd, GWL_WNDPROC);
85 DPRINT("Proc %X\n", Proc);
86 /* Call the window procedure; notice kernel messages are always unicode. */
87 Result.Result = CallWindowProcW(Proc, CallbackArgs->Wnd, WM_GETMINMAXINFO,
88 0, (LPARAM)&CallbackArgs->MinMaxInfo);
89 Result.MinMaxInfo = CallbackArgs->MinMaxInfo;
90 DPRINT("Returning result %d.\n", Result);
91 return(ZwCallbackReturn(&Result, sizeof(Result), STATUS_SUCCESS));
92 }
93
94
95 NTSTATUS STDCALL
96 User32SendCREATEMessageForKernel(PVOID Arguments, ULONG ArgumentLength)
97 {
98 PSENDCREATEMESSAGE_CALLBACK_ARGUMENTS CallbackArgs;
99 WNDPROC Proc;
100 LRESULT Result;
101
102 DPRINT("User32SendCREATEMessageForKernel.\n");
103 CallbackArgs = (PSENDCREATEMESSAGE_CALLBACK_ARGUMENTS)Arguments;
104 if (ArgumentLength != sizeof(SENDCREATEMESSAGE_CALLBACK_ARGUMENTS))
105 {
106 DPRINT("Wrong length.\n");
107 return(STATUS_INFO_LENGTH_MISMATCH);
108 }
109 Proc = (WNDPROC)GetWindowLongW(CallbackArgs->Wnd, GWL_WNDPROC);
110 DPRINT("Proc %X\n", Proc);
111 /* Call the window procedure; notice kernel messages are always unicode. */
112 Result = CallWindowProcW(Proc, CallbackArgs->Wnd, WM_CREATE, 0,
113 (LPARAM)&CallbackArgs->CreateStruct);
114 DPRINT("Returning result %d.\n", Result);
115 return(ZwCallbackReturn(&Result, sizeof(LRESULT), STATUS_SUCCESS));
116 }
117
118
119 NTSTATUS STDCALL
120 User32SendNCCREATEMessageForKernel(PVOID Arguments, ULONG ArgumentLength)
121 {
122 PSENDNCCREATEMESSAGE_CALLBACK_ARGUMENTS CallbackArgs;
123 WNDPROC Proc;
124 LRESULT Result;
125
126 DPRINT("User32SendNCCREATEMessageForKernel.\n");
127 CallbackArgs = (PSENDNCCREATEMESSAGE_CALLBACK_ARGUMENTS)Arguments;
128 if (ArgumentLength != sizeof(SENDNCCREATEMESSAGE_CALLBACK_ARGUMENTS))
129 {
130 DPRINT("Wrong length.\n");
131 return(STATUS_INFO_LENGTH_MISMATCH);
132 }
133 Proc = (WNDPROC)GetWindowLongW(CallbackArgs->Wnd, GWL_WNDPROC);
134 DPRINT("Proc %X\n", Proc);
135 /* Call the window procedure; notice kernel messages are always unicode. */
136 Result = CallWindowProcW(Proc, CallbackArgs->Wnd, WM_NCCREATE, 0,
137 (LPARAM)&CallbackArgs->CreateStruct);
138 DPRINT("Returning result %d.\n", Result);
139 return(ZwCallbackReturn(&Result, sizeof(LRESULT), STATUS_SUCCESS));
140 }
141
142
143 NTSTATUS STDCALL
144 User32SendWINDOWPOSCHANGINGMessageForKernel(PVOID Arguments, ULONG ArgumentLength)
145 {
146 PSENDWINDOWPOSCHANGING_CALLBACK_ARGUMENTS CallbackArgs;
147 WNDPROC Proc;
148 LRESULT Result;
149
150 DPRINT("User32SendWINDOWPOSCHANGINGMessageForKernel.\n");
151 CallbackArgs = (PSENDWINDOWPOSCHANGING_CALLBACK_ARGUMENTS)Arguments;
152 if (ArgumentLength != sizeof(SENDWINDOWPOSCHANGING_CALLBACK_ARGUMENTS))
153 {
154 DPRINT("Wrong length.\n");
155 return(STATUS_INFO_LENGTH_MISMATCH);
156 }
157 Proc = (WNDPROC)GetWindowLongW(CallbackArgs->Wnd, GWL_WNDPROC);
158 DPRINT("Proc %X\n", Proc);
159 /* Call the window procedure; notice kernel messages are always unicode. */
160 Result = CallWindowProcW(Proc, CallbackArgs->Wnd, WM_WINDOWPOSCHANGING, 0,
161 (LPARAM)&CallbackArgs->WindowPos);
162 DPRINT("Returning result %d.\n", Result);
163 return(ZwCallbackReturn(&Result, sizeof(LRESULT), STATUS_SUCCESS));
164 }
165
166
167 NTSTATUS STDCALL
168 User32SendWINDOWPOSCHANGEDMessageForKernel(PVOID Arguments, ULONG ArgumentLength)
169 {
170 PSENDWINDOWPOSCHANGED_CALLBACK_ARGUMENTS CallbackArgs;
171 WNDPROC Proc;
172 LRESULT Result;
173
174 DPRINT("User32SendWINDOWPOSCHANGEDMessageForKernel.\n");
175 CallbackArgs = (PSENDWINDOWPOSCHANGED_CALLBACK_ARGUMENTS)Arguments;
176 if (ArgumentLength != sizeof(SENDWINDOWPOSCHANGED_CALLBACK_ARGUMENTS))
177 {
178 DPRINT("Wrong length.\n");
179 return(STATUS_INFO_LENGTH_MISMATCH);
180 }
181 Proc = (WNDPROC)GetWindowLongW(CallbackArgs->Wnd, GWL_WNDPROC);
182 DPRINT("Proc %X\n", Proc);
183 /* Call the window procedure; notice kernel messages are always unicode. */
184 Result = CallWindowProcW(Proc, CallbackArgs->Wnd, WM_WINDOWPOSCHANGED, 0,
185 (LPARAM)&CallbackArgs->WindowPos);
186 DPRINT("Returning result %d.\n", Result);
187 return(ZwCallbackReturn(&Result, sizeof(LRESULT), STATUS_SUCCESS));
188 }
189
190
191 NTSTATUS STDCALL
192 User32SendSTYLECHANGINGMessageForKernel(PVOID Arguments, ULONG ArgumentLength)
193 {
194 PSENDSTYLECHANGING_CALLBACK_ARGUMENTS CallbackArgs;
195 WNDPROC Proc;
196 LRESULT Result;
197
198 DPRINT("User32SendSTYLECHANGINGMessageForKernel.\n");
199 CallbackArgs = (PSENDSTYLECHANGING_CALLBACK_ARGUMENTS)Arguments;
200 if (ArgumentLength != sizeof(SENDSTYLECHANGING_CALLBACK_ARGUMENTS))
201 {
202 DPRINT("Wrong length.\n");
203 return(STATUS_INFO_LENGTH_MISMATCH);
204 }
205 Proc = (WNDPROC)GetWindowLongW(CallbackArgs->Wnd, GWL_WNDPROC);
206 DPRINT("Proc %X\n", Proc);
207 /* Call the window procedure; notice kernel messages are always unicode. */
208 Result = CallWindowProcW(Proc, CallbackArgs->Wnd, WM_STYLECHANGING, CallbackArgs->WhichStyle,
209 (LPARAM)&CallbackArgs->Style);
210 DPRINT("Returning result %d.\n", Result);
211 return(ZwCallbackReturn(&Result, sizeof(LRESULT), STATUS_SUCCESS));
212 }
213
214
215 NTSTATUS STDCALL
216 User32SendSTYLECHANGEDMessageForKernel(PVOID Arguments, ULONG ArgumentLength)
217 {
218 PSENDSTYLECHANGED_CALLBACK_ARGUMENTS CallbackArgs;
219 WNDPROC Proc;
220 LRESULT Result;
221
222 DPRINT("User32SendSTYLECHANGEDGMessageForKernel.\n");
223 CallbackArgs = (PSENDSTYLECHANGED_CALLBACK_ARGUMENTS)Arguments;
224 if (ArgumentLength != sizeof(SENDSTYLECHANGED_CALLBACK_ARGUMENTS))
225 {
226 DPRINT("Wrong length.\n");
227 return(STATUS_INFO_LENGTH_MISMATCH);
228 }
229 Proc = (WNDPROC)GetWindowLongW(CallbackArgs->Wnd, GWL_WNDPROC);
230 DPRINT("Proc %X\n", Proc);
231 /* Call the window procedure; notice kernel messages are always unicode. */
232 Result = CallWindowProcW(Proc, CallbackArgs->Wnd, WM_STYLECHANGED, CallbackArgs->WhichStyle,
233 (LPARAM)&CallbackArgs->Style);
234 DPRINT("Returning result %d.\n", Result);
235 return(ZwCallbackReturn(&Result, sizeof(LRESULT), STATUS_SUCCESS));
236 }
237
238
239 NTSTATUS STDCALL
240 User32CallSendAsyncProcForKernel(PVOID Arguments, ULONG ArgumentLength)
241 {
242 PSENDASYNCPROC_CALLBACK_ARGUMENTS CallbackArgs;
243
244 DPRINT("User32CallSendAsyncProcKernel()\n");
245 CallbackArgs = (PSENDASYNCPROC_CALLBACK_ARGUMENTS)Arguments;
246 if (ArgumentLength != sizeof(WINDOWPROC_CALLBACK_ARGUMENTS))
247 {
248 return(STATUS_INFO_LENGTH_MISMATCH);
249 }
250 CallbackArgs->Callback(CallbackArgs->Wnd, CallbackArgs->Msg,
251 CallbackArgs->Context, CallbackArgs->Result);
252 return(STATUS_SUCCESS);
253 }
254
255
256 NTSTATUS STDCALL
257 User32CallWindowProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
258 {
259 PWINDOWPROC_CALLBACK_ARGUMENTS CallbackArgs;
260 LRESULT Result;
261
262 CallbackArgs = (PWINDOWPROC_CALLBACK_ARGUMENTS)Arguments;
263 if (ArgumentLength != sizeof(WINDOWPROC_CALLBACK_ARGUMENTS))
264 {
265 return(STATUS_INFO_LENGTH_MISMATCH);
266 }
267 if (CallbackArgs->Proc == NULL)
268 {
269 CallbackArgs->Proc = (WNDPROC)GetWindowLongW(CallbackArgs->Wnd, GWL_WNDPROC);
270 }
271 Result = CallWindowProcW(CallbackArgs->Proc, CallbackArgs->Wnd,
272 CallbackArgs->Msg, CallbackArgs->wParam,
273 CallbackArgs->lParam);
274 return(ZwCallbackReturn(&Result, sizeof(LRESULT), STATUS_SUCCESS));
275 }
276
277
278 static void NC_AdjustRectOuter95 (LPRECT rect, DWORD style, BOOL menu, DWORD exStyle)
279 {
280 int adjust;
281 if(style & WS_ICONIC) return;
282
283 if ((exStyle & (WS_EX_STATICEDGE|WS_EX_DLGMODALFRAME)) ==
284 WS_EX_STATICEDGE)
285 {
286 adjust = 1; /* for the outer frame always present */
287 }
288 else
289 {
290 adjust = 0;
291 if ((exStyle & WS_EX_DLGMODALFRAME) ||
292 (style & (WS_THICKFRAME|WS_DLGFRAME))) adjust = 2; /* outer */
293 }
294 if (style & WS_THICKFRAME)
295 adjust += ( GetSystemMetrics (SM_CXFRAME)
296 - GetSystemMetrics (SM_CXDLGFRAME)); /* The resize border */
297 if ((style & (WS_BORDER|WS_DLGFRAME)) ||
298 (exStyle & WS_EX_DLGMODALFRAME))
299 adjust++; /* The other border */
300
301 InflateRect (rect, adjust, adjust);
302
303 if ((style & WS_CAPTION) == WS_CAPTION)
304 {
305 if (exStyle & WS_EX_TOOLWINDOW)
306 rect->top -= GetSystemMetrics(SM_CYSMCAPTION);
307 else
308 rect->top -= GetSystemMetrics(SM_CYCAPTION);
309 }
310 if (menu) rect->top -= GetSystemMetrics(SM_CYMENU);
311 }
312
313
314 static void
315 NC_AdjustRectInner95 (LPRECT rect, DWORD style, DWORD exStyle)
316 {
317 if(style & WS_ICONIC) return;
318
319 if (exStyle & WS_EX_CLIENTEDGE)
320 InflateRect(rect, GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE));
321
322 if (style & WS_VSCROLL)
323 {
324 if((exStyle & WS_EX_LEFTSCROLLBAR) != 0)
325 rect->left -= GetSystemMetrics(SM_CXVSCROLL);
326 else
327 rect->right += GetSystemMetrics(SM_CXVSCROLL);
328 }
329 if (style & WS_HSCROLL) rect->bottom += GetSystemMetrics(SM_CYHSCROLL);
330 }
331
332
333 /*
334 * @implemented
335 */
336 WINBOOL STDCALL
337 AdjustWindowRect(LPRECT lpRect,
338 DWORD dwStyle,
339 WINBOOL bMenu)
340 {
341 return(AdjustWindowRectEx(lpRect, dwStyle, bMenu, 0));
342 }
343
344
345 /*
346 * @implemented
347 */
348 WINBOOL STDCALL
349 AdjustWindowRectEx(LPRECT lpRect,
350 DWORD dwStyle,
351 WINBOOL bMenu,
352 DWORD dwExStyle)
353 {
354 dwStyle &= (WS_DLGFRAME | WS_BORDER | WS_THICKFRAME | WS_CHILD);
355 dwExStyle &= (WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE |
356 WS_EX_STATICEDGE | WS_EX_TOOLWINDOW);
357 if (dwExStyle & WS_EX_DLGMODALFRAME) dwStyle &= ~WS_THICKFRAME;
358
359 NC_AdjustRectOuter95( lpRect, dwStyle, bMenu, dwExStyle );
360 NC_AdjustRectInner95( lpRect, dwStyle, dwExStyle );
361 lpRect->right += 2;
362 lpRect->bottom += 2;
363 return TRUE;
364 }
365
366
367 /*
368 * @unimplemented
369 */
370 WINBOOL STDCALL
371 AllowSetForegroundWindow(DWORD dwProcessId)
372 {
373 UNIMPLEMENTED;
374 return(FALSE);
375 }
376
377
378 /*
379 * @unimplemented
380 */
381 WINBOOL STDCALL
382 AnimateWindow(HWND hwnd,
383 DWORD dwTime,
384 DWORD dwFlags)
385 {
386 UNIMPLEMENTED;
387 return FALSE;
388 }
389
390
391 /*
392 * @unimplemented
393 */
394 UINT STDCALL
395 ArrangeIconicWindows(HWND hWnd)
396 {
397 UNIMPLEMENTED;
398 return 0;
399 }
400
401
402 /*
403 * @unimplemented
404 */
405 HDWP STDCALL
406 BeginDeferWindowPos(int nNumWindows)
407 {
408 UNIMPLEMENTED;
409 return (HDWP)0;
410 }
411
412
413 /*
414 * @unimplemented
415 */
416 WINBOOL STDCALL
417 BringWindowToTop(HWND hWnd)
418 {
419 UNIMPLEMENTED;
420 return FALSE;
421 }
422
423
424 /*
425 * @unimplemented
426 */
427 WORD STDCALL
428 CascadeWindows(HWND hwndParent,
429 UINT wHow,
430 CONST RECT *lpRect,
431 UINT cKids,
432 const HWND *lpKids)
433 {
434 UNIMPLEMENTED;
435 return 0;
436 }
437
438
439 /*
440 * @unimplemented
441 */
442 HWND STDCALL
443 ChildWindowFromPoint(HWND hWndParent,
444 POINT Point)
445 {
446 UNIMPLEMENTED;
447 return (HWND)0;
448 }
449
450
451 /*
452 * @unimplemented
453 */
454 HWND STDCALL
455 ChildWindowFromPointEx(HWND hwndParent,
456 POINT pt,
457 UINT uFlags)
458 {
459 UNIMPLEMENTED;
460 return (HWND)0;
461 }
462
463
464 /*
465 * @implemented
466 */
467 WINBOOL STDCALL
468 CloseWindow(HWND hWnd)
469 {
470 SendMessageA(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0);
471
472 return (WINBOOL)(hWnd);
473 }
474
475 /*
476 * @implemented
477 */
478 HWND STDCALL
479 CreateWindowExA(DWORD dwExStyle,
480 LPCSTR lpClassName,
481 LPCSTR lpWindowName,
482 DWORD dwStyle,
483 int x,
484 int y,
485 int nWidth,
486 int nHeight,
487 HWND hWndParent,
488 HMENU hMenu,
489 HINSTANCE hInstance,
490 LPVOID lpParam)
491 {
492 UNICODE_STRING WindowName;
493 UNICODE_STRING ClassName;
494 HWND Handle;
495 INT sw;
496
497 /* Register built-in controls if not already done */
498 if (! ControlsInitCalled)
499 {
500 ControlsInit();
501 ControlsInitCalled = TRUE;
502 }
503
504 if (IS_ATOM(lpClassName))
505 {
506 RtlInitUnicodeString(&ClassName, NULL);
507 ClassName.Buffer = (LPWSTR)lpClassName;
508 }
509 else
510 {
511 if (!RtlCreateUnicodeStringFromAsciiz(&(ClassName), (PCSZ)lpClassName))
512 {
513 SetLastError(ERROR_OUTOFMEMORY);
514 return (HWND)0;
515 }
516 }
517
518 if (!RtlCreateUnicodeStringFromAsciiz(&WindowName, (PCSZ)lpWindowName))
519 {
520 if (!IS_ATOM(lpClassName))
521 {
522 RtlFreeUnicodeString(&ClassName);
523 }
524 SetLastError(ERROR_OUTOFMEMORY);
525 return (HWND)0;
526 }
527
528 /* Fixup default coordinates. */
529 sw = SW_SHOW;
530 if (x == (LONG) CW_USEDEFAULT || nWidth == (LONG) CW_USEDEFAULT)
531 {
532 if (dwStyle & (WS_CHILD | WS_POPUP))
533 {
534 if (x == (LONG) CW_USEDEFAULT)
535 {
536 x = y = 0;
537 }
538 if (nWidth == (LONG) CW_USEDEFAULT)
539 {
540 nWidth = nHeight = 0;
541 }
542 }
543 else
544 {
545 STARTUPINFOA info;
546
547 GetStartupInfoA(&info);
548
549 if (x == (LONG) CW_USEDEFAULT)
550 {
551 if (y != (LONG) CW_USEDEFAULT)
552 {
553 sw = y;
554 }
555 x = (info.dwFlags & STARTF_USEPOSITION) ? info.dwX : 0;
556 y = (info.dwFlags & STARTF_USEPOSITION) ? info.dwY : 0;
557 }
558
559 if (nWidth == (LONG) CW_USEDEFAULT)
560 {
561 if (info.dwFlags & STARTF_USESIZE)
562 {
563 nWidth = info.dwXSize;
564 nHeight = info.dwYSize;
565 }
566 else
567 {
568 RECT r;
569
570 SystemParametersInfoA(SPI_GETWORKAREA, 0, &r, 0);
571 nWidth = (((r.right - r.left) * 3) / 4) - x;
572 nHeight = (((r.bottom - r.top) * 3) / 4) - y;
573 }
574 }
575 }
576 }
577
578 Handle = NtUserCreateWindowEx(dwExStyle,
579 &ClassName,
580 &WindowName,
581 dwStyle,
582 x,
583 y,
584 nWidth,
585 nHeight,
586 hWndParent,
587 hMenu,
588 hInstance,
589 lpParam,
590 sw);
591
592 RtlFreeUnicodeString(&WindowName);
593
594 if (!IS_ATOM(lpClassName))
595 {
596 RtlFreeUnicodeString(&ClassName);
597 }
598
599 return Handle;
600 }
601
602
603 /*
604 * @implemented
605 */
606 HWND STDCALL
607 CreateWindowExW(DWORD dwExStyle,
608 LPCWSTR lpClassName,
609 LPCWSTR lpWindowName,
610 DWORD dwStyle,
611 int x,
612 int y,
613 int nWidth,
614 int nHeight,
615 HWND hWndParent,
616 HMENU hMenu,
617 HINSTANCE hInstance,
618 LPVOID lpParam)
619 {
620 UNICODE_STRING WindowName;
621 UNICODE_STRING ClassName;
622 HANDLE Handle;
623 UINT sw;
624
625 /* Register built-in controls if not already done */
626 if (! ControlsInitCalled)
627 {
628 ControlsInit();
629 ControlsInitCalled = TRUE;
630 }
631
632 if (IS_ATOM(lpClassName))
633 {
634 RtlInitUnicodeString(&ClassName, NULL);
635 ClassName.Buffer = (LPWSTR)lpClassName;
636 }
637 else
638 {
639 RtlInitUnicodeString(&ClassName, lpClassName);
640 }
641
642 RtlInitUnicodeString(&WindowName, lpWindowName);
643
644 /* Fixup default coordinates. */
645 sw = SW_SHOW;
646 if (x == (LONG) CW_USEDEFAULT || nWidth == (LONG) CW_USEDEFAULT)
647 {
648 if (dwStyle & (WS_CHILD | WS_POPUP))
649 {
650 if (x == (LONG) CW_USEDEFAULT)
651 {
652 x = y = 0;
653 }
654 if (nWidth == (LONG) CW_USEDEFAULT)
655 {
656 nWidth = nHeight = 0;
657 }
658 }
659 else
660 {
661 STARTUPINFOW info;
662
663 GetStartupInfoW(&info);
664
665 if (x == (LONG) CW_USEDEFAULT)
666 {
667 if (y != (LONG) CW_USEDEFAULT)
668 {
669 sw = y;
670 }
671 x = (info.dwFlags & STARTF_USEPOSITION) ? info.dwX : 0;
672 y = (info.dwFlags & STARTF_USEPOSITION) ? info.dwY : 0;
673 }
674
675 if (nWidth == (LONG) CW_USEDEFAULT)
676 {
677 if (info.dwFlags & STARTF_USESIZE)
678 {
679 nWidth = info.dwXSize;
680 nHeight = info.dwYSize;
681 }
682 else
683 {
684 RECT r;
685
686 SystemParametersInfoW(SPI_GETWORKAREA, 0, &r, 0);
687 nWidth = (((r.right - r.left) * 3) / 4) - x;
688 nHeight = (((r.bottom - r.top) * 3) / 4) - y;
689 }
690 }
691 }
692 }
693
694 Handle = NtUserCreateWindowEx(dwExStyle,
695 &ClassName,
696 &WindowName,
697 dwStyle,
698 x,
699 y,
700 nWidth,
701 nHeight,
702 hWndParent,
703 hMenu,
704 hInstance,
705 lpParam,
706 0);
707
708 return (HWND)Handle;
709 }
710
711
712 /*
713 * @unimplemented
714 */
715 HDWP STDCALL
716 DeferWindowPos(HDWP hWinPosInfo,
717 HWND hWnd,
718 HWND hWndInsertAfter,
719 int x,
720 int y,
721 int cx,
722 int cy,
723 UINT uFlags)
724 {
725 return NtUserDeferWindowPos(hWinPosInfo, hWnd, hWndInsertAfter, x, y, cx, cy, uFlags);
726 }
727
728
729 /*
730 * @implemented
731 */
732 WINBOOL STDCALL
733 DestroyWindow(HWND hWnd)
734 {
735 return NtUserDestroyWindow(hWnd);
736 }
737
738
739 /*
740 * @unimplemented
741 */
742 WINBOOL STDCALL
743 EndDeferWindowPos(HDWP hWinPosInfo)
744 {
745 UNIMPLEMENTED;
746 return FALSE;
747 }
748
749
750 WINBOOL
751 STATIC
752 User32EnumWindows (
753 HDESK hDesktop,
754 HWND hWndparent,
755 ENUMWINDOWSPROC lpfn,
756 LPARAM lParam,
757 DWORD dwThreadId,
758 BOOL bChildren )
759 {
760 DWORD i, dwCount = 0;
761 HWND* pHwnd = NULL;
762 HANDLE hHeap;
763
764 if ( !lpfn )
765 {
766 SetLastError ( ERROR_INVALID_PARAMETER );
767 return FALSE;
768 }
769
770 /* FIXME instead of always making two calls, should we use some
771 sort of persistent buffer and only grow it ( requiring a 2nd
772 call ) when the buffer wasn't already big enough? */
773 /* first get how many window entries there are */
774 SetLastError(0);
775 dwCount = NtUserBuildHwndList (
776 hDesktop, hWndparent, bChildren, dwThreadId, lParam, NULL, 0 );
777 if ( !dwCount || GetLastError() )
778 return FALSE;
779
780 /* allocate buffer to receive HWND handles */
781 hHeap = GetProcessHeap();
782 pHwnd = HeapAlloc ( hHeap, 0, sizeof(HWND)*(dwCount+1) );
783 if ( !pHwnd )
784 {
785 SetLastError ( ERROR_NOT_ENOUGH_MEMORY );
786 return FALSE;
787 }
788
789 /* now call kernel again to fill the buffer this time */
790 dwCount = NtUserBuildHwndList (
791 hDesktop, hWndparent, bChildren, dwThreadId, lParam, pHwnd, dwCount );
792 if ( !dwCount || GetLastError() )
793 {
794 if ( pHwnd )
795 HeapFree ( hHeap, 0, pHwnd );
796 return FALSE;
797 }
798
799 /* call the user's callback function until we're done or
800 they tell us to quit */
801 for ( i = 0; i < dwCount; i++ )
802 {
803 /* FIXME I'm only getting NULLs from Thread Enumeration, and it's
804 * probably because I'm not doing it right in NtUserBuildHwndList.
805 * Once that's fixed, we shouldn't have to check for a NULL HWND
806 * here
807 */
808 if ( !(ULONG)pHwnd[i] ) /* don't enumerate a NULL HWND */
809 continue;
810 if ( !(*lpfn)( pHwnd[i], lParam ) )
811 break;
812 }
813 if ( pHwnd )
814 HeapFree ( hHeap, 0, pHwnd );
815 return TRUE;
816 }
817
818
819 /*
820 * @implemented
821 */
822 WINBOOL
823 STDCALL
824 EnumChildWindows(
825 HWND hWndParent,
826 ENUMWINDOWSPROC lpEnumFunc,
827 LPARAM lParam)
828 {
829 if ( !hWndParent )
830 hWndParent = GetDesktopWindow();
831 return User32EnumWindows ( NULL, hWndParent, lpEnumFunc, lParam, 0, FALSE );
832 }
833
834
835 /*
836 * @implemented
837 */
838 WINBOOL
839 STDCALL
840 EnumThreadWindows(DWORD dwThreadId,
841 ENUMWINDOWSPROC lpfn,
842 LPARAM lParam)
843 {
844 if ( !dwThreadId )
845 dwThreadId = GetCurrentThreadId();
846 return User32EnumWindows ( NULL, NULL, lpfn, lParam, dwThreadId, FALSE );
847 }
848
849
850 /*
851 * @implemented
852 */
853 WINBOOL STDCALL
854 EnumWindows(ENUMWINDOWSPROC lpEnumFunc,
855 LPARAM lParam)
856 {
857 return User32EnumWindows ( NULL, NULL, lpEnumFunc, lParam, 0, FALSE );
858 }
859
860
861 /*
862 * @implemented
863 */
864 WINBOOL
865 STDCALL
866 EnumDesktopWindows(
867 HDESK hDesktop,
868 ENUMWINDOWSPROC lpfn,
869 LPARAM lParam)
870 {
871 return User32EnumWindows ( hDesktop, NULL, lpfn, lParam, 0, FALSE );
872 }
873
874
875 /*
876 * @implemented
877 */
878 HWND STDCALL
879 FindWindowA(LPCSTR lpClassName, LPCSTR lpWindowName)
880 {
881 //FIXME: FindWindow does not search children, but FindWindowEx does.
882 // what should we do about this?
883 return FindWindowExA (NULL, NULL, lpClassName, lpWindowName);
884 }
885
886
887 /*
888 * @unimplemented
889 */
890 HWND STDCALL
891 FindWindowExA(HWND hwndParent,
892 HWND hwndChildAfter,
893 LPCSTR lpszClass,
894 LPCSTR lpszWindow)
895 {
896 UNIMPLEMENTED;
897 return (HWND)0;
898 }
899
900
901 /*
902 * @implemented
903 */
904 HWND STDCALL
905 FindWindowW(LPCWSTR lpClassName, LPCWSTR lpWindowName)
906 {
907 /*
908
909 There was a FIXME here earlier, but I think it is just a documentation unclarity.
910
911 FindWindow only searches top level windows. What they mean is that child
912 windows of other windows than the desktop can be searched.
913 FindWindowExW never does a recursive search.
914
915 / Joakim
916 */
917
918 return FindWindowExW (NULL, NULL, lpClassName, lpWindowName);
919 }
920
921
922 /*
923 * @implemented
924 */
925 HWND STDCALL
926 FindWindowExW(HWND hwndParent,
927 HWND hwndChildAfter,
928 LPCWSTR lpszClass,
929 LPCWSTR lpszWindow)
930 {
931 UNICODE_STRING ucClassName;
932 UNICODE_STRING ucWindowName;
933
934 if (IS_ATOM(lpszClass))
935 {
936 RtlInitUnicodeString(&ucClassName, NULL);
937 ucClassName.Buffer = (LPWSTR)lpszClass;
938 }
939 else
940 {
941 RtlInitUnicodeString(&ucClassName, lpszClass);
942 }
943
944 // Window names can't be atoms, and if lpszWindow = NULL,
945 // RtlInitUnicodeString will clear it
946
947 RtlInitUnicodeString(&ucWindowName, lpszWindow);
948
949
950 return NtUserFindWindowEx(hwndParent, hwndChildAfter, &ucClassName, &ucWindowName);
951 }
952
953 /*
954 * @unimplemented
955 */
956 WINBOOL STDCALL
957 GetAltTabInfoA(HWND hwnd,
958 int iItem,
959 PALTTABINFO pati,
960 LPSTR pszItemText,
961 UINT cchItemText)
962 {
963 UNIMPLEMENTED;
964 return FALSE;
965 }
966
967
968 /*
969 * @unimplemented
970 */
971 WINBOOL STDCALL
972 GetAltTabInfoW(HWND hwnd,
973 int iItem,
974 PALTTABINFO pati,
975 LPWSTR pszItemText,
976 UINT cchItemText)
977 {
978 UNIMPLEMENTED;
979 return FALSE;
980 }
981
982
983 /*
984 * @implemented
985 */
986 HWND STDCALL
987 GetAncestor(HWND hwnd, UINT gaFlags)
988 {
989 return(NtUserGetAncestor(hwnd, gaFlags));
990 }
991
992
993 /*
994 * @implemented
995 */
996 WINBOOL STDCALL
997 GetClientRect(HWND hWnd, LPRECT lpRect)
998 {
999 return(NtUserGetClientRect(hWnd, lpRect));
1000 }
1001
1002
1003 /*
1004 * @implemented
1005 */
1006 HWND STDCALL
1007 GetDesktopWindow(VOID)
1008 {
1009 return NtUserGetDesktopWindow();
1010 }
1011
1012
1013 /*
1014 * @unimplemented
1015 */
1016 HWND STDCALL
1017 GetForegroundWindow(VOID)
1018 {
1019 UNIMPLEMENTED;
1020 return (HWND)0;
1021 }
1022
1023
1024 /*
1025 * @unimplemented
1026 */
1027 WINBOOL STDCALL
1028 GetGUIThreadInfo(DWORD idThread,
1029 LPGUITHREADINFO lpgui)
1030 {
1031 UNIMPLEMENTED;
1032 return FALSE;
1033 }
1034
1035
1036 /*
1037 * @unimplemented
1038 */
1039 HWND STDCALL
1040 GetLastActivePopup(HWND hWnd)
1041 {
1042 return NtUserGetLastActivePopup(hWnd);
1043 }
1044
1045
1046 /*
1047 * @implemented
1048 */
1049 HWND STDCALL
1050 GetParent(HWND hWnd)
1051 {
1052 return NtUserGetParent(hWnd);
1053 }
1054
1055
1056 /*
1057 * @unimplemented
1058 */
1059 WINBOOL STDCALL
1060 GetProcessDefaultLayout(DWORD *pdwDefaultLayout)
1061 {
1062 UNIMPLEMENTED;
1063 return FALSE;
1064 }
1065
1066
1067 /*
1068 * @unimplemented
1069 */
1070 WINBOOL STDCALL
1071 GetTitleBarInfo(HWND hwnd,
1072 PTITLEBARINFO pti)
1073 {
1074 UNIMPLEMENTED;
1075 return FALSE;
1076 }
1077
1078
1079 /*
1080 * @implemented
1081 */
1082 HWND STDCALL
1083 GetTopWindow(HWND hWnd)
1084 {
1085 if (!hWnd) hWnd = GetDesktopWindow();
1086 return GetWindow( hWnd, GW_CHILD );
1087 }
1088
1089
1090 /*
1091 * @implemented
1092 */
1093 HWND STDCALL
1094 GetWindow(HWND hWnd,
1095 UINT uCmd)
1096 {
1097 return NtUserGetWindow(hWnd, uCmd);
1098 }
1099
1100
1101 /*
1102 * @unimplemented
1103 */
1104 WINBOOL STDCALL
1105 GetWindowInfo(HWND hwnd,
1106 PWINDOWINFO pwi)
1107 {
1108 UNIMPLEMENTED;
1109 return FALSE;
1110 }
1111
1112
1113 /*
1114 * @unimplemented
1115 */
1116 UINT STDCALL
1117 GetWindowModuleFileName(HWND hwnd,
1118 LPSTR lpszFileName,
1119 UINT cchFileNameMax)
1120 {
1121 UNIMPLEMENTED;
1122 return 0;
1123 }
1124
1125
1126 /*
1127 * @unimplemented
1128 */
1129 UINT STDCALL
1130 GetWindowModuleFileNameA(HWND hwnd,
1131 LPSTR lpszFileName,
1132 UINT cchFileNameMax)
1133 {
1134 UNIMPLEMENTED;
1135 return 0;
1136 }
1137
1138
1139 /*
1140 * @unimplemented
1141 */
1142 UINT STDCALL
1143 GetWindowModuleFileNameW(HWND hwnd,
1144 LPWSTR lpszFileName,
1145 UINT cchFileNameMax)
1146 {
1147 UNIMPLEMENTED;
1148 return 0;
1149 }
1150
1151
1152 /*
1153 * @unimplemented
1154 */
1155 WINBOOL STDCALL
1156 GetWindowPlacement(HWND hWnd,
1157 WINDOWPLACEMENT *lpwndpl)
1158 {
1159 UNIMPLEMENTED;
1160 return FALSE;
1161 }
1162
1163
1164 /*
1165 * @implemented
1166 */
1167 WINBOOL STDCALL
1168 GetWindowRect(HWND hWnd,
1169 LPRECT lpRect)
1170 {
1171 return(NtUserGetWindowRect(hWnd, lpRect));
1172 }
1173
1174
1175 /*
1176 * @implemented
1177 */
1178 int STDCALL
1179 GetWindowTextA(HWND hWnd, LPSTR lpString, int nMaxCount)
1180 {
1181 return(SendMessageA(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString));
1182 }
1183
1184
1185 /*
1186 * @implemented
1187 */
1188 int STDCALL
1189 GetWindowTextLengthA(HWND hWnd)
1190 {
1191 return(SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0));
1192 }
1193
1194
1195 /*
1196 * @implemented
1197 */
1198 int STDCALL
1199 GetWindowTextLengthW(HWND hWnd)
1200 {
1201 return(SendMessageW(hWnd, WM_GETTEXTLENGTH, 0, 0));
1202 }
1203
1204
1205 /*
1206 * @implemented
1207 */
1208 int STDCALL
1209 GetWindowTextW(
1210 HWND hWnd,
1211 LPWSTR lpString,
1212 int nMaxCount)
1213 {
1214 return(SendMessageW(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString));
1215 }
1216
1217 DWORD STDCALL
1218 GetWindowThreadProcessId(HWND hWnd,
1219 LPDWORD lpdwProcessId)
1220 {
1221 return NtUserGetWindowThreadProcessId(hWnd, lpdwProcessId);
1222 }
1223
1224
1225 /*
1226 * @unimplemented
1227 */
1228 WINBOOL STDCALL
1229 IsChild(HWND hWndParent,
1230 HWND hWnd)
1231 {
1232 UNIMPLEMENTED;
1233 return FALSE;
1234 }
1235
1236
1237 /*
1238 * @implemented
1239 */
1240 WINBOOL STDCALL
1241 IsIconic(HWND hWnd)
1242 {
1243 return (NtUserGetWindowLong( hWnd, GWL_STYLE, FALSE) & WS_MINIMIZE) != 0;
1244 }
1245
1246
1247 /*
1248 * @implemented
1249 */
1250 WINBOOL STDCALL
1251 IsWindow(HWND hWnd)
1252 {
1253 DWORD WndProc = NtUserGetWindowLong(hWnd, GWL_WNDPROC, FALSE);
1254 return (0 != WndProc || ERROR_INVALID_HANDLE != GetLastError());
1255 }
1256
1257
1258 /*
1259 * @implemented
1260 */
1261 WINBOOL STDCALL
1262 IsWindowUnicode(HWND hWnd)
1263 {
1264 return (WINBOOL)NtUserCallOneParam((DWORD)hWnd,ONEPARAM_ROUTINE_ISWINDOWUNICODE);
1265 }
1266
1267
1268 /*
1269 * @implemented
1270 */
1271 WINBOOL STDCALL
1272 IsWindowVisible(HWND hWnd)
1273 {
1274 while (GetWindowLongW(hWnd, GWL_STYLE) & WS_CHILD)
1275 {
1276 if (!(GetWindowLongW(hWnd, GWL_STYLE) & WS_VISIBLE))
1277 {
1278 return(FALSE);
1279 }
1280 hWnd = GetAncestor(hWnd, GA_PARENT);
1281 }
1282 return(GetWindowLongW(hWnd, GWL_STYLE) & WS_VISIBLE);
1283 }
1284
1285
1286 /*
1287 * @implemented
1288 */
1289 WINBOOL STDCALL
1290 IsZoomed(HWND hWnd)
1291 {
1292 ULONG uStyle = GetWindowLongW(hWnd, GWL_STYLE);
1293
1294 return (uStyle & WS_MAXIMIZE);
1295 }
1296
1297
1298 /*
1299 * @unimplemented
1300 */
1301 WINBOOL STDCALL
1302 LockSetForegroundWindow(UINT uLockCode)
1303 {
1304 UNIMPLEMENTED;
1305 return FALSE;
1306 }
1307
1308
1309 /*
1310 * @implemented
1311 */
1312 WINBOOL STDCALL
1313 MoveWindow(HWND hWnd,
1314 int X,
1315 int Y,
1316 int nWidth,
1317 int nHeight,
1318 WINBOOL bRepaint)
1319 {
1320 return NtUserMoveWindow(hWnd, X, Y, nWidth, nHeight, bRepaint);
1321 }
1322
1323
1324 /*
1325 * @unimplemented
1326 */
1327 WINBOOL STDCALL
1328 OpenIcon(HWND hWnd)
1329 {
1330 UNIMPLEMENTED;
1331 return FALSE;
1332 }
1333
1334
1335 /*
1336 * @unimplemented
1337 */
1338 HWND STDCALL
1339 RealChildWindowFromPoint(HWND hwndParent,
1340 POINT ptParentClientCoords)
1341 {
1342 UNIMPLEMENTED;
1343 return (HWND)0;
1344 }
1345
1346 /*
1347 * @unimplemented
1348 */
1349 WINBOOL STDCALL
1350 SetForegroundWindow(HWND hWnd)
1351 {
1352 UNIMPLEMENTED;
1353 return FALSE;
1354 }
1355
1356
1357 /*
1358 * @unimplemented
1359 */
1360 WINBOOL STDCALL
1361 SetLayeredWindowAttributes(HWND hwnd,
1362 COLORREF crKey,
1363 BYTE bAlpha,
1364 DWORD dwFlags)
1365 {
1366 UNIMPLEMENTED;
1367 return FALSE;
1368 }
1369
1370
1371 /*
1372 * @unimplemented
1373 */
1374 HWND STDCALL
1375 SetParent(HWND hWndChild,
1376 HWND hWndNewParent)
1377 {
1378 return NtUserSetParent(hWndChild, hWndNewParent);
1379 }
1380
1381
1382 /*
1383 * @unimplemented
1384 */
1385 WINBOOL STDCALL
1386 SetProcessDefaultLayout(DWORD dwDefaultLayout)
1387 {
1388 UNIMPLEMENTED;
1389 return FALSE;
1390 }
1391
1392
1393 /*
1394 * @unimplemented
1395 */
1396 WINBOOL STDCALL
1397 SetWindowPlacement(HWND hWnd,
1398 CONST WINDOWPLACEMENT *lpwndpl)
1399 {
1400 UNIMPLEMENTED;
1401 return FALSE;
1402 }
1403
1404
1405 /*
1406 * @implemented
1407 */
1408 WINBOOL STDCALL
1409 SetWindowPos(HWND hWnd,
1410 HWND hWndInsertAfter,
1411 int X,
1412 int Y,
1413 int cx,
1414 int cy,
1415 UINT uFlags)
1416 {
1417 return NtUserSetWindowPos(hWnd,hWndInsertAfter, X, Y, cx, cy, uFlags);
1418 }
1419
1420
1421 /*
1422 * @implemented
1423 */
1424 WINBOOL STDCALL
1425 SetWindowTextA(HWND hWnd,
1426 LPCSTR lpString)
1427 {
1428 return SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)lpString);
1429 }
1430
1431
1432 /*
1433 * @implemented
1434 */
1435 WINBOOL STDCALL
1436 SetWindowTextW(HWND hWnd,
1437 LPCWSTR lpString)
1438 {
1439 return SendMessageW(hWnd, WM_SETTEXT, 0, (LPARAM)lpString);
1440 }
1441
1442
1443 /*
1444 * @unimplemented
1445 */
1446 WINBOOL STDCALL
1447 ShowOwnedPopups(HWND hWnd,
1448 WINBOOL fShow)
1449 {
1450 UNIMPLEMENTED;
1451 return FALSE;
1452 }
1453
1454
1455 /*
1456 * @implemented
1457 */
1458 WINBOOL STDCALL
1459 ShowWindow(HWND hWnd,
1460 int nCmdShow)
1461 {
1462 return NtUserShowWindow(hWnd, nCmdShow);
1463 }
1464
1465
1466 /*
1467 * @unimplemented
1468 */
1469 WINBOOL STDCALL
1470 ShowWindowAsync(HWND hWnd,
1471 int nCmdShow)
1472 {
1473 UNIMPLEMENTED;
1474 return FALSE;
1475 }
1476
1477
1478 /*
1479 * @unimplemented
1480 */
1481 WORD STDCALL
1482 TileWindows(HWND hwndParent,
1483 UINT wHow,
1484 CONST RECT *lpRect,
1485 UINT cKids,
1486 const HWND *lpKids)
1487 {
1488 UNIMPLEMENTED;
1489 return 0;
1490 }
1491
1492
1493 /*
1494 * @unimplemented
1495 */
1496 WINBOOL STDCALL
1497 UpdateLayeredWindow(HWND hwnd,
1498 HDC hdcDst,
1499 POINT *pptDst,
1500 SIZE *psize,
1501 HDC hdcSrc,
1502 POINT *pptSrc,
1503 COLORREF crKey,
1504 BLENDFUNCTION *pblend,
1505 DWORD dwFlags)
1506 {
1507 UNIMPLEMENTED;
1508 return FALSE;
1509 }
1510
1511
1512 /*
1513 * @unimplemented
1514 */
1515 HWND STDCALL
1516 WindowFromPoint(POINT Point)
1517 {
1518 UNIMPLEMENTED;
1519 return (HWND)0;
1520 }
1521
1522
1523 /*
1524 * @implemented
1525 */
1526 int STDCALL
1527 MapWindowPoints(HWND hWndFrom, HWND hWndTo, LPPOINT lpPoints, UINT cPoints)
1528 {
1529 POINT FromOffset, ToOffset;
1530 LONG XMove, YMove;
1531 ULONG i;
1532
1533 NtUserGetClientOrigin(hWndFrom, &FromOffset);
1534 NtUserGetClientOrigin(hWndTo, &ToOffset);
1535 XMove = FromOffset.x - ToOffset.x;
1536 YMove = FromOffset.y - ToOffset.y;
1537
1538 for (i = 0; i < cPoints; i++)
1539 {
1540 lpPoints[i].x += XMove;
1541 lpPoints[i].y += YMove;
1542 }
1543 return(MAKELONG(LOWORD(XMove), LOWORD(YMove)));
1544 }
1545
1546
1547 /*
1548 * @implemented
1549 */
1550 WINBOOL STDCALL
1551 ScreenToClient(HWND hWnd, LPPOINT lpPoint)
1552 {
1553 return(MapWindowPoints(NULL, hWnd, lpPoint, 1));
1554 }
1555
1556
1557 /*
1558 * @implemented
1559 */
1560 WINBOOL STDCALL
1561 ClientToScreen(HWND hWnd, LPPOINT lpPoint)
1562 {
1563 return (MapWindowPoints( hWnd, NULL, lpPoint, 1 ));
1564 }
1565
1566
1567 WINBOOL
1568 STDCALL
1569 SetWindowContextHelpId(HWND hwnd,
1570 DWORD dwContextHelpId)
1571 {
1572 UNIMPLEMENTED;
1573 return(FALSE);
1574 }
1575
1576
1577 /*
1578 * @unimplemented
1579 */
1580 DWORD
1581 STDCALL
1582 GetWindowContextHelpId(HWND hwnd)
1583 {
1584 UNIMPLEMENTED;
1585 return(0);
1586 }
1587
1588 /*
1589 * @implemented
1590 */
1591 DWORD
1592 STDCALL
1593 InternalGetWindowText(HWND hWnd, LPWSTR lpString, int nMaxCount)
1594 {
1595 DWORD res = 0;
1596 LPWSTR lps = NULL;
1597 if(lpString && (nMaxCount > 0))
1598 {
1599 lps = RtlAllocateHeap(RtlGetProcessHeap(), 0, nMaxCount * sizeof(WCHAR));
1600 if(!lps)
1601 {
1602 SetLastError(ERROR_OUTOFMEMORY);
1603 return 0;
1604 }
1605 }
1606
1607 res = NtUserInternalGetWindowText(hWnd, lps, nMaxCount);
1608
1609 if(lps)
1610 {
1611 RtlCopyMemory(lpString, lps, res * sizeof(WCHAR));
1612 lpString[res] = (WCHAR)"\0"; /* null-terminate the string */
1613
1614 RtlFreeHeap(RtlGetProcessHeap(), 0, lps);
1615 }
1616
1617 return res;
1618 }
1619
1620 /*
1621 * @implemented
1622 */
1623 WINBOOL STDCALL IsHungAppWindow(HWND hwnd)
1624 {
1625 /* FIXME: ReactOS doesnt identify hung app windows yet */
1626 return FALSE;
1627 }
1628
1629 /* EOF */