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

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

PF: ShowWindow(SW_RESTORE) should start the same PM restoration routine as WM_SYSCOMMAND

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