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

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

Send focus messages when we receive the undocumented WM_FOCUSCHANGED PM message. Removes the need for the ugly hack to deal with nested focus changes.

File size: 75.5 KB
Line 
1/* $Id: window.cpp,v 1.135 2003-06-03 11:58:38 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 lastFocus = OSLibWinQueryFocus (OSLIB_HWND_DESKTOP);
784
785 hwndTopParent = window->GetTopParent();
786 activate = FALSE;
787 lastFocus_W = OS2ToWin32Handle(lastFocus);
788 if(lastFocus_W) {
789 oldfocuswnd = Win32BaseWindow::GetWindowFromHandle(lastFocus_W);
790 if(lastFocus_W != hwnd && hwndTopParent != oldfocuswnd->GetTopParent()) {
791 activate = TRUE;
792 }
793 RELEASE_WNDOBJ(oldfocuswnd);
794 }
795 else activate = TRUE;
796
797 dprintf(("SetFocus %x (%x) -> %x (%x) act %d", lastFocus_W, lastFocus, hwnd, hwnd_O, activate));
798
799 if(HOOK_CallHooksA(WH_CBT, HCBT_SETFOCUS, hwnd, (LPARAM)lastFocus_W)) {
800 dprintf(("hook cancelled SetFocus call!"));
801 RELEASE_WNDOBJ(window);
802 return 0;
803 }
804
805 if(!IsWindow(hwnd)) return FALSE; //abort if window destroyed
806
807 //NOTE: Don't always activate the window or else the z-order will be changed!!
808 ret = (OSLibWinSetFocus(OSLIB_HWND_DESKTOP, hwnd_O, activate)) ? lastFocus_W : 0;
809 RELEASE_WNDOBJ(window);
810
811 //If keystrokes were ignored and focus is set to the old focus window, then
812 //PM won't send us a WM_SETFOCUS message. (as we don't inform PM for SetFocus(0))
813 if(fIgnoreKeystrokes && lastFocus_W == hwnd) {
814 dprintf(("Manually send WM_SETFOCUS; real focus window hasn't changed"));
815 SendMessageA(lastFocus_W, WM_SETFOCUS, 0, 0);
816 }
817 fIgnoreKeystrokes = FALSE;
818 return ret;
819}
820//******************************************************************************
821//******************************************************************************
822HWND WIN32API GetFocus()
823{
824 TEB *teb;
825 HWND hwnd;
826
827 teb = GetThreadTEB();
828 if(teb == NULL) {
829 DebugInt3();
830 return 0;
831 }
832 //If keystrokes are ignored (SetFocus(0)), then return 0
833 if(fIgnoreKeystrokes) {
834 dprintf(("GetFocus; returning 0 after SetFocus(0) call"));
835 return 0;
836 }
837 hwnd = OSLibWinQueryFocus(OSLIB_HWND_DESKTOP);
838 hwnd = OS2ToWin32Handle(hwnd);
839 dprintf(("USER32: GetFocus %x\n", hwnd));
840 return hwnd;
841}
842//******************************************************************************
843//******************************************************************************
844BOOL WIN32API GetGUIThreadInfo(DWORD dwThreadId, GUITHREADINFO *lpThreadInfo)
845{
846 dprintf(("!WARNING!: GetGUIThreadInfo not completely implemented!!"));
847
848 if(!lpThreadInfo || lpThreadInfo->cbSize != sizeof(GUITHREADINFO)) {
849 SetLastError(ERROR_INVALID_PARAMETER);
850 return FALSE;
851 }
852 //dwThreadId == 0 -> current thread
853 if(!dwThreadId) dwThreadId = GetCurrentThreadId();
854
855 lpThreadInfo->flags;
856 lpThreadInfo->hwndActive = GetActiveWindow();
857 if(lpThreadInfo->hwndActive) {
858 if(dwThreadId != GetWindowThreadProcessId(lpThreadInfo->hwndActive, NULL))
859 {//this thread doesn't own the active window (TODO: correct??)
860 lpThreadInfo->hwndActive = 0;
861 }
862 }
863 lpThreadInfo->hwndFocus = GetFocus();
864 lpThreadInfo->hwndCapture = GetCapture();
865 lpThreadInfo->flags = 0; //TODO:
866 lpThreadInfo->hwndMenuOwner = 0; //TODO: Handle to the window that owns any active menus
867 lpThreadInfo->hwndMoveSize = 0; //TODO: Handle to the window in a move or size loop.
868 lpThreadInfo->hwndCaret = 0; //TODO: Handle to the window that is displaying the caret
869 lpThreadInfo->rcCaret.left = 0;
870 lpThreadInfo->rcCaret.top = 0;
871 lpThreadInfo->rcCaret.right = 0;
872 lpThreadInfo->rcCaret.bottom = 0;
873
874 SetLastError(ERROR_SUCCESS);
875 return TRUE;
876}
877//******************************************************************************
878//******************************************************************************
879BOOL WIN32API IsZoomed(HWND hwnd)
880{
881 DWORD style;
882
883 style = GetWindowLongA(hwnd, GWL_STYLE);
884 dprintf(("USER32: IsZoomed %x returned %d", hwnd, ((style & WS_MAXIMIZE) != 0)));
885
886 return (style & WS_MAXIMIZE) != 0;
887}
888//******************************************************************************
889//******************************************************************************
890BOOL WIN32API LockWindowUpdate(HWND hwnd)
891{
892 return OSLibWinLockWindowUpdate(Win32ToOS2Handle(hwnd));
893}
894//******************************************************************************
895//******************************************************************************
896BOOL WIN32API GetWindowRect(HWND hwnd, PRECT pRect)
897{
898 Win32BaseWindow *window;
899
900 if(pRect == NULL) {
901 dprintf(("GetWindowRect %x invalid parameter!", hwnd));
902 SetLastError(ERROR_INVALID_PARAMETER);
903 return FALSE;
904 }
905
906 if(hwnd == HWND_DESKTOP) {
907 windowDesktop->addRef();
908 window = windowDesktop;
909 }
910 else window = Win32BaseWindow::GetWindowFromHandle(hwnd);
911
912 if(!window) {
913 dprintf(("GetWindowRect, window %x not found", hwnd));
914 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
915 return FALSE;
916 }
917 *pRect = *window->getWindowRect();
918
919 //convert from parent coordinates to screen (if necessary)
920 if(window->getParent()) {
921 MapWindowPoints(window->getParent()->getWindowHandle(), 0, (PPOINT)pRect, 2);
922 }
923 RELEASE_WNDOBJ(window);
924 dprintf(("GetWindowRect %x (%d,%d) (%d,%d)", hwnd, pRect->left, pRect->top, pRect->right, pRect->bottom));
925 return TRUE;
926}
927//******************************************************************************
928//******************************************************************************
929INT WIN32API GetWindowTextLengthA(HWND hwnd)
930{
931 Win32BaseWindow *window;
932
933 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
934 if(!window) {
935 dprintf(("GetWindowTextLengthA, window %x not found", hwnd));
936 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
937 return 0;
938 }
939 dprintf(("GetWindowTextLengthA %x", hwnd));
940 int ret = window->GetWindowTextLengthA();
941 RELEASE_WNDOBJ(window);
942 return ret;
943}
944//******************************************************************************
945//******************************************************************************
946int WIN32API GetWindowTextA( HWND hwnd, LPSTR lpsz, int cch)
947{
948 Win32BaseWindow *window;
949 int rc;
950
951 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
952 if(!window) {
953 dprintf(("GetWindowTextA, window %x not found", hwnd));
954 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
955 return 0;
956 }
957 rc = window->GetWindowTextA(lpsz, cch);
958 dprintf(("GetWindowTextA %x %s", hwnd, lpsz));
959 RELEASE_WNDOBJ(window);
960 return rc;
961}
962//******************************************************************************
963//******************************************************************************
964int WIN32API GetWindowTextLengthW( HWND hwnd)
965{
966 Win32BaseWindow *window;
967
968 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
969 if(!window) {
970 dprintf(("GetWindowTextLengthW, window %x not found", hwnd));
971 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
972 return 0;
973 }
974 dprintf(("GetWindowTextLengthW %x", hwnd));
975 int ret = window->GetWindowTextLengthW();
976 RELEASE_WNDOBJ(window);
977 return ret;
978}
979//******************************************************************************
980//******************************************************************************
981int WIN32API GetWindowTextW(HWND hwnd, LPWSTR lpsz, int cch)
982{
983 Win32BaseWindow *window;
984
985 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
986 if(!window) {
987 dprintf(("GetWindowTextW, window %x not found", hwnd));
988 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
989 return 0;
990 }
991 int rc = window->GetWindowTextW(lpsz, cch);
992 RELEASE_WNDOBJ(window);
993 dprintf(("GetWindowTextW %x %ls", hwnd, lpsz));
994 return rc;
995}
996//******************************************************************************
997//******************************************************************************
998BOOL WIN32API SetWindowTextA(HWND hwnd, LPCSTR lpsz)
999{
1000 Win32BaseWindow *window;
1001
1002 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
1003 if(!window) {
1004 dprintf(("SetWindowTextA, window %x not found", hwnd));
1005 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
1006 return 0;
1007 }
1008 dprintf(("SetWindowTextA %x %s", hwnd, lpsz));
1009 BOOL ret = window->SetWindowTextA((LPSTR)lpsz);
1010 RELEASE_WNDOBJ(window);
1011 return ret;
1012}
1013//******************************************************************************
1014//******************************************************************************
1015BOOL WIN32API SetWindowTextW( HWND hwnd, LPCWSTR lpsz)
1016{
1017 Win32BaseWindow *window;
1018
1019 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
1020 if(!window) {
1021 dprintf(("SetWindowTextA, window %x not found", hwnd));
1022 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
1023 return 0;
1024 }
1025 dprintf(("SetWindowTextW %x %ls", hwnd, lpsz));
1026 BOOL ret = window->SetWindowTextW((LPWSTR)lpsz);
1027 RELEASE_WNDOBJ(window);
1028 return ret;
1029}
1030/*******************************************************************
1031 * InternalGetWindowText (USER32.326)
1032 */
1033int WIN32API InternalGetWindowText(HWND hwnd,
1034 LPWSTR lpString,
1035 INT nMaxCount )
1036{
1037 dprintf(("USER32: InternalGetWindowText(%08xh,%08xh,%08xh) not properly implemented.\n",
1038 hwnd, lpString, nMaxCount));
1039
1040 return GetWindowTextW(hwnd, lpString,nMaxCount);
1041}
1042//******************************************************************************
1043//TODO: Correct?
1044//******************************************************************************
1045BOOL WIN32API SetForegroundWindow(HWND hwnd)
1046{
1047 dprintf((" SetForegroundWindow %x", hwnd));
1048
1049 return SetWindowPos( hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
1050}
1051//******************************************************************************
1052//******************************************************************************
1053BOOL WIN32API GetClientRect( HWND hwnd, PRECT pRect)
1054{
1055 HWND hwndWin32 = hwnd;
1056 Win32BaseWindow *window;
1057
1058 if (!pRect)
1059 {
1060 SetLastError(ERROR_INVALID_PARAMETER);
1061 return FALSE;
1062 }
1063 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
1064 if(!window) {
1065 dprintf(("GetClientRect, window %x not found", hwnd));
1066 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
1067 return FALSE;
1068 }
1069 window->getClientRect(pRect);
1070 dprintf(("GetClientRect of %X returned (%d,%d) (%d,%d)\n", hwndWin32, pRect->left, pRect->top, pRect->right, pRect->bottom));
1071 RELEASE_WNDOBJ(window);
1072 return TRUE;
1073}
1074//******************************************************************************
1075//******************************************************************************
1076BOOL WIN32API AdjustWindowRect(PRECT rect, DWORD style, BOOL menu)
1077{
1078 return AdjustWindowRectEx(rect, style, menu, 0);
1079}
1080//******************************************************************************
1081//Calculate window rectangle based on given client rectangle, style, menu and extended style
1082//******************************************************************************
1083BOOL WIN32API AdjustWindowRectEx( PRECT rect, DWORD style, BOOL menu, DWORD exStyle)
1084{
1085 if(style == 0 && menu == FALSE && exStyle == 0) {
1086 dprintf(("AdjustWindowRectEx %x %x %d (%d,%d)(%d,%d) -> no change required", style, exStyle, menu, rect->left, rect->top, rect->right, rect->bottom));
1087 return TRUE; //nothing needs to be changed (VERIFIED in NT 4)
1088 }
1089 dprintf(("AdjustWindowRectEx %x %x %d (%d,%d)(%d,%d)\n", style, exStyle, menu, rect->left, rect->top, rect->right, rect->bottom));
1090 /* Correct the window style */
1091 if (!(style & (WS_POPUP | WS_CHILD))) /* Overlapped window */
1092 style |= WS_CAPTION;
1093
1094 //SvL: Include WS_POPUP -> otherwise HAS_THINFRAME is true for popup windows
1095 // Also include WS_CHILD -> otherwise HAS_THICKFRAME doesn't work correctly
1096 style &= (WS_DLGFRAME | WS_BORDER | WS_THICKFRAME | WS_CHILD | WS_VSCROLL | WS_HSCROLL | WS_POPUP);
1097 exStyle &= (WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE | WS_EX_TOOLWINDOW);
1098 if (exStyle & WS_EX_DLGMODALFRAME) style &= ~WS_THICKFRAME;
1099
1100 //Adjust rect outer (Win32BaseWindow::AdjustRectOuter)
1101 if (HAS_THICKFRAME(style,exStyle))
1102 InflateRect( rect, GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME) );
1103 else
1104 if (HAS_DLGFRAME(style,exStyle))
1105 InflateRect(rect, GetSystemMetrics(SM_CXDLGFRAME), GetSystemMetrics(SM_CYDLGFRAME) );
1106 else
1107 if (HAS_THINFRAME(style))
1108 InflateRect( rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
1109
1110 if ((style & WS_CAPTION) == WS_CAPTION)
1111 {
1112 if (exStyle & WS_EX_TOOLWINDOW)
1113 rect->top -= GetSystemMetrics(SM_CYSMCAPTION);
1114 else
1115 rect->top -= GetSystemMetrics(SM_CYCAPTION);
1116 }
1117
1118 if (menu)
1119 rect->top -= GetSystemMetrics(SM_CYMENU);
1120
1121 //Adjust rect inner (Win32BaseWindow::AdjustRectInner)
1122 if(!(style & WS_ICONIC)) {
1123 if (exStyle & WS_EX_CLIENTEDGE)
1124 InflateRect (rect, GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE));
1125
1126 if (exStyle & WS_EX_STATICEDGE)
1127 InflateRect (rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
1128
1129 //SvL: scrollbars aren't checked *UNLESS* the style includes a border (any border)
1130 // --> VERIFIED IN NT4, SP6 (fixes MFC apps with scrollbars + bar controls)
1131 if(style & (WS_THICKFRAME|WS_BORDER|WS_DLGFRAME)) {
1132 if (style & WS_VSCROLL) rect->right += GetSystemMetrics(SM_CXVSCROLL);
1133 if (style & WS_HSCROLL) rect->bottom += GetSystemMetrics(SM_CYHSCROLL);
1134 }
1135 }
1136
1137 dprintf(("AdjustWindowRectEx returned (%d,%d)(%d,%d)\n", rect->left, rect->top, rect->right, rect->bottom));
1138
1139 return TRUE;
1140}
1141//******************************************************************************
1142/* Coordinate Space and Transformation Functions */
1143//******************************************************************************
1144/*******************************************************************
1145 * WINPOS_GetWinOffset
1146 *
1147 * Calculate the offset between the origin of the two windows. Used
1148 * to implement MapWindowPoints.
1149 */
1150static void WINPOS_GetWinOffset( Win32BaseWindow *wndFrom, Win32BaseWindow *wndTo,
1151 POINT *offset )
1152{
1153 Win32BaseWindow *window;
1154
1155 offset->x = offset->y = 0;
1156
1157 /* Translate source window origin to screen coords */
1158 if(wndFrom != windowDesktop)
1159 {
1160 window = wndFrom;
1161 while(window)
1162 {
1163 offset->x += window->getClientRectPtr()->left + window->getWindowRect()->left;
1164 offset->y += window->getClientRectPtr()->top + window->getWindowRect()->top;
1165 window = window->getParent();
1166 }
1167 }
1168
1169 /* Translate origin to destination window coords */
1170 if(wndTo != windowDesktop)
1171 {
1172 window = wndTo;
1173 while(window)
1174 {
1175 offset->x -= window->getClientRectPtr()->left + window->getWindowRect()->left;
1176 offset->y -= window->getClientRectPtr()->top + window->getWindowRect()->top;
1177 window = window->getParent();
1178 }
1179 }
1180}
1181//******************************************************************************
1182//******************************************************************************
1183int WIN32API MapWindowPoints(HWND hwndFrom, HWND hwndTo, LPPOINT lpPoints,
1184 UINT cPoints)
1185{
1186 Win32BaseWindow *wndfrom, *wndto;
1187 int retval = 0;
1188 POINT offset;
1189
1190 SetLastError(0);
1191 if(lpPoints == NULL || cPoints == 0) {
1192 SetLastError(ERROR_INVALID_PARAMETER);
1193 return 0;
1194 }
1195 if(hwndTo == hwndFrom)
1196 return 0; //nothing to do
1197
1198 if(hwndFrom == HWND_DESKTOP)
1199 {
1200 windowDesktop->addRef();
1201 wndfrom = windowDesktop;
1202 }
1203 else {
1204 wndfrom = Win32BaseWindow::GetWindowFromHandle(hwndFrom);
1205 if(!wndfrom) {
1206 dprintf(("MapWindowPoints, window %x not found", hwndFrom));
1207 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
1208 return 0;
1209 }
1210 }
1211
1212 if(hwndTo == HWND_DESKTOP)
1213 {
1214 windowDesktop->addRef();
1215 wndto = windowDesktop;
1216 }
1217 else {
1218 wndto = Win32BaseWindow::GetWindowFromHandle(hwndTo);
1219 if(!wndto) {
1220 dprintf(("MapWindowPoints, window %x not found", hwndTo));
1221 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
1222 return 0;
1223 }
1224 }
1225
1226 dprintf2(("USER32: MapWindowPoints %x to %x (%d,%d) (%d)", hwndFrom, hwndTo, lpPoints->x, lpPoints->y, cPoints));
1227 WINPOS_GetWinOffset(wndfrom, wndto, &offset);
1228
1229 RELEASE_WNDOBJ(wndto);
1230 RELEASE_WNDOBJ(wndfrom);
1231 for(int i=0;i<cPoints;i++)
1232 {
1233 lpPoints[i].x += offset.x;
1234 lpPoints[i].y += offset.y;
1235 }
1236 retval = ((LONG)offset.y << 16) | offset.x;
1237 return retval;
1238}
1239//******************************************************************************
1240//******************************************************************************
1241BOOL WIN32API ScreenToClient(HWND hwnd, LPPOINT pt)
1242{
1243 PRECT rcl;
1244 BOOL rc;
1245
1246 if(hwnd == HWND_DESKTOP) {
1247 return (TRUE); //nothing to do
1248 }
1249 if (!IsWindow(hwnd)) {
1250 dprintf(("warning: ScreenToClient: window %x not found!", hwnd));
1251 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
1252 return FALSE;
1253 }
1254 SetLastError(0);
1255#ifdef DEBUG
1256 POINT tmp = *pt;
1257#endif
1258 MapWindowPoints(0, hwnd, pt, 1);
1259 dprintf2(("ScreenToClient %x (%d,%d) -> (%d,%d)", hwnd, tmp.x, tmp.y, pt->x, pt->y));
1260 return TRUE;
1261}
1262//******************************************************************************
1263//******************************************************************************
1264HWND WIN32API GetDesktopWindow(void)
1265{
1266 HWND hDesktopWindow = windowDesktop->getWindowHandle();
1267 dprintf2(("USER32: GetDesktopWindow, returned %x\n", hDesktopWindow));
1268 return hDesktopWindow;
1269}
1270//******************************************************************************
1271//******************************************************************************
1272HWND WIN32API FindWindowA(LPCSTR lpszClass, LPCSTR lpszWindow)
1273{
1274 return FindWindowExA( NULL, NULL, lpszClass, lpszWindow );
1275}
1276//******************************************************************************
1277//******************************************************************************
1278HWND WIN32API FindWindowW( LPCWSTR lpClassName, LPCWSTR lpWindowName)
1279{
1280 return FindWindowExW( NULL, NULL, lpClassName, lpWindowName );
1281}
1282//******************************************************************************
1283//******************************************************************************
1284HWND WIN32API FindWindowExA(HWND hwndParent, HWND hwndChildAfter, LPCSTR lpszClass, LPCSTR lpszWindow)
1285{
1286 ATOM atom = 0;
1287
1288 if (lpszClass)
1289 {
1290 /* If the atom doesn't exist, then no class */
1291 /* with this name exists either. */
1292 if (!(atom = GlobalFindAtomA( lpszClass )))
1293 {
1294 SetLastError(ERROR_CANNOT_FIND_WND_CLASS);
1295 return 0;
1296 }
1297 }
1298 return Win32BaseWindow::FindWindowEx(hwndParent, hwndChildAfter, atom, (LPSTR)lpszWindow);
1299}
1300/*****************************************************************************
1301 * Name : HWND WIN32API FindWindowExW
1302 * Purpose : The FindWindowEx function retrieves the handle of a window whose
1303 * class name and window name match the specified strings. The
1304 * function searches child windows, beginning with the one following
1305 * the given child window.
1306 * Parameters: HWND hwndParent handle of parent window
1307 * HWND hwndChildAfter handle of a child window
1308 * LPCTSTR lpszClass address of class name
1309 * LPCTSTR lpszWindow address of window name
1310 * Variables :
1311 * Result : If the function succeeds, the return value is the handle of the
1312 * window that has the specified class and window names.
1313 * If the function fails, the return value is NULL. To get extended
1314 * error information, call GetLastError.
1315 * Remark :
1316 *
1317 *****************************************************************************/
1318
1319HWND WIN32API FindWindowExW(HWND hwndParent,
1320 HWND hwndChildAfter,
1321 LPCWSTR lpszClass,
1322 LPCWSTR lpszWindow)
1323{
1324 ATOM atom = 0;
1325 char *buffer;
1326 HWND hwnd;
1327
1328 if (lpszClass)
1329 {
1330 /* If the atom doesn't exist, then no class */
1331 /* with this name exists either. */
1332 if (!(atom = GlobalFindAtomW( lpszClass )))
1333 {
1334 SetLastError(ERROR_CANNOT_FIND_WND_CLASS);
1335 return 0;
1336 }
1337 }
1338 buffer = HEAP_strdupWtoA( GetProcessHeap(), 0, lpszWindow );
1339 hwnd = Win32BaseWindow::FindWindowEx(hwndParent, hwndChildAfter, atom, buffer);
1340 HeapFree( GetProcessHeap(), 0, buffer );
1341 return hwnd;
1342}
1343//******************************************************************************
1344//******************************************************************************
1345BOOL WIN32API FlashWindow(HWND hwnd, BOOL fFlash)
1346{
1347 dprintf(("FlashWindow %x %d\n", hwnd, fFlash));
1348// return OSLibWinFlashWindow(Win32ToOS2Handle(hwnd), fFlash);
1349 return 1;
1350}
1351//******************************************************************************
1352//******************************************************************************
1353BOOL WIN32API MoveWindow( HWND hwnd, INT x, INT y, INT cx, INT cy,
1354 BOOL repaint )
1355{
1356 int flags = SWP_NOZORDER | SWP_NOACTIVATE;
1357
1358 if (!repaint) flags |= SWP_NOREDRAW;
1359 dprintf(("MoveWindow: %x %d,%d %dx%d %d\n", hwnd, x, y, cx, cy, repaint ));
1360
1361 return SetWindowPos( hwnd, 0, x, y, cx, cy, flags );
1362}
1363//******************************************************************************
1364//******************************************************************************
1365BOOL WIN32API ClientToScreen (HWND hwnd, PPOINT pt)
1366{
1367 PRECT rcl;
1368
1369 if(hwnd == HWND_DESKTOP) {
1370 return(TRUE); //nothing to do
1371 }
1372 if(!IsWindow(hwnd)) {
1373 dprintf(("warning: ClientToScreen window %x not found!", hwnd));
1374 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
1375 return (FALSE);
1376 }
1377#ifdef DEBUG
1378 POINT tmp = *pt;
1379#endif
1380 MapWindowPoints(hwnd, 0, pt, 1);
1381 dprintf2(("ClientToScreen %x (%d,%d) -> (%d,%d)", hwnd, tmp.x, tmp.y, pt->x, pt->y));
1382
1383 return TRUE;
1384}
1385//******************************************************************************
1386//Note: count 0 is a legal parameter (verified in NT4)
1387//******************************************************************************
1388HDWP WIN32API BeginDeferWindowPos(int count)
1389{
1390 HDWP handle;
1391 DWP *pDWP;
1392
1393 if (count < 0)
1394 {
1395 dprintf(("USER32: BeginDeferWindowPos invalid param %d", count));
1396 SetLastError(ERROR_INVALID_PARAMETER);
1397 return 0;
1398 }
1399 dprintf(("USER32: BeginDeferWindowPos %d", count));
1400 if(count == 0)
1401 count = 8; // change to any non-zero value
1402
1403 handle = (HDWP)HeapAlloc(GetProcessHeap(), 0, sizeof(DWP) + (count-1)*sizeof(WINDOWPOS));
1404 if (!handle)
1405 return 0;
1406
1407 pDWP = (DWP *) handle;
1408 pDWP->actualCount = 0;
1409 pDWP->suggestedCount = count;
1410 pDWP->valid = TRUE;
1411 pDWP->wMagic = DWP_MAGIC;
1412 pDWP->hwndParent = 0;
1413 return handle;
1414}
1415/***********************************************************************
1416 * DeferWindowPos (USER32.128)
1417 *
1418 * TODO: SvL: Does this need to be thread safe?
1419 *
1420 */
1421HDWP WIN32API DeferWindowPos( HDWP hdwp, HWND hwnd, HWND hwndAfter,
1422 INT x, INT y, INT cx, INT cy,
1423 UINT flags )
1424{
1425 DWP *pDWP;
1426 int i;
1427 HDWP newhdwp = hdwp,retvalue;
1428
1429 pDWP = (DWP *)hdwp;
1430 if (!pDWP) {
1431 SetLastError(ERROR_INVALID_PARAMETER);
1432 return 0;
1433 }
1434
1435 if (hwnd == GetDesktopWindow())
1436 return 0;
1437
1438 if(!IsWindow(hwnd)) {
1439 dprintf(("DeferWindowPos, window %x not found", hwnd));
1440 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
1441 HeapFree(GetProcessHeap(), 0, (LPVOID)hdwp);
1442 return 0;
1443 }
1444
1445 dprintf(("USER32: DeferWindowPos hdwp %x hwnd %x hwndAfter %x (%d,%d)(%d,%d) %x", hdwp, hwnd, hwndAfter,
1446 x, y, cx, cy, flags));
1447
1448/* Numega Bounds Checker Demo dislikes the following code.
1449 In fact, I've not been able to find any "same parent" requirement in any docu
1450 [AM 980509]
1451 */
1452#if 0
1453 /* All the windows of a DeferWindowPos() must have the same parent */
1454 parent = pWnd->parent->hwndSelf;
1455 if (pDWP->actualCount == 0) pDWP->hwndParent = parent;
1456 else if (parent != pDWP->hwndParent)
1457 {
1458 USER_HEAP_FREE( hdwp );
1459 retvalue = 0;
1460 goto END;
1461 }
1462#endif
1463
1464 for (i = 0; i < pDWP->actualCount; i++)
1465 {
1466 if (pDWP->winPos[i].hwnd == hwnd)
1467 {
1468 /* Merge with the other changes */
1469 if (!(flags & SWP_NOZORDER))
1470 {
1471 pDWP->winPos[i].hwndInsertAfter = hwndAfter;
1472 }
1473 if (!(flags & SWP_NOMOVE))
1474 {
1475 pDWP->winPos[i].x = x;
1476 pDWP->winPos[i].y = y;
1477 }
1478 if (!(flags & SWP_NOSIZE))
1479 {
1480 pDWP->winPos[i].cx = cx;
1481 pDWP->winPos[i].cy = cy;
1482 }
1483 pDWP->winPos[i].flags &= flags | ~(SWP_NOSIZE | SWP_NOMOVE |
1484 SWP_NOZORDER | SWP_NOREDRAW |
1485 SWP_NOACTIVATE | SWP_NOCOPYBITS|
1486 SWP_NOOWNERZORDER);
1487 pDWP->winPos[i].flags |= flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW |
1488 SWP_FRAMECHANGED);
1489 retvalue = hdwp;
1490 goto END;
1491 }
1492 }
1493 if (pDWP->actualCount >= pDWP->suggestedCount)
1494 {
1495 //DWP structure already contains WINDOWPOS, allocated with (count-1)
1496 //in BeginDeferWindowPos; pDWP->suggestedCount alloc increases it by one
1497 newhdwp = (HDWP)HeapReAlloc(GetProcessHeap(), 0, (LPVOID)hdwp,
1498 sizeof(DWP) + pDWP->suggestedCount*sizeof(WINDOWPOS));
1499 if (!newhdwp)
1500 {
1501 retvalue = 0;
1502 goto END;
1503 }
1504 pDWP = (DWP *) newhdwp;
1505 pDWP->suggestedCount++;
1506 }
1507 pDWP->winPos[pDWP->actualCount].hwnd = hwnd;
1508 pDWP->winPos[pDWP->actualCount].hwndInsertAfter = hwndAfter;
1509 pDWP->winPos[pDWP->actualCount].x = x;
1510 pDWP->winPos[pDWP->actualCount].y = y;
1511 pDWP->winPos[pDWP->actualCount].cx = cx;
1512 pDWP->winPos[pDWP->actualCount].cy = cy;
1513 pDWP->winPos[pDWP->actualCount].flags = flags;
1514 pDWP->actualCount++;
1515 retvalue = newhdwp;
1516END:
1517 return retvalue;
1518}
1519//******************************************************************************
1520//******************************************************************************
1521BOOL WIN32API EndDeferWindowPos( HDWP hdwp)
1522{
1523 DWP *pDWP;
1524 WINDOWPOS *winpos;
1525 BOOL res = TRUE;
1526 int i;
1527
1528 pDWP = (DWP *) hdwp;
1529 if (!pDWP) {
1530 dprintf(("**EndDeferWindowPos invalid parameter\n"));
1531 SetLastError(ERROR_INVALID_PARAMETER);
1532 return FALSE;
1533 }
1534 dprintf(("**EndDeferWindowPos for %d windows", pDWP->actualCount));
1535 for (i = 0, winpos = pDWP->winPos; i < pDWP->actualCount; i++, winpos++)
1536 {
1537 dprintf(("**EndDeferWindowPos %x (%d,%d) (%d,%d) %x", winpos->hwnd, winpos->x, winpos->y, winpos->cx, winpos->cy, winpos->flags));
1538 if (!(res = SetWindowPos(winpos->hwnd, winpos->hwndInsertAfter,
1539 winpos->x, winpos->y, winpos->cx,
1540 winpos->cy, winpos->flags )))
1541 break;
1542 }
1543 dprintf(("**EndDeferWindowPos DONE"));
1544 HeapFree(GetProcessHeap(), 0, (LPVOID)hdwp);
1545 return res;
1546}
1547//******************************************************************************
1548//******************************************************************************
1549HWND WIN32API ChildWindowFromPoint( HWND hwnd, POINT pt)
1550{
1551 dprintf(("USER32: ChildWindowFromPoint\n"));
1552 return ChildWindowFromPointEx(hwnd, pt, 0);
1553}
1554/*****************************************************************************
1555 * Name : HWND WIN32API ChildWindowFromPointEx
1556 * Purpose : pt: client coordinates
1557 * Parameters:
1558 * Variables :
1559 * Result : If the function succeeds, the return value is the window handle.
1560 * If the function fails, the return value is zero
1561 * Remark :
1562 * Status : COMPLETELY IMPLEMENTED AND TESTED
1563 *
1564 * Author : Rene Pronk [Sun, 1999/08/08 23:30]
1565 *****************************************************************************/
1566HWND WIN32API ChildWindowFromPointEx (HWND hwndParent, POINT pt, UINT uFlags)
1567{
1568 RECT rect;
1569 HWND hWnd;
1570
1571 dprintf(("ChildWindowFromPointEx(%08xh,%08xh,%08xh).\n",
1572 hwndParent, pt, uFlags));
1573
1574 if (GetWindowRect (hwndParent, &rect) == 0) {
1575 // oops, invalid handle
1576 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
1577 return NULL;
1578 }
1579
1580 ClientToScreen(hwndParent, &pt);
1581 if (PtInRect (&rect, pt) == 0) {
1582 // point is outside window
1583 return NULL;
1584 }
1585
1586 // get first child
1587 hWnd = GetWindow (hwndParent, GW_CHILD);
1588
1589 while (hWnd != NULL)
1590 {
1591 // do I need to skip this window?
1592 if (((uFlags & CWP_SKIPINVISIBLE) &&
1593 (IsWindowVisible (hWnd) == FALSE)) ||
1594 ((uFlags & CWP_SKIPDISABLED) &&
1595 (IsWindowEnabled (hWnd) == FALSE)) ||
1596 ((uFlags & CWP_SKIPTRANSPARENT) &&
1597 (GetWindowLongA (hWnd, GWL_EXSTYLE) & WS_EX_TRANSPARENT)))
1598 {
1599 hWnd = GetWindow (hWnd, GW_HWNDNEXT);
1600 continue;
1601 }
1602
1603 // is the point in this window's rect?
1604 GetWindowRect (hWnd, &rect);
1605 if (PtInRect (&rect,pt) == FALSE) {
1606 hWnd = GetWindow (hWnd, GW_HWNDNEXT);
1607 continue;
1608 }
1609
1610 dprintf(("ChildWindowFromPointEx returned %x", hWnd));
1611 // found it!
1612 return hWnd;
1613 }
1614 // the point is in the parentwindow but the parentwindow has no child
1615 // at this coordinate
1616 dprintf(("ChildWindowFromPointEx returned parent %x", hwndParent));
1617 return hwndParent;
1618}
1619//******************************************************************************
1620//******************************************************************************
1621BOOL WIN32API CloseWindow(HWND hwnd)
1622{
1623 Win32BaseWindow *window;
1624
1625 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
1626 if(!window) {
1627 dprintf(("CloseWindow, window %x not found", hwnd));
1628 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
1629 return 0;
1630 }
1631 dprintf(("CloseWindow %x\n", hwnd));
1632 BOOL ret = window->CloseWindow();
1633 RELEASE_WNDOBJ(window);
1634 return ret;
1635}
1636//******************************************************************************
1637//******************************************************************************
1638static BOOL IsPointInWindow(HWND hwnd, POINT point)
1639{
1640 RECT rectWindow;
1641 DWORD hittest, dwStyle, dwExStyle;
1642
1643 dwStyle = GetWindowLongA(hwnd, GWL_STYLE);
1644 dwExStyle = GetWindowLongA(hwnd, GWL_EXSTYLE);
1645
1646 GetWindowRect(hwnd, &rectWindow);
1647
1648 /* If point is in window, and window is visible, and it */
1649 /* is enabled (or it's a top-level window), then explore */
1650 /* its children. Otherwise, go to the next window. */
1651
1652 if( (dwStyle & WS_VISIBLE) &&
1653 ((dwExStyle & (WS_EX_LAYERED | WS_EX_TRANSPARENT)) != (WS_EX_LAYERED | WS_EX_TRANSPARENT)) &&
1654 (!(dwStyle & WS_DISABLED) || ((dwStyle & (WS_POPUP | WS_CHILD)) != WS_CHILD)) &&
1655 ((point.x >= rectWindow.left) && (point.x < rectWindow.right) &&
1656 (point.y >= rectWindow.top) && (point.y < rectWindow.bottom))
1657#if 1
1658 )
1659#else
1660 &&
1661 (wndPtr->hrgnWnd ? PtInRegion(wndPtr->hrgnWnd, 1))
1662#endif
1663 {
1664 DWORD dwThreadId = GetCurrentThreadId();
1665
1666 //Don't send WM_NCHITTEST if this window doesn't belong to the current thread
1667 if(dwThreadId != GetWindowThreadProcessId(hwnd, NULL))
1668 {
1669 return TRUE;
1670 }
1671 hittest = SendMessageA(hwnd, WM_NCHITTEST, 0, MAKELONG(point.x, point.y));
1672 if(hittest != HTTRANSPARENT) {
1673 return TRUE;
1674 }
1675 }
1676 return FALSE;
1677}
1678//******************************************************************************
1679//TODO: Does this return handles of hidden or disabled windows?
1680//******************************************************************************
1681HWND WIN32API WindowFromPoint( POINT point)
1682{
1683 HWND hwndOS2, hwnd;
1684 POINT wPoint;
1685
1686 wPoint.x = point.x;
1687 wPoint.y = mapScreenY(point.y);
1688
1689 hwndOS2 = OSLibWinWindowFromPoint(OSLIB_HWND_DESKTOP, (PVOID)&wPoint);
1690 if(hwndOS2)
1691 {
1692 hwnd = OS2ToWin32Handle(hwndOS2);
1693 while(hwnd)
1694 {
1695 if(IsPointInWindow(hwnd, point)) {
1696 dprintf(("WindowFromPoint (%d,%d) %x->%x\n", point.x, point.y, hwndOS2, hwnd));
1697 return hwnd;
1698 }
1699#if 0
1700//TODO: breaks a lot of things
1701 hwnd = GetWindow(hwnd, GW_HWNDNEXT);
1702#else
1703 //try siblings
1704 HWND hwndSibling;
1705 HWND hwndParent = GetParent(hwnd);
1706
1707 if(hwndParent) {
1708 hwndSibling = GetWindow(hwndParent, GW_CHILD);
1709 while(hwndSibling) {
1710 if(hwndSibling != hwnd) {
1711 if(IsPointInWindow(hwndSibling, point)) {
1712 dprintf(("WindowFromPoint (%d,%d) %x->%x\n", point.x, point.y, hwndOS2, hwndSibling));
1713 return hwndSibling;
1714 }
1715 }
1716 hwndSibling = GetWindow(hwndSibling, GW_HWNDNEXT);
1717 }
1718 }
1719 hwnd = hwndParent;
1720#endif
1721 }
1722 }
1723 dprintf(("WindowFromPoint (%d,%d) %x->1\n", point.x, point.y, hwndOS2));
1724 return windowDesktop->getWindowHandle();
1725}
1726//******************************************************************************
1727//******************************************************************************
1728BOOL WIN32API IsWindowUnicode(HWND hwnd)
1729{
1730 Win32BaseWindow *window;
1731
1732 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
1733 if(!window) {
1734 dprintf(("IsWindowUnicode, window %x not found", hwnd));
1735 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
1736 return 0;
1737 }
1738 BOOL ret = window->IsWindowUnicode();
1739 RELEASE_WNDOBJ(window);
1740 return ret;
1741}
1742/***********************************************************************
1743 * SwitchToThisWindow (USER32.539)
1744 */
1745VOID WINAPI SwitchToThisWindow( HWND hwnd, BOOL restore )
1746{
1747 ShowWindow( hwnd, restore ? SW_RESTORE : SW_SHOWMINIMIZED );
1748}
1749//******************************************************************************
1750//******************************************************************************
1751BOOL WIN32API EnumThreadWindows(DWORD dwThreadId, WNDENUMPROC lpfn, LPARAM lParam)
1752{
1753 return windowDesktop->EnumThreadWindows(dwThreadId, lpfn, lParam);
1754}
1755//******************************************************************************
1756//******************************************************************************
1757BOOL WIN32API EnumChildWindows(HWND hwnd, WNDENUMPROC lpfn, LPARAM lParam)
1758{
1759 Win32BaseWindow *window;
1760 BOOL ret = TRUE;
1761 ULONG henum;
1762 HWND hwndNext;
1763
1764 if(lpfn == NULL) {
1765 dprintf(("EnumChildWindows invalid parameter %x %x\n", hwnd, lParam));
1766 SetLastError(ERROR_INVALID_PARAMETER);
1767 return FALSE;
1768 }
1769 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
1770 if(!window) {
1771 dprintf(("EnumChildWindows, window %x not found", hwnd));
1772 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
1773 return FALSE;
1774 }
1775 ret = window->EnumChildWindows(lpfn, lParam);
1776 RELEASE_WNDOBJ(window);
1777 return ret;
1778}
1779//******************************************************************************
1780//******************************************************************************
1781BOOL WIN32API EnumWindows(WNDENUMPROC lpfn, LPARAM lParam)
1782{
1783 return windowDesktop->EnumWindows(lpfn, lParam);
1784}
1785//******************************************************************************
1786//******************************************************************************
1787UINT WIN32API ArrangeIconicWindows( HWND parent)
1788{
1789 RECT rectParent;
1790 HWND hwndChild;
1791 INT x, y, xspacing, yspacing;
1792
1793 dprintf(("USER32: ArrangeIconicWindows %x", parent));
1794 dprintf(("USER32: TODO: icon title!!"));
1795
1796 GetClientRect(parent, &rectParent);
1797 x = rectParent.left;
1798 y = rectParent.bottom;
1799 xspacing = GetSystemMetrics(SM_CXICONSPACING);
1800 yspacing = GetSystemMetrics(SM_CYICONSPACING);
1801
1802 hwndChild = GetWindow( parent, GW_CHILD );
1803 while (hwndChild)
1804 {
1805 if( IsIconic( hwndChild ) )
1806 {
1807// WND *wndPtr = WIN_FindWndPtr(hwndChild);
1808
1809// WINPOS_ShowIconTitle( wndPtr, FALSE );
1810
1811 SetWindowPos( hwndChild, 0, x + (xspacing - GetSystemMetrics(SM_CXICON)) / 2,
1812 y - yspacing - GetSystemMetrics(SM_CYICON)/2, 0, 0,
1813 SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
1814// if( IsWindow(hwndChild) )
1815// WINPOS_ShowIconTitle(wndPtr , TRUE );
1816// WIN_ReleaseWndPtr(wndPtr);
1817
1818 if (x <= rectParent.right - xspacing) x += xspacing;
1819 else
1820 {
1821 x = rectParent.left;
1822 y -= yspacing;
1823 }
1824 }
1825 hwndChild = GetWindow( hwndChild, GW_HWNDNEXT );
1826 }
1827 return yspacing;
1828}
1829//******************************************************************************
1830//restores iconized window to previous size/position
1831//******************************************************************************
1832BOOL WIN32API OpenIcon(HWND hwnd)
1833{
1834 dprintf(("USER32: OpenIcon %x", hwnd));
1835
1836 if(!IsIconic(hwnd))
1837 return FALSE;
1838 ShowWindow(hwnd, SW_SHOWNORMAL);
1839 return TRUE;
1840}
1841//******************************************************************************
1842//SDK: Windows can only be shown with ShowOwnedPopups if they were previously
1843// hidden with the same api
1844//TODO: -> needs testing
1845//******************************************************************************
1846BOOL WIN32API ShowOwnedPopups(HWND hwndOwner, BOOL fShow)
1847{
1848 Win32BaseWindow *window, *owner;
1849 HWND hwnd;
1850
1851 owner = Win32BaseWindow::GetWindowFromHandle(hwndOwner);
1852 if(!owner) {
1853 dprintf(("ShowOwnedPopups, window %x not found", hwndOwner));
1854 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
1855 return FALSE;
1856 }
1857 dprintf(("USER32: ShowOwnedPopups %x %d", hwndOwner, fShow));
1858
1859 hwnd = GetWindow(GetDesktopWindow(), GW_CHILD);
1860 while(hwnd) {
1861 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
1862 if(window) {
1863 if(window == owner && (window->getStyle() & WS_POPUP))
1864 {
1865 if(fShow) {
1866 if(window->getFlags() & WIN_NEEDS_SHOW_OWNEDPOPUP)
1867 {
1868 /*
1869 * In Windows, ShowOwnedPopups(TRUE) generates WM_SHOWWINDOW messages with SW_PARENTOPENING,
1870 * regardless of the state of the owner
1871 */
1872 SendMessageA(hwnd, WM_SHOWWINDOW, SW_SHOW, SW_PARENTOPENING);
1873 window->setFlags(window->getFlags() & ~WIN_NEEDS_SHOW_OWNEDPOPUP);
1874 }
1875 }
1876 else
1877 {
1878 if(IsWindowVisible(hwnd))
1879 {
1880 /*
1881 * In Windows, ShowOwnedPopups(FALSE) generates WM_SHOWWINDOW messages with SW_PARENTCLOSING,
1882 * regardless of the state of the owner
1883 */
1884 SendMessageA(hwnd, WM_SHOWWINDOW, SW_HIDE, SW_PARENTCLOSING);
1885 window->setFlags(window->getFlags() | WIN_NEEDS_SHOW_OWNEDPOPUP);
1886 }
1887 }
1888 }
1889 RELEASE_WNDOBJ(window);
1890 }
1891 else dprintf(("WARNING: window %x is not valid", hwnd));
1892
1893 hwnd = GetWindow(hwnd, GW_HWNDNEXT);
1894 }
1895 RELEASE_WNDOBJ(owner);
1896 return TRUE;
1897}
1898//******************************************************************************
1899//******************************************************************************
1900HWND WIN32API GetForegroundWindow()
1901{
1902 HWND hwnd;
1903
1904 hwnd = OS2ToWin32Handle(OSLibWinQueryActiveWindow());
1905 return hwnd;
1906}
1907//******************************************************************************
1908
1909/******************************************************************************
1910 * The return value identifies the most recently active pop-up window.
1911 * The return value is the same as the hWnd parameter, if any of the
1912 * following conditions are met:
1913 *
1914 * - The window identified by hWnd was most recently active.
1915 * - The window identified by hWnd does not own any pop-up windows.
1916 * - The window identified by hWnd is not a top-level window or it is
1917 * owned by another window.
1918 */
1919HWND WIN32API GetLastActivePopup(HWND hWnd)
1920{
1921 Win32BaseWindow *owner;
1922
1923 owner = Win32BaseWindow::GetWindowFromHandle(hWnd);
1924 if(!owner)
1925 {
1926 dprintf(("GetLastActivePopup, window %x not found", hWnd));
1927 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
1928 return hWnd;
1929 }
1930
1931 HWND hwndRetVal = owner->getLastActive();
1932 if (!IsWindow( hwndRetVal ))
1933 hwndRetVal = owner->getWindowHandle();
1934
1935 RELEASE_WNDOBJ(owner);
1936
1937 return hwndRetVal;
1938}
1939//******************************************************************************
1940//******************************************************************************
1941DWORD WIN32API GetWindowThreadProcessId(HWND hwnd, PDWORD lpdwProcessId)
1942{
1943 Win32BaseWindow *window;
1944 DWORD dwThreadId;
1945
1946 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
1947 if(!window) {
1948 dprintf(("GetWindowThreadProcessId, window %x not found", hwnd));
1949 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
1950 return 0;
1951 }
1952 dwThreadId = window->getThreadId();
1953 if(lpdwProcessId) {
1954 *lpdwProcessId = window->getProcessId();
1955 }
1956 RELEASE_WNDOBJ(window);
1957
1958 return dwThreadId;
1959}
1960//******************************************************************************
1961//******************************************************************************
1962DWORD WIN32API GetWindowContextHelpId(HWND hwnd)
1963{
1964 Win32BaseWindow *window;
1965
1966 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
1967 if(!window) {
1968 dprintf(("GetWindowContextHelpId, window %x not found", hwnd));
1969 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
1970 return 0;
1971 }
1972 dprintf(("GetWindowContextHelpId %x", hwnd));
1973 DWORD ret = window->getWindowContextHelpId();
1974 RELEASE_WNDOBJ(window);
1975 return ret;
1976}
1977//******************************************************************************
1978//******************************************************************************
1979BOOL WIN32API SetWindowContextHelpId(HWND hwnd, DWORD dwContextHelpId)
1980{
1981 Win32BaseWindow *window;
1982
1983 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
1984 if(!window) {
1985 dprintf(("SetWindowContextHelpId, window %x not found", hwnd));
1986 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
1987 return 0;
1988 }
1989 dprintf(("SetWindowContextHelpId %x %d", hwnd, dwContextHelpId));
1990 window->setWindowContextHelpId(dwContextHelpId);
1991 RELEASE_WNDOBJ(window);
1992 return(TRUE);
1993}
1994//******************************************************************************
1995//******************************************************************************
1996HANDLE WIN32API GetPropA(HWND hwnd, LPCSTR str )
1997{
1998 Win32BaseWindow *window;
1999
2000 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
2001 if(!window) {
2002 dprintf(("GetPropA, window %x not found", hwnd));
2003 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
2004 return 0;
2005 }
2006 HANDLE ret = window->getProp(str);
2007 RELEASE_WNDOBJ(window);
2008 return ret;
2009}
2010//******************************************************************************
2011//******************************************************************************
2012HANDLE WIN32API GetPropW(HWND hwnd, LPCWSTR str)
2013{
2014 Win32BaseWindow *window;
2015 LPSTR strA;
2016 HANDLE ret;
2017
2018 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
2019 if(!window) {
2020 dprintf(("GetPropW, window %x not found", hwnd));
2021 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
2022 return 0;
2023 }
2024
2025 if(HIWORD(str)) {
2026 strA = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
2027 }
2028 else strA = (LPSTR)str;
2029
2030 ret = window->getProp(strA);
2031
2032 RELEASE_WNDOBJ(window);
2033 if(HIWORD(str)) HeapFree( GetProcessHeap(), 0, strA );
2034 return ret;
2035}
2036//******************************************************************************
2037//******************************************************************************
2038BOOL WIN32API SetPropA(HWND hwnd, LPCSTR str, HANDLE handle )
2039{
2040 Win32BaseWindow *window;
2041
2042 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
2043 if(!window) {
2044 dprintf(("SetPropA, window %x not found", hwnd));
2045 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
2046 return FALSE;
2047 }
2048 BOOL ret = window->setProp(str, handle);
2049 RELEASE_WNDOBJ(window);
2050 return ret;
2051}
2052//******************************************************************************
2053//******************************************************************************
2054BOOL SetPropW(HWND hwnd, LPCWSTR str, HANDLE handle )
2055{
2056 BOOL ret;
2057 LPSTR strA;
2058
2059 if (!HIWORD(str))
2060 return SetPropA( hwnd, (LPCSTR)(UINT)LOWORD(str), handle );
2061 strA = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
2062 ret = SetPropA( hwnd, strA, handle );
2063 HeapFree( GetProcessHeap(), 0, strA );
2064 return ret;
2065}
2066//******************************************************************************
2067//******************************************************************************
2068HANDLE WIN32API RemovePropA(HWND hwnd, LPCSTR str)
2069{
2070 Win32BaseWindow *window;
2071
2072 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
2073 if(!window) {
2074 dprintf(("RemovePropA, window %x not found", hwnd));
2075 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
2076 return 0;
2077 }
2078 HANDLE ret = window->removeProp(str);
2079 RELEASE_WNDOBJ(window);
2080 return ret;
2081}
2082//******************************************************************************
2083//******************************************************************************
2084HANDLE WIN32API RemovePropW(HWND hwnd, LPCWSTR str)
2085{
2086 LPSTR strA;
2087 HANDLE ret;
2088
2089 if (!HIWORD(str))
2090 return RemovePropA( hwnd, (LPCSTR)(UINT)LOWORD(str) );
2091 strA = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
2092 ret = RemovePropA( hwnd, strA );
2093 HeapFree( GetProcessHeap(), 0, strA );
2094 return ret;
2095}
2096//******************************************************************************
2097//******************************************************************************
2098INT WIN32API EnumPropsA(HWND hwnd, PROPENUMPROCA func )
2099{
2100 return EnumPropsExA( hwnd, (PROPENUMPROCEXA)func, 0 );
2101}
2102//******************************************************************************
2103//******************************************************************************
2104INT WIN32API EnumPropsW(HWND hwnd, PROPENUMPROCW func )
2105{
2106 return EnumPropsExW( hwnd, (PROPENUMPROCEXW)func, 0 );
2107}
2108//******************************************************************************
2109//******************************************************************************
2110INT WIN32API EnumPropsExA(HWND hwnd, PROPENUMPROCEXA func, LPARAM lParam)
2111{
2112 Win32BaseWindow *window;
2113
2114 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
2115 if(!window) {
2116 dprintf(("EnumPropsExA, window %x not found", hwnd));
2117 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
2118 return -1;
2119 }
2120 INT ret = window->enumPropsExA(func, lParam);
2121 RELEASE_WNDOBJ(window);
2122 return ret;
2123}
2124//******************************************************************************
2125//******************************************************************************
2126INT WIN32API EnumPropsExW(HWND hwnd, PROPENUMPROCEXW func, LPARAM lParam)
2127{
2128 Win32BaseWindow *window;
2129
2130 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
2131 if(!window) {
2132 dprintf(("EnumPropsExA, window %x not found", hwnd));
2133 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
2134 return -1;
2135 }
2136 INT ret = window->enumPropsExW(func, lParam);
2137 RELEASE_WNDOBJ(window);
2138 return ret;
2139}
2140//******************************************************************************
2141//******************************************************************************
2142
2143
2144/*****************************************************************************
2145 * Name : BOOL WIN32API AnyPopup
2146 * Purpose : The AnyPopup function indicates whether an owned, visible,
2147 * top-level pop-up, or overlapped window exists on the screen. The
2148 * function searches the entire Windows screen, not just the calling
2149 * application's client area.
2150 * Parameters: VOID
2151 * Variables :
2152 * Result : If a pop-up window exists, the return value is TRUE even if the
2153 * pop-up window is completely covered by other windows. Otherwise,
2154 * it is FALSE.
2155 * Remark : AnyPopup is a Windows version 1.x function and is retained for
2156 * compatibility purposes. It is generally not useful.
2157 * Status : UNTESTED STUB
2158 *
2159 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
2160 *****************************************************************************/
2161BOOL WIN32API AnyPopup()
2162{
2163 dprintf(("USER32:AnyPopup() not implemented.\n"));
2164
2165 return (FALSE);
2166}
Note: See TracBrowser for help on using the repository browser.