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

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

Changes for fake windows. Moved them into a seperate C++ class and overload some methods to correct the behaviour

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