source: trunk/src/user32/window.cpp@ 9928

Last change on this file since 9928 was 9928, checked in by sandervl, 22 years ago

WindowFromPoint: only send WM_NCHITTEST to windows belonging to the current thread

File size: 78.0 KB
Line 
1/* $Id: window.cpp,v 1.132 2003-03-20 09:15:31 sandervl Exp $ */
2/*
3 * Win32 window apis for OS/2
4 *
5 * Copyright 1999-2001 Sander van Leeuwen (sandervl@xs4all.nl)
6 * Copyright 1999 Daniela Engert (dani@ngrt.de)
7 * Copyright 2000 Christoph Bratschi (cbratschi@datacomm.ch)
8 *
9 * Parts based on Wine Windows code (windows\win.c, windows\property.c, windows\winpos.c)
10 *
11 * Copyright 1993, 1994, 1995 Alexandre Julliard
12 * 1995, 1996, 1999 Alex Korobka
13 *
14 * Project Odin Software License can be found in LICENSE.TXT
15 *
16 *
17 * TODO: Decide what to do about commands for OS/2 windows (non-Win32 apps)
18 * TODO: ShowOwnedPopups needs to be tested
19 * GetLastActivePopup needs to be rewritten
20 *
21 */
22
23#include <odin.h>
24#include <odinwrap.h>
25#include <os2sel.h>
26
27#include <os2win.h>
28#include <misc.h>
29#include <string.h>
30#include <stdio.h>
31#include <win32wbase.h>
32#include <win32wmdiclient.h>
33#include <win32wdesktop.h>
34#include "win32dlg.h"
35#include <oslibwin.h>
36#include <oslibgdi.h>
37#include "user32.h"
38#include "winicon.h"
39#include "oslibmsg.h"
40#include <win\winpos.h>
41#include <win\win.h>
42#include <heapstring.h>
43#include <winuser32.h>
44#include "hook.h"
45
46#define DBG_LOCALLOG DBG_window
47#include "dbglocal.h"
48
49ODINDEBUGCHANNEL(USER32-WINDOW)
50
51
52//******************************************************************************
53//******************************************************************************
54HWND WIN32API CreateWindowExA(DWORD exStyle,
55 LPCSTR className,
56 LPCSTR windowName,
57 DWORD style,
58 INT x,
59 INT y,
60 INT width,
61 INT height,
62 HWND parent,
63 HMENU menu,
64 HINSTANCE instance,
65 LPVOID data )
66{
67 Win32BaseWindow *window;
68 ATOM classAtom;
69 CREATESTRUCTA cs;
70 char tmpClass[20];
71
72 if(exStyle & WS_EX_MDICHILD)
73 return CreateMDIWindowA(className, windowName, style, x, y, width, height, parent, instance, (LPARAM)data);
74
75 /* Find the class atom */
76 if (!(classAtom = GlobalFindAtomA(className)))
77 {
78 if (!HIWORD(className))
79 dprintf(("CreateWindowEx32A: bad class name %04x\n",LOWORD(className)));
80 else
81 dprintf(("CreateWindowEx32A: bad class name '%s'\n", className));
82
83 SetLastError(ERROR_INVALID_PARAMETER);
84 return 0;
85 }
86
87 // if the pointer to the classname string has the high word cleared,
88 // then it's not a pointer but a number for one of the builtin classes
89 if (!HIWORD(className))
90 {
91 sprintf(tmpClass,"#%d", (int) className);
92 className = tmpClass;
93 }
94
95 /* Create the window */
96 cs.lpCreateParams = data;
97 cs.hInstance = instance;
98 cs.hMenu = menu;
99 cs.hwndParent = parent;
100 cs.x = x;
101 cs.y = y;
102 cs.cx = width;
103 cs.cy = height;
104 cs.style = style;
105 cs.lpszName = windowName;
106 cs.lpszClass = className;
107 cs.dwExStyle = exStyle;
108 if(HIWORD(className)) {
109 dprintf(("CreateWindowExA: class %s parent %x (%d,%d) (%d,%d), %x %x menu=%x", className, parent, x, y, width, height, style, exStyle, menu));
110 }
111 else dprintf(("CreateWindowExA: class %d parent %x (%d,%d) (%d,%d), %x %x menu=%x", className, parent, x, y, width, height, style, exStyle, menu));
112
113 if(!strcmpi(className, MDICLIENTCLASSNAMEA)) {
114 window = (Win32BaseWindow *) new Win32MDIClientWindow(&cs, classAtom, FALSE);
115 }
116 else
117 if(!strcmpi((char *) className, DIALOG_CLASS_NAMEA))
118 {
119 DLG_TEMPLATE dlgTemplate = {0};
120 dlgTemplate.style = cs.style;
121 dlgTemplate.exStyle = cs.dwExStyle;
122 dlgTemplate.x = cs.x;
123 dlgTemplate.y = cs.y;
124 dlgTemplate.cx = cs.cx;
125 dlgTemplate.cy = cs.cy;
126 dlgTemplate.className = cs.lpszClass;
127 dlgTemplate.caption = cs.lpszName;
128 window = (Win32BaseWindow *) new Win32Dialog(cs.hInstance,
129 (LPCSTR) &dlgTemplate,
130 cs.hwndParent,
131 NULL,
132 (LPARAM) data,
133 FALSE);
134 }
135 else {
136 window = new Win32BaseWindow( &cs, classAtom, FALSE );
137 }
138 if(window == NULL)
139 {
140 dprintf(("Win32BaseWindow creation failed!!"));
141 return 0;
142 }
143 if(GetLastError() != 0)
144 {
145 dprintf(("Win32BaseWindow error found!!"));
146 RELEASE_WNDOBJ(window);
147 delete window;
148 return 0;
149 }
150 HWND hwnd = window->getWindowHandle();
151
152 // set myself as last active popup / window
153 window->setLastActive( hwnd );
154
155 RELEASE_WNDOBJ(window);
156 return hwnd;
157}
158//******************************************************************************
159//******************************************************************************
160HWND WIN32API CreateWindowExW(DWORD exStyle,
161 LPCWSTR className,
162 LPCWSTR windowName,
163 DWORD style,
164 INT x,
165 INT y,
166 INT width,
167 INT height,
168 HWND parent,
169 HMENU menu,
170 HINSTANCE instance,
171 LPVOID data )
172{
173 Win32BaseWindow *window;
174 ATOM classAtom;
175 CREATESTRUCTA cs;
176 WCHAR tmpClassW[20];
177
178 if(exStyle & WS_EX_MDICHILD)
179 return CreateMDIWindowW(className, windowName, style, x, y, width, height, parent, instance, (LPARAM)data);
180
181 /* Find the class atom */
182 if (!(classAtom = GlobalFindAtomW(className)))
183 {
184 if (!HIWORD(className))
185 dprintf(("CreateWindowEx32W: bad class name %04x",LOWORD(className)));
186 else
187 dprintf(("CreateWindowEx32W: bad class name '%ls'", className));
188
189 SetLastError(ERROR_INVALID_PARAMETER);
190 return 0;
191 }
192#ifdef DEBUG
193 if(HIWORD(className)) {
194 dprintf(("CreateWindowExW: class %ls name %ls parent %x (%d,%d) (%d,%d), %x %x menu=%x", className, HIWORD(windowName) ? windowName : NULL, parent, x, y, width, height, style, exStyle, menu));
195 }
196 else dprintf(("CreateWindowExW: class %d name %ls parent %x (%d,%d) (%d,%d), %x %x menu=%x", className, HIWORD(windowName) ? windowName : NULL, parent, x, y, width, height, style, exStyle, menu));
197#endif
198 // if the pointer to the classname string has the high word cleared,
199 // then it's not a pointer but a number for one of the builtin classes
200 if (!HIWORD(className))
201 {
202 wsprintfW(tmpClassW, (LPCWSTR)L"#%d", (int) className);
203 className = tmpClassW;
204 }
205
206 /* Create the window */
207 cs.lpCreateParams = data;
208 cs.hInstance = instance;
209 cs.hMenu = menu;
210 cs.hwndParent = parent;
211 cs.x = x;
212 cs.y = y;
213 cs.cx = width;
214 cs.cy = height;
215 cs.style = style;
216 cs.lpszName = (LPSTR)windowName;
217 cs.lpszClass = (LPSTR)className;
218 cs.dwExStyle = exStyle;
219
220 if(!lstrcmpiW(className, (LPWSTR)MDICLIENTCLASSNAMEW)) {
221 window = (Win32BaseWindow *) new Win32MDIClientWindow(&cs, classAtom, TRUE);
222 }
223 else
224 if(!lstrcmpiW(className, (LPWSTR)DIALOG_CLASS_NAMEW))
225 {
226 DLG_TEMPLATE dlgTemplate = {0};
227 dlgTemplate.style = cs.style;
228 dlgTemplate.exStyle = cs.dwExStyle;
229 dlgTemplate.x = cs.x;
230 dlgTemplate.y = cs.y;
231 dlgTemplate.cx = cs.cx;
232 dlgTemplate.cy = cs.cy;
233 dlgTemplate.className = cs.lpszClass;
234 dlgTemplate.caption = cs.lpszName;
235 window = (Win32BaseWindow *) new Win32Dialog(cs.hInstance,
236 (LPCSTR) &dlgTemplate,
237 cs.hwndParent,
238 NULL,
239 (LPARAM) data,
240 TRUE);
241 }
242 else {
243 window = new Win32BaseWindow( &cs, classAtom, TRUE );
244 }
245 if(window == NULL)
246 {
247 dprintf(("Win32BaseWindow creation failed!!"));
248 return 0;
249 }
250 if(GetLastError() != 0)
251 {
252 dprintf(("Win32BaseWindow error found!!"));
253 RELEASE_WNDOBJ(window);
254 delete window;
255 return 0;
256 }
257 HWND hwnd = window->getWindowHandle();
258
259 // set myself as last active popup / window
260 window->setLastActive( hwnd );
261
262 RELEASE_WNDOBJ(window);
263 return hwnd;
264}
265//******************************************************************************
266//******************************************************************************
267HWND WIN32API CreateFakeWindowEx(HWND hwndOS2, ATOM classAtom)
268{
269 Win32BaseWindow *window;
270
271 window = new Win32BaseWindow(hwndOS2, classAtom);
272 if(window == NULL)
273 {
274 dprintf(("Win32BaseWindow creation failed!!"));
275 return 0;
276 }
277 HWND hwnd = window->getWindowHandle();
278
279 // set myself as last active popup / window
280 window->setLastActive( hwnd );
281
282 RELEASE_WNDOBJ(window);
283 return hwnd;
284}
285//******************************************************************************
286//******************************************************************************
287BOOL WIN32API DestroyFakeWindow(HWND hwnd)
288{
289 Win32BaseWindow *window;
290
291 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
292 if(!window) {
293 dprintf(("DestroyFakeWindow, window %x not found", hwnd));
294 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
295 return 0;
296 }
297 delete window;
298 return TRUE;
299}
300//******************************************************************************
301//******************************************************************************
302BOOL WIN32API DestroyWindow(HWND hwnd)
303{
304 Win32BaseWindow *window;
305 BOOL ret;
306
307 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
308 if(!window) {
309 dprintf(("DestroyWindow, window %x not found", hwnd));
310 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
311 return 0;
312 }
313 ret = window->DestroyWindow();
314 RELEASE_WNDOBJ(window);
315 return ret;
316}
317//******************************************************************************
318//******************************************************************************
319HWND WIN32API SetActiveWindow(HWND hwnd)
320{
321 Win32BaseWindow *window;
322 HWND hwndActive;
323
324 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
325 if(!window) {
326 dprintf(("SetActiveWindow, window %x not found", hwnd));
327 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
328 return 0;
329 }
330 hwndActive = window->SetActiveWindow();
331
332 // check last active popup window
333 if (hwndActive)
334 {
335 // TODO:
336 // set last active popup window to the ancestor window
337 dprintf(("support for last active popup incorrectly implemented"));
338 }
339
340 RELEASE_WNDOBJ(window);
341 return hwndActive;
342}
343//******************************************************************************
344//Note: does not set last error if no parent (verified in NT4, SP6)
345//******************************************************************************
346HWND WIN32API GetParent(HWND hwnd)
347{
348 Win32BaseWindow *window;
349 HWND hwndParent;
350
351 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
352 if(!window) {
353 dprintf(("GetParent, window %x not found", hwnd));
354 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
355 return 0;
356 }
357 dprintf2(("GetParent %x", hwnd));
358 hwndParent = window->GetParent();
359 RELEASE_WNDOBJ(window);
360 return hwndParent;
361}
362//******************************************************************************
363//******************************************************************************
364HWND WIN32API SetParent(HWND hwndChild, HWND hwndNewParent)
365{
366 Win32BaseWindow *window;
367 HWND hwndOldParent;
368
369 window = Win32BaseWindow::GetWindowFromHandle(hwndChild);
370 if(!window) {
371 dprintf(("SetParent, window %x not found", hwndChild));
372 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
373 return 0;
374 }
375 if(hwndNewParent == HWND_DESKTOP) {
376 hwndNewParent = GetDesktopWindow();
377 }
378 else {
379 if(!IsWindow(hwndNewParent)) {
380 RELEASE_WNDOBJ(window);
381 dprintf(("SetParent, parent %x not found", hwndNewParent));
382 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
383 return 0;
384 }
385 }
386 dprintf(("SetParent %x %x", hwndChild, hwndNewParent));
387 hwndOldParent = window->SetParent(hwndNewParent);
388 RELEASE_WNDOBJ(window);
389 return hwndOldParent;
390}
391//******************************************************************************
392//******************************************************************************
393BOOL WIN32API IsChild(HWND hwndParent, HWND hwnd)
394{
395 Win32BaseWindow *window;
396 BOOL fIsChild;
397
398 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
399 if(!window) {
400 dprintf(("IsChild %x, window %x not found", hwndParent, hwnd));
401 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
402 return 0;
403 }
404 dprintf(("IsChild %x %x", hwndParent, hwnd));
405 fIsChild = window->IsChild(hwndParent);
406 RELEASE_WNDOBJ(window);
407 return fIsChild;
408}
409//******************************************************************************
410//******************************************************************************
411HWND WIN32API GetTopWindow(HWND hwnd)
412{
413 Win32BaseWindow *window;
414 HWND hwndTop;
415
416 if(hwnd == HWND_DESKTOP) {
417 windowDesktop->addRef();
418 window = windowDesktop;
419 }
420 else {
421 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
422 if(!window) {
423 dprintf(("GetTopWindow, window %x not found", hwnd));
424 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
425 return 0;
426 }
427 }
428 hwndTop = window->GetTopWindow();
429 dprintf2(("GetTopWindow %x returned %x", hwnd, hwndTop));
430 RELEASE_WNDOBJ(window);
431 return hwndTop;
432}
433//******************************************************************************
434//******************************************************************************
435BOOL WIN32API IsIconic(HWND hwnd)
436{
437 Win32BaseWindow *window;
438 BOOL fIsIconic;
439
440 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
441 if(!window) {
442 dprintf(("IsIconic, window %x not found", hwnd));
443 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
444 return FALSE;
445 }
446 fIsIconic = window->IsWindowIconic();
447 dprintf(("IsIconic %x returned %d", hwnd, fIsIconic));
448 RELEASE_WNDOBJ(window);
449 return fIsIconic;
450}
451//******************************************************************************
452//******************************************************************************
453HWND WIN32API GetWindow(HWND hwnd, UINT uCmd)
454{
455 Win32BaseWindow *window;
456 HWND hwndRelated;
457
458 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
459 if(!window) {
460 dprintf(("GetWindow, window %x not found", hwnd));
461 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
462 return 0;
463 }
464 hwndRelated = window->GetWindow(uCmd);
465 RELEASE_WNDOBJ(window);
466 return hwndRelated;
467}
468//******************************************************************************
469//******************************************************************************
470BOOL WIN32API EnableWindow(HWND hwnd, BOOL fEnable)
471{
472 Win32BaseWindow *window;
473 BOOL fEnabled;
474
475 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
476 if(!window) {
477 dprintf(("EnableWindow, window %x not found", hwnd));
478 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
479 return 0;
480 }
481 dprintf(("EnableWindow %x %d", hwnd, fEnable));
482 fEnabled = window->EnableWindow(fEnable);
483 RELEASE_WNDOBJ(window);
484 return fEnabled;
485}
486//******************************************************************************
487//******************************************************************************
488BOOL WIN32API BringWindowToTop(HWND hwnd)
489{
490 dprintf(("BringWindowToTop %x", hwnd));
491 return SetWindowPos( hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE );
492}
493/***********************************************************************
494 * SetInternalWindowPos (USER32.483)
495 */
496VOID WIN32API SetInternalWindowPos(HWND hwnd, UINT showCmd, LPRECT lpRect,
497 LPPOINT lpPoint )
498{
499 if( IsWindow(hwnd) )
500 {
501 WINDOWPLACEMENT wndpl;
502 UINT flags;
503
504 GetWindowPlacement(hwnd, &wndpl);
505 wndpl.length = sizeof(wndpl);
506 wndpl.showCmd = showCmd;
507 wndpl.flags = 0;
508
509 if(lpPoint)
510 {
511 wndpl.flags |= WPF_SETMINPOSITION;
512 wndpl.ptMinPosition = *lpPoint;
513 }
514 if(lpRect)
515 {
516 wndpl.rcNormalPosition = *lpRect;
517 }
518 SetWindowPlacement(hwnd, &wndpl);
519 }
520
521}
522/***********************************************************************
523 * GetInternalWindowPos (USER32.245)
524 */
525UINT WIN32API GetInternalWindowPos(HWND hwnd, LPRECT rectWnd, LPPOINT ptIcon )
526{
527 WINDOWPLACEMENT wndpl;
528
529 if(GetWindowPlacement( hwnd, &wndpl ))
530 {
531 if (rectWnd) *rectWnd = wndpl.rcNormalPosition;
532 if (ptIcon) *ptIcon = wndpl.ptMinPosition;
533 return wndpl.showCmd;
534 }
535 return 0;
536}
537//******************************************************************************
538//******************************************************************************
539HWND GetActiveWindow()
540{
541 return Win32BaseWindow::GetActiveWindow();
542}
543//******************************************************************************
544//******************************************************************************
545BOOL WIN32API ShowWindow(HWND hwnd, INT nCmdShow)
546{
547 Win32BaseWindow *window;
548 BOOL ret;
549
550 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
551 if(!window) {
552 dprintf(("ShowWindow, window %x not found", hwnd));
553 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
554 return 0;
555 }
556 ret = window->ShowWindow(nCmdShow);
557 RELEASE_WNDOBJ(window);
558 return ret;
559}
560/*****************************************************************************
561 * Name : BOOL WIN32API ShowWindowAsync
562 * Purpose : The ShowWindowAsync function sets the show state of a window
563 * created by a different thread.
564 * Parameters: HWND hwnd handle of window
565 * int nCmdShow show state of window
566 * Variables :
567 * Result : If the window was previously visible, the return value is TRUE.
568 * If the window was previously hidden, the return value is FALSE.
569 * Remark :
570 * Status : UNTESTED STUB
571 *
572 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
573 *****************************************************************************/
574BOOL WIN32API ShowWindowAsync(HWND hwnd, int nCmdShow)
575{
576 dprintf(("USER32:ShowWindowAsync (%08xh,%08x) not correctly implemented.\n",
577 hwnd, nCmdShow));
578
579 return ShowWindow(hwnd, nCmdShow);
580}
581//******************************************************************************
582//******************************************************************************
583BOOL WIN32API SetWindowPos(HWND hwnd, HWND hwndInsertAfter, INT x,
584 INT y, INT cx, INT cy, UINT fuFlags)
585{
586 Win32BaseWindow *window;
587
588 if (!hwnd)
589 {
590 dprintf(("SetWindowPos: Can't move desktop!"));
591 return TRUE;
592 }
593 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
594 if(!window) {
595 dprintf(("SetWindowPos, window %x not found", hwnd));
596 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
597 return FALSE;
598 }
599 dprintf(("SetWindowPos %x %x x=%d y=%d cx=%d cy=%d %x", hwnd, hwndInsertAfter, x, y, cx, cy, fuFlags));
600 BOOL ret = window->SetWindowPos(hwndInsertAfter, x, y, cx, cy, fuFlags);
601 RELEASE_WNDOBJ(window);
602 return ret;
603}
604//******************************************************************************
605//NOTE: length must equal structure size or else api fails (verified in NT4, SP6)
606//******************************************************************************
607BOOL WIN32API SetWindowPlacement(HWND hwnd, const WINDOWPLACEMENT *winpos)
608{
609 Win32BaseWindow *window;
610
611 if(!winpos || winpos->length != sizeof(WINDOWPLACEMENT)) {
612 dprintf(("SetWindowPlacement %x invalid parameter", hwnd));
613 SetLastError(ERROR_INVALID_PARAMETER);
614 return FALSE;
615 }
616 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
617 if(!window) {
618 dprintf(("SetWindowPlacement, window %x not found", hwnd));
619 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
620 return FALSE;
621 }
622 dprintf(("USER32: SetWindowPlacement %x %x", hwnd, winpos));
623 BOOL ret = window->SetWindowPlacement((WINDOWPLACEMENT *)winpos);
624 RELEASE_WNDOBJ(window);
625 return ret;
626}
627//******************************************************************************
628//NOTE: Length does not need to be correct (even though the SDK docs claim otherwise)
629// (Verified in NT4, SP6)
630//******************************************************************************
631BOOL WIN32API GetWindowPlacement(HWND hwnd, LPWINDOWPLACEMENT winpos)
632{
633 Win32BaseWindow *window;
634
635 if(!winpos) {
636 dprintf(("GetWindowPlacement %x invalid parameter", hwnd));
637 SetLastError(ERROR_INVALID_PARAMETER);
638 return FALSE;
639 }
640 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
641 if(!window) {
642 dprintf(("GetWindowPlacement, window %x not found", hwnd));
643 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
644 return FALSE;
645 }
646 dprintf(("USER32: GetWindowPlacement %x %x", hwnd, winpos));
647 BOOL ret = window->GetWindowPlacement(winpos);
648 RELEASE_WNDOBJ(window);
649 return ret;
650}
651//******************************************************************************
652//******************************************************************************
653BOOL WIN32API IsWindow(HWND hwnd)
654{
655 Win32BaseWindow *window;
656
657 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
658 if(!window) {
659 dprintf(("IsWindow, window %x not found", hwnd));
660 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
661 return FALSE;
662 }
663 dprintf2(("IsWindow %x", hwnd));
664 BOOL fIsWindow = window->IsWindow();
665 RELEASE_WNDOBJ(window);
666 return fIsWindow;
667}
668//******************************************************************************
669//******************************************************************************
670BOOL WIN32API IsWindowEnabled(HWND hwnd)
671{
672 DWORD dwStyle;
673
674 if(!IsWindow(hwnd)) {
675 dprintf(("IsWindowEnabled, window %x not found", hwnd));
676 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
677 return 0;
678 }
679 dprintf(("IsWindowEnabled %x", hwnd));
680 dwStyle = GetWindowLongA(hwnd, GWL_STYLE);
681 if(dwStyle & WS_DISABLED) {
682 return FALSE;
683 }
684 return TRUE;
685}
686//******************************************************************************
687//******************************************************************************
688BOOL WIN32API IsWindowVisible(HWND hwnd)
689{
690 BOOL ret;
691 HWND hwndParent;
692 DWORD dwStyle;
693
694 if(hwnd == HWND_DESKTOP) {//TODO: verify in NT!
695 dprintf(("IsWindowVisible DESKTOP returned TRUE"));
696 return TRUE; //desktop is always visible
697 }
698 if(!IsWindow(hwnd)) {
699 dprintf(("IsWindowVisible, window %x not found", hwnd));
700 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
701 return 0;
702 }
703 //check visibility of this window
704 dwStyle = GetWindowLongA(hwnd, GWL_STYLE);
705 if(!(dwStyle & WS_VISIBLE)) {
706 ret = FALSE;
707 goto end;
708 }
709 ret = TRUE;
710
711 if(dwStyle & WS_CHILD)
712 {
713 //check visibility of parents
714 hwndParent = GetParent(hwnd);
715 while(hwndParent) {
716 dwStyle = GetWindowLongA(hwndParent, GWL_STYLE);
717 if(!(dwStyle & WS_VISIBLE)) {
718 dprintf(("IsWindowVisible %x returned FALSE (parent %x invisible)", hwnd, hwndParent));
719 return FALSE;
720 }
721 if(!(dwStyle & WS_CHILD)) {
722 break; //GetParent can also return the owner
723 }
724 hwndParent = GetParent(hwndParent);
725 }
726 }
727end:
728 dprintf(("IsWindowVisible %x returned %d", hwnd, ret));
729 return ret;
730}
731//******************************************************************************
732//******************************************************************************
733HWND WINAPI GetAncestor( HWND hwnd, UINT type )
734{
735 HWND hwndAncestor = 0;
736
737 if (type == GA_PARENT)
738 {
739 LONG dwStyle = GetWindowLongW( hwnd, GWL_STYLE );
740 if(dwStyle & WS_CHILD) {
741 hwndAncestor = GetParent(hwnd);
742 }
743 //else no child -> no parent (GetParent returns owner otherwise!)
744 return hwndAncestor;
745 }
746 dprintf(("Unsupported type %d", type));
747 return 0;
748}
749//******************************************************************************
750BOOL fIgnoreKeystrokes = FALSE;
751//******************************************************************************
752void SetFocusChanged()
753{
754 //Focus has changed; invalidate SetFocus(0) state
755 fIgnoreKeystrokes = FALSE;
756}
757//******************************************************************************
758//******************************************************************************
759HWND WIN32API SetFocus(HWND hwnd)
760{
761 Win32BaseWindow *window;
762 Win32BaseWindow *oldfocuswnd;
763 HWND lastFocus, lastFocus_W, hwnd_O, hwndTopParent, hwndTop;
764 BOOL activate, ret;
765 TEB *teb;
766
767 dprintf(("SetFocus %x", hwnd));
768 teb = GetThreadTEB();
769 if(teb == NULL) {
770 DebugInt3();
771 return 0;
772 }
773 //Special case; SetFocus(0) tells Windows to ignore keystrokes. Pressing
774 //a key now generates WM_SYSKEYDOWN/(WM_SYSCHAR)/WM_SYSKEYUP instead
775 //of WM_KEYDOWN/(WM_CHAR)/WM_KEYUP
776 //WM_KILLFOCUS is sent to the window that currently has focus
777 if(hwnd == 0) {
778 lastFocus_W = GetFocus();
779 if(lastFocus_W == 0) return 0; //nothing to do
780
781 if(HOOK_CallHooksA(WH_CBT, HCBT_SETFOCUS, 0, (LPARAM)lastFocus_W)) {
782 dprintf(("hook cancelled SetFocus call!"));
783 return 0;
784 }
785 SendMessageA(lastFocus_W, WM_KILLFOCUS, 0, 0);
786
787 fIgnoreKeystrokes = TRUE;
788
789 return lastFocus_W;
790 }
791
792 //SetFocus is not allowed for minimized or disabled windows (this window
793 //or any parent)
794 hwndTop = hwnd;
795 for (;;)
796 {
797 HWND parent;
798
799 LONG style = GetWindowLongW( hwndTop, GWL_STYLE );
800 if (style & (WS_MINIMIZE | WS_DISABLED)) {
801 dprintf(("SetFocus, %x not allowed on minimized or disabled window (%x)", hwnd, style));
802 return 0;
803 }
804 parent = GetAncestor(hwndTop, GA_PARENT);
805 if (!parent || parent == GetDesktopWindow()) break;
806 hwndTop = parent;
807 }
808
809 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
810 if(!window) {
811 dprintf(("SetFocus, window %x not found", hwnd));
812 //Note: last error not set (NT4, SP6), returns current focus window
813 //SetLastError(ERROR_INVALID_WINDOW_HANDLE);
814 return GetFocus();
815 }
816
817 hwnd_O = window->getOS2WindowHandle();
818 if(teb->o.odin.hwndFocus) {
819 lastFocus = teb->o.odin.hwndFocus;
820 }
821 else lastFocus = OSLibWinQueryFocus (OSLIB_HWND_DESKTOP);
822
823 hwndTopParent = window->GetTopParent();
824 activate = FALSE;
825 lastFocus_W = OS2ToWin32Handle(lastFocus);
826 if(lastFocus_W) {
827 oldfocuswnd = Win32BaseWindow::GetWindowFromHandle(lastFocus_W);
828 if(lastFocus_W != hwnd && hwndTopParent != oldfocuswnd->GetTopParent()) {
829 activate = TRUE;
830 }
831 RELEASE_WNDOBJ(oldfocuswnd);
832 }
833 else activate = TRUE;
834
835 dprintf(("SetFocus %x (%x) -> %x (%x) act %d", lastFocus_W, lastFocus, hwnd, hwnd_O, activate));
836
837 if(HOOK_CallHooksA(WH_CBT, HCBT_SETFOCUS, hwnd, (LPARAM)lastFocus_W)) {
838 dprintf(("hook cancelled SetFocus call!"));
839 RELEASE_WNDOBJ(window);
840 return 0;
841 }
842
843 //PM doesn't allow SetFocus calls during WM_SETFOCUS message processing;
844 //must delay this function call
845 if(teb->o.odin.fWM_SETFOCUS) {
846 dprintf(("USER32: Delay SetFocus call!"));
847 teb->o.odin.hwndFocus = hwnd;
848
849 //If keystrokes were ignored and focus is set to the old focus window, then
850 //PM won't send us a WM_SETFOCUS message. (as we don't inform PM for SetFocus(0))
851 if(fIgnoreKeystrokes && lastFocus_W == hwnd) {
852 dprintf(("Manually send WM_SETFOCUS; real focus window hasn't changed"));
853 SendMessageA(lastFocus_W, WM_SETFOCUS, 0, 0);
854 }
855 else {
856 //mp1 = win32 window handle
857 //mp2 = top parent if activation required
858 OSLibPostMessageDirect(hwnd_O, WIN32APP_SETFOCUSMSG, hwnd, (activate) ? hwndTopParent : 0);
859 }
860 RELEASE_WNDOBJ(window);
861 return lastFocus_W;
862 }
863 teb->o.odin.hwndFocus = 0;
864 if(!IsWindow(hwnd)) return FALSE; //abort if window destroyed
865
866 //NOTE: Don't always activate the window or else the z-order will be changed!!
867 ret = (OSLibWinSetFocus(OSLIB_HWND_DESKTOP, hwnd_O, activate)) ? lastFocus_W : 0;
868 RELEASE_WNDOBJ(window);
869
870 //If keystrokes were ignored and focus is set to the old focus window, then
871 //PM won't send us a WM_SETFOCUS message. (as we don't inform PM for SetFocus(0))
872 if(fIgnoreKeystrokes && lastFocus_W == hwnd) {
873 dprintf(("Manually send WM_SETFOCUS; real focus window hasn't changed"));
874 SendMessageA(lastFocus_W, WM_SETFOCUS, 0, 0);
875 }
876
877 fIgnoreKeystrokes = FALSE;
878 return ret;
879}
880//******************************************************************************
881//******************************************************************************
882HWND WIN32API GetFocus()
883{
884 TEB *teb;
885 HWND hwnd;
886
887 teb = GetThreadTEB();
888 if(teb == NULL) {
889 DebugInt3();
890 return 0;
891 }
892 //If keystrokes are ignored (SetFocus(0)), then return 0
893 if(fIgnoreKeystrokes) {
894 dprintf(("GetFocus; returning 0 after SetFocus(0) call"));
895 return 0;
896 }
897 //PM doesn't allow SetFocus calls during WM_SETFOCUS message processing;
898 //If focus was changed during WM_SETFOCUS, the focus window handle is
899 //stored in teb->o.odin.hwndFocus (set back to 0 when delayed SetFocus
900 //is activated)
901 if(teb->o.odin.hwndFocus) {
902 dprintf(("USER32: GetFocus %x (DURING WM_SETFOCUS PROCESSING)", teb->o.odin.hwndFocus));
903 return teb->o.odin.hwndFocus;
904 }
905
906 hwnd = OSLibWinQueryFocus(OSLIB_HWND_DESKTOP);
907 hwnd = OS2ToWin32Handle(hwnd);
908 dprintf(("USER32: GetFocus %x\n", hwnd));
909 return hwnd;
910}
911//******************************************************************************
912//******************************************************************************
913BOOL WIN32API GetGUIThreadInfo(DWORD dwThreadId, GUITHREADINFO *lpThreadInfo)
914{
915 dprintf(("!WARNING!: GetGUIThreadInfo not completely implemented!!"));
916
917 if(!lpThreadInfo || lpThreadInfo->cbSize != sizeof(GUITHREADINFO)) {
918 SetLastError(ERROR_INVALID_PARAMETER);
919 return FALSE;
920 }
921 //dwThreadId == 0 -> current thread
922 if(!dwThreadId) dwThreadId = GetCurrentThreadId();
923
924 lpThreadInfo->flags;
925 lpThreadInfo->hwndActive = GetActiveWindow();
926 if(lpThreadInfo->hwndActive) {
927 if(dwThreadId != GetWindowThreadProcessId(lpThreadInfo->hwndActive, NULL))
928 {//this thread doesn't own the active window (TODO: correct??)
929 lpThreadInfo->hwndActive = 0;
930 }
931 }
932 lpThreadInfo->hwndFocus = GetFocus();
933 lpThreadInfo->hwndCapture = GetCapture();
934 lpThreadInfo->flags = 0; //TODO:
935 lpThreadInfo->hwndMenuOwner = 0; //TODO: Handle to the window that owns any active menus
936 lpThreadInfo->hwndMoveSize = 0; //TODO: Handle to the window in a move or size loop.
937 lpThreadInfo->hwndCaret = 0; //TODO: Handle to the window that is displaying the caret
938 lpThreadInfo->rcCaret.left = 0;
939 lpThreadInfo->rcCaret.top = 0;
940 lpThreadInfo->rcCaret.right = 0;
941 lpThreadInfo->rcCaret.bottom = 0;
942
943 SetLastError(ERROR_SUCCESS);
944 return TRUE;
945}
946//******************************************************************************
947//******************************************************************************
948BOOL WIN32API IsZoomed(HWND hwnd)
949{
950 DWORD style;
951
952 style = GetWindowLongA(hwnd, GWL_STYLE);
953 dprintf(("USER32: IsZoomed %x returned %d", hwnd, ((style & WS_MAXIMIZE) != 0)));
954
955 return (style & WS_MAXIMIZE) != 0;
956}
957//******************************************************************************
958//******************************************************************************
959BOOL WIN32API LockWindowUpdate(HWND hwnd)
960{
961 return OSLibWinLockWindowUpdate(Win32ToOS2Handle(hwnd));
962}
963//******************************************************************************
964//******************************************************************************
965BOOL WIN32API GetWindowRect(HWND hwnd, PRECT pRect)
966{
967 Win32BaseWindow *window;
968
969 if(pRect == NULL) {
970 dprintf(("GetWindowRect %x invalid parameter!", hwnd));
971 SetLastError(ERROR_INVALID_PARAMETER);
972 return FALSE;
973 }
974
975 if(hwnd == HWND_DESKTOP) {
976 windowDesktop->addRef();
977 window = windowDesktop;
978 }
979 else window = Win32BaseWindow::GetWindowFromHandle(hwnd);
980
981 if(!window) {
982 dprintf(("GetWindowRect, window %x not found", hwnd));
983 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
984 return FALSE;
985 }
986 *pRect = *window->getWindowRect();
987
988 //convert from parent coordinates to screen (if necessary)
989 if(window->getParent()) {
990 MapWindowPoints(window->getParent()->getWindowHandle(), 0, (PPOINT)pRect, 2);
991 }
992 RELEASE_WNDOBJ(window);
993 dprintf(("GetWindowRect %x (%d,%d) (%d,%d)", hwnd, pRect->left, pRect->top, pRect->right, pRect->bottom));
994 return TRUE;
995}
996//******************************************************************************
997//******************************************************************************
998INT WIN32API GetWindowTextLengthA(HWND hwnd)
999{
1000 Win32BaseWindow *window;
1001
1002 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
1003 if(!window) {
1004 dprintf(("GetWindowTextLengthA, window %x not found", hwnd));
1005 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
1006 return 0;
1007 }
1008 dprintf(("GetWindowTextLengthA %x", hwnd));
1009 int ret = window->GetWindowTextLengthA();
1010 RELEASE_WNDOBJ(window);
1011 return ret;
1012}
1013//******************************************************************************
1014//******************************************************************************
1015int WIN32API GetWindowTextA( HWND hwnd, LPSTR lpsz, int cch)
1016{
1017 Win32BaseWindow *window;
1018 int rc;
1019
1020 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
1021 if(!window) {
1022 dprintf(("GetWindowTextA, window %x not found", hwnd));
1023 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
1024 return 0;
1025 }
1026 rc = window->GetWindowTextA(lpsz, cch);
1027 dprintf(("GetWindowTextA %x %s", hwnd, lpsz));
1028 RELEASE_WNDOBJ(window);
1029 return rc;
1030}
1031//******************************************************************************
1032//******************************************************************************
1033int WIN32API GetWindowTextLengthW( HWND hwnd)
1034{
1035 Win32BaseWindow *window;
1036
1037 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
1038 if(!window) {
1039 dprintf(("GetWindowTextLengthW, window %x not found", hwnd));
1040 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
1041 return 0;
1042 }
1043 dprintf(("GetWindowTextLengthW %x", hwnd));
1044 int ret = window->GetWindowTextLengthW();
1045 RELEASE_WNDOBJ(window);
1046 return ret;
1047}
1048//******************************************************************************
1049//******************************************************************************
1050int WIN32API GetWindowTextW(HWND hwnd, LPWSTR lpsz, int cch)
1051{
1052 Win32BaseWindow *window;
1053
1054 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
1055 if(!window) {
1056 dprintf(("GetWindowTextW, window %x not found", hwnd));
1057 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
1058 return 0;
1059 }
1060 int rc = window->GetWindowTextW(lpsz, cch);
1061 RELEASE_WNDOBJ(window);
1062 dprintf(("GetWindowTextW %x %ls", hwnd, lpsz));
1063 return rc;
1064}
1065//******************************************************************************
1066//******************************************************************************
1067BOOL WIN32API SetWindowTextA(HWND hwnd, LPCSTR lpsz)
1068{
1069 Win32BaseWindow *window;
1070
1071 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
1072 if(!window) {
1073 dprintf(("SetWindowTextA, window %x not found", hwnd));
1074 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
1075 return 0;
1076 }
1077 dprintf(("SetWindowTextA %x %s", hwnd, lpsz));
1078 BOOL ret = window->SetWindowTextA((LPSTR)lpsz);
1079 RELEASE_WNDOBJ(window);
1080 return ret;
1081}
1082//******************************************************************************
1083//******************************************************************************
1084BOOL WIN32API SetWindowTextW( HWND hwnd, LPCWSTR lpsz)
1085{
1086 Win32BaseWindow *window;
1087
1088 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
1089 if(!window) {
1090 dprintf(("SetWindowTextA, window %x not found", hwnd));
1091 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
1092 return 0;
1093 }
1094 dprintf(("SetWindowTextW %x %ls", hwnd, lpsz));
1095 BOOL ret = window->SetWindowTextW((LPWSTR)lpsz);
1096 RELEASE_WNDOBJ(window);
1097 return ret;
1098}
1099/*******************************************************************
1100 * InternalGetWindowText (USER32.326)
1101 */
1102int WIN32API InternalGetWindowText(HWND hwnd,
1103 LPWSTR lpString,
1104 INT nMaxCount )
1105{
1106 dprintf(("USER32: InternalGetWindowText(%08xh,%08xh,%08xh) not properly implemented.\n",
1107 hwnd, lpString, nMaxCount));
1108
1109 return GetWindowTextW(hwnd, lpString,nMaxCount);
1110}
1111//******************************************************************************
1112//TODO: Correct?
1113//******************************************************************************
1114BOOL WIN32API SetForegroundWindow(HWND hwnd)
1115{
1116 dprintf((" SetForegroundWindow %x", hwnd));
1117
1118 return SetWindowPos( hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
1119}
1120//******************************************************************************
1121//******************************************************************************
1122BOOL WIN32API GetClientRect( HWND hwnd, PRECT pRect)
1123{
1124 HWND hwndWin32 = hwnd;
1125 Win32BaseWindow *window;
1126
1127 if (!pRect)
1128 {
1129 SetLastError(ERROR_INVALID_PARAMETER);
1130 return FALSE;
1131 }
1132 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
1133 if(!window) {
1134 dprintf(("GetClientRect, window %x not found", hwnd));
1135 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
1136 return FALSE;
1137 }
1138 window->getClientRect(pRect);
1139 dprintf(("GetClientRect of %X returned (%d,%d) (%d,%d)\n", hwndWin32, pRect->left, pRect->top, pRect->right, pRect->bottom));
1140 RELEASE_WNDOBJ(window);
1141 return TRUE;
1142}
1143//******************************************************************************
1144//******************************************************************************
1145BOOL WIN32API AdjustWindowRect(PRECT rect, DWORD style, BOOL menu)
1146{
1147 return AdjustWindowRectEx(rect, style, menu, 0);
1148}
1149//******************************************************************************
1150//Calculate window rectangle based on given client rectangle, style, menu and extended style
1151//******************************************************************************
1152BOOL WIN32API AdjustWindowRectEx( PRECT rect, DWORD style, BOOL menu, DWORD exStyle)
1153{
1154 if(style == 0 && menu == FALSE && exStyle == 0) {
1155 dprintf(("AdjustWindowRectEx %x %x %d (%d,%d)(%d,%d) -> no change required", style, exStyle, menu, rect->left, rect->top, rect->right, rect->bottom));
1156 return TRUE; //nothing needs to be changed (VERIFIED in NT 4)
1157 }
1158 dprintf(("AdjustWindowRectEx %x %x %d (%d,%d)(%d,%d)\n", style, exStyle, menu, rect->left, rect->top, rect->right, rect->bottom));
1159 /* Correct the window style */
1160 if (!(style & (WS_POPUP | WS_CHILD))) /* Overlapped window */
1161 style |= WS_CAPTION;
1162
1163 //SvL: Include WS_POPUP -> otherwise HAS_THINFRAME is true for popup windows
1164 // Also include WS_CHILD -> otherwise HAS_THICKFRAME doesn't work correctly
1165 style &= (WS_DLGFRAME | WS_BORDER | WS_THICKFRAME | WS_CHILD | WS_VSCROLL | WS_HSCROLL | WS_POPUP);
1166 exStyle &= (WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE | WS_EX_TOOLWINDOW);
1167 if (exStyle & WS_EX_DLGMODALFRAME) style &= ~WS_THICKFRAME;
1168
1169 //Adjust rect outer (Win32BaseWindow::AdjustRectOuter)
1170 if (HAS_THICKFRAME(style,exStyle))
1171 InflateRect( rect, GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME) );
1172 else
1173 if (HAS_DLGFRAME(style,exStyle))
1174 InflateRect(rect, GetSystemMetrics(SM_CXDLGFRAME), GetSystemMetrics(SM_CYDLGFRAME) );
1175 else
1176 if (HAS_THINFRAME(style))
1177 InflateRect( rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
1178
1179 if ((style & WS_CAPTION) == WS_CAPTION)
1180 {
1181 if (exStyle & WS_EX_TOOLWINDOW)
1182 rect->top -= GetSystemMetrics(SM_CYSMCAPTION);
1183 else
1184 rect->top -= GetSystemMetrics(SM_CYCAPTION);
1185 }
1186
1187 if (menu)
1188 rect->top -= GetSystemMetrics(SM_CYMENU);
1189
1190 //Adjust rect inner (Win32BaseWindow::AdjustRectInner)
1191 if(!(style & WS_ICONIC)) {
1192 if (exStyle & WS_EX_CLIENTEDGE)
1193 InflateRect (rect, GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE));
1194
1195 if (exStyle & WS_EX_STATICEDGE)
1196 InflateRect (rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
1197
1198 //SvL: scrollbars aren't checked *UNLESS* the style includes a border (any border)
1199 // --> VERIFIED IN NT4, SP6 (fixes MFC apps with scrollbars + bar controls)
1200 if(style & (WS_THICKFRAME|WS_BORDER|WS_DLGFRAME)) {
1201 if (style & WS_VSCROLL) rect->right += GetSystemMetrics(SM_CXVSCROLL);
1202 if (style & WS_HSCROLL) rect->bottom += GetSystemMetrics(SM_CYHSCROLL);
1203 }
1204 }
1205
1206 dprintf(("AdjustWindowRectEx returned (%d,%d)(%d,%d)\n", rect->left, rect->top, rect->right, rect->bottom));
1207
1208 return TRUE;
1209}
1210//******************************************************************************
1211/* Coordinate Space and Transformation Functions */
1212//******************************************************************************
1213/*******************************************************************
1214 * WINPOS_GetWinOffset
1215 *
1216 * Calculate the offset between the origin of the two windows. Used
1217 * to implement MapWindowPoints.
1218 */
1219static void WINPOS_GetWinOffset( Win32BaseWindow *wndFrom, Win32BaseWindow *wndTo,
1220 POINT *offset )
1221{
1222 Win32BaseWindow *window;
1223
1224 offset->x = offset->y = 0;
1225
1226 /* Translate source window origin to screen coords */
1227 if(wndFrom != windowDesktop)
1228 {
1229 window = wndFrom;
1230 while(window)
1231 {
1232 offset->x += window->getClientRectPtr()->left + window->getWindowRect()->left;
1233 offset->y += window->getClientRectPtr()->top + window->getWindowRect()->top;
1234 window = window->getParent();
1235 }
1236 }
1237
1238 /* Translate origin to destination window coords */
1239 if(wndTo != windowDesktop)
1240 {
1241 window = wndTo;
1242 while(window)
1243 {
1244 offset->x -= window->getClientRectPtr()->left + window->getWindowRect()->left;
1245 offset->y -= window->getClientRectPtr()->top + window->getWindowRect()->top;
1246 window = window->getParent();
1247 }
1248 }
1249}
1250//******************************************************************************
1251//******************************************************************************
1252int WIN32API MapWindowPoints(HWND hwndFrom, HWND hwndTo, LPPOINT lpPoints,
1253 UINT cPoints)
1254{
1255 Win32BaseWindow *wndfrom, *wndto;
1256 int retval = 0;
1257 POINT offset;
1258
1259 SetLastError(0);
1260 if(lpPoints == NULL || cPoints == 0) {
1261 SetLastError(ERROR_INVALID_PARAMETER);
1262 return 0;
1263 }
1264 if(hwndTo == hwndFrom)
1265 return 0; //nothing to do
1266
1267 if(hwndFrom == HWND_DESKTOP)
1268 {
1269 windowDesktop->addRef();
1270 wndfrom = windowDesktop;
1271 }
1272 else {
1273 wndfrom = Win32BaseWindow::GetWindowFromHandle(hwndFrom);
1274 if(!wndfrom) {
1275 dprintf(("MapWindowPoints, window %x not found", hwndFrom));
1276 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
1277 return 0;
1278 }
1279 }
1280
1281 if(hwndTo == HWND_DESKTOP)
1282 {
1283 windowDesktop->addRef();
1284 wndto = windowDesktop;
1285 }
1286 else {
1287 wndto = Win32BaseWindow::GetWindowFromHandle(hwndTo);
1288 if(!wndto) {
1289 dprintf(("MapWindowPoints, window %x not found", hwndTo));
1290 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
1291 return 0;
1292 }
1293 }
1294
1295 dprintf2(("USER32: MapWindowPoints %x to %x (%d,%d) (%d)", hwndFrom, hwndTo, lpPoints->x, lpPoints->y, cPoints));
1296 WINPOS_GetWinOffset(wndfrom, wndto, &offset);
1297
1298 RELEASE_WNDOBJ(wndto);
1299 RELEASE_WNDOBJ(wndfrom);
1300 for(int i=0;i<cPoints;i++)
1301 {
1302 lpPoints[i].x += offset.x;
1303 lpPoints[i].y += offset.y;
1304 }
1305 retval = ((LONG)offset.y << 16) | offset.x;
1306 return retval;
1307}
1308//******************************************************************************
1309//******************************************************************************
1310BOOL WIN32API ScreenToClient(HWND hwnd, LPPOINT pt)
1311{
1312 PRECT rcl;
1313 BOOL rc;
1314
1315 if(hwnd == HWND_DESKTOP) {
1316 return (TRUE); //nothing to do
1317 }
1318 if (!IsWindow(hwnd)) {
1319 dprintf(("warning: ScreenToClient: window %x not found!", hwnd));
1320 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
1321 return FALSE;
1322 }
1323 SetLastError(0);
1324#ifdef DEBUG
1325 POINT tmp = *pt;
1326#endif
1327 MapWindowPoints(0, hwnd, pt, 1);
1328 dprintf2(("ScreenToClient %x (%d,%d) -> (%d,%d)", hwnd, tmp.x, tmp.y, pt->x, pt->y));
1329 return TRUE;
1330}
1331//******************************************************************************
1332//******************************************************************************
1333HWND WIN32API GetDesktopWindow(void)
1334{
1335 HWND hDesktopWindow = windowDesktop->getWindowHandle();
1336 dprintf2(("USER32: GetDesktopWindow, returned %x\n", hDesktopWindow));
1337 return hDesktopWindow;
1338}
1339//******************************************************************************
1340//******************************************************************************
1341HWND WIN32API FindWindowA(LPCSTR lpszClass, LPCSTR lpszWindow)
1342{
1343 return FindWindowExA( NULL, NULL, lpszClass, lpszWindow );
1344}
1345//******************************************************************************
1346//******************************************************************************
1347HWND WIN32API FindWindowW( LPCWSTR lpClassName, LPCWSTR lpWindowName)
1348{
1349 return FindWindowExW( NULL, NULL, lpClassName, lpWindowName );
1350}
1351//******************************************************************************
1352//******************************************************************************
1353HWND WIN32API FindWindowExA(HWND hwndParent, HWND hwndChildAfter, LPCSTR lpszClass, LPCSTR lpszWindow)
1354{
1355 ATOM atom = 0;
1356
1357 if (lpszClass)
1358 {
1359 /* If the atom doesn't exist, then no class */
1360 /* with this name exists either. */
1361 if (!(atom = GlobalFindAtomA( lpszClass )))
1362 {
1363 SetLastError(ERROR_CANNOT_FIND_WND_CLASS);
1364 return 0;
1365 }
1366 }
1367 return Win32BaseWindow::FindWindowEx(hwndParent, hwndChildAfter, atom, (LPSTR)lpszWindow);
1368}
1369/*****************************************************************************
1370 * Name : HWND WIN32API FindWindowExW
1371 * Purpose : The FindWindowEx function retrieves the handle of a window whose
1372 * class name and window name match the specified strings. The
1373 * function searches child windows, beginning with the one following
1374 * the given child window.
1375 * Parameters: HWND hwndParent handle of parent window
1376 * HWND hwndChildAfter handle of a child window
1377 * LPCTSTR lpszClass address of class name
1378 * LPCTSTR lpszWindow address of window name
1379 * Variables :
1380 * Result : If the function succeeds, the return value is the handle of the
1381 * window that has the specified class and window names.
1382 * If the function fails, the return value is NULL. To get extended
1383 * error information, call GetLastError.
1384 * Remark :
1385 *
1386 *****************************************************************************/
1387
1388HWND WIN32API FindWindowExW(HWND hwndParent,
1389 HWND hwndChildAfter,
1390 LPCWSTR lpszClass,
1391 LPCWSTR lpszWindow)
1392{
1393 ATOM atom = 0;
1394 char *buffer;
1395 HWND hwnd;
1396
1397 if (lpszClass)
1398 {
1399 /* If the atom doesn't exist, then no class */
1400 /* with this name exists either. */
1401 if (!(atom = GlobalFindAtomW( lpszClass )))
1402 {
1403 SetLastError(ERROR_CANNOT_FIND_WND_CLASS);
1404 return 0;
1405 }
1406 }
1407 buffer = HEAP_strdupWtoA( GetProcessHeap(), 0, lpszWindow );
1408 hwnd = Win32BaseWindow::FindWindowEx(hwndParent, hwndChildAfter, atom, buffer);
1409 HeapFree( GetProcessHeap(), 0, buffer );
1410 return hwnd;
1411}
1412//******************************************************************************
1413//******************************************************************************
1414BOOL WIN32API FlashWindow(HWND hwnd, BOOL fFlash)
1415{
1416 dprintf(("FlashWindow %x %d\n", hwnd, fFlash));
1417// return OSLibWinFlashWindow(Win32ToOS2Handle(hwnd), fFlash);
1418 return 1;
1419}
1420//******************************************************************************
1421//******************************************************************************
1422BOOL WIN32API MoveWindow( HWND hwnd, INT x, INT y, INT cx, INT cy,
1423 BOOL repaint )
1424{
1425 int flags = SWP_NOZORDER | SWP_NOACTIVATE;
1426
1427 if (!repaint) flags |= SWP_NOREDRAW;
1428 dprintf(("MoveWindow: %x %d,%d %dx%d %d\n", hwnd, x, y, cx, cy, repaint ));
1429
1430 return SetWindowPos( hwnd, 0, x, y, cx, cy, flags );
1431}
1432//******************************************************************************
1433//******************************************************************************
1434BOOL WIN32API ClientToScreen (HWND hwnd, PPOINT pt)
1435{
1436 PRECT rcl;
1437
1438 if(hwnd == HWND_DESKTOP) {
1439 return(TRUE); //nothing to do
1440 }
1441 if(!IsWindow(hwnd)) {
1442 dprintf(("warning: ClientToScreen window %x not found!", hwnd));
1443 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
1444 return (FALSE);
1445 }
1446#ifdef DEBUG
1447 POINT tmp = *pt;
1448#endif
1449 MapWindowPoints(hwnd, 0, pt, 1);
1450 dprintf2(("ClientToScreen %x (%d,%d) -> (%d,%d)", hwnd, tmp.x, tmp.y, pt->x, pt->y));
1451
1452 return TRUE;
1453}
1454//******************************************************************************
1455//Note: count 0 is a legal parameter (verified in NT4)
1456//******************************************************************************
1457HDWP WIN32API BeginDeferWindowPos(int count)
1458{
1459 HDWP handle;
1460 DWP *pDWP;
1461
1462 if (count < 0)
1463 {
1464 dprintf(("USER32: BeginDeferWindowPos invalid param %d", count));
1465 SetLastError(ERROR_INVALID_PARAMETER);
1466 return 0;
1467 }
1468 dprintf(("USER32: BeginDeferWindowPos %d", count));
1469 if(count == 0)
1470 count = 8; // change to any non-zero value
1471
1472 handle = (HDWP)HeapAlloc(GetProcessHeap(), 0, sizeof(DWP) + (count-1)*sizeof(WINDOWPOS));
1473 if (!handle)
1474 return 0;
1475
1476 pDWP = (DWP *) handle;
1477 pDWP->actualCount = 0;
1478 pDWP->suggestedCount = count;
1479 pDWP->valid = TRUE;
1480 pDWP->wMagic = DWP_MAGIC;
1481 pDWP->hwndParent = 0;
1482 return handle;
1483}
1484/***********************************************************************
1485 * DeferWindowPos (USER32.128)
1486 *
1487 * TODO: SvL: Does this need to be thread safe?
1488 *
1489 */
1490HDWP WIN32API DeferWindowPos( HDWP hdwp, HWND hwnd, HWND hwndAfter,
1491 INT x, INT y, INT cx, INT cy,
1492 UINT flags )
1493{
1494 DWP *pDWP;
1495 int i;
1496 HDWP newhdwp = hdwp,retvalue;
1497
1498 pDWP = (DWP *)hdwp;
1499 if (!pDWP) {
1500 SetLastError(ERROR_INVALID_PARAMETER);
1501 return 0;
1502 }
1503
1504 if (hwnd == GetDesktopWindow())
1505 return 0;
1506
1507 if(!IsWindow(hwnd)) {
1508 dprintf(("DeferWindowPos, window %x not found", hwnd));
1509 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
1510 HeapFree(GetProcessHeap(), 0, (LPVOID)hdwp);
1511 return 0;
1512 }
1513
1514 dprintf(("USER32: DeferWindowPos hdwp %x hwnd %x hwndAfter %x (%d,%d)(%d,%d) %x", hdwp, hwnd, hwndAfter,
1515 x, y, cx, cy, flags));
1516
1517/* Numega Bounds Checker Demo dislikes the following code.
1518 In fact, I've not been able to find any "same parent" requirement in any docu
1519 [AM 980509]
1520 */
1521#if 0
1522 /* All the windows of a DeferWindowPos() must have the same parent */
1523 parent = pWnd->parent->hwndSelf;
1524 if (pDWP->actualCount == 0) pDWP->hwndParent = parent;
1525 else if (parent != pDWP->hwndParent)
1526 {
1527 USER_HEAP_FREE( hdwp );
1528 retvalue = 0;
1529 goto END;
1530 }
1531#endif
1532
1533 for (i = 0; i < pDWP->actualCount; i++)
1534 {
1535 if (pDWP->winPos[i].hwnd == hwnd)
1536 {
1537 /* Merge with the other changes */
1538 if (!(flags & SWP_NOZORDER))
1539 {
1540 pDWP->winPos[i].hwndInsertAfter = hwndAfter;
1541 }
1542 if (!(flags & SWP_NOMOVE))
1543 {
1544 pDWP->winPos[i].x = x;
1545 pDWP->winPos[i].y = y;
1546 }
1547 if (!(flags & SWP_NOSIZE))
1548 {
1549 pDWP->winPos[i].cx = cx;
1550 pDWP->winPos[i].cy = cy;
1551 }
1552 pDWP->winPos[i].flags &= flags | ~(SWP_NOSIZE | SWP_NOMOVE |
1553 SWP_NOZORDER | SWP_NOREDRAW |
1554 SWP_NOACTIVATE | SWP_NOCOPYBITS|
1555 SWP_NOOWNERZORDER);
1556 pDWP->winPos[i].flags |= flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW |
1557 SWP_FRAMECHANGED);
1558 retvalue = hdwp;
1559 goto END;
1560 }
1561 }
1562 if (pDWP->actualCount >= pDWP->suggestedCount)
1563 {
1564 //DWP structure already contains WINDOWPOS, allocated with (count-1)
1565 //in BeginDeferWindowPos; pDWP->suggestedCount alloc increases it by one
1566 newhdwp = (HDWP)HeapReAlloc(GetProcessHeap(), 0, (LPVOID)hdwp,
1567 sizeof(DWP) + pDWP->suggestedCount*sizeof(WINDOWPOS));
1568 if (!newhdwp)
1569 {
1570 retvalue = 0;
1571 goto END;
1572 }
1573 pDWP = (DWP *) newhdwp;
1574 pDWP->suggestedCount++;
1575 }
1576 pDWP->winPos[pDWP->actualCount].hwnd = hwnd;
1577 pDWP->winPos[pDWP->actualCount].hwndInsertAfter = hwndAfter;
1578 pDWP->winPos[pDWP->actualCount].x = x;
1579 pDWP->winPos[pDWP->actualCount].y = y;
1580 pDWP->winPos[pDWP->actualCount].cx = cx;
1581 pDWP->winPos[pDWP->actualCount].cy = cy;
1582 pDWP->winPos[pDWP->actualCount].flags = flags;
1583 pDWP->actualCount++;
1584 retvalue = newhdwp;
1585END:
1586 return retvalue;
1587}
1588//******************************************************************************
1589//******************************************************************************
1590BOOL WIN32API EndDeferWindowPos( HDWP hdwp)
1591{
1592 DWP *pDWP;
1593 WINDOWPOS *winpos;
1594 BOOL res = TRUE;
1595 int i;
1596
1597 pDWP = (DWP *) hdwp;
1598 if (!pDWP) {
1599 dprintf(("**EndDeferWindowPos invalid parameter\n"));
1600 SetLastError(ERROR_INVALID_PARAMETER);
1601 return FALSE;
1602 }
1603 dprintf(("**EndDeferWindowPos for %d windows", pDWP->actualCount));
1604 for (i = 0, winpos = pDWP->winPos; i < pDWP->actualCount; i++, winpos++)
1605 {
1606 dprintf(("**EndDeferWindowPos %x (%d,%d) (%d,%d) %x", winpos->hwnd, winpos->x, winpos->y, winpos->cx, winpos->cy, winpos->flags));
1607 if (!(res = SetWindowPos(winpos->hwnd, winpos->hwndInsertAfter,
1608 winpos->x, winpos->y, winpos->cx,
1609 winpos->cy, winpos->flags )))
1610 break;
1611 }
1612 dprintf(("**EndDeferWindowPos DONE"));
1613 HeapFree(GetProcessHeap(), 0, (LPVOID)hdwp);
1614 return res;
1615}
1616//******************************************************************************
1617//******************************************************************************
1618HWND WIN32API ChildWindowFromPoint( HWND hwnd, POINT pt)
1619{
1620 dprintf(("USER32: ChildWindowFromPoint\n"));
1621 return ChildWindowFromPointEx(hwnd, pt, 0);
1622}
1623/*****************************************************************************
1624 * Name : HWND WIN32API ChildWindowFromPointEx
1625 * Purpose : pt: client coordinates
1626 * Parameters:
1627 * Variables :
1628 * Result : If the function succeeds, the return value is the window handle.
1629 * If the function fails, the return value is zero
1630 * Remark :
1631 * Status : COMPLETELY IMPLEMENTED AND TESTED
1632 *
1633 * Author : Rene Pronk [Sun, 1999/08/08 23:30]
1634 *****************************************************************************/
1635HWND WIN32API ChildWindowFromPointEx (HWND hwndParent, POINT pt, UINT uFlags)
1636{
1637 RECT rect;
1638 HWND hWnd;
1639
1640 dprintf(("ChildWindowFromPointEx(%08xh,%08xh,%08xh).\n",
1641 hwndParent, pt, uFlags));
1642
1643 if (GetWindowRect (hwndParent, &rect) == 0) {
1644 // oops, invalid handle
1645 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
1646 return NULL;
1647 }
1648
1649 ClientToScreen(hwndParent, &pt);
1650 if (PtInRect (&rect, pt) == 0) {
1651 // point is outside window
1652 return NULL;
1653 }
1654
1655 // get first child
1656 hWnd = GetWindow (hwndParent, GW_CHILD);
1657
1658 while (hWnd != NULL)
1659 {
1660 // do I need to skip this window?
1661 if (((uFlags & CWP_SKIPINVISIBLE) &&
1662 (IsWindowVisible (hWnd) == FALSE)) ||
1663 ((uFlags & CWP_SKIPDISABLED) &&
1664 (IsWindowEnabled (hWnd) == FALSE)) ||
1665 ((uFlags & CWP_SKIPTRANSPARENT) &&
1666 (GetWindowLongA (hWnd, GWL_EXSTYLE) & WS_EX_TRANSPARENT)))
1667 {
1668 hWnd = GetWindow (hWnd, GW_HWNDNEXT);
1669 continue;
1670 }
1671
1672 // is the point in this window's rect?
1673 GetWindowRect (hWnd, &rect);
1674 if (PtInRect (&rect,pt) == FALSE) {
1675 hWnd = GetWindow (hWnd, GW_HWNDNEXT);
1676 continue;
1677 }
1678
1679 dprintf(("ChildWindowFromPointEx returned %x", hWnd));
1680 // found it!
1681 return hWnd;
1682 }
1683 // the point is in the parentwindow but the parentwindow has no child
1684 // at this coordinate
1685 dprintf(("ChildWindowFromPointEx returned parent %x", hwndParent));
1686 return hwndParent;
1687}
1688//******************************************************************************
1689//******************************************************************************
1690BOOL WIN32API CloseWindow(HWND hwnd)
1691{
1692 Win32BaseWindow *window;
1693
1694 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
1695 if(!window) {
1696 dprintf(("CloseWindow, window %x not found", hwnd));
1697 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
1698 return 0;
1699 }
1700 dprintf(("CloseWindow %x\n", hwnd));
1701 BOOL ret = window->CloseWindow();
1702 RELEASE_WNDOBJ(window);
1703 return ret;
1704}
1705//******************************************************************************
1706//******************************************************************************
1707static BOOL IsPointInWindow(HWND hwnd, POINT point)
1708{
1709 RECT rectWindow;
1710 DWORD hittest, dwStyle, dwExStyle;
1711
1712 dwStyle = GetWindowLongA(hwnd, GWL_STYLE);
1713 dwExStyle = GetWindowLongA(hwnd, GWL_EXSTYLE);
1714
1715 GetWindowRect(hwnd, &rectWindow);
1716
1717 /* If point is in window, and window is visible, and it */
1718 /* is enabled (or it's a top-level window), then explore */
1719 /* its children. Otherwise, go to the next window. */
1720
1721 if( (dwStyle & WS_VISIBLE) &&
1722 ((dwExStyle & (WS_EX_LAYERED | WS_EX_TRANSPARENT)) != (WS_EX_LAYERED | WS_EX_TRANSPARENT)) &&
1723 (!(dwStyle & WS_DISABLED) || ((dwStyle & (WS_POPUP | WS_CHILD)) != WS_CHILD)) &&
1724 ((point.x >= rectWindow.left) && (point.x < rectWindow.right) &&
1725 (point.y >= rectWindow.top) && (point.y < rectWindow.bottom))
1726#if 1
1727 )
1728#else
1729 &&
1730 (wndPtr->hrgnWnd ? PtInRegion(wndPtr->hrgnWnd, 1))
1731#endif
1732 {
1733 DWORD dwThreadId = GetCurrentThreadId();
1734
1735 //Don't send WM_NCHITTEST if this window doesn't belong to the current thread
1736 if(dwThreadId != GetWindowThreadProcessId(hwnd, NULL))
1737 {
1738 return TRUE;
1739 }
1740 hittest = SendMessageA(hwnd, WM_NCHITTEST, 0, MAKELONG(point.x, point.y));
1741 if(hittest != HTTRANSPARENT) {
1742 return TRUE;
1743 }
1744 }
1745 return FALSE;
1746}
1747//******************************************************************************
1748//TODO: Does this return handles of hidden or disabled windows?
1749//******************************************************************************
1750HWND WIN32API WindowFromPoint( POINT point)
1751{
1752 HWND hwndOS2, hwnd;
1753 POINT wPoint;
1754
1755 wPoint.x = point.x;
1756 wPoint.y = mapScreenY(point.y);
1757
1758 hwndOS2 = OSLibWinWindowFromPoint(OSLIB_HWND_DESKTOP, (PVOID)&wPoint);
1759 if(hwndOS2)
1760 {
1761 hwnd = OS2ToWin32Handle(hwndOS2);
1762 while(hwnd)
1763 {
1764 if(IsPointInWindow(hwnd, point)) {
1765 dprintf(("WindowFromPoint (%d,%d) %x->%x\n", point.x, point.y, hwndOS2, hwnd));
1766 return hwnd;
1767 }
1768#if 0
1769//TODO: breaks a lot of things
1770 hwnd = GetWindow(hwnd, GW_HWNDNEXT);
1771#else
1772 //try siblings
1773 HWND hwndSibling;
1774 HWND hwndParent = GetParent(hwnd);
1775
1776 if(hwndParent) {
1777 hwndSibling = GetWindow(hwndParent, GW_CHILD);
1778 while(hwndSibling) {
1779 if(hwndSibling != hwnd) {
1780 if(IsPointInWindow(hwndSibling, point)) {
1781 dprintf(("WindowFromPoint (%d,%d) %x->%x\n", point.x, point.y, hwndOS2, hwndSibling));
1782 return hwndSibling;
1783 }
1784 }
1785 hwndSibling = GetWindow(hwndSibling, GW_HWNDNEXT);
1786 }
1787 }
1788 hwnd = hwndParent;
1789#endif
1790 }
1791 }
1792 dprintf(("WindowFromPoint (%d,%d) %x->1\n", point.x, point.y, hwndOS2));
1793 return windowDesktop->getWindowHandle();
1794}
1795//******************************************************************************
1796//******************************************************************************
1797BOOL WIN32API IsWindowUnicode(HWND hwnd)
1798{
1799 Win32BaseWindow *window;
1800
1801 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
1802 if(!window) {
1803 dprintf(("IsWindowUnicode, window %x not found", hwnd));
1804 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
1805 return 0;
1806 }
1807 BOOL ret = window->IsWindowUnicode();
1808 RELEASE_WNDOBJ(window);
1809 return ret;
1810}
1811/***********************************************************************
1812 * SwitchToThisWindow (USER32.539)
1813 */
1814DWORD WINAPI SwitchToThisWindow( HWND hwnd, BOOL restore )
1815{
1816 return ShowWindow( hwnd, restore ? SW_RESTORE : SW_SHOWMINIMIZED );
1817}
1818//******************************************************************************
1819//******************************************************************************
1820BOOL WIN32API EnumThreadWindows(DWORD dwThreadId, WNDENUMPROC lpfn, LPARAM lParam)
1821{
1822 return windowDesktop->EnumThreadWindows(dwThreadId, lpfn, lParam);
1823}
1824//******************************************************************************
1825//******************************************************************************
1826BOOL WIN32API EnumChildWindows(HWND hwnd, WNDENUMPROC lpfn, LPARAM lParam)
1827{
1828 Win32BaseWindow *window;
1829 BOOL ret = TRUE;
1830 ULONG henum;
1831 HWND hwndNext;
1832
1833 if(lpfn == NULL) {
1834 dprintf(("EnumChildWindows invalid parameter %x %x\n", hwnd, lParam));
1835 SetLastError(ERROR_INVALID_PARAMETER);
1836 return FALSE;
1837 }
1838 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
1839 if(!window) {
1840 dprintf(("EnumChildWindows, window %x not found", hwnd));
1841 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
1842 return FALSE;
1843 }
1844 ret = window->EnumChildWindows(lpfn, lParam);
1845 RELEASE_WNDOBJ(window);
1846 return ret;
1847}
1848//******************************************************************************
1849//******************************************************************************
1850BOOL WIN32API EnumWindows(WNDENUMPROC lpfn, LPARAM lParam)
1851{
1852 return windowDesktop->EnumWindows(lpfn, lParam);
1853}
1854//******************************************************************************
1855//******************************************************************************
1856UINT WIN32API ArrangeIconicWindows( HWND parent)
1857{
1858 RECT rectParent;
1859 HWND hwndChild;
1860 INT x, y, xspacing, yspacing;
1861
1862 dprintf(("USER32: ArrangeIconicWindows %x", parent));
1863 dprintf(("USER32: TODO: icon title!!"));
1864
1865 GetClientRect(parent, &rectParent);
1866 x = rectParent.left;
1867 y = rectParent.bottom;
1868 xspacing = GetSystemMetrics(SM_CXICONSPACING);
1869 yspacing = GetSystemMetrics(SM_CYICONSPACING);
1870
1871 hwndChild = GetWindow( parent, GW_CHILD );
1872 while (hwndChild)
1873 {
1874 if( IsIconic( hwndChild ) )
1875 {
1876// WND *wndPtr = WIN_FindWndPtr(hwndChild);
1877
1878// WINPOS_ShowIconTitle( wndPtr, FALSE );
1879
1880 SetWindowPos( hwndChild, 0, x + (xspacing - GetSystemMetrics(SM_CXICON)) / 2,
1881 y - yspacing - GetSystemMetrics(SM_CYICON)/2, 0, 0,
1882 SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
1883// if( IsWindow(hwndChild) )
1884// WINPOS_ShowIconTitle(wndPtr , TRUE );
1885// WIN_ReleaseWndPtr(wndPtr);
1886
1887 if (x <= rectParent.right - xspacing) x += xspacing;
1888 else
1889 {
1890 x = rectParent.left;
1891 y -= yspacing;
1892 }
1893 }
1894 hwndChild = GetWindow( hwndChild, GW_HWNDNEXT );
1895 }
1896 return yspacing;
1897}
1898//******************************************************************************
1899//restores iconized window to previous size/position
1900//******************************************************************************
1901BOOL WIN32API OpenIcon(HWND hwnd)
1902{
1903 dprintf(("USER32: OpenIcon %x", hwnd));
1904
1905 if(!IsIconic(hwnd))
1906 return FALSE;
1907 ShowWindow(hwnd, SW_SHOWNORMAL);
1908 return TRUE;
1909}
1910//******************************************************************************
1911//SDK: Windows can only be shown with ShowOwnedPopups if they were previously
1912// hidden with the same api
1913//TODO: -> needs testing
1914//******************************************************************************
1915BOOL WIN32API ShowOwnedPopups(HWND hwndOwner, BOOL fShow)
1916{
1917 Win32BaseWindow *window, *owner;
1918 HWND hwnd;
1919
1920 owner = Win32BaseWindow::GetWindowFromHandle(hwndOwner);
1921 if(!owner) {
1922 dprintf(("ShowOwnedPopups, window %x not found", hwndOwner));
1923 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
1924 return FALSE;
1925 }
1926 dprintf(("USER32: ShowOwnedPopups %x %d", hwndOwner, fShow));
1927
1928 hwnd = GetWindow(GetDesktopWindow(), GW_CHILD);
1929 while(hwnd) {
1930 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
1931 if(window) {
1932 if(window == owner && (window->getStyle() & WS_POPUP))
1933 {
1934 if(fShow) {
1935 if(window->getFlags() & WIN_NEEDS_SHOW_OWNEDPOPUP)
1936 {
1937 /*
1938 * In Windows, ShowOwnedPopups(TRUE) generates WM_SHOWWINDOW messages with SW_PARENTOPENING,
1939 * regardless of the state of the owner
1940 */
1941 SendMessageA(hwnd, WM_SHOWWINDOW, SW_SHOW, SW_PARENTOPENING);
1942 window->setFlags(window->getFlags() & ~WIN_NEEDS_SHOW_OWNEDPOPUP);
1943 }
1944 }
1945 else
1946 {
1947 if(IsWindowVisible(hwnd))
1948 {
1949 /*
1950 * In Windows, ShowOwnedPopups(FALSE) generates WM_SHOWWINDOW messages with SW_PARENTCLOSING,
1951 * regardless of the state of the owner
1952 */
1953 SendMessageA(hwnd, WM_SHOWWINDOW, SW_HIDE, SW_PARENTCLOSING);
1954 window->setFlags(window->getFlags() | WIN_NEEDS_SHOW_OWNEDPOPUP);
1955 }
1956 }
1957 }
1958 RELEASE_WNDOBJ(window);
1959 }
1960 else dprintf(("WARNING: window %x is not valid", hwnd));
1961
1962 hwnd = GetWindow(hwnd, GW_HWNDNEXT);
1963 }
1964 RELEASE_WNDOBJ(owner);
1965 return TRUE;
1966}
1967//******************************************************************************
1968//******************************************************************************
1969HWND WIN32API GetForegroundWindow()
1970{
1971 HWND hwnd;
1972
1973 hwnd = OS2ToWin32Handle(OSLibWinQueryActiveWindow());
1974 return hwnd;
1975}
1976//******************************************************************************
1977
1978/******************************************************************************
1979 * The return value identifies the most recently active pop-up window.
1980 * The return value is the same as the hWnd parameter, if any of the
1981 * following conditions are met:
1982 *
1983 * - The window identified by hWnd was most recently active.
1984 * - The window identified by hWnd does not own any pop-up windows.
1985 * - The window identified by hWnd is not a top-level window or it is
1986 * owned by another window.
1987 */
1988HWND WIN32API GetLastActivePopup(HWND hWnd)
1989{
1990 Win32BaseWindow *owner;
1991
1992 owner = Win32BaseWindow::GetWindowFromHandle(hWnd);
1993 if(!owner)
1994 {
1995 dprintf(("GetLastActivePopup, window %x not found", hWnd));
1996 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
1997 return hWnd;
1998 }
1999
2000 HWND hwndRetVal = owner->getLastActive();
2001 if (!IsWindow( hwndRetVal ))
2002 hwndRetVal = owner->getWindowHandle();
2003
2004 RELEASE_WNDOBJ(owner);
2005
2006 return hwndRetVal;
2007}
2008//******************************************************************************
2009//******************************************************************************
2010DWORD WIN32API GetWindowThreadProcessId(HWND hwnd, PDWORD lpdwProcessId)
2011{
2012 Win32BaseWindow *window;
2013 DWORD dwThreadId;
2014
2015 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
2016 if(!window) {
2017 dprintf(("GetWindowThreadProcessId, window %x not found", hwnd));
2018 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
2019 return 0;
2020 }
2021 dwThreadId = window->getThreadId();
2022 if(lpdwProcessId) {
2023 *lpdwProcessId = window->getProcessId();
2024 }
2025 RELEASE_WNDOBJ(window);
2026
2027 return dwThreadId;
2028}
2029//******************************************************************************
2030//******************************************************************************
2031DWORD WIN32API GetWindowContextHelpId(HWND hwnd)
2032{
2033 Win32BaseWindow *window;
2034
2035 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
2036 if(!window) {
2037 dprintf(("GetWindowContextHelpId, window %x not found", hwnd));
2038 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
2039 return 0;
2040 }
2041 dprintf(("GetWindowContextHelpId %x", hwnd));
2042 DWORD ret = window->getWindowContextHelpId();
2043 RELEASE_WNDOBJ(window);
2044 return ret;
2045}
2046//******************************************************************************
2047//******************************************************************************
2048BOOL WIN32API SetWindowContextHelpId(HWND hwnd, DWORD dwContextHelpId)
2049{
2050 Win32BaseWindow *window;
2051
2052 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
2053 if(!window) {
2054 dprintf(("SetWindowContextHelpId, window %x not found", hwnd));
2055 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
2056 return 0;
2057 }
2058 dprintf(("SetWindowContextHelpId %x %d", hwnd, dwContextHelpId));
2059 window->setWindowContextHelpId(dwContextHelpId);
2060 RELEASE_WNDOBJ(window);
2061 return(TRUE);
2062}
2063//******************************************************************************
2064//******************************************************************************
2065HANDLE WIN32API GetPropA(HWND hwnd, LPCSTR str )
2066{
2067 Win32BaseWindow *window;
2068
2069 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
2070 if(!window) {
2071 dprintf(("GetPropA, window %x not found", hwnd));
2072 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
2073 return 0;
2074 }
2075 HANDLE ret = window->getProp(str);
2076 RELEASE_WNDOBJ(window);
2077 return ret;
2078}
2079//******************************************************************************
2080//******************************************************************************
2081HANDLE WIN32API GetPropW(HWND hwnd, LPCWSTR str)
2082{
2083 Win32BaseWindow *window;
2084 LPSTR strA;
2085 HANDLE ret;
2086
2087 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
2088 if(!window) {
2089 dprintf(("GetPropW, window %x not found", hwnd));
2090 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
2091 return 0;
2092 }
2093
2094 if(HIWORD(str)) {
2095 strA = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
2096 }
2097 else strA = (LPSTR)str;
2098
2099 ret = window->getProp(strA);
2100
2101 RELEASE_WNDOBJ(window);
2102 if(HIWORD(str)) HeapFree( GetProcessHeap(), 0, strA );
2103 return ret;
2104}
2105//******************************************************************************
2106//******************************************************************************
2107BOOL WIN32API SetPropA(HWND hwnd, LPCSTR str, HANDLE handle )
2108{
2109 Win32BaseWindow *window;
2110
2111 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
2112 if(!window) {
2113 dprintf(("SetPropA, window %x not found", hwnd));
2114 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
2115 return FALSE;
2116 }
2117 BOOL ret = window->setProp(str, handle);
2118 RELEASE_WNDOBJ(window);
2119 return ret;
2120}
2121//******************************************************************************
2122//******************************************************************************
2123BOOL SetPropW(HWND hwnd, LPCWSTR str, HANDLE handle )
2124{
2125 BOOL ret;
2126 LPSTR strA;
2127
2128 if (!HIWORD(str))
2129 return SetPropA( hwnd, (LPCSTR)(UINT)LOWORD(str), handle );
2130 strA = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
2131 ret = SetPropA( hwnd, strA, handle );
2132 HeapFree( GetProcessHeap(), 0, strA );
2133 return ret;
2134}
2135//******************************************************************************
2136//******************************************************************************
2137HANDLE WIN32API RemovePropA(HWND hwnd, LPCSTR str)
2138{
2139 Win32BaseWindow *window;
2140
2141 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
2142 if(!window) {
2143 dprintf(("RemovePropA, window %x not found", hwnd));
2144 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
2145 return 0;
2146 }
2147 HANDLE ret = window->removeProp(str);
2148 RELEASE_WNDOBJ(window);
2149 return ret;
2150}
2151//******************************************************************************
2152//******************************************************************************
2153HANDLE WIN32API RemovePropW(HWND hwnd, LPCWSTR str)
2154{
2155 LPSTR strA;
2156 HANDLE ret;
2157
2158 if (!HIWORD(str))
2159 return RemovePropA( hwnd, (LPCSTR)(UINT)LOWORD(str) );
2160 strA = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
2161 ret = RemovePropA( hwnd, strA );
2162 HeapFree( GetProcessHeap(), 0, strA );
2163 return ret;
2164}
2165//******************************************************************************
2166//******************************************************************************
2167INT WIN32API EnumPropsA(HWND hwnd, PROPENUMPROCA func )
2168{
2169 return EnumPropsExA( hwnd, (PROPENUMPROCEXA)func, 0 );
2170}
2171//******************************************************************************
2172//******************************************************************************
2173INT WIN32API EnumPropsW(HWND hwnd, PROPENUMPROCW func )
2174{
2175 return EnumPropsExW( hwnd, (PROPENUMPROCEXW)func, 0 );
2176}
2177//******************************************************************************
2178//******************************************************************************
2179INT WIN32API EnumPropsExA(HWND hwnd, PROPENUMPROCEXA func, LPARAM lParam)
2180{
2181 Win32BaseWindow *window;
2182
2183 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
2184 if(!window) {
2185 dprintf(("EnumPropsExA, window %x not found", hwnd));
2186 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
2187 return -1;
2188 }
2189 INT ret = window->enumPropsExA(func, lParam);
2190 RELEASE_WNDOBJ(window);
2191 return ret;
2192}
2193//******************************************************************************
2194//******************************************************************************
2195INT WIN32API EnumPropsExW(HWND hwnd, PROPENUMPROCEXW func, LPARAM lParam)
2196{
2197 Win32BaseWindow *window;
2198
2199 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
2200 if(!window) {
2201 dprintf(("EnumPropsExA, window %x not found", hwnd));
2202 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
2203 return -1;
2204 }
2205 INT ret = window->enumPropsExW(func, lParam);
2206 RELEASE_WNDOBJ(window);
2207 return ret;
2208}
2209//******************************************************************************
2210//******************************************************************************
2211
2212
2213/*****************************************************************************
2214 * Name : BOOL WIN32API AnyPopup
2215 * Purpose : The AnyPopup function indicates whether an owned, visible,
2216 * top-level pop-up, or overlapped window exists on the screen. The
2217 * function searches the entire Windows screen, not just the calling
2218 * application's client area.
2219 * Parameters: VOID
2220 * Variables :
2221 * Result : If a pop-up window exists, the return value is TRUE even if the
2222 * pop-up window is completely covered by other windows. Otherwise,
2223 * it is FALSE.
2224 * Remark : AnyPopup is a Windows version 1.x function and is retained for
2225 * compatibility purposes. It is generally not useful.
2226 * Status : UNTESTED STUB
2227 *
2228 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
2229 *****************************************************************************/
2230BOOL WIN32API AnyPopup()
2231{
2232 dprintf(("USER32:AnyPopup() not implemented.\n"));
2233
2234 return (FALSE);
2235}
Note: See TracBrowser for help on using the repository browser.